mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-06-14 20:42:28 -04:00
Merge master
This commit is contained in:
commit
b897b2176d
3
.github/workflows/sdrangel.yml
vendored
3
.github/workflows/sdrangel.yml
vendored
@ -41,6 +41,9 @@ jobs:
|
||||
echo github.event_name: ${{ github.event_name }}
|
||||
echo github.ref: ${{ github.ref }}
|
||||
echo github.workspace: ${{ github.workspace }}
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install basic dependencies on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
|
5
.github/workflows/windows.yml
vendored
5
.github/workflows/windows.yml
vendored
@ -37,6 +37,9 @@ jobs:
|
||||
echo github.event_name: ${{ github.event_name }}
|
||||
echo github.ref: ${{ github.ref }}
|
||||
echo github.workspace: ${{ github.workspace }}
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install basic dependencies on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
@ -70,7 +73,7 @@ jobs:
|
||||
version: '6.7.3'
|
||||
dir: ${{matrix.config.QT_INST_DIR}}
|
||||
arch: ${{matrix.config.QT_ARCH}}
|
||||
setup-python: false
|
||||
setup-python: 'false'
|
||||
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
|
||||
- name: build sdrangel on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
|
@ -1,3 +1,9 @@
|
||||
sdrangel (7.22.7-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
|
||||
|
||||
sdrangel (7.22.6-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
@ -20,7 +20,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# configure version
|
||||
set(sdrangel_VERSION_MAJOR "7")
|
||||
set(sdrangel_VERSION_MINOR "22")
|
||||
set(sdrangel_VERSION_PATCH "6")
|
||||
set(sdrangel_VERSION_PATCH "7")
|
||||
set(sdrangel_VERSION_SUFFIX "")
|
||||
|
||||
# SDRAngel cmake options
|
||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
sdrangel (7.22.7-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
|
||||
|
||||
sdrangel (7.22.6-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
3
external/CMakeLists.txt
vendored
3
external/CMakeLists.txt
vendored
@ -11,7 +11,7 @@
|
||||
set(CODEC2_TAG "v1.0.3")
|
||||
set(CM256CC_TAG c0e92b92aca3d1d36c990b642b937c64d363c559)
|
||||
set(MBELIB_TAG fe83b32c6a60cdd7bce8cecf3c7a0b9ec87a7667)
|
||||
set(SERIALDV_TAG "v1.1.4")
|
||||
set(SERIALDV_TAG "v1.1.5")
|
||||
set(DSDCC_TAG "v1.9.5")
|
||||
set(LIMESUITE_TAG b39cb61ed03d74c35a2de757d495e901acbb6404)
|
||||
set(BLADERF_TAG "2021.02")
|
||||
@ -54,6 +54,7 @@ if (WIN32)
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
)
|
||||
elseif (LINUX)
|
||||
set(COMMON_CMAKE_ARGS
|
||||
|
@ -82,7 +82,7 @@ std::string Packing::unpackcall(int x)
|
||||
|
||||
if (x <= 1002)
|
||||
{
|
||||
sprintf(tmp, "CQ %d", x - 3);
|
||||
snprintf(tmp, sizeof(tmp), "CQ %d", x - 3);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ std::string Packing::unpackcall(int x)
|
||||
int ci3 = x / 27;
|
||||
x %= 27;
|
||||
int ci4 = x;
|
||||
sprintf(tmp, "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
|
||||
snprintf(tmp, sizeof(tmp), "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
@ -193,9 +193,9 @@ std::string Packing::unpackgrid15(int ng, int ir)
|
||||
char tmp[16];
|
||||
|
||||
if (db >= 0) {
|
||||
sprintf(tmp, "%s+%02d", ir ? "R" : "", db);
|
||||
snprintf(tmp, sizeof(tmp), "%s+%02d", ir ? "R" : "", db);
|
||||
} else {
|
||||
sprintf(tmp, "%s-%02d", ir ? "R" : "", 0 - db);
|
||||
snprintf(tmp, sizeof(tmp), "%s-%02d", ir ? "R" : "", 0 - db);
|
||||
}
|
||||
|
||||
return std::string(tmp);
|
||||
@ -396,7 +396,7 @@ std::string Packing::unpack_5(int a77[], std::string& call1str, std::string& cal
|
||||
i += 3;
|
||||
int qsonb = un64(a77, i, 11);
|
||||
char report[16];
|
||||
sprintf(report, "%d%04d", rst, qsonb);
|
||||
snprintf(report, sizeof(report), "%d%04d", rst, qsonb);
|
||||
i += 11;
|
||||
// g25
|
||||
int ng = un64(a77, i, 25);
|
||||
@ -467,9 +467,9 @@ std::string Packing::unpack_0_1(int a77[], std::string& call1str, std::string& c
|
||||
char tmp[32];
|
||||
|
||||
if (r >= 0) {
|
||||
sprintf(tmp, "+%02d", r);
|
||||
snprintf(tmp, sizeof(tmp), "+%02d", r);
|
||||
} else {
|
||||
sprintf(tmp, "-%02d", -r);
|
||||
snprintf(tmp, sizeof(tmp), "-%02d", -r);
|
||||
}
|
||||
|
||||
locstr = std::string(tmp);
|
||||
@ -553,7 +553,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
|
||||
else
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%04d", serial);
|
||||
snprintf(tmp, sizeof(tmp), "%04d", serial);
|
||||
serialstr = std::string(tmp);
|
||||
}
|
||||
|
||||
@ -571,7 +571,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
|
||||
}
|
||||
{
|
||||
char tmp[16];
|
||||
sprintf(tmp, "%d ", rst);
|
||||
snprintf(tmp, sizeof(tmp), "%d ", rst);
|
||||
msg += std::string(tmp);
|
||||
}
|
||||
|
||||
@ -634,7 +634,7 @@ std::string Packing::unpack_0_3(int a77[], int n3, std::string& call1str, std::s
|
||||
|
||||
{
|
||||
char tmp[16];
|
||||
sprintf(tmp, "%d%c ", n_transmitters + 1, clss + 'A');
|
||||
snprintf(tmp, sizeof(tmp), "%d%c ", n_transmitters + 1, clss + 'A');
|
||||
msg += std::string(tmp);
|
||||
}
|
||||
|
||||
@ -658,9 +658,9 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
|
||||
char tmp[64];
|
||||
|
||||
if (i3 == 0) {
|
||||
sprintf(tmp, "%d.%d", i3, n3);
|
||||
snprintf(tmp, sizeof(tmp), "%d.%d", i3, n3);
|
||||
} else {
|
||||
sprintf(tmp, "%d", i3);
|
||||
snprintf(tmp, sizeof(tmp), "%d", i3);
|
||||
}
|
||||
|
||||
type = std::string(tmp);
|
||||
@ -714,7 +714,7 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
|
||||
}
|
||||
|
||||
call1 = "UNK";
|
||||
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
|
||||
snprintf(tmp, sizeof(tmp), "UNK i3=%d n3=%d", i3, n3);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,5 @@ for plugin in $PLUGINS
|
||||
do
|
||||
FILE=$(find $BASEDIR/plugins/$plugin -name "*plugin.cpp")
|
||||
echo $FILE
|
||||
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.6\"\)/" $FILE
|
||||
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.7\"\)/" $FILE
|
||||
done
|
||||
|
||||
|
@ -211,6 +211,26 @@ else()
|
||||
message(STATUS "Not building wdsprx (ENABLE_CHANNELRX_WDSPRX=${ENABLE_CHANNELRX_WDSPRX} WDSP_SUPPORT=${WDSP_SUPPORT})")
|
||||
endif()
|
||||
|
||||
# need ffmpeg 3.1 that correstonds to
|
||||
# libavutil 55.27.100
|
||||
# libavcodec 57.48.101
|
||||
# libavformat 57.40.101
|
||||
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
|
||||
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
|
||||
if(WIN32)
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
|
||||
message(STATUS "Include demoddatv")
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
|
||||
endif()
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
if (ENABLE_CHANNELRX_HEATMAP)
|
||||
@ -230,25 +250,4 @@ if(NOT SERVER_MODE)
|
||||
else()
|
||||
message(STATUS "Not building demodatv (ENABLE_CHANNELRX_DEMODATV=${ENABLE_CHANNELRX_DEMODATV})")
|
||||
endif()
|
||||
|
||||
# need ffmpeg 3.1 that correstonds to
|
||||
# libavutil 55.27.100
|
||||
# libavcodec 57.48.101
|
||||
# libavformat 57.40.101
|
||||
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
|
||||
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
|
||||
if(WIN32)
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
|
||||
message(STATUS "Include demoddatv")
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -3,17 +3,14 @@ project(datv)
|
||||
|
||||
set(datv_SOURCES
|
||||
datvdemod.cpp
|
||||
datvdemodgui.cpp
|
||||
datvdemodplugin.cpp
|
||||
datvdemodsettings.cpp
|
||||
datvdemodwebapiadapter.cpp
|
||||
datvideostream.cpp
|
||||
datvudpstream.cpp
|
||||
datvideorender.cpp
|
||||
datvdemodreport.cpp
|
||||
datvdemodsink.cpp
|
||||
datvdemodbaseband.cpp
|
||||
datvdvbs2ldpcdialog.cpp
|
||||
leansdr/dvb.cpp
|
||||
leansdr/filtergen.cpp
|
||||
leansdr/framework.cpp
|
||||
@ -30,19 +27,14 @@ set(ldpc_SOURCES
|
||||
|
||||
set(datv_HEADERS
|
||||
datvdemod.h
|
||||
datvdemodgui.h
|
||||
datvdemodplugin.h
|
||||
datvdemodsettings.h
|
||||
datvdemodwebapiadapter.h
|
||||
datvideostream.h
|
||||
datvudpstream.h
|
||||
datvideorender.h
|
||||
datvconstellation.h
|
||||
datvdvbs2constellation.h
|
||||
datvdemodreport.h
|
||||
datvdemodsink.h
|
||||
datvdemodbaseband.h
|
||||
datvdvbs2ldpcdialog.h
|
||||
leansdr/dvb.h
|
||||
leansdr/dvbs2.h
|
||||
leansdr/filtergen.h
|
||||
@ -59,6 +51,33 @@ set(ldpc_HEADERS
|
||||
ldpctool/ldpcworker.h
|
||||
)
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
set(datv_SOURCES
|
||||
${datv_SOURCES}
|
||||
datvdemodgui.ui
|
||||
datvdvbs2ldpcdialog.ui
|
||||
datvdemodgui.cpp
|
||||
datvdvbs2ldpcdialog.cpp
|
||||
datvideorender.cpp
|
||||
)
|
||||
set(datv_HEADERS ${datv_HEADERS}
|
||||
datvdemodgui.h
|
||||
datvdvbs2ldpcdialog.h
|
||||
datvconstellation.h
|
||||
datvdvbs2constellation.h
|
||||
datvideorender.h
|
||||
)
|
||||
set(TARGET_NAME ${PLUGINS_PREFIX}demoddatv)
|
||||
set(TARGET_LIB Qt::Widgets Qt::Multimedia Qt::MultimediaWidgets)
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
else()
|
||||
set(TARGET_NAME ${PLUGINSSRV_PREFIX}demoddatvsrv)
|
||||
set(TARGET_LIB "")
|
||||
set(TARGET_LIB_GUI "")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${AVCODEC_INCLUDE_DIRS}
|
||||
${AVFORMAT_INCLUDE_DIRS}
|
||||
@ -68,10 +87,6 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
)
|
||||
|
||||
set(TARGET_NAME ${PLUGINS_PREFIX}demoddatv)
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
|
||||
|
||||
if(NOT Qt6_FOUND)
|
||||
add_library(${TARGET_NAME} ${datv_SOURCES} ${ldpc_SOURCES})
|
||||
else()
|
||||
@ -84,11 +99,9 @@ endif()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||
Qt::Core
|
||||
Qt::Widgets
|
||||
Qt::Multimedia
|
||||
Qt::MultimediaWidgets
|
||||
${TARGET_LIB}
|
||||
sdrbase
|
||||
sdrgui
|
||||
${TARGET_LIB_GUI}
|
||||
${AVCODEC_LIBRARIES}
|
||||
${AVFORMAT_LIBRARIES}
|
||||
${AVUTIL_LIBRARIES}
|
||||
@ -96,12 +109,6 @@ target_link_libraries(${TARGET_NAME} PRIVATE
|
||||
${SWRESAMPLE_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(ldpctool
|
||||
ldpctool/ldpc_tool.cpp
|
||||
ldpctool/tables_handler.cpp
|
||||
)
|
||||
install(TARGETS ldpctool DESTINATION ${INSTALL_BIN_DIR})
|
||||
|
||||
if(DEFINED FFMPEG_DEPENDS)
|
||||
add_dependencies(${TARGET_NAME} ${FFMPEG_DEPENDS})
|
||||
endif()
|
||||
|
@ -31,84 +31,6 @@ namespace leansdr {
|
||||
|
||||
static const int DEFAULT_GUI_DECIMATION = 64;
|
||||
|
||||
static inline cstln_lut<eucl_ss, 256> * make_dvbs_constellation(cstln_lut<eucl_ss, 256>::predef c,
|
||||
code_rate r)
|
||||
{
|
||||
float gamma1 = 1, gamma2 = 1, gamma3 = 1;
|
||||
switch (c)
|
||||
{
|
||||
case cstln_lut<eucl_ss, 256>::APSK16:
|
||||
// EN 302 307, section 5.4.3, Table 9
|
||||
switch (r)
|
||||
{
|
||||
case FEC23:
|
||||
case FEC46:
|
||||
gamma1 = 3.15;
|
||||
break;
|
||||
case FEC34:
|
||||
gamma1 = 2.85;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.75;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.70;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.60;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.57;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<256>::make_dvbs_constellation: Code rate not supported with APSK16");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<eucl_ss, 256>::APSK32:
|
||||
// EN 302 307, section 5.4.4, Table 10
|
||||
switch (r)
|
||||
{
|
||||
case FEC34:
|
||||
gamma1 = 2.84;
|
||||
gamma2 = 5.27;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.72;
|
||||
gamma2 = 4.87;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.64;
|
||||
gamma2 = 4.64;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.54;
|
||||
gamma2 = 4.33;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.53;
|
||||
gamma2 = 4.30;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<eucl_ss, 256>::make_dvbs_constellation: Code rate not supported with APSK32");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<eucl_ss, 256>::APSK64E:
|
||||
// EN 302 307-2, section 5.4.5, Table 13f
|
||||
gamma1 = 2.4;
|
||||
gamma2 = 4.3;
|
||||
gamma3 = 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cstln_lut<eucl_ss, 256> *newCstln = new cstln_lut<eucl_ss, 256>(c, 10, gamma1, gamma2, gamma3);
|
||||
newCstln->m_rateCode = (int) r;
|
||||
newCstln->m_typeCode = (int) c;
|
||||
newCstln->m_setByModcod = false;
|
||||
return newCstln;
|
||||
}
|
||||
|
||||
template<typename T> struct datvconstellation: runnable
|
||||
{
|
||||
|
194
plugins/channelrx/demoddatv/datvcstlnlut.h
Normal file
194
plugins/channelrx/demoddatv/datvcstlnlut.h
Normal file
@ -0,0 +1,194 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2025 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// using LeanSDR Framework (C) 2016 F4DAV //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DATV_CSTLN_LUT_H
|
||||
#define DATV_CSTLN_LUT_H
|
||||
|
||||
#include "leansdr/dvb.h"
|
||||
#include "leansdr/framework.h"
|
||||
|
||||
namespace leansdr {
|
||||
|
||||
static cstln_lut<eucl_ss, 256> * make_dvbs_constellation(
|
||||
cstln_lut<eucl_ss, 256>::predef c,
|
||||
code_rate r
|
||||
)
|
||||
{
|
||||
float gamma1 = 1, gamma2 = 1, gamma3 = 1;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case cstln_lut<eucl_ss, 256>::APSK16:
|
||||
// EN 302 307, section 5.4.3, Table 9
|
||||
switch (r)
|
||||
{
|
||||
case FEC23:
|
||||
case FEC46:
|
||||
gamma1 = 3.15;
|
||||
break;
|
||||
case FEC34:
|
||||
gamma1 = 2.85;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.75;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.70;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.60;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.57;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<256>::make_dvbs_constellation: Code rate not supported with APSK16");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<eucl_ss, 256>::APSK32:
|
||||
// EN 302 307, section 5.4.4, Table 10
|
||||
switch (r)
|
||||
{
|
||||
case FEC34:
|
||||
gamma1 = 2.84;
|
||||
gamma2 = 5.27;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.72;
|
||||
gamma2 = 4.87;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.64;
|
||||
gamma2 = 4.64;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.54;
|
||||
gamma2 = 4.33;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.53;
|
||||
gamma2 = 4.30;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<eucl_ss, 256>::make_dvbs_constellation: Code rate not supported with APSK32");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<eucl_ss, 256>::APSK64E:
|
||||
// EN 302 307-2, section 5.4.5, Table 13f
|
||||
gamma1 = 2.4;
|
||||
gamma2 = 4.3;
|
||||
gamma3 = 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cstln_lut<eucl_ss, 256> *newCstln = new cstln_lut<eucl_ss, 256>(c, 10, gamma1, gamma2, gamma3);
|
||||
newCstln->m_rateCode = (int) r;
|
||||
newCstln->m_typeCode = (int) c;
|
||||
newCstln->m_setByModcod = false;
|
||||
return newCstln;
|
||||
}
|
||||
|
||||
static cstln_lut<llr_ss, 256> * make_dvbs2_constellation(
|
||||
cstln_lut<llr_ss, 256>::predef c,
|
||||
code_rate r
|
||||
)
|
||||
{
|
||||
float gamma1 = 1, gamma2 = 1, gamma3 = 1;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case cstln_lut<llr_ss, 256>::APSK16:
|
||||
// EN 302 307, section 5.4.3, Table 9
|
||||
switch (r)
|
||||
{
|
||||
case FEC23:
|
||||
case FEC46:
|
||||
gamma1 = 3.15;
|
||||
break;
|
||||
case FEC34:
|
||||
gamma1 = 2.85;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.75;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.70;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.60;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.57;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<256>::make_dvbs2_constellation: Code rate not supported with APSK16");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<llr_ss, 256>::APSK32:
|
||||
// EN 302 307, section 5.4.4, Table 10
|
||||
switch (r)
|
||||
{
|
||||
case FEC34:
|
||||
gamma1 = 2.84;
|
||||
gamma2 = 5.27;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.72;
|
||||
gamma2 = 4.87;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.64;
|
||||
gamma2 = 4.64;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.54;
|
||||
gamma2 = 4.33;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.53;
|
||||
gamma2 = 4.30;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<llr_ss, 256>::make_dvbs2_constellation: Code rate not supported with APSK32");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<llr_ss, 256>::APSK64E:
|
||||
// EN 302 307-2, section 5.4.5, Table 13f
|
||||
gamma1 = 2.4;
|
||||
gamma2 = 4.3;
|
||||
gamma3 = 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cstln_lut<llr_ss, 256> *newCstln = new cstln_lut<llr_ss, 256>(c, 10, gamma1, gamma2, gamma3);
|
||||
newCstln->m_rateCode = r < code_rate::FEC_COUNT ? r : -1;
|
||||
newCstln->m_typeCode = c < cstln_lut<llr_ss, 256>::predef::COUNT ? c : -1;
|
||||
newCstln->m_setByModcod = false;
|
||||
return newCstln;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // DATV_CSTLN_LUT_H
|
@ -212,9 +212,6 @@ void DATVDemod::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
if (settings.m_softLDPC != m_settings.m_softLDPC) {
|
||||
reverseAPIKeys.append("softLDPC");
|
||||
}
|
||||
if (settings.m_softLDPCToolPath != m_settings.m_softLDPCToolPath) {
|
||||
reverseAPIKeys.append("softLDPCToolPath");
|
||||
}
|
||||
if (settings.m_softLDPCMaxTrials != m_settings.m_softLDPCMaxTrials) {
|
||||
reverseAPIKeys.append("softLDPCMaxTrials");
|
||||
}
|
||||
@ -401,9 +398,6 @@ void DATVDemod::webapiUpdateChannelSettings(
|
||||
if (channelSettingsKeys.contains("softLDPC")) {
|
||||
settings.m_softLDPC = response.getDatvDemodSettings()->getSoftLdpc() == 1;
|
||||
}
|
||||
if (channelSettingsKeys.contains("softLDPCToolPath")) {
|
||||
settings.m_softLDPCToolPath = *response.getDatvDemodSettings()->getSoftLdpcToolPath();
|
||||
}
|
||||
if (channelSettingsKeys.contains("softLDPCMaxTrials")) {
|
||||
settings.m_softLDPCMaxTrials = response.getDatvDemodSettings()->getSoftLdpcMaxTrials();
|
||||
}
|
||||
@ -503,13 +497,6 @@ void DATVDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res
|
||||
response.getDatvDemodSettings()->setModulation((int) settings.m_modulation);
|
||||
response.getDatvDemodSettings()->setFec((int) settings.m_fec);
|
||||
response.getDatvDemodSettings()->setSoftLdpc((int) settings.m_softLDPC ? 1 : 0);
|
||||
|
||||
if (response.getDatvDemodSettings()->getSoftLdpcToolPath()) {
|
||||
*response.getDatvDemodSettings()->getSoftLdpcToolPath() = settings.m_softLDPCToolPath;
|
||||
} else {
|
||||
response.getDatvDemodSettings()->setSoftLdpcToolPath(new QString(settings.m_softLDPCToolPath));
|
||||
}
|
||||
|
||||
response.getDatvDemodSettings()->setSoftLdpcMaxTrials(settings.m_softLDPCMaxTrials);
|
||||
response.getDatvDemodSettings()->setMaxBitflips(settings.m_maxBitflips);
|
||||
response.getDatvDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
|
||||
@ -589,6 +576,7 @@ void DATVDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& respons
|
||||
response.getDatvDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsq));
|
||||
response.getDatvDemodReport()->setAudioActive(audioActive() ? 1 : 0);
|
||||
response.getDatvDemodReport()->setAudioDecodeOk(audioDecodeOK() ? 1 : 0);
|
||||
response.getDatvDemodReport()->setSymbolRate(m_settings.m_symbolRate); // This is repeated from settings for convenience
|
||||
response.getDatvDemodReport()->setModcodCodeRate(getModcodCodeRate());
|
||||
response.getDatvDemodReport()->setModcodModulation(getModcodModulation());
|
||||
response.getDatvDemodReport()->setSetByModcod(isCstlnSetByModcod() ? 1 : 0);
|
||||
@ -664,9 +652,6 @@ void DATVDemod::webapiFormatChannelSettings(
|
||||
if (channelSettingsKeys.contains("softLDPC") || force) {
|
||||
swgDATVDemodSettings->setSoftLdpc(settings.m_softLDPC ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("softLDPCToolPath") || force) {
|
||||
swgDATVDemodSettings->setSoftLdpcToolPath(new QString(settings.m_softLDPCToolPath));
|
||||
}
|
||||
if (channelSettingsKeys.contains("softLDPCMaxTrials") || force) {
|
||||
swgDATVDemodSettings->setSoftLdpcMaxTrials(settings.m_softLDPCMaxTrials);
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "maincore.h"
|
||||
|
||||
#include "ui_datvdemodgui.h"
|
||||
#include "datvideorender.h"
|
||||
#include "datvdemodreport.h"
|
||||
#include "datvdvbs2ldpcdialog.h"
|
||||
#include "datvdemodgui.h"
|
||||
@ -531,14 +532,12 @@ void DATVDemodGUI::ldpcToolSelect(const QPoint& p)
|
||||
{
|
||||
qDebug("DATVDemodGUI::ldpcToolSelect");
|
||||
DatvDvbS2LdpcDialog ldpcDialog;
|
||||
ldpcDialog.setFileName(m_settings.m_softLDPCToolPath);
|
||||
ldpcDialog.setMaxTrials(m_settings.m_softLDPCMaxTrials);
|
||||
ldpcDialog.move(p);
|
||||
|
||||
if (ldpcDialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
m_settings.m_softLDPCMaxTrials = ldpcDialog.getMaxTrials();
|
||||
m_settings.m_softLDPCToolPath = ldpcDialog.getFileName();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
class DataTSMetaData2;
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
|
@ -20,10 +20,12 @@
|
||||
|
||||
|
||||
#include <QtPlugin>
|
||||
#include <QAction>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "datvdemodgui.h"
|
||||
#endif
|
||||
#include "datvdemod.h"
|
||||
#include "datvdemodplugin.h"
|
||||
#include "datvdemodwebapiadapter.h"
|
||||
|
||||
@ -31,7 +33,7 @@ const PluginDescriptor DATVDemodPlugin::m_ptrPluginDescriptor =
|
||||
{
|
||||
DATVDemod::m_channelId,
|
||||
QStringLiteral("DATV Demodulator"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) F4HKW for SDRAngel using LeanSDR framework (c) F4DAV"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
@ -75,10 +77,21 @@ void DATVDemodPlugin::createRxChannel(DeviceAPI *deviceAPI, BasebandSampleSink *
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERVER_MODE
|
||||
ChannelGUI* DATVDemodPlugin::createRxChannelGUI(
|
||||
DeviceUISet *deviceUISet,
|
||||
BasebandSampleSink *rxChannel) const
|
||||
{
|
||||
(void) deviceUISet;
|
||||
(void) rxChannel;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ChannelGUI* DATVDemodPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) const
|
||||
{
|
||||
return DATVDemodGUI::create(m_ptrPluginAPI, deviceUISet, rxChannel);
|
||||
}
|
||||
#endif
|
||||
|
||||
ChannelWebAPIAdapter* DATVDemodPlugin::createChannelWebAPIAdapter() const
|
||||
{
|
||||
|
@ -28,12 +28,6 @@
|
||||
|
||||
#include "datvdemodsettings.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define DEFAULT_LDPCTOOLPATH "C:/Program Files/SDRangel/ldpctool.exe"
|
||||
#else
|
||||
#define DEFAULT_LDPCTOOLPATH "/opt/install/sdrangel/bin/ldpctool"
|
||||
#endif
|
||||
|
||||
DATVDemodSettings::DATVDemodSettings() :
|
||||
m_channelMarker(nullptr),
|
||||
m_rollupState(nullptr)
|
||||
@ -51,7 +45,6 @@ void DATVDemodSettings::resetToDefaults()
|
||||
m_modulation = BPSK;
|
||||
m_fec = FEC12;
|
||||
m_softLDPC = false;
|
||||
m_softLDPCToolPath = DEFAULT_LDPCTOOLPATH;
|
||||
m_softLDPCMaxTrials = 8;
|
||||
m_maxBitflips = 0;
|
||||
m_symbolRate = 250000;
|
||||
@ -120,7 +113,6 @@ QByteArray DATVDemodSettings::serialize() const
|
||||
s.writeU32(31, m_reverseAPIChannelIndex);
|
||||
s.writeBool(32, m_softLDPC);
|
||||
s.writeS32(33, m_maxBitflips);
|
||||
s.writeString(34, m_softLDPCToolPath);
|
||||
s.writeS32(35, m_softLDPCMaxTrials);
|
||||
s.writeBool(36, m_playerEnable);
|
||||
|
||||
@ -215,7 +207,6 @@ bool DATVDemodSettings::deserialize(const QByteArray& data)
|
||||
|
||||
d.readBool(32, &m_softLDPC, false);
|
||||
d.readS32(33, &m_maxBitflips, 0);
|
||||
d.readString(34, &m_softLDPCToolPath, DEFAULT_LDPCTOOLPATH);
|
||||
d.readS32(35, &tmp, 8);
|
||||
m_softLDPCMaxTrials = tmp < 1 ? 1 : tmp > m_softLDPCMaxMaxTrials ? m_softLDPCMaxMaxTrials : tmp;
|
||||
d.readBool(36, &m_playerEnable, true);
|
||||
@ -256,7 +247,6 @@ void DATVDemodSettings::debug(const QString& msg) const
|
||||
<< " m_fec: " << m_fec
|
||||
<< " m_softLDPC: " << m_softLDPC
|
||||
<< " m_softLDPCMaxTrials: " << m_softLDPCMaxTrials
|
||||
<< " m_softLDPCToolPath: " << m_softLDPCToolPath
|
||||
<< " m_maxBitflips: " << m_maxBitflips
|
||||
<< " m_modulation: " << m_modulation
|
||||
<< " m_standard: " << m_standard
|
||||
@ -284,7 +274,6 @@ bool DATVDemodSettings::isDifferent(const DATVDemodSettings& other)
|
||||
|| (m_fec != other.m_fec)
|
||||
|| (m_softLDPC != other.m_softLDPC)
|
||||
|| (m_softLDPCMaxTrials != other.m_softLDPCMaxTrials)
|
||||
|| (m_softLDPCToolPath != other.m_softLDPCToolPath)
|
||||
|| (m_maxBitflips != other.m_maxBitflips)
|
||||
|| (m_modulation != other.m_modulation)
|
||||
|| (m_notchFilters != other.m_notchFilters)
|
||||
|
@ -84,7 +84,6 @@ struct DATVDemodSettings
|
||||
DATVModulation m_modulation;
|
||||
DATVCodeRate m_fec;
|
||||
bool m_softLDPC;
|
||||
QString m_softLDPCToolPath;
|
||||
int m_softLDPCMaxTrials;
|
||||
int m_maxBitflips;
|
||||
bool m_audioMute;
|
||||
|
@ -17,6 +17,10 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "datvideorender.h"
|
||||
#endif
|
||||
#include "datvcstlnlut.h"
|
||||
#include "datvdemodsink.h"
|
||||
|
||||
#include "leansdr/dvbs2.h"
|
||||
@ -33,7 +37,9 @@ const unsigned int DATVDemodSink::m_rfFilterFftLength = 512;
|
||||
DATVDemodSink::DATVDemodSink() :
|
||||
m_blnNeedConfigUpdate(false),
|
||||
m_tvScreen(nullptr),
|
||||
#ifndef SERVER_MODE
|
||||
m_videoRender(nullptr),
|
||||
#endif
|
||||
m_videoStream(new DATVideostream()),
|
||||
m_udpStream(leansdr::tspacket::SIZE),
|
||||
m_videoThread(nullptr),
|
||||
@ -69,6 +75,7 @@ DATVDemodSink::~DATVDemodSink()
|
||||
|
||||
void DATVDemodSink::stopVideo()
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoThread)
|
||||
{
|
||||
if (m_videoThread->isRunning())
|
||||
@ -78,6 +85,7 @@ void DATVDemodSink::stopVideo()
|
||||
m_videoThread->wait();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DATVDemodSink::setTVScreen(TVScreen *tvScreen)
|
||||
@ -87,46 +95,64 @@ void DATVDemodSink::setTVScreen(TVScreen *tvScreen)
|
||||
|
||||
void DATVDemodSink::SetVideoRender(DATVideoRender *screen)
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
m_videoRender = screen;
|
||||
m_videoRender->setAudioFIFO(&m_audioFifo);
|
||||
m_videoThread = new DATVideoRenderThread(m_videoRender, m_videoStream);
|
||||
m_videoThread->setObjectName("vtDATVDemodSink");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DATVDemodSink::audioActive()
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoRender) {
|
||||
return m_videoRender->getAudioStreamIndex() >= 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DATVDemodSink::videoActive()
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoRender) {
|
||||
return m_videoRender->getVideoStreamIndex() >= 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DATVDemodSink::audioDecodeOK()
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoRender) {
|
||||
return m_videoRender->getAudioDecodeOK();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DATVDemodSink::videoDecodeOK()
|
||||
{
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoRender) {
|
||||
return m_videoRender->getVideoDecodeOK();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DATVDemodSink::udpRunning()
|
||||
@ -136,7 +162,6 @@ bool DATVDemodSink::udpRunning()
|
||||
}
|
||||
|
||||
bool udpRunning = r_videoplayer->isUDPRunning();
|
||||
r_videoplayer->resetUDPRunning();
|
||||
|
||||
return udpRunning;
|
||||
}
|
||||
@ -145,6 +170,7 @@ bool DATVDemodSink::playVideo()
|
||||
{
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
if (m_videoStream == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -167,7 +193,7 @@ bool DATVDemodSink::playVideo()
|
||||
m_videoStream->setThreadTimeout(DATVideoRenderThread::videoThreadTimeoutMs);
|
||||
m_videoThread->start();
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -341,10 +367,11 @@ void DATVDemodSink::CleanUpDATVFramework()
|
||||
}
|
||||
|
||||
//CONSTELLATION
|
||||
#ifndef SERVER_MODE
|
||||
if (r_scope_symbols != nullptr) {
|
||||
delete r_scope_symbols;
|
||||
}
|
||||
|
||||
#endif
|
||||
// INPUT
|
||||
if (p_rawiq != nullptr) {
|
||||
delete p_rawiq;
|
||||
@ -405,11 +432,11 @@ void DATVDemodSink::CleanUpDATVFramework()
|
||||
if (p_deframer != nullptr) {
|
||||
delete (leansdr::s2_deframer*) p_deframer;
|
||||
}
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
if (r_scope_symbols_dvbs2 != nullptr) {
|
||||
delete r_scope_symbols_dvbs2;
|
||||
}
|
||||
|
||||
#endif
|
||||
ResetDATVFrameworkPointers();
|
||||
}
|
||||
|
||||
@ -498,7 +525,9 @@ void DATVDemodSink::ResetDATVFrameworkPointers()
|
||||
r_videoplayer = nullptr;
|
||||
|
||||
//CONSTELLATION
|
||||
#ifndef SERVER_MODE
|
||||
r_scope_symbols = nullptr;
|
||||
#endif
|
||||
|
||||
//DVB-S2
|
||||
p_slots_dvbs2 = nullptr;
|
||||
@ -513,7 +542,9 @@ void DATVDemodSink::ResetDATVFrameworkPointers()
|
||||
r_fecdecsoft = nullptr;
|
||||
r_fecdechelper = nullptr;
|
||||
p_deframer = nullptr;
|
||||
#ifndef SERVER_MODE
|
||||
r_scope_symbols_dvbs2 = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DATVDemodSink::InitDATVFramework()
|
||||
@ -761,7 +792,7 @@ void DATVDemodSink::InitDATVFramework()
|
||||
}
|
||||
|
||||
//constellation
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
if (m_tvScreen)
|
||||
{
|
||||
qDebug("DATVDemodSink::InitDATVFramework: Register DVB constellation TV screen");
|
||||
@ -771,7 +802,7 @@ void DATVDemodSink::InitDATVFramework()
|
||||
r_scope_symbols->cstln = &m_objDemodulator->cstln;
|
||||
r_scope_symbols->calculate_cstln_points();
|
||||
}
|
||||
|
||||
#endif
|
||||
r_merMeter = new leansdr::datvmeter(m_objScheduler, *p_mer);
|
||||
r_cnrMeter = new leansdr::datvmeter(m_objScheduler, *p_cnr);
|
||||
|
||||
@ -847,6 +878,7 @@ void DATVDemodSink::InitDATVFramework()
|
||||
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, nullptr, &m_udpStream);
|
||||
}
|
||||
|
||||
r_videoplayer->setSymbolRate(m_settings.m_symbolRate);
|
||||
m_blnDVBInitialized = true;
|
||||
}
|
||||
|
||||
@ -873,8 +905,7 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
<< " Excursion: " << m_settings.m_excursion
|
||||
<< " Channel sample rate: " << m_channelSampleRate
|
||||
<< " Input sample rate: " << 2 * m_settings.m_symbolRate
|
||||
<< " m_softLDPCMaxTrials: " << m_settings.m_softLDPCMaxTrials
|
||||
<< " m_softLDPCToolPath: " << m_settings.m_softLDPCToolPath;
|
||||
<< " m_softLDPCMaxTrials: " << m_settings.m_softLDPCMaxTrials;
|
||||
|
||||
m_objCfg.standard = m_settings.m_standard;
|
||||
|
||||
@ -1067,7 +1098,7 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
m_cstlnSetByModcod = false;
|
||||
|
||||
//constellation
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
if (m_tvScreen)
|
||||
{
|
||||
qDebug("DATVDemodSink::InitDATVS2Framework: Register DVBS 2 TVSCREEN");
|
||||
@ -1076,7 +1107,7 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
r_scope_symbols_dvbs2->cstln = (leansdr::cstln_base**) &objDemodulatorDVBS2->cstln;
|
||||
r_scope_symbols_dvbs2->calculate_cstln_points();
|
||||
}
|
||||
|
||||
#endif
|
||||
r_merMeter = new leansdr::datvmeter(m_objScheduler, *p_mer);
|
||||
r_cnrMeter = new leansdr::datvmeter(m_objScheduler, *p_cnr);
|
||||
|
||||
@ -1098,12 +1129,6 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
|
||||
// bool commandFileValid = false;
|
||||
|
||||
if (QFileInfo::exists(m_settings.m_softLDPCToolPath))
|
||||
{
|
||||
QFileInfo fileInfo = QFileInfo(m_settings.m_softLDPCToolPath);
|
||||
// commandFileValid = fileInfo.isExecutable();
|
||||
}
|
||||
|
||||
if (m_settings.m_softLDPC /*&& commandFileValid*/)
|
||||
{
|
||||
#if 0
|
||||
@ -1128,8 +1153,6 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
// External LDPC decoder mode.
|
||||
// Deinterleave into soft bits.
|
||||
// TBD Latency
|
||||
QByteArray ba = m_settings.m_softLDPCToolPath.toLocal8Bit();
|
||||
const char *c_str2 = ba.data();
|
||||
p_fecframes = new leansdr::pipebuf<leansdr::fecframe<leansdr::llr_sb> >(m_objScheduler, "FEC frames", BUF_FRAMES);
|
||||
p_s2_deinterleaver = new leansdr::s2_deinterleaver<leansdr::llr_ss, leansdr::llr_sb>(
|
||||
m_objScheduler,
|
||||
@ -1141,7 +1164,6 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
m_objScheduler,
|
||||
*(leansdr::pipebuf< leansdr::fecframe<leansdr::llr_sb> > *) p_fecframes,
|
||||
*(leansdr::pipebuf<leansdr::bbframe> *) p_bbframes,
|
||||
c_str2,
|
||||
p_vbitcount,
|
||||
p_verrcount)
|
||||
;
|
||||
@ -1190,6 +1212,7 @@ void DATVDemodSink::InitDATVS2Framework()
|
||||
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, nullptr, &m_udpStream);
|
||||
}
|
||||
|
||||
r_videoplayer->setSymbolRate(m_settings.m_symbolRate);
|
||||
m_blnDVBInitialized = true;
|
||||
}
|
||||
|
||||
@ -1205,10 +1228,12 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
|
||||
{
|
||||
qDebug("DATVDemodSink::feed: change by MODCOD detected");
|
||||
|
||||
// Update constellation
|
||||
#ifndef SERVER_MODE
|
||||
if (r_scope_symbols_dvbs2) {
|
||||
r_scope_symbols_dvbs2->calculate_cstln_points();
|
||||
}
|
||||
|
||||
#endif
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
DATVDemodReport::MsgReportModcodCstlnChange *msg = DATVDemodReport::MsgReportModcodCstlnChange::create(
|
||||
@ -1362,6 +1387,7 @@ void DATVDemodSink::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
if ((settings.m_audioVolume) != (m_settings.m_audioVolume) || force)
|
||||
{
|
||||
if (m_videoRender) {
|
||||
@ -1382,6 +1408,7 @@ void DATVDemodSink::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
m_videoRender->setVideoMute(settings.m_videoMute);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((m_settings.m_rfBandwidth != settings.m_rfBandwidth)
|
||||
|| (m_settings.m_symbolRate != settings.m_symbolRate)
|
||||
@ -1393,8 +1420,19 @@ void DATVDemodSink::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
m_nco.setFreq(-(float) settings.m_centerFrequency, (float) m_channelSampleRate);
|
||||
}
|
||||
|
||||
if ((m_settings.m_udpTS != settings.m_udpTS) || force) {
|
||||
if ((m_settings.m_udpTS != settings.m_udpTS) || force)
|
||||
{
|
||||
m_udpStream.setActive(settings.m_udpTS);
|
||||
|
||||
if (r_videoplayer && !settings.m_udpTS) {
|
||||
r_videoplayer->resetUDPRunning();
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_symbolRate != settings.m_symbolRate) || force) {
|
||||
if (r_videoplayer) {
|
||||
r_videoplayer->setSymbolRate(settings.m_symbolRate);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_udpTSAddress != settings.m_udpTSAddress) || force) {
|
||||
|
@ -30,13 +30,14 @@
|
||||
#include "leansdr/hdlc.h"
|
||||
#include "leansdr/iess.h"
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "datvconstellation.h"
|
||||
#include "datvmeter.h"
|
||||
#include "datvdvbs2constellation.h"
|
||||
#endif
|
||||
#include "datvmeter.h"
|
||||
#include "datvvideoplayer.h"
|
||||
#include "datvideostream.h"
|
||||
#include "datvudpstream.h"
|
||||
#include "datvideorender.h"
|
||||
#include "datvdemodsettings.h"
|
||||
|
||||
#include "dsp/channelsamplesink.h"
|
||||
@ -50,6 +51,7 @@
|
||||
|
||||
class TVScreen;
|
||||
class DATVideoRender;
|
||||
class DATVideoRenderThread;
|
||||
class QLabel;
|
||||
|
||||
class DATVDemodSink : public ChannelSampleSink {
|
||||
@ -314,8 +316,10 @@ private:
|
||||
leansdr::datvvideoplayer<leansdr::tspacket> *r_videoplayer;
|
||||
|
||||
//CONSTELLATION
|
||||
#ifndef SERVER_MODE
|
||||
leansdr::datvconstellation<leansdr::f32> *r_scope_symbols;
|
||||
leansdr::datvdvbs2constellation<leansdr::f32> *r_scope_symbols_dvbs2;
|
||||
#endif
|
||||
leansdr::datvmeter *r_merMeter;
|
||||
leansdr::datvmeter *r_cnrMeter;
|
||||
|
||||
|
@ -31,88 +31,6 @@ namespace leansdr {
|
||||
|
||||
static const int DEFAULT_GUI_DVBS2_DECIMATION = 64;
|
||||
|
||||
static inline cstln_lut<llr_ss, 256> * make_dvbs2_constellation(
|
||||
cstln_lut<llr_ss, 256>::predef c,
|
||||
code_rate r
|
||||
)
|
||||
{
|
||||
float gamma1 = 1, gamma2 = 1, gamma3 = 1;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case cstln_lut<llr_ss, 256>::APSK16:
|
||||
// EN 302 307, section 5.4.3, Table 9
|
||||
switch (r)
|
||||
{
|
||||
case FEC23:
|
||||
case FEC46:
|
||||
gamma1 = 3.15;
|
||||
break;
|
||||
case FEC34:
|
||||
gamma1 = 2.85;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.75;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.70;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.60;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.57;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<256>::make_dvbs2_constellation: Code rate not supported with APSK16");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<llr_ss, 256>::APSK32:
|
||||
// EN 302 307, section 5.4.4, Table 10
|
||||
switch (r)
|
||||
{
|
||||
case FEC34:
|
||||
gamma1 = 2.84;
|
||||
gamma2 = 5.27;
|
||||
break;
|
||||
case FEC45:
|
||||
gamma1 = 2.72;
|
||||
gamma2 = 4.87;
|
||||
break;
|
||||
case FEC56:
|
||||
gamma1 = 2.64;
|
||||
gamma2 = 4.64;
|
||||
break;
|
||||
case FEC89:
|
||||
gamma1 = 2.54;
|
||||
gamma2 = 4.33;
|
||||
break;
|
||||
case FEC910:
|
||||
gamma1 = 2.53;
|
||||
gamma2 = 4.30;
|
||||
break;
|
||||
default:
|
||||
fail("cstln_lut<llr_ss, 256>::make_dvbs2_constellation: Code rate not supported with APSK32");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case cstln_lut<llr_ss, 256>::APSK64E:
|
||||
// EN 302 307-2, section 5.4.5, Table 13f
|
||||
gamma1 = 2.4;
|
||||
gamma2 = 4.3;
|
||||
gamma3 = 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cstln_lut<llr_ss, 256> *newCstln = new cstln_lut<llr_ss, 256>(c, 10, gamma1, gamma2, gamma3);
|
||||
newCstln->m_rateCode = r < code_rate::FEC_COUNT ? r : -1;
|
||||
newCstln->m_typeCode = c < cstln_lut<llr_ss, 256>::predef::COUNT ? c : -1;
|
||||
newCstln->m_setByModcod = false;
|
||||
return newCstln;
|
||||
}
|
||||
|
||||
template<typename T> struct datvdvbs2constellation: runnable
|
||||
{
|
||||
|
@ -42,12 +42,6 @@ void DatvDvbS2LdpcDialog::accept()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void DatvDvbS2LdpcDialog::setFileName(const QString& fileName)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
ui->ldpcToolText->setText(m_fileName);
|
||||
}
|
||||
|
||||
void DatvDvbS2LdpcDialog::setMaxTrials(int maxTrials)
|
||||
{
|
||||
m_maxTrials = maxTrials < 1 ? 1 :
|
||||
@ -55,31 +49,6 @@ void DatvDvbS2LdpcDialog::setMaxTrials(int maxTrials)
|
||||
ui->maxTrials->setValue(m_maxTrials);
|
||||
}
|
||||
|
||||
void DatvDvbS2LdpcDialog::on_showFileDialog_clicked(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
|
||||
QFileDialog fileDialog(this, "Select LDPC tool");
|
||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog, true);
|
||||
#ifdef _MSC_VER
|
||||
fileDialog.setNameFilter("*.exe");
|
||||
#else
|
||||
fileDialog.setFilter(QDir::Executable | QDir::Files);
|
||||
#endif
|
||||
fileDialog.selectFile(m_fileName);
|
||||
|
||||
if (fileDialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
QStringList fileNames = fileDialog.selectedFiles();
|
||||
|
||||
if (fileNames.size() > 0)
|
||||
{
|
||||
m_fileName = fileNames[0];
|
||||
ui->ldpcToolText->setText(m_fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DatvDvbS2LdpcDialog::on_maxTrials_valueChanged(int value)
|
||||
{
|
||||
m_maxTrials = value;
|
||||
|
@ -33,19 +33,15 @@ public:
|
||||
explicit DatvDvbS2LdpcDialog(QWidget* parent = nullptr);
|
||||
~DatvDvbS2LdpcDialog();
|
||||
|
||||
void setFileName(const QString& fileName);
|
||||
void setMaxTrials(int maxTrials);
|
||||
QString& getFileName() { return m_fileName; }
|
||||
int getMaxTrials() { return m_maxTrials; }
|
||||
|
||||
private:
|
||||
Ui::DatvDvbS2LdpcDialog* ui;
|
||||
QString m_fileName;
|
||||
int m_maxTrials;
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
void on_showFileDialog_clicked(bool checked);
|
||||
void on_maxTrials_valueChanged(int value);
|
||||
};
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>461</width>
|
||||
<height>121</height>
|
||||
<width>454</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@ -63,66 +63,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="logFileLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="ldpcToolLabel">
|
||||
<property name="text">
|
||||
<string>LDPC tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="showFileDialog">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Choose a log file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/preset-load.png</normaloff>:/preset-load.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="ldpcToolText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Log file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
|
@ -42,7 +42,9 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
in(_in),
|
||||
m_videoStream(videoStream),
|
||||
m_udpStream(udpStream),
|
||||
m_atomicUDPRunning(0)
|
||||
m_atomicUDPRunning(0),
|
||||
m_count(0),
|
||||
m_sr(1500000)
|
||||
{
|
||||
}
|
||||
|
||||
@ -50,7 +52,18 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
{
|
||||
int size = in.readable() * sizeof(T);
|
||||
|
||||
if (!size) {
|
||||
if (!size)
|
||||
{
|
||||
if (m_count == 0)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
m_atomicUDPRunning.storeRelaxed(0);
|
||||
#else
|
||||
m_atomicUDPRunning.store(0);
|
||||
#endif
|
||||
} else {
|
||||
m_count--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -62,6 +75,8 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
#else
|
||||
m_atomicUDPRunning.store(m_udpStream->isActive() && (size > 0) ? 1 : 0);
|
||||
#endif
|
||||
m_count = m_sr / 10000;
|
||||
|
||||
if (m_videoStream)
|
||||
{
|
||||
nw = m_videoStream->pushData((const char *) in.rd(), size);
|
||||
@ -114,11 +129,18 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
#endif
|
||||
}
|
||||
|
||||
void setSymbolRate(unsigned int sr)
|
||||
{
|
||||
m_sr = sr;
|
||||
}
|
||||
|
||||
private:
|
||||
pipereader<T> in;
|
||||
DATVideostream *m_videoStream;
|
||||
DATVUDPStream *m_udpStream;
|
||||
QAtomicInt m_atomicUDPRunning;
|
||||
unsigned int m_count;
|
||||
unsigned int m_sr; // Symbol rate in S/s used for UDP running detection
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -700,8 +700,9 @@ struct s2_frame_receiver : runnable
|
||||
|
||||
char *format() {
|
||||
static char buf[256];
|
||||
sprintf(
|
||||
snprintf(
|
||||
buf,
|
||||
sizeof(buf),
|
||||
"%9.2lf %+6.0f ppm %+3.0f ° %f",
|
||||
(double)((p-(std::complex<T>*)NULL)&262143)+mu, // Arbitrary wrap
|
||||
fw16*1e6/65536,
|
||||
@ -3516,11 +3517,11 @@ struct s2_fecdec_helper : runnable
|
||||
close(rx[0]);
|
||||
dup2(rx[1], 1);
|
||||
char max_trials_arg[16];
|
||||
sprintf(max_trials_arg, "%d", max_trials);
|
||||
snprintf(max_trials_arg, sizeof(max_trial_args), "%d", max_trials);
|
||||
char batch_size_arg[16];
|
||||
sprintf(batch_size_arg, "%d", batch_size);
|
||||
snprintf(batch_size_arg, sizeof(batch_size_args), "%d", batch_size);
|
||||
char mc_arg[16];
|
||||
sprintf(mc_arg, "%d", pls->modcod);
|
||||
snprintf(mc_arg, sizeof(mc_arg), "%d", pls->modcod);
|
||||
const char *sf_arg = pls->sf ? "--shortframes" : nullptr;
|
||||
const char *argv[] = {
|
||||
command,
|
||||
@ -3643,7 +3644,6 @@ struct s2_fecdec_helper : runnable
|
||||
scheduler *sch,
|
||||
pipebuf<fecframe<SOFTBYTE>> &_in,
|
||||
pipebuf<bbframe> &_out,
|
||||
const char *_command,
|
||||
pipebuf<int> *_bitcount = nullptr,
|
||||
pipebuf<int> *_errcount = nullptr
|
||||
) :
|
||||
@ -3657,7 +3657,6 @@ struct s2_fecdec_helper : runnable
|
||||
bitcount(opt_writer(_bitcount, 1)),
|
||||
errcount(opt_writer(_errcount, 1))
|
||||
{
|
||||
command = strdup(_command);
|
||||
|
||||
for (int mc = 0; mc < 32; ++mc) {
|
||||
for (int sf = 0; sf < 2; ++sf) {
|
||||
@ -3668,7 +3667,6 @@ struct s2_fecdec_helper : runnable
|
||||
|
||||
~s2_fecdec_helper()
|
||||
{
|
||||
free(command);
|
||||
killall(); // also deletes pools[mc][sf].procs if necessary
|
||||
}
|
||||
|
||||
|
@ -368,7 +368,7 @@ struct slowmultiscope : runnable
|
||||
channel *c = &chans[i];
|
||||
g.setfg(c->spec.rgb[0], c->spec.rgb[1], c->spec.rgb[2]);
|
||||
char text[256];
|
||||
sprintf(text, c->spec.format, c->print_val);
|
||||
snprintf(text, sizeof(text), c->spec.format, c->print_val);
|
||||
g.transient_text(5, 20 + 16 * i, text);
|
||||
}
|
||||
run_gui();
|
||||
@ -445,7 +445,7 @@ struct slowmultiscope : runnable
|
||||
float ct = g.mx * samples_per_pixel / sample_freq;
|
||||
float tt = total_samples / sample_freq;
|
||||
char text[256];
|
||||
sprintf(text, "%.3f / %.3f s", ct, tt);
|
||||
snprintf(text, sizeof(text), "%.3f / %.3f s", ct, tt);
|
||||
g.setfg(255, 255, 255);
|
||||
g.transient_text(g.w * 3 / 4, 20, text);
|
||||
}
|
||||
@ -529,7 +529,7 @@ struct spectrumscope : runnable
|
||||
{
|
||||
char s[256];
|
||||
float f = 2.4e6 * (g.mx - g.w / 2) / g.w;
|
||||
sprintf(s, "%f", f);
|
||||
snprintf(s, sizeof(s), "%f", f);
|
||||
g.text(16, 16, s);
|
||||
}
|
||||
g.show();
|
||||
@ -637,7 +637,7 @@ struct rfscope : runnable
|
||||
char s[256];
|
||||
float freq = Fc + Fs * (g.mx - g.w / 2) / g.w / hzoom;
|
||||
float val = db0 + (float)((g.h - 1) - g.my) * dbrange / g.h;
|
||||
sprintf(s, "%f.3 Hz %f.2 dB", freq, val);
|
||||
snprintf(s, sizeof(s), "%f.3 Hz %f.2 dB", freq, val);
|
||||
g.setfg(255, 255, 255);
|
||||
g.text(16, 16, s);
|
||||
}
|
||||
@ -726,7 +726,7 @@ struct genscope : runnable
|
||||
g.line(pc->spec.r.x - dx, pc->spec.r.y - dy,
|
||||
pc->spec.r.x + dx, pc->spec.r.y + dy);
|
||||
char txt[16];
|
||||
sprintf(txt, "%d", (int)last);
|
||||
snprintf(txt, sizeof(txt), "%d", (int)last);
|
||||
g.text(pc->spec.r.x + 5, pc->spec.r.y - 2, txt);
|
||||
}
|
||||
struct timeval newtv;
|
||||
|
@ -191,7 +191,7 @@ It can be used to decode signals lower that ~10 db MER which is the limit of LDP
|
||||
|
||||
Right clicking on this control opens a dialog where you can choose:
|
||||
|
||||
- The `ldpctool` executable. Obsolete.
|
||||
- ~~The `ldpctool` executable.~~ Obsolete removed.
|
||||
- The maximum of retries in LDPC decoding from 1 to 8.
|
||||
|
||||
<h5>B.2b.7: DVB-S2 specific - LDPC maximum number of bit flips allowed</h5>
|
||||
|
@ -33,7 +33,7 @@
|
||||
const PluginDescriptor NavtexDemodPlugin::m_pluginDescriptor = {
|
||||
NavtexDemod::m_channelId,
|
||||
QStringLiteral("Navtex Demodulator"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -354,7 +354,7 @@ void NavtexDemodSink::receiveBit(bool bit)
|
||||
getMessageQueueToChannel()->push(msg);
|
||||
}
|
||||
// Add character to message buffer
|
||||
m_messageBuffer.append(QChar(c));
|
||||
m_messageBuffer.append(QChar((char) c));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -34,7 +34,7 @@
|
||||
const PluginDescriptor RemoteSinkPlugin::m_pluginDescriptor = {
|
||||
RemoteSink::m_channelId,
|
||||
QStringLiteral("Remote channel sink"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <QMutexLocker>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
@ -258,8 +258,8 @@ void PacketModGUI::on_insertPosition_clicked()
|
||||
longFrac = round(longitude);
|
||||
|
||||
// Insert position with house symbol (-) in to data field
|
||||
sprintf(latBuf, "%02d%02d.%02d%c", latDeg, latMin, latFrac, latNorth ? 'N' : 'S');
|
||||
sprintf(longBuf, "%03d%02d.%02d%c", longDeg, longMin, longFrac, longEast ? 'E' : 'W');
|
||||
snprintf(latBuf, sizeof(latBuf), "%02d%02d.%02d%c", latDeg, latMin, latFrac, latNorth ? 'N' : 'S');
|
||||
snprintf(longBuf, sizeof(longBuf), "%03d%02d.%02d%c", longDeg, longMin, longFrac, longEast ? 'E' : 'W');
|
||||
QString packet = QString("%1/%2-").arg(latBuf).arg(longBuf);
|
||||
ui->packet->insert(packet);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
const PluginDescriptor PacketModPlugin::m_pluginDescriptor = {
|
||||
PacketMod::m_channelId,
|
||||
QStringLiteral("Packet Modulator"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -32,7 +32,7 @@
|
||||
const PluginDescriptor RemoteSourcePlugin::m_pluginDescriptor = {
|
||||
RemoteSource::m_channelId,
|
||||
QStringLiteral("Remote channel source"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -15,6 +15,8 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
|
@ -75,7 +75,7 @@ void AMBEEngine::getComList()
|
||||
// Arbitrarily set the list to the 20 first COM ports
|
||||
for (int i = 1; i <= 20; i++)
|
||||
{
|
||||
sprintf(comCStr, "COM%d", i);
|
||||
snprintf(comCStr, sizeof(comCStr), "COM%d", i);
|
||||
m_comList.push_back(std::string(comCStr));
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
const PluginDescriptor AMBEPlugin::m_pluginDescriptor = {
|
||||
AMBE::m_featureId,
|
||||
QStringLiteral("AMBE Controller"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -34,7 +34,7 @@
|
||||
const PluginDescriptor GS232ControllerPlugin::m_pluginDescriptor = {
|
||||
GS232Controller::m_featureId,
|
||||
QStringLiteral("Rotator Controller"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -54,23 +54,37 @@ void GS232Protocol::readData()
|
||||
if (len != -1)
|
||||
{
|
||||
QString response = QString::fromUtf8(buf, len);
|
||||
// MD-02 can return AZ=-00 EL=-00 and other negative angles
|
||||
QRegularExpression re("AZ=([-\\d]\\d\\d) *EL=([-\\d]\\d\\d)");
|
||||
QRegularExpressionMatch match = re.match(response);
|
||||
if (match.hasMatch())
|
||||
// Handle both formats:
|
||||
// 1. AZ=XXX EL=XXX (MD-02 can return negative angles like AZ=-00 EL=-00)
|
||||
// 2. +XXXX+YYYY (direct angle format)
|
||||
QRegularExpression reAzEl("AZ=([-\\d]\\d\\d) *EL=([-\\d]\\d\\d)");
|
||||
QRegularExpression reAngles("([+-]\\d{4})([+-]\\d{4})");
|
||||
|
||||
QRegularExpressionMatch matchAzEl = reAzEl.match(response);
|
||||
QRegularExpressionMatch matchAngles = reAngles.match(response);
|
||||
if (matchAzEl.hasMatch())
|
||||
{
|
||||
QString az = match.captured(1);
|
||||
QString el = match.captured(2);
|
||||
//qDebug() << "SPIDProtocol::readData read Az " << az << " El " << el;
|
||||
QString az = matchAzEl.captured(1);
|
||||
QString el = matchAzEl.captured(2);
|
||||
//qDebug() << "GS232Protocol::readData read Az " << az << " El " << el;
|
||||
reportAzEl(az.toFloat(), el.toFloat());
|
||||
}
|
||||
else if (matchAngles.hasMatch())
|
||||
{
|
||||
// Convert from +XXXX format to float
|
||||
QString az = matchAngles.captured(1);
|
||||
QString el = matchAngles.captured(2);
|
||||
//qDebug() << "GS232Protocol::readData read direct angles Az " << az << " El " << el;
|
||||
// The format gives angles in tenths of a degree, so divide by 10
|
||||
reportAzEl(az.toFloat()/10.0f, el.toFloat()/10.0f);
|
||||
}
|
||||
else if (response == "\r\n")
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "SPIDProtocol::readData - unexpected GS-232 response \"" << response << "\"";
|
||||
qWarning() << "GS232Protocol::readData - unexpected GS-232 response \"" << response << "\"";
|
||||
reportError(QString("Unexpected GS-232 response: %1").arg(response));
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
const PluginDescriptor RigCtlServerPlugin::m_pluginDescriptor = {
|
||||
RigCtlServer::m_featureId,
|
||||
QStringLiteral("RigCtl Server"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE and Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -203,7 +203,7 @@ void RigCtlServerWorker::getCommand()
|
||||
// Set frequency
|
||||
double targetFrequency = atof(cmd[0] == 'F' ? &cmd[2] : &cmd[9]);
|
||||
setFrequency(targetFrequency, rigCtlRC);
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
else if (!strncmp(cmd, "f", 1) || !strncmp(cmd, "get_freq", 8))
|
||||
{
|
||||
@ -211,9 +211,9 @@ void RigCtlServerWorker::getCommand()
|
||||
double frequency;
|
||||
|
||||
if (getFrequency(frequency, rigCtlRC)) {
|
||||
sprintf(response, "%u\n", (unsigned int) frequency);
|
||||
snprintf(response, sizeof(response), "%u\n", (unsigned int) frequency);
|
||||
} else {
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(cmd, "M ?", 3) || !(strncmp(cmd, "set_mode ?", 10)))
|
||||
@ -263,11 +263,11 @@ void RigCtlServerWorker::getCommand()
|
||||
if (m_modeMap[i].modem != nullptr)
|
||||
{
|
||||
changeModem(targetMode, targetModem, targetBW, rigCtlRC);
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(response, "RPRT %d\n", RIG_EINVAL);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", RIG_EINVAL);
|
||||
m_clientConnection->write(response, strlen(response));
|
||||
}
|
||||
}
|
||||
@ -280,27 +280,27 @@ void RigCtlServerWorker::getCommand()
|
||||
if (getMode(&mode, passband, rigCtlRC))
|
||||
{
|
||||
if (passband < 0) {
|
||||
sprintf(response, "%s\n", mode);
|
||||
snprintf(response, sizeof(response), "%s\n", mode);
|
||||
} else {
|
||||
sprintf(response, "%s %u\n", mode, (unsigned int) passband);
|
||||
snprintf(response, sizeof(response), "%s %u\n", mode, (unsigned int) passband);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(cmd, "set_powerstat 0", 15))
|
||||
{
|
||||
// Power off radio
|
||||
setPowerOff(rigCtlRC);
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
else if (!strncmp(cmd, "set_powerstat 1", 15))
|
||||
{
|
||||
// Power on radio
|
||||
setPowerOn(rigCtlRC);
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
else if (!strncmp(cmd, "get_powerstat", 13))
|
||||
{
|
||||
@ -309,20 +309,20 @@ void RigCtlServerWorker::getCommand()
|
||||
if (getPower(power, rigCtlRC))
|
||||
{
|
||||
if (power) {
|
||||
sprintf(response, "1\n");
|
||||
snprintf(response, sizeof(response), "1\n");
|
||||
} else {
|
||||
sprintf(response, "0\n");
|
||||
snprintf(response, sizeof(response), "0\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(response, "RPRT %d\n", rigCtlRC);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", rigCtlRC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unimplemented command
|
||||
sprintf(response, "RPRT %d\n", RIG_ENIMPL);
|
||||
snprintf(response, sizeof(response), "RPRT %d\n", RIG_ENIMPL);
|
||||
m_clientConnection->write(response, strlen(response));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
const PluginDescriptor SatelliteTrackerPlugin::m_pluginDescriptor = {
|
||||
SatelliteTracker::m_featureId,
|
||||
QStringLiteral("Satellite Tracker"),
|
||||
QStringLiteral("7.22.3"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE and Daniel Warner (SGP4 library)"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -826,9 +826,7 @@ void SatelliteTrackerWorker::enableDoppler(SatWorkerState *satWorkerState)
|
||||
if (devSettings->m_doppler.size() > 0)
|
||||
{
|
||||
requiresDoppler = true;
|
||||
for (int j = 0; j < devSettings->m_doppler.size(); j++) {
|
||||
satWorkerState->m_doppler.append(0);
|
||||
}
|
||||
satWorkerState->m_doppler.append(0);
|
||||
}
|
||||
}
|
||||
if (requiresDoppler)
|
||||
@ -836,7 +834,8 @@ void SatelliteTrackerWorker::enableDoppler(SatWorkerState *satWorkerState)
|
||||
qDebug() << "SatelliteTrackerWorker::applyDeviceAOSSettings: Enabling doppler for " << satWorkerState->m_name;
|
||||
satWorkerState->m_dopplerTimer.setInterval(m_settings.m_dopplerPeriod * 1000);
|
||||
satWorkerState->m_dopplerTimer.start();
|
||||
connect(&satWorkerState->m_dopplerTimer, &QTimer::timeout, [this, satWorkerState]() {
|
||||
disconnect(satWorkerState->m_connection);
|
||||
satWorkerState->m_connection = connect(&satWorkerState->m_dopplerTimer, &QTimer::timeout, [this, satWorkerState]() {
|
||||
doppler(satWorkerState);
|
||||
});
|
||||
}
|
||||
@ -848,29 +847,46 @@ void SatelliteTrackerWorker::disableDoppler(SatWorkerState *satWorkerState)
|
||||
// Stop Doppler timer, and set interval to 0, so we don't restart it in start()
|
||||
satWorkerState->m_dopplerTimer.stop();
|
||||
satWorkerState->m_dopplerTimer.setInterval(0);
|
||||
disconnect(satWorkerState->m_connection);
|
||||
// Remove doppler correction from any channel
|
||||
QList<SatelliteTrackerSettings::SatelliteDeviceSettings *> *m_deviceSettingsList = m_settings.m_deviceSettings.value(satWorkerState->m_name);
|
||||
if (m_deviceSettingsList)
|
||||
if (satWorkerState->m_doppler.size() > 0)
|
||||
{
|
||||
for (int i = 0; i < m_deviceSettingsList->size(); i++)
|
||||
QList<SatelliteTrackerSettings::SatelliteDeviceSettings *> *m_deviceSettingsList = m_settings.m_deviceSettings.value(satWorkerState->m_name);
|
||||
if (m_deviceSettingsList)
|
||||
{
|
||||
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
|
||||
if (devSettings->m_doppler.size() > 0)
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < m_deviceSettingsList->size(); i++)
|
||||
{
|
||||
for (int j = 0; j < devSettings->m_doppler.size(); j++)
|
||||
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
|
||||
if (devSettings->m_doppler.size() > 0)
|
||||
{
|
||||
int offset;
|
||||
if (ChannelWebAPIUtils::getFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
|
||||
for (int j = 0; j < devSettings->m_doppler.size(); j++)
|
||||
{
|
||||
// Remove old doppler
|
||||
offset += satWorkerState->m_doppler[i];
|
||||
if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
|
||||
qDebug() << "SatelliteTrackerWorker::doppler: Failed to set frequency offset";
|
||||
int offset;
|
||||
if (ChannelWebAPIUtils::getFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
|
||||
{
|
||||
// Remove old doppler
|
||||
std::vector<DeviceSet*>& deviceSets = MainCore::instance()->getDeviceSets();
|
||||
ChannelAPI *channel = deviceSets[devSettings->m_deviceSetIndex]->getChannelAt(j);
|
||||
int tx = false;
|
||||
if (channel) {
|
||||
tx = channel->getStreamType() == ChannelAPI::StreamSingleSource; // What if MIMO?
|
||||
}
|
||||
if (tx) {
|
||||
offset -= satWorkerState->m_doppler[idx];
|
||||
} else {
|
||||
offset += satWorkerState->m_doppler[idx];
|
||||
}
|
||||
if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
|
||||
qDebug() << "SatelliteTrackerWorker::disableDoppler: Failed to set frequency offset";
|
||||
}
|
||||
else
|
||||
qDebug() << "SatelliteTrackerWorker::disableDoppler: Failed to get frequency offset";
|
||||
}
|
||||
else
|
||||
qDebug() << "SatelliteTrackerWorker::doppler: Failed to get frequency offset";
|
||||
satWorkerState->m_doppler[idx] = 0;
|
||||
idx++;
|
||||
}
|
||||
satWorkerState->m_doppler[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -883,6 +899,8 @@ void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState)
|
||||
QList<SatelliteTrackerSettings::SatelliteDeviceSettings *> *m_deviceSettingsList = m_settings.m_deviceSettings.value(satWorkerState->m_name);
|
||||
if (m_deviceSettingsList)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < m_deviceSettingsList->size(); i++)
|
||||
{
|
||||
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
|
||||
@ -915,15 +933,14 @@ void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState)
|
||||
int initOffset;
|
||||
if (tx)
|
||||
{
|
||||
initOffset = offset - satWorkerState->m_doppler[i];
|
||||
initOffset = offset - satWorkerState->m_doppler[idx];
|
||||
offset = initOffset + doppler;
|
||||
}
|
||||
else
|
||||
{
|
||||
initOffset = offset + satWorkerState->m_doppler[i];
|
||||
initOffset = offset + satWorkerState->m_doppler[idx];
|
||||
offset = initOffset - doppler;
|
||||
}
|
||||
|
||||
if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
|
||||
qDebug() << "SatelliteTrackerWorker::doppler: Failed to set frequency offset";
|
||||
}
|
||||
@ -931,10 +948,12 @@ void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState)
|
||||
qDebug() << "SatelliteTrackerWorker::doppler: Failed to get frequency offset";
|
||||
}
|
||||
|
||||
satWorkerState->m_doppler[i] = doppler;
|
||||
satWorkerState->m_doppler[idx] = doppler;
|
||||
}
|
||||
else
|
||||
qDebug() << "SatelliteTrackerWorker::doppler: couldn't get centre frequency for device at " << devSettings->m_deviceSetIndex;
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ protected:
|
||||
QList<int> m_doppler; // How much doppler we've applied to a channel
|
||||
SatelliteState m_satState;
|
||||
bool m_hasSignalledAOS; // For pass specified by m_aos and m_los
|
||||
QMetaObject::Connection m_connection;
|
||||
|
||||
friend SatelliteTrackerWorker;
|
||||
};
|
||||
|
@ -627,7 +627,7 @@ void AudioCATSISO::listComPorts()
|
||||
{
|
||||
m_comPorts.clear();
|
||||
std::vector<std::string> comPorts;
|
||||
SerialUtil::getComPorts(comPorts, "tty(USB|ACM)[0-9]+"); // regex is for Linux only
|
||||
SerialUtil::getComPorts(comPorts, "tty(S|USB|ACM)[0-9]+"); // regex is for Linux only
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = comPorts.begin(); it != comPorts.end(); ++it) {
|
||||
m_comPorts.push_back(QString(it->c_str()));
|
||||
|
@ -32,7 +32,7 @@
|
||||
const PluginDescriptor AudioCATSISOPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("AudioCATSISO"),
|
||||
QStringLiteral("Audio CAT SISO"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -33,7 +33,7 @@
|
||||
const PluginDescriptor MetisMISOPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("MetisMISO"),
|
||||
QStringLiteral("Metis MISO"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -16,6 +16,8 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/samplemififo.h"
|
||||
#include "dsp/samplemofifo.h"
|
||||
|
||||
|
@ -807,7 +807,9 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, const Q
|
||||
if (settingsKeys.contains("devSampleRate")
|
||||
|| settingsKeys.contains("log2HardInterp") || force)
|
||||
{
|
||||
forwardChangeAllDSP = true; //m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
//forwardChangeAllDSP = true; //m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
forwardChangeTxDSP = m_settings.m_log2HardInterp != settings.m_log2HardInterp;
|
||||
forwardChangeAllDSP = m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
|
||||
if (m_deviceShared.m_deviceParams->getDevice())
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ LimeSDROutputGUI::LimeSDROutputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
|
||||
displaySettings();
|
||||
|
||||
char recFileNameCStr[30];
|
||||
sprintf(recFileNameCStr, "test_%d.sdriq", m_deviceUISet->m_deviceAPI->getDeviceUID());
|
||||
snprintf(recFileNameCStr, sizeof(recFileNameCStr), "test_%d.sdriq", m_deviceUISet->m_deviceAPI->getDeviceUID());
|
||||
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
|
||||
|
@ -36,7 +36,7 @@
|
||||
const PluginDescriptor LimeSDROutputPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("LimeSDR"),
|
||||
QStringLiteral("LimeSDR Output"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -82,7 +82,7 @@ USRPOutputGUI::USRPOutputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
|
||||
displaySettings();
|
||||
|
||||
char recFileNameCStr[30];
|
||||
sprintf(recFileNameCStr, "test_%d.sdriq", m_deviceUISet->m_deviceAPI->getDeviceUID());
|
||||
snprintf(recFileNameCStr, sizeof(recFileNameCStr), "test_%d.sdriq", m_deviceUISet->m_deviceAPI->getDeviceUID());
|
||||
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
|
||||
|
@ -36,7 +36,7 @@
|
||||
const PluginDescriptor USRPOutputPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("USRP"),
|
||||
QStringLiteral("URSP Output"),
|
||||
QStringLiteral("7.22.6"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE and Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -33,7 +33,7 @@
|
||||
const PluginDescriptor HackRFInputPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("HackRF"),
|
||||
QStringLiteral("HackRF Input"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -969,8 +969,14 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, const QLi
|
||||
if (settingsKeys.contains("devSampleRate")
|
||||
|| settingsKeys.contains("log2HardDecim") || force)
|
||||
{
|
||||
forwardChangeAllDSP = true; //m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
|
||||
|
||||
if(!settings.m_splitFreq) {
|
||||
forwardChangeAllDSP = true; //m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
qDebug() << "LimeSDRInput::applySettings: Split is false, val:" << settings.m_splitFreq;
|
||||
}else{
|
||||
forwardChangeRxDSP = m_settings.m_log2HardDecim != settings.m_log2HardDecim;
|
||||
forwardChangeAllDSP = m_settings.m_devSampleRate != settings.m_devSampleRate;
|
||||
}
|
||||
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
|
||||
{
|
||||
if (LMS_SetSampleRateDir(m_deviceShared.m_deviceParams->getDevice(),
|
||||
@ -1439,6 +1445,9 @@ void LimeSDRInput::webapiUpdateDeviceSettings(
|
||||
if (deviceSettingsKeys.contains("dcBlock")) {
|
||||
settings.m_dcBlock = response.getLimeSdrInputSettings()->getDcBlock() != 0;
|
||||
}
|
||||
if (deviceSettingsKeys.contains("splitFreq")) {
|
||||
settings.m_splitFreq = response.getLimeSdrInputSettings()->getSplitFreq() != 0;
|
||||
}
|
||||
if (deviceSettingsKeys.contains("devSampleRate")) {
|
||||
settings.m_devSampleRate = response.getLimeSdrInputSettings()->getDevSampleRate();
|
||||
}
|
||||
@ -1521,6 +1530,7 @@ void LimeSDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re
|
||||
response.getLimeSdrInputSettings()->setAntennaPath((int) settings.m_antennaPath);
|
||||
response.getLimeSdrInputSettings()->setCenterFrequency(settings.m_centerFrequency);
|
||||
response.getLimeSdrInputSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
|
||||
response.getLimeSdrInputSettings()->setSplitFreq(settings.m_splitFreq ? 1 : 0);
|
||||
response.getLimeSdrInputSettings()->setDevSampleRate(settings.m_devSampleRate);
|
||||
response.getLimeSdrInputSettings()->setExtClock(settings.m_extClock ? 1 : 0);
|
||||
response.getLimeSdrInputSettings()->setExtClockFreq(settings.m_extClockFreq);
|
||||
@ -1653,6 +1663,9 @@ void LimeSDRInput::webapiReverseSendSettings(const QList<QString>& deviceSetting
|
||||
if (deviceSettingsKeys.contains("dcBlock") || force) {
|
||||
swgLimeSdrInputSettings->setDcBlock(settings.m_dcBlock ? 1 : 0);
|
||||
}
|
||||
if (deviceSettingsKeys.contains("splitFreq") || force) {
|
||||
swgLimeSdrInputSettings->setSplitFreq(settings.m_splitFreq ? 1 : 0);
|
||||
}
|
||||
if (deviceSettingsKeys.contains("devSampleRate") || force) {
|
||||
swgLimeSdrInputSettings->setDevSampleRate(settings.m_devSampleRate);
|
||||
}
|
||||
|
@ -428,6 +428,7 @@ void LimeSDRInputGUI::displaySettings()
|
||||
displaySampleRate();
|
||||
|
||||
ui->dcOffset->setChecked(m_settings.m_dcBlock);
|
||||
ui->splitFreq->setChecked(m_settings.m_splitFreq);
|
||||
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
|
||||
|
||||
ui->hwDecim->setCurrentIndex(m_settings.m_log2HardDecim);
|
||||
@ -635,6 +636,13 @@ void LimeSDRInputGUI::on_dcOffset_toggled(bool checked)
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void LimeSDRInputGUI::on_splitFreq_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_splitFreq = checked;
|
||||
m_settingsKeys.append("splitFreq");
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void LimeSDRInputGUI::on_iqImbalance_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_iqCorrection = checked;
|
||||
@ -939,6 +947,7 @@ void LimeSDRInputGUI::makeUIConnections()
|
||||
QObject::connect(ui->ncoFrequency, &ValueDialZ::changed, this, &LimeSDRInputGUI::on_ncoFrequency_changed);
|
||||
QObject::connect(ui->ncoEnable, &ButtonSwitch::toggled, this, &LimeSDRInputGUI::on_ncoEnable_toggled);
|
||||
QObject::connect(ui->dcOffset, &ButtonSwitch::toggled, this, &LimeSDRInputGUI::on_dcOffset_toggled);
|
||||
QObject::connect(ui->splitFreq, &ButtonSwitch::toggled, this, &LimeSDRInputGUI::on_splitFreq_toggled);
|
||||
QObject::connect(ui->iqImbalance, &ButtonSwitch::toggled, this, &LimeSDRInputGUI::on_iqImbalance_toggled);
|
||||
QObject::connect(ui->sampleRate, &ValueDial::changed, this, &LimeSDRInputGUI::on_sampleRate_changed);
|
||||
QObject::connect(ui->hwDecim, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LimeSDRInputGUI::on_hwDecim_currentIndexChanged);
|
||||
|
@ -89,6 +89,7 @@ private slots:
|
||||
void on_ncoFrequency_changed(qint64 value);
|
||||
void on_ncoEnable_toggled(bool checked);
|
||||
void on_dcOffset_toggled(bool checked);
|
||||
void on_splitFreq_toggled(bool checked);
|
||||
void on_iqImbalance_toggled(bool checked);
|
||||
void on_sampleRate_changed(quint64 value);
|
||||
void on_hwDecim_currentIndexChanged(int index);
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<width>386</width>
|
||||
<height>255</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -312,6 +312,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="splitFreq">
|
||||
<property name="toolTip">
|
||||
<string>Disable RX/TX frequency being locked</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Split</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -36,7 +36,7 @@
|
||||
const PluginDescriptor LimeSDRInputPlugin::m_pluginDescriptor = {
|
||||
QStringLiteral("LimeSDR"),
|
||||
QStringLiteral("LimeSDR Input"),
|
||||
QStringLiteral("7.22.3"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -31,6 +31,7 @@ void LimeSDRInputSettings::resetToDefaults()
|
||||
m_devSampleRate = 5000000;
|
||||
m_log2HardDecim = 3;
|
||||
m_dcBlock = false;
|
||||
m_splitFreq = false;
|
||||
m_iqCorrection = false;
|
||||
m_log2SoftDecim = 0;
|
||||
m_lpfBW = 4.5e6f;
|
||||
@ -96,6 +97,7 @@ QByteArray LimeSDRInputSettings::serialize() const
|
||||
s.writeFloat(30, m_replayLength);
|
||||
s.writeFloat(31, m_replayStep);
|
||||
s.writeBool(32, m_replayLoop);
|
||||
s.writeBool(33, m_splitFreq);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -158,6 +160,7 @@ bool LimeSDRInputSettings::deserialize(const QByteArray& data)
|
||||
d.readFloat(30, &m_replayLength, 20.0f);
|
||||
d.readFloat(31, &m_replayStep, 5.0f);
|
||||
d.readBool(32, &m_replayLoop, false);
|
||||
d.readBool(33, &m_splitFreq, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -183,6 +186,9 @@ void LimeSDRInputSettings::applySettings(const QStringList& settingsKeys, const
|
||||
if (settingsKeys.contains("dcBlock")) {
|
||||
m_dcBlock = settings.m_dcBlock;
|
||||
}
|
||||
if (settingsKeys.contains("splitFreq")) {
|
||||
m_splitFreq = settings.m_splitFreq;
|
||||
}
|
||||
if (settingsKeys.contains("iqCorrection")) {
|
||||
m_iqCorrection = settings.m_iqCorrection;
|
||||
}
|
||||
@ -285,6 +291,9 @@ QString LimeSDRInputSettings::getDebugString(const QStringList& settingsKeys, bo
|
||||
if (settingsKeys.contains("dcBlock") || force) {
|
||||
ostr << " m_dcBlock: " << m_dcBlock;
|
||||
}
|
||||
if (settingsKeys.contains("splitFreq") || force) {
|
||||
ostr << " m_splitFreq: " << m_splitFreq;
|
||||
}
|
||||
if (settingsKeys.contains("iqCorrection") || force) {
|
||||
ostr << " m_iqCorrection: " << m_iqCorrection;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ struct LimeSDRInputSettings
|
||||
uint32_t m_log2HardDecim;
|
||||
// channel settings
|
||||
bool m_dcBlock;
|
||||
bool m_splitFreq;
|
||||
bool m_iqCorrection;
|
||||
uint32_t m_log2SoftDecim;
|
||||
float m_lpfBW; //!< LMS amalog lowpass filter bandwidth (Hz)
|
||||
|
@ -32,6 +32,23 @@ Normal sequence of operations:
|
||||
- In SDRangel connect the Frequency Tracker plugin by clicking on the grey square at the left of the top bar of the Frequency Tracker GUI. It opens the channel settings dialog. Check the 'Reverse API' box. Next to this box is the address and port at which the channel will be connected. If you use the defaults for `freqtracking.py` you may leave it as it is else you have to adjust it to the address and port of `freqtracking.py` (options `-A` and `-P`).
|
||||
- In the same manner connect the channel you want to be controlled by `freqtracking.py`. You may connect any number of channels like this. When a channel is removed `freqtracking.py` will automatically remove it from its list at the first attempt to synchronize that will fail.
|
||||
|
||||
<h2>plutodvbrpt.py</h2>
|
||||
|
||||
Control PlutoDVB2 Tx firmware from SDRangel DATV demod as Rx. This is to effectively implement a DATV repeater based on SDRangel (supposedly sdrangelsrv running on a RPi5 or mini PC) as the receiver and a Pluto equipped with F5OEO PlutoDVB2 firmware as the transmitter. PlutoDVB2 has not such a thing as a "vox" on its UDP TS input so it needs an external command (via MQTT) to switch on/off Tx when the UDP flux starts or stops.
|
||||
|
||||
This script polls the DATV Demod channel report every second via the REST API interface and sends appropriate command to the Pluto to switch Tx on or off according to the UDP status. In addition it can clone the DVBS2 essential parameters to the Tx to match exactly the input parameters on the Rx. These are symbol rate, modulation and FEC.
|
||||
|
||||
- `-h` or `--help` show help message and exit
|
||||
- `-a` or `--sdr_address` SDRangel address and port. Default: `127.0.0.1:8091`
|
||||
- `-d` or `--device` index of device set. Default `0`
|
||||
- `-c` or `--channel` Index of DATV demod channel. Default `0`
|
||||
- `-A` or `--pluto_address` Pluto MQTT address. Mandatory
|
||||
- `-P` or `--pluto_port` Pluto MQTT port. Default `1883`
|
||||
- `-C` or `--callsign` Amateur Radio callsign. Mandatory
|
||||
- `-l` or `--clone` Clone symbol rate, constellation and fec to Pluto
|
||||
|
||||
The Pluto address and amateur radio callsign have to be specified. The rest have default values as mentioned.
|
||||
|
||||
<h2>ptt_feature.py</h2>
|
||||
|
||||
Control a PTT feature and optionally a LimeRFE feature in coordination.
|
||||
|
304
scriptsapi/plutodvbrpt.py
Executable file
304
scriptsapi/plutodvbrpt.py
Executable file
@ -0,0 +1,304 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Control PlutoDVB2 enabled Pluto Tx switchover watching UDP status of a DATV demodulator channel
|
||||
This is a way to implement a DATV repeater system
|
||||
Uses PlutoDVB2 MQTT "mute" command to switch on/off the Tx
|
||||
"""
|
||||
from optparse import OptionParser # pylint: disable=deprecated-module
|
||||
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import signal
|
||||
import traceback
|
||||
import sys
|
||||
import time
|
||||
import requests
|
||||
import paho.mqtt.client as mqttclient
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
mqtt_client = None
|
||||
pluto_state = {}
|
||||
|
||||
FEC_TABLE = {
|
||||
0: "1/2",
|
||||
1: "2/3",
|
||||
2: "4/6",
|
||||
3: "3/4",
|
||||
4: "5/6",
|
||||
5: "7/8",
|
||||
6: "4/5",
|
||||
7: "8/9",
|
||||
8: "9/10",
|
||||
9: "1/4",
|
||||
10: "1/3",
|
||||
11: "2/5",
|
||||
12: "3/5"
|
||||
}
|
||||
|
||||
CONSTEL_TABLE = {
|
||||
0: "BPSK",
|
||||
1: "QPSK",
|
||||
2: "PSK8",
|
||||
3: "APSK16",
|
||||
4: "APSK32",
|
||||
5: "APSK64E",
|
||||
6: "QAM16",
|
||||
7: "QAM64",
|
||||
8: "QAM256"
|
||||
}
|
||||
|
||||
# ======================================================================
|
||||
def signal_handler(signum, frame):
|
||||
""" Signal handler """
|
||||
logger.info("Signal handler called with signal %d", signum)
|
||||
# Clean up and exit
|
||||
# Close MQTT connection
|
||||
if mqtt_client:
|
||||
mqtt_client.disconnect()
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
# ======================================================================
|
||||
def get_input_options():
|
||||
""" Parse options """
|
||||
# ----------------------------------------------------------------------
|
||||
parser = OptionParser(usage="usage: %%prog [-t]\n")
|
||||
parser.add_option("-a", "--sdr_address", dest="sdr_address", help="SDRangel address and port. Default: 127.0.0.1:8091", metavar="ADDRESS:PORT", type="string")
|
||||
parser.add_option("-d", "--device", dest="device_index", help="Index of device set. Default 0", metavar="INT", type="int")
|
||||
parser.add_option("-c", "--channel", dest="channel_index", help="Index of DATV demod channel. Default 0", metavar="INT", type="int")
|
||||
parser.add_option("-A", "--pluto_address", dest="pluto_address", help="Pluto MQTT address and port. Mandatory", metavar="ADDRESS", type="string")
|
||||
parser.add_option("-P", "--pluto_port", dest="pluto_port", help="Pluto MQTT port. Default 1883", metavar="INT", type="int")
|
||||
parser.add_option("-C", "--callsign", dest="callsign", help="Amateur Radio callsign", metavar="CALLSIGN", type="string")
|
||||
parser.add_option("-l", "--clone", dest="clone", help="Clone symbol rate, constellation and fec to Pluto", metavar="BOOL", action="store_true", default=False)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if options.sdr_address is None:
|
||||
options.sdr_address = "127.0.0.1:8091"
|
||||
if options.device_index is None:
|
||||
options.device_index = 0
|
||||
if options.channel_index is None:
|
||||
options.channel_index = 0
|
||||
if options.pluto_port is None:
|
||||
options.pluto_port = 1883
|
||||
if options.pluto_address is None:
|
||||
raise RuntimeError("Pluto address (-A or --pluto_address) is mandatory")
|
||||
if options.callsign is None:
|
||||
raise RuntimeError("Callsign (-C or --callsign) is mandatory")
|
||||
|
||||
return options
|
||||
|
||||
# ======================================================================
|
||||
def pluto_state_change(state, value):
|
||||
""" Change Pluto state """
|
||||
# ----------------------------------------------------------------------
|
||||
global pluto_state
|
||||
if state not in pluto_state:
|
||||
pluto_state[state] = value
|
||||
else:
|
||||
pluto_state[state] = value
|
||||
logger.debug("Pluto state changed: %s = %s", state, value)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def connect_mqtt(options):
|
||||
""" Connect to Pluto MQTT broker """
|
||||
# ----------------------------------------------------------------------
|
||||
global mqtt_client
|
||||
mqtt_client = mqttclient.Client()
|
||||
mqtt_client.enable_logger(logger)
|
||||
mqtt_client.on_connect = on_connect
|
||||
mqtt_client.on_message = on_message
|
||||
mqtt_client.on_subscribe = on_subscribe
|
||||
|
||||
# Connect to the MQTT broker
|
||||
logger.info("Connecting to Pluto MQTT broker at %s:%d", options.pluto_address, options.pluto_port)
|
||||
try:
|
||||
mqtt_client.connect(options.pluto_address, options.pluto_port, 60)
|
||||
mqtt_client.loop_start()
|
||||
except Exception as ex:
|
||||
raise RuntimeError(f"Failed to connect to Pluto MQTT broker: {ex}")
|
||||
logger.info("Connected to Pluto MQTT broker at %s:%d", options.pluto_address, options.pluto_port)
|
||||
return mqtt_client
|
||||
|
||||
# ======================================================================
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
""" Callback for MQTT connection """
|
||||
# ----------------------------------------------------------------------
|
||||
logger.info("Connected to MQTT broker with result code %d", rc)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def on_message(client, userdata, msg):
|
||||
""" Callback for MQTT message """
|
||||
# ----------------------------------------------------------------------
|
||||
logger.debug("Received message on topic %s: %s", msg.topic, msg.payload)
|
||||
# Parse the message
|
||||
try:
|
||||
if msg.topic.endswith("/mute"):
|
||||
logger.debug("Tx mute message received")
|
||||
pluto_state_change("muted", msg.payload == b'1')
|
||||
elif msg.topic.endswith("/sr"):
|
||||
logger.debug("Tx symbol rate message received: %d", int(msg.payload))
|
||||
pluto_state_change("symbol_rate", int(msg.payload))
|
||||
elif msg.topic.endswith("/constel"):
|
||||
logger.debug("Tx constellation message received: %s", msg.payload.decode('utf-8'))
|
||||
pluto_state_change("constellation", msg.payload.decode('utf-8'))
|
||||
elif msg.topic.endswith("/fec"):
|
||||
logger.debug("Tx fec message received: %s", msg.payload.decode('utf-8'))
|
||||
pluto_state_change("fec", msg.payload.decode('utf-8'))
|
||||
else:
|
||||
message = json.loads(msg.payload)
|
||||
logger.debug("Message payload is JSON: %s", message)
|
||||
except json.JSONDecodeError as ex:
|
||||
logger.error("Failed to decode JSON message: %s", ex)
|
||||
except Exception as ex:
|
||||
logger.error("Failed to handle message: %s", ex)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def on_subscribe(client, userdata, mid, granted_qos):
|
||||
""" Callback for MQTT subscription """
|
||||
# ----------------------------------------------------------------------
|
||||
logger.info("Subscribed to topic with mid %d and granted QoS %s", mid, granted_qos)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def subscribe_to_pluto(options, mqtt_client):
|
||||
""" Subscribe to Pluto MQTT broker """
|
||||
# ----------------------------------------------------------------------
|
||||
if mqtt_client is None:
|
||||
raise RuntimeError("MQTT client is not connected")
|
||||
tx_base_topic = f"dt/pluto/{options.callsign.upper()}/tx"
|
||||
mute_dt_topic = f"{tx_base_topic}/mute"
|
||||
logger.info("Subscribing to topic %s", mute_dt_topic)
|
||||
mqtt_client.subscribe(mute_dt_topic)
|
||||
logger.info("Subscribed to topic %s", mute_dt_topic)
|
||||
if options.clone:
|
||||
# Subscribe to Pluto Tx symbol rate
|
||||
symbol_rate_topic = f"{tx_base_topic}/dvbs2/sr"
|
||||
logger.info("Subscribing to topic %s", symbol_rate_topic)
|
||||
mqtt_client.subscribe(symbol_rate_topic)
|
||||
# Subscribe to Pluto Tx constellation
|
||||
constellation_topic = f"{tx_base_topic}/dvbs2/constel"
|
||||
logger.info("Subscribing to topic %s", constellation_topic)
|
||||
mqtt_client.subscribe(constellation_topic)
|
||||
# Subscribe to Pluto Tx fec
|
||||
fec_topic = f"{tx_base_topic}/dvbs2/fec"
|
||||
logger.info("Subscribing to topic %s", fec_topic)
|
||||
mqtt_client.subscribe(fec_topic)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def mute_pluto_tx(options, mute):
|
||||
""" Mute or unmute Pluto Tx """
|
||||
# ----------------------------------------------------------------------
|
||||
global mqtt_client
|
||||
if mqtt_client is None:
|
||||
raise RuntimeError("MQTT client is not connected")
|
||||
topic = f"cmd/pluto/{options.callsign.upper()}/tx/mute"
|
||||
message = b'1' if mute else b'0'
|
||||
logger.info("Publishing message to topic %s: %s", topic, message)
|
||||
mqtt_client.publish(topic, message)
|
||||
logger.info("Published message to topic %s", topic)
|
||||
# Update Pluto state
|
||||
pluto_state_change("muted", mute)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def set_pluto_tx_dvbs2(options, symbol_rate, constellation, fec):
|
||||
""" Set Pluto Tx DVBS2 parameters """
|
||||
# ----------------------------------------------------------------------
|
||||
global mqtt_client
|
||||
if mqtt_client is None:
|
||||
raise RuntimeError("MQTT client is not connected")
|
||||
topic_dvbs2 = f"cmd/pluto/{options.callsign.upper()}/tx/dvbs2"
|
||||
topic_sr = f"{topic_dvbs2}/sr"
|
||||
topic_constel = f"{topic_dvbs2}/constel"
|
||||
topic_fec = f"{topic_dvbs2}/fec"
|
||||
logger.info("Publishing message to topic %s: %d", topic_sr, symbol_rate)
|
||||
mqtt_client.publish(topic_sr, symbol_rate)
|
||||
logger.info("Published message to topic %s", topic_sr)
|
||||
logger.info("Publishing message to topic %s: %s", topic_constel, constellation)
|
||||
mqtt_client.publish(topic_constel, constellation)
|
||||
logger.info("Published message to topic %s", topic_constel)
|
||||
logger.info("Publishing message to topic %s: %s", topic_fec, fec)
|
||||
mqtt_client.publish(topic_fec, fec)
|
||||
logger.info("Published message to topic %s", topic_fec)
|
||||
# Update Pluto state
|
||||
pluto_state_change("symbol_rate", symbol_rate)
|
||||
pluto_state_change("constellation", constellation)
|
||||
pluto_state_change("fec", fec)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def monitor_datv_demod(options):
|
||||
""" Monitor DATV demodulator channel and control Pluto Tx """
|
||||
# ----------------------------------------------------------------------
|
||||
# Check DATV demodulator channel status
|
||||
sdrangel_url = f"http://{options.sdr_address}/sdrangel"
|
||||
report_url = f"{sdrangel_url}/deviceset/{options.device_index}/channel/{options.channel_index}/report"
|
||||
response = requests.get(report_url)
|
||||
if response.status_code != 200:
|
||||
raise RuntimeError(f"Failed to read report at {report_url}")
|
||||
datv_channel_report = response.json().get("DATVDemodReport", None)
|
||||
if not datv_channel_report:
|
||||
raise RuntimeError(f"Failed to read DATV demodulator report at {report_url}")
|
||||
udp_running = datv_channel_report.get("udpRunning", None)
|
||||
if udp_running is None:
|
||||
raise RuntimeError(f"Failed to read udpRunning in {datv_channel_report}")
|
||||
logger.debug("DATV UDP: %d", udp_running)
|
||||
if "muted" in pluto_state and pluto_state["muted"] == udp_running or "muted" not in pluto_state:
|
||||
logger.info("Pluto Tx %s", "muted" if not udp_running else "unmuted")
|
||||
mute_pluto_tx(options, not udp_running)
|
||||
logger.info("Pluto state: %s", pluto_state)
|
||||
if options.clone and datv_channel_report.get("setByModcod", None):
|
||||
mod = datv_channel_report.get("modcodModulation", -1)
|
||||
logger.debug("DATV Modulation: %s", CONSTEL_TABLE.get(mod, "Unknown"))
|
||||
fec = datv_channel_report.get("modcodCodeRate", -1)
|
||||
logger.debug("DATV FEC: %s", FEC_TABLE.get(fec, "Unknown"))
|
||||
symbol_rate = datv_channel_report.get("symbolRate", 0)
|
||||
logger.debug("DATV Symbol Rate: %d", symbol_rate)
|
||||
if "symbol_rate" in pluto_state and pluto_state["symbol_rate"] == symbol_rate and \
|
||||
"constellation" in pluto_state and pluto_state["constellation"].upper() == CONSTEL_TABLE.get(mod, "Unknown") and \
|
||||
"fec" in pluto_state and pluto_state["fec"] == FEC_TABLE.get(fec, "Unknown"):
|
||||
logger.debug("Pluto Tx parameters unchanged")
|
||||
else:
|
||||
logger.info("Pluto Tx parameters changed")
|
||||
set_pluto_tx_dvbs2(options, symbol_rate, CONSTEL_TABLE.get(mod, "Unknown").lower(), FEC_TABLE.get(fec, "Unknown"))
|
||||
logger.info("Pluto state: %s", pluto_state)
|
||||
return
|
||||
|
||||
# ======================================================================
|
||||
def main():
|
||||
""" Main program """
|
||||
# ----------------------------------------------------------------------
|
||||
try:
|
||||
FORMAT = '%(asctime)s %(levelname)s %(message)s'
|
||||
logging.basicConfig(format=FORMAT, level=logging.INFO)
|
||||
options = get_input_options()
|
||||
|
||||
connect_mqtt(options)
|
||||
subscribe_to_pluto(options, mqtt_client)
|
||||
|
||||
# Run forever
|
||||
logger.info("Start monitoring SDRangel channel %d:%d at %s", options.device_index, options.channel_index, options.sdr_address)
|
||||
while True:
|
||||
# Monitor DATV demodulator channel
|
||||
monitor_datv_demod(options)
|
||||
|
||||
# Sleep for a while before checking again
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as ex: # pylint: disable=broad-except
|
||||
tb = traceback.format_exc()
|
||||
print(f"Exception caught {ex}")
|
||||
print(tb, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# ======================================================================
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1354,6 +1354,63 @@ bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QStr
|
||||
}
|
||||
}
|
||||
|
||||
bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QString &setting, double value)
|
||||
{
|
||||
SWGSDRangel::SWGDeviceSettings deviceSettingsResponse;
|
||||
QString errorResponse;
|
||||
int httpRC;
|
||||
DeviceSet *deviceSet;
|
||||
|
||||
if (getDeviceSettings(deviceIndex, deviceSettingsResponse, deviceSet))
|
||||
{
|
||||
// Patch setting
|
||||
QJsonObject *jsonObj = deviceSettingsResponse.asJsonObject();
|
||||
double oldValue;
|
||||
if (WebAPIUtils::getSubObjectDouble(*jsonObj, setting, oldValue))
|
||||
{
|
||||
WebAPIUtils::setSubObjectDouble(*jsonObj, setting, value);
|
||||
QStringList deviceSettingsKeys;
|
||||
deviceSettingsKeys.append(setting);
|
||||
deviceSettingsResponse.init();
|
||||
deviceSettingsResponse.fromJsonObject(*jsonObj);
|
||||
SWGSDRangel::SWGErrorResponse errorResponse2;
|
||||
delete jsonObj;
|
||||
|
||||
if (DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource()) {
|
||||
httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage());
|
||||
} else if (DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink()) {
|
||||
httpRC = sink->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage());
|
||||
} else if (DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO()) {
|
||||
httpRC = mimo->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage());
|
||||
} else {
|
||||
httpRC = 404;
|
||||
}
|
||||
|
||||
if (httpRC/100 == 2)
|
||||
{
|
||||
qDebug("ChannelWebAPIUtils::patchDeviceSetting: set device setting %s OK", qPrintable(setting));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("ChannelWebAPIUtils::patchDeviceSetting: set device setting error %d: %s",
|
||||
httpRC, qPrintable(*errorResponse2.getMessage()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete jsonObj;
|
||||
qWarning("ChannelWebAPIUtils::patchDeviceSetting: no key %s in device settings", qPrintable(setting));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set feature setting
|
||||
bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, const QString &value)
|
||||
{
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
static bool getDeviceReportList(unsigned int deviceIndex, const QString &key, const QString &subKey, QList<int> &values);
|
||||
static bool getDevicePosition(unsigned int deviceIndex, float& latitude, float& longitude, float& altitude);
|
||||
static bool patchDeviceSetting(unsigned int deviceIndex, const QString &setting, int value);
|
||||
static bool patchDeviceSetting(unsigned int deviceIndex, const QString &setting, double value);
|
||||
static bool runFeature(unsigned int featureSetIndex, unsigned int featureIndex);
|
||||
static bool stopFeature(unsigned int featureSetIndex, unsigned int featureIndex);
|
||||
static bool patchFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, const QString &value);
|
||||
|
@ -135,10 +135,12 @@
|
||||
<file>webapi/doc/swagger/include/VORLocalizer.yaml</file>
|
||||
<file>webapi/doc/swagger/include/WFMDemod.yaml</file>
|
||||
<file>webapi/doc/swagger/include/WFMMod.yaml</file>
|
||||
<file>webapi/doc/swagger/include/WDSPRx.yaml</file>
|
||||
<file>webapi/doc/swagger/include/Xtrx.yaml</file>
|
||||
<file>webapi/doc/swagger-ui/favicon-16x16.png</file>
|
||||
<file>webapi/doc/swagger-ui/favicon-32x32.png</file>
|
||||
<file>webapi/doc/swagger-ui/index.html</file>
|
||||
<file>webapi/doc/swagger-ui/index.css</file>
|
||||
<file>webapi/doc/swagger-ui/oauth2-redirect.html</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui-bundle.js</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui-bundle.js.map</file>
|
||||
@ -148,6 +150,7 @@
|
||||
<file>webapi/doc/swagger-ui/swagger-ui-es-bundle.js.map</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js.map</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-initializer.js</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui.css</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui.css.map</file>
|
||||
<file>webapi/doc/swagger-ui/swagger-ui.js</file>
|
||||
|
@ -4877,6 +4877,10 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "UDP thread (1 running, 0 idle)"
|
||||
},
|
||||
"symbolRate" : {
|
||||
"type" : "integer",
|
||||
"description" : "Symbol rate in symbols per second - repeated from settings for convenience\n"
|
||||
},
|
||||
"modcodModulation" : {
|
||||
"type" : "integer",
|
||||
"description" : "Modulation set by DVB-S2 MODCOD\n * -1: Unset\n * 0: BPSK\n * 1: QPSK\n * 2: PSK8\n * 3: APSK16\n * 4: APSK32\n * 5: APSK64E\n * 6: QAM16\n * 7: QAM64\n * 8: QAM256\n"
|
||||
@ -4930,10 +4934,6 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "(boolean) engage sodt LDPC with LDPC tool sub processes (Linux only)"
|
||||
},
|
||||
"softLDPCToolPath" : {
|
||||
"type" : "string",
|
||||
"description" : "O/S path to the LDPC tool binary"
|
||||
},
|
||||
"softLDPCMaxTrials" : {
|
||||
"type" : "integer",
|
||||
"description" : "maximum number of trials in the soft LDPC algorithm (LDPC tool parameter)"
|
||||
@ -5530,6 +5530,7 @@ margin-bottom: 20px;
|
||||
"description" : "List of DV serial devices available in the system"
|
||||
};
|
||||
defs.DemodAnalyzerActions = {
|
||||
"required" : [ "channelId", "deviceId" ],
|
||||
"properties" : {
|
||||
"deviceId" : {
|
||||
"type" : "integer",
|
||||
@ -8962,6 +8963,9 @@ margin-bottom: 20px;
|
||||
"dcBlock" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"splitFreq" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"iqCorrection" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
@ -10716,6 +10720,7 @@ margin-bottom: 20px;
|
||||
"description" : "MetisMISOSettings"
|
||||
};
|
||||
defs.MorseDecoderActions = {
|
||||
"required" : [ "channelId", "deviceId" ],
|
||||
"properties" : {
|
||||
"deviceId" : {
|
||||
"type" : "integer",
|
||||
@ -13386,10 +13391,12 @@ margin-bottom: 20px;
|
||||
"type" : "integer"
|
||||
},
|
||||
"deviceIndex" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "remote SDRangel instance deviceset index"
|
||||
},
|
||||
"channelIndex" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "remote SDRangel instance channel index"
|
||||
},
|
||||
"useReverseAPI" : {
|
||||
"type" : "integer",
|
||||
@ -17359,7 +17366,8 @@ margin-bottom: 20px;
|
||||
},
|
||||
"nbLeadTime" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Advance time (s)"
|
||||
},
|
||||
"nbLagTime" : {
|
||||
"type" : "number",
|
||||
@ -59601,7 +59609,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2025-03-06T14:54:56.926+01:00
|
||||
Generated 2025-06-02T13:08:26.366+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
16
sdrbase/resources/webapi/doc/swagger-ui/index.css
Normal file
16
sdrbase/resources/webapi/doc/swagger-ui/index.css
Normal file
@ -0,0 +1,16 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fafafa;
|
||||
}
|
@ -4,35 +4,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
|
||||
<link rel="stylesheet" type="text/css" href="index.css" />
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script>
|
||||
|
@ -4,8 +4,6 @@
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
@ -15,31 +13,32 @@
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
qp = window.location.hash.substring(1).replace('?', '&');
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
|
||||
});
|
||||
}
|
||||
|
||||
@ -48,7 +47,7 @@
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
@ -59,7 +58,7 @@
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -68,7 +67,13 @@
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
if (document.readyState !== 'loading') {
|
||||
run();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,20 @@
|
||||
window.onload = function() {
|
||||
//<editor-fold desc="Changeable Configuration Block">
|
||||
|
||||
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: "https://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
});
|
||||
|
||||
//</editor-fold>
|
||||
};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -48,9 +48,6 @@ DATVDemodSettings:
|
||||
softLDPC:
|
||||
description: (boolean) engage sodt LDPC with LDPC tool sub processes (Linux only)
|
||||
type: integer
|
||||
softLDPCToolPath:
|
||||
description: O/S path to the LDPC tool binary
|
||||
type: string
|
||||
softLDPCMaxTrials:
|
||||
description: maximum number of trials in the soft LDPC algorithm (LDPC tool parameter)
|
||||
type: integer
|
||||
@ -148,6 +145,10 @@ DATVDemodReport:
|
||||
udpRunning:
|
||||
description: UDP thread (1 running, 0 idle)
|
||||
type: integer
|
||||
symbolRate:
|
||||
type: integer
|
||||
description: >
|
||||
Symbol rate in symbols per second - repeated from settings for convenience
|
||||
modcodModulation:
|
||||
type: integer
|
||||
description: >
|
||||
|
@ -42,12 +42,13 @@ DemodAnalyzerSettings:
|
||||
|
||||
DemodAnalyzerActions:
|
||||
description: "Demod Analyzer actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Channel Id/Number of the channel within the device"
|
||||
|
@ -10,6 +10,8 @@ LimeSdrInputSettings:
|
||||
type: integer
|
||||
dcBlock:
|
||||
type: integer
|
||||
splitFreq:
|
||||
type: integer
|
||||
iqCorrection:
|
||||
type: integer
|
||||
log2SoftDecim:
|
||||
|
@ -59,12 +59,13 @@ MorseDecoderSettings:
|
||||
|
||||
MorseDecoderActions:
|
||||
description: "Morse Decoder actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Channel Id/Number of the channel within the device"
|
||||
|
@ -19,10 +19,10 @@ RemoteOutputSettings:
|
||||
dataPort:
|
||||
type: integer
|
||||
deviceIndex:
|
||||
device: remote SDRangel instance deviceset index
|
||||
description: remote SDRangel instance deviceset index
|
||||
type: integer
|
||||
channelIndex:
|
||||
device: remote SDRangel instance channel index
|
||||
description: remote SDRangel instance channel index
|
||||
type: integer
|
||||
useReverseAPI:
|
||||
description: Synchronize with reverse API (1 for yes, 0 for no)
|
||||
|
@ -76,7 +76,7 @@ WDSPRxSettings:
|
||||
nbLeadTime:
|
||||
type: number
|
||||
format: float
|
||||
descriuption: Advance time (s)
|
||||
description: Advance time (s)
|
||||
nbLagTime:
|
||||
type: number
|
||||
format: float
|
||||
|
@ -2973,7 +2973,6 @@ definitions:
|
||||
FeatureSet:
|
||||
description: "Grouping of features"
|
||||
required:
|
||||
- index
|
||||
- featurecount
|
||||
properties:
|
||||
featurecount:
|
||||
@ -3018,7 +3017,6 @@ definitions:
|
||||
required:
|
||||
- index
|
||||
- hwType
|
||||
- streamIndex
|
||||
- sequence
|
||||
- serial
|
||||
- centerFrequency
|
||||
@ -3422,7 +3420,6 @@ definitions:
|
||||
description: "Group of configuration"
|
||||
required:
|
||||
- groupName
|
||||
- nbPresets
|
||||
properties:
|
||||
groupName:
|
||||
description: "Name of the configuration group"
|
||||
@ -3530,4 +3527,3 @@ responses:
|
||||
description: Function not implemented
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
|
||||
|
@ -44,7 +44,7 @@ void SerialUtil::getComPorts(std::vector<std::string>& comPorts, const std::stri
|
||||
|
||||
for (int i = 0; i<255; i++) // checking ports from COM0 to COM255
|
||||
{
|
||||
sprintf(portName, "COM%d", i);
|
||||
snprintf(portName, sizeof(portName), "COM%d", i);
|
||||
|
||||
test = QueryDosDeviceA((LPCSTR)portName, (LPSTR)lpTargetPath, 5000);
|
||||
|
||||
|
@ -22,6 +22,18 @@ services:
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 172.20.0.3
|
||||
swaggerclient:
|
||||
image: "jeanberu/swagger-cli"
|
||||
user: "1000:1000"
|
||||
entrypoint: "/bin/sh"
|
||||
container_name: "sdrangel_swaggerclient"
|
||||
volumes:
|
||||
- "${SDRANGEL_BASE}:/opt/build/sdrangel:rw"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 172.20.0.4
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
|
@ -41,8 +41,14 @@ Use `run.sh` to create or delete the Docker compose stack. It takes the followin
|
||||
- `-b`: SDRangel source code root path (default `/opt/build/sdrangel`)
|
||||
- `-c`: Compose stack name (default `sdrangelswg`)
|
||||
|
||||
The stack is composed of two containers sharing the `172.20.0.0/16` network internally.
|
||||
The stack is composed of three containers sharing the `172.20.0.0/16` network internally.
|
||||
- `sdrangel_swgserver`: The http server that listens on port `8081` serving files in `/opt/build/sdrangel/swagger/sdrangel`
|
||||
- `sdrangel_swgcodegen`: The container with the Swagger code generator. The working directory is `/opt/build/sdrangel/swagger/sdrangel`.
|
||||
- `sdrangel_swgcodegen`: The container with the Swagger code generator. The working directory is `/opt/build/sdrangel/swagger/sdrangel`
|
||||
- `sdrangel_swaggerclient`: based on the `jeanberu/swagger-cli` image it can be used to validate the swagger schema (see next).
|
||||
|
||||
Use `login.sh` to start a shell in the `sdrangel_swgcodegen` container. At the prompt run `generate.sh` to generate the code from the Swagger definition files.
|
||||
|
||||
To validate the swagger schema:
|
||||
- Enter the `sdrangel_swaggerclient` container with: `docker exec -it sdrangel_swaggerclient /bin/sh`
|
||||
- Validate the schema with the command: `swagger-cli validate /opt/build/sdrangel/swagger/sdrangel/api/swagger/swagger.yaml`
|
||||
- Correct errors from the most inner ones (maximum tabs). Top level errors usually result from low level errors and are therefore quite cryptic.
|
||||
|
@ -48,9 +48,6 @@ DATVDemodSettings:
|
||||
softLDPC:
|
||||
description: (boolean) engage sodt LDPC with LDPC tool sub processes (Linux only)
|
||||
type: integer
|
||||
softLDPCToolPath:
|
||||
description: O/S path to the LDPC tool binary
|
||||
type: string
|
||||
softLDPCMaxTrials:
|
||||
description: maximum number of trials in the soft LDPC algorithm (LDPC tool parameter)
|
||||
type: integer
|
||||
@ -148,6 +145,10 @@ DATVDemodReport:
|
||||
udpRunning:
|
||||
description: UDP thread (1 running, 0 idle)
|
||||
type: integer
|
||||
symbolRate:
|
||||
type: integer
|
||||
description: >
|
||||
Symbol rate in symbols per second - repeated from settings for convenience
|
||||
modcodModulation:
|
||||
type: integer
|
||||
description: >
|
||||
|
@ -42,12 +42,13 @@ DemodAnalyzerSettings:
|
||||
|
||||
DemodAnalyzerActions:
|
||||
description: "Demod Analyzer actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Channel Id/Number of the channel within the device"
|
||||
|
@ -10,6 +10,8 @@ LimeSdrInputSettings:
|
||||
type: integer
|
||||
dcBlock:
|
||||
type: integer
|
||||
splitFreq:
|
||||
type: integer
|
||||
iqCorrection:
|
||||
type: integer
|
||||
log2SoftDecim:
|
||||
|
@ -59,12 +59,13 @@ MorseDecoderSettings:
|
||||
|
||||
MorseDecoderActions:
|
||||
description: "Morse Decoder actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
required: true
|
||||
description: "Channel Id/Number of the channel within the device"
|
||||
|
@ -19,10 +19,10 @@ RemoteOutputSettings:
|
||||
dataPort:
|
||||
type: integer
|
||||
deviceIndex:
|
||||
device: remote SDRangel instance deviceset index
|
||||
description: remote SDRangel instance deviceset index
|
||||
type: integer
|
||||
channelIndex:
|
||||
device: remote SDRangel instance channel index
|
||||
description: remote SDRangel instance channel index
|
||||
type: integer
|
||||
useReverseAPI:
|
||||
description: Synchronize with reverse API (1 for yes, 0 for no)
|
||||
|
@ -76,7 +76,7 @@ WDSPRxSettings:
|
||||
nbLeadTime:
|
||||
type: number
|
||||
format: float
|
||||
descriuption: Advance time (s)
|
||||
description: Advance time (s)
|
||||
nbLagTime:
|
||||
type: number
|
||||
format: float
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user