Compare commits
	
		
			22 Commits
		
	
	
		
			active_arr
			...
			develop
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 57f55bbdd5 | ||
|   | e8ba61bb81 | ||
|   | cb5b2e64af | ||
|   | 685b9970d2 | ||
|   | c385a8f6b1 | ||
|   | aa60b9d4a7 | ||
|   | bff09e3363 | ||
|   | 774f8bd91a | ||
|   | b1684908a4 | ||
|   | ed76fd7606 | ||
|   | 7b3f212ccb | ||
|   | 216a3db45d | ||
|   | c16de474c6 | ||
|   | afcd8277d1 | ||
|   | 525b70d495 | ||
|   | f58023f3e5 | ||
|   | 252edb7a5a | ||
|   | 2993cc4279 | ||
|   | cc4f3c6c1d | ||
|   | 0de597481c | ||
|   | 2342bb5d29 | ||
|   | b1ac8caf9b | 
| @@ -1,5 +1,6 @@ | ||||
| **unreleased** | ||||
| - SDR device log messages are now available in the web configuration to simplify troubleshooting | ||||
| - Added support for the MSK144 digimode | ||||
|  | ||||
| **1.2.1** | ||||
| - FifiSDR support fixed (pipeline formats now line up correctly) | ||||
|   | ||||
| @@ -14,7 +14,7 @@ It has the following features: | ||||
| - supports a wide range of [SDR hardware](https://github.com/jketterl/openwebrx/wiki/Supported-Hardware#sdr-devices) | ||||
| - Multiple SDR devices can be used simultaneously | ||||
| - [digiham](https://github.com/jketterl/digiham) based demodularors (DMR, YSF, Pocsag, D-Star, NXDN) | ||||
| - [wsjt-x](https://physics.princeton.edu/pulsar/k1jt/wsjtx.html) based demodulators (FT8, FT4, WSPR, JT65, JT9, FST4, | ||||
| - [wsjt-x](https://wsjt.sourceforge.io/) based demodulators (FT8, FT4, WSPR, JT65, JT9, FST4, | ||||
|   FST4W) | ||||
| - [direwolf](https://github.com/wb2osz/direwolf) based demodulation of APRS packets | ||||
| - [JS8Call](http://js8call.com/) support | ||||
|   | ||||
							
								
								
									
										12
									
								
								bands.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								bands.json
									
									
									
									
									
								
							| @@ -177,7 +177,8 @@ | ||||
|       "jt9": 50312000, | ||||
|       "ft4": 50318000, | ||||
|       "js8": 50318000, | ||||
|       "q65": [50211000, 50275000] | ||||
|       "q65": [50211000, 50275000], | ||||
|       "msk144": 50260000 | ||||
|     }, | ||||
|     "tags": ["hamradio"] | ||||
|   }, | ||||
| @@ -186,7 +187,8 @@ | ||||
|     "lower_bound": 70150000, | ||||
|     "upper_bound": 70200000, | ||||
|     "frequencies": { | ||||
|       "wspr": 70091000 | ||||
|       "wspr": 70091000, | ||||
|       "msk144": 70230000 | ||||
|     }, | ||||
|     "tags": ["hamradio"] | ||||
|   }, | ||||
| @@ -200,7 +202,8 @@ | ||||
|       "ft4": 144170000, | ||||
|       "jt65": 144120000, | ||||
|       "packet": 144800000, | ||||
|       "q65": 144116000 | ||||
|       "q65": 144116000, | ||||
|       "msk144": 144360000 | ||||
|     }, | ||||
|     "tags": ["hamradio"] | ||||
|   }, | ||||
| @@ -210,7 +213,8 @@ | ||||
|     "upper_bound": 440000000, | ||||
|     "frequencies": { | ||||
|       "pocsag": 439987500, | ||||
|       "q65": 432065000 | ||||
|       "q65": 432065000, | ||||
|       "msk144": 432360000 | ||||
|     }, | ||||
|     "tags": ["hamradio"] | ||||
|   }, | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from csdr.chain.demodulator import ServiceDemodulator, SecondaryDemodulator, DialFrequencyReceiver, SecondarySelectorChain | ||||
| from csdr.module.msk144 import Msk144Module, ParserAdapter | ||||
| from owrx.audio.chopper import AudioChopper, AudioChopperParser | ||||
| from owrx.aprs.kiss import KissDeframer | ||||
| from owrx.aprs import Ax25Parser, AprsParser | ||||
| @@ -20,6 +21,23 @@ class AudioChopperDemodulator(ServiceDemodulator, DialFrequencyReceiver): | ||||
|         self.chopper.setDialFrequency(frequency) | ||||
|  | ||||
|  | ||||
| class Msk144Demodulator(ServiceDemodulator, DialFrequencyReceiver): | ||||
|     def __init__(self): | ||||
|         self.parser = ParserAdapter() | ||||
|         workers = [ | ||||
|             Convert(Format.FLOAT, Format.SHORT), | ||||
|             Msk144Module(), | ||||
|             self.parser, | ||||
|         ] | ||||
|         super().__init__(workers) | ||||
|  | ||||
|     def getFixedAudioRate(self) -> int: | ||||
|         return 12000 | ||||
|  | ||||
|     def setDialFrequency(self, frequency: int) -> None: | ||||
|         self.parser.setDialFrequency(frequency) | ||||
|  | ||||
|  | ||||
| class PacketDemodulator(ServiceDemodulator, DialFrequencyReceiver): | ||||
|     def __init__(self, service: bool = False): | ||||
|         self.parser = AprsParser() | ||||
|   | ||||
| @@ -126,7 +126,7 @@ class PopenModule(AutoStartModule, metaclass=ABCMeta): | ||||
|         # resume in case the reader has been stop()ed before | ||||
|         self.reader.resume() | ||||
|         Thread(target=self.pump(self.reader.read, self.process.stdin.write)).start() | ||||
|         Thread(target=self.pump(partial(self.process.stdout.read, 1024), self.writer.write)).start() | ||||
|         Thread(target=self.pump(partial(self.process.stdout.read1, 1024), self.writer.write)).start() | ||||
|  | ||||
|     def stop(self): | ||||
|         if self.process is not None: | ||||
|   | ||||
							
								
								
									
										57
									
								
								csdr/module/msk144.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								csdr/module/msk144.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| from pycsdr.types import Format | ||||
| from csdr.module import PopenModule, ThreadModule | ||||
| from owrx.wsjt import WsjtParser, Msk144Profile | ||||
| import pickle | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| class Msk144Module(PopenModule): | ||||
|     def getCommand(self): | ||||
|         return ["msk144decoder"] | ||||
|  | ||||
|     def getInputFormat(self) -> Format: | ||||
|         return Format.SHORT | ||||
|  | ||||
|     def getOutputFormat(self) -> Format: | ||||
|         return Format.CHAR | ||||
|  | ||||
|  | ||||
| class ParserAdapter(ThreadModule): | ||||
|     def __init__(self): | ||||
|         self.retained = bytes() | ||||
|         self.parser = WsjtParser() | ||||
|         self.dialFrequency = 0 | ||||
|         super().__init__() | ||||
|  | ||||
|     def run(self): | ||||
|         profile = Msk144Profile() | ||||
|  | ||||
|         while self.doRun: | ||||
|             data = self.reader.read() | ||||
|             if data is None: | ||||
|                 self.doRun = False | ||||
|             else: | ||||
|                 self.retained += data | ||||
|                 lines = self.retained.split(b"\n") | ||||
|  | ||||
|                 # keep the last line | ||||
|                 # this should either be empty if the last char was \n | ||||
|                 # or an incomplete line if the read returned early | ||||
|                 self.retained = lines[-1] | ||||
|  | ||||
|                 # parse all completed lines | ||||
|                 for line in lines[0:-1]: | ||||
|                     # actual messages from msk144decoder should start with "*** " | ||||
|                     if line[0:4] == b"*** ": | ||||
|                         self.writer.write(pickle.dumps(self.parser.parse(profile, self.dialFrequency, line[4:]))) | ||||
|  | ||||
|     def getInputFormat(self) -> Format: | ||||
|         return Format.CHAR | ||||
|  | ||||
|     def getOutputFormat(self) -> Format: | ||||
|         return Format.CHAR | ||||
|  | ||||
|     def setDialFrequency(self, frequency: int) -> None: | ||||
|         self.dialFrequency = frequency | ||||
							
								
								
									
										1
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| openwebrx (1.3.0) UNRELEASED; urgency=low | ||||
|   * SDR device log messages are now available in the web configuration to | ||||
|     simplify troubleshooting | ||||
|   * Added support for the MSK144 digimode | ||||
|  | ||||
|  -- Jakob Ketterl <jakob.ketterl@gmx.de>  Fri, 30 Sep 2022 16:47:00 +0000 | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							| @@ -11,6 +11,6 @@ Vcs-Git: https://github.com/jketterl/openwebrx.git | ||||
| Package: openwebrx | ||||
| Architecture: all | ||||
| Depends: adduser, python3 (>= 3.5), python3-pkg-resources, owrx-connector (>= 0.5), soapysdr-tools, python3-csdr (>= 0.18), ${python3:Depends}, ${misc:Depends} | ||||
| Recommends: python3-digiham (>= 0.6), direwolf (>= 1.4), wsjtx, js8call, runds-connector (>= 0.2), hpsdrconnector, aprs-symbols, m17-demod, js8call, python3-js8py (>= 0.2), nmux (>= 0.18), codecserver (>= 0.1) | ||||
| Recommends: python3-digiham (>= 0.6), direwolf (>= 1.4), wsjtx, js8call, runds-connector (>= 0.2), hpsdrconnector, aprs-symbols, m17-demod, js8call, python3-js8py (>= 0.2), nmux (>= 0.18), codecserver (>= 0.1), msk144decoder | ||||
| Description: multi-user web sdr | ||||
|  Open source, multi-user SDR receiver with a web interface | ||||
|   | ||||
| @@ -1,310 +1,341 @@ | ||||
| diff -ur wsjtx-orig/CMakeLists.txt wsjtx/CMakeLists.txt | ||||
| --- wsjtx-orig/CMakeLists.txt	2021-11-02 16:34:09.361811689 +0100 | ||||
| +++ wsjtx/CMakeLists.txt	2021-11-02 16:38:36.696088115 +0100 | ||||
| --- wsjtx-orig/CMakeLists.txt	2023-01-28 17:43:05.586124507 +0100 | ||||
| +++ wsjtx/CMakeLists.txt	2023-01-28 17:56:07.108634912 +0100 | ||||
| @@ -122,7 +122,7 @@ | ||||
|  option (WSJT_QDEBUG_TO_FILE "Redirect Qt debuging messages to a trace file.") | ||||
|  option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce transients." ON) | ||||
|  option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.") | ||||
| -option (WSJT_GENERATE_DOCS "Generate documentation files." ON) | ||||
| +option (WSJT_GENERATE_DOCS "Generate documentation files.") | ||||
|  option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.") | ||||
|  option (WSJT_TRACE_UDP "Debugging option that turns on UDP message protocol diagnostics.") | ||||
|  option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON) | ||||
| @@ -169,76 +169,7 @@ | ||||
|    ) | ||||
|   | ||||
|  set (wsjt_qt_CXXSRCS | ||||
| -  helper_functions.cpp | ||||
| -  qt_helpers.cpp | ||||
| -  widgets/MessageBox.cpp | ||||
| -  MetaDataRegistry.cpp | ||||
| -  Network/NetworkServerLookup.cpp | ||||
|    revision_utils.cpp | ||||
| -  L10nLoader.cpp | ||||
| -  WFPalette.cpp | ||||
| -  Radio.cpp | ||||
| -  RadioMetaType.cpp | ||||
| -  NonInheritingProcess.cpp | ||||
| -  models/IARURegions.cpp | ||||
| -  models/Bands.cpp | ||||
| -  models/Modes.cpp | ||||
| -  models/FrequencyList.cpp | ||||
| -  models/StationList.cpp | ||||
| -  widgets/FrequencyLineEdit.cpp | ||||
| -  widgets/FrequencyDeltaLineEdit.cpp | ||||
| -  item_delegates/CandidateKeyFilter.cpp | ||||
| -  item_delegates/ForeignKeyDelegate.cpp | ||||
| -  validators/LiveFrequencyValidator.cpp | ||||
| -  GetUserId.cpp | ||||
| -  Audio/AudioDevice.cpp | ||||
| -  Transceiver/Transceiver.cpp | ||||
| -  Transceiver/TransceiverBase.cpp | ||||
| -  Transceiver/EmulateSplitTransceiver.cpp | ||||
| -  Transceiver/TransceiverFactory.cpp | ||||
| -  Transceiver/PollingTransceiver.cpp | ||||
| -  Transceiver/HamlibTransceiver.cpp | ||||
| -  Transceiver/HRDTransceiver.cpp | ||||
| -  Transceiver/DXLabSuiteCommanderTransceiver.cpp | ||||
| -  Network/NetworkMessage.cpp | ||||
| -  Network/MessageClient.cpp | ||||
| -  widgets/LettersSpinBox.cpp | ||||
| -  widgets/HintedSpinBox.cpp | ||||
| -  widgets/RestrictedSpinBox.cpp | ||||
| -  widgets/HelpTextWindow.cpp | ||||
| -  SampleDownloader.cpp | ||||
| -  SampleDownloader/DirectoryDelegate.cpp | ||||
| -  SampleDownloader/Directory.cpp | ||||
| -  SampleDownloader/FileNode.cpp | ||||
| -  SampleDownloader/RemoteFile.cpp | ||||
| -  DisplayManual.cpp | ||||
| -  MultiSettings.cpp | ||||
| -  validators/MaidenheadLocatorValidator.cpp | ||||
| -  validators/CallsignValidator.cpp | ||||
| -  widgets/SplashScreen.cpp | ||||
| -  EqualizationToolsDialog.cpp | ||||
| -  widgets/DoubleClickablePushButton.cpp | ||||
| -  widgets/DoubleClickableRadioButton.cpp | ||||
| -  Network/LotWUsers.cpp | ||||
| -  models/DecodeHighlightingModel.cpp | ||||
| -  widgets/DecodeHighlightingListView.cpp | ||||
| -  models/FoxLog.cpp | ||||
| -  widgets/AbstractLogWindow.cpp | ||||
| -  widgets/FoxLogWindow.cpp | ||||
| -  widgets/CabrilloLogWindow.cpp | ||||
| -  item_delegates/CallsignDelegate.cpp | ||||
| -  item_delegates/MaidenheadLocatorDelegate.cpp | ||||
| -  item_delegates/FrequencyDelegate.cpp | ||||
| -  item_delegates/FrequencyDeltaDelegate.cpp | ||||
| -  item_delegates/SQLiteDateTimeDelegate.cpp | ||||
| -  models/CabrilloLog.cpp | ||||
| -  logbook/AD1CCty.cpp | ||||
| -  logbook/WorkedBefore.cpp | ||||
| -  logbook/Multiplier.cpp | ||||
| -  Network/NetworkAccessManager.cpp | ||||
| -  widgets/LazyFillComboBox.cpp | ||||
| -  widgets/CheckableItemComboBox.cpp | ||||
| -  widgets/BandComboBox.cpp | ||||
|    ) | ||||
|   | ||||
|  set (wsjt_qtmm_CXXSRCS | ||||
| @@ -1079,9 +1010,6 @@ | ||||
|  if (WSJT_GENERATE_DOCS) | ||||
|    add_subdirectory (doc) | ||||
|  endif (WSJT_GENERATE_DOCS) | ||||
| -if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests) | ||||
| -  add_subdirectory (tests) | ||||
| -endif () | ||||
|   | ||||
|  # build a library of package functionality (without and optionally with OpenMP support) | ||||
|  add_library (wsjt_cxx STATIC ${wsjt_CSRCS} ${wsjt_CXXSRCS}) | ||||
| @@ -1340,10 +1268,7 @@ | ||||
|  add_library (wsjt_qt STATIC ${wsjt_qt_CXXSRCS} ${wsjt_qt_GENUISRCS} ${GENAXSRCS}) | ||||
|  # set wsjtx_udp exports to static variants | ||||
|  target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE) | ||||
| -target_link_libraries (wsjt_qt Hamlib::Hamlib Boost::log qcp Qt5::Widgets Qt5::Network Qt5::Sql) | ||||
| -if (WIN32) | ||||
| -  target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase) | ||||
| -endif (WIN32) | ||||
| +target_link_libraries (wsjt_qt Qt5::Core) | ||||
|   | ||||
|  # build a library of package Qt functionality used in Fortran utilities | ||||
|  add_library (fort_qt STATIC ${fort_qt_CXXSRCS}) | ||||
| @@ -1408,60 +1333,6 @@ | ||||
|    add_subdirectory (map65) | ||||
|  endif () | ||||
|   | ||||
| -# build the main application | ||||
| -generate_version_info (wsjtx_VERSION_RESOURCES | ||||
| -  NAME wsjtx | ||||
| -  BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| -  ICON ${WSJTX_ICON_FILE} | ||||
| -  ) | ||||
| - | ||||
| -add_executable (wsjtx MACOSX_BUNDLE | ||||
| -  ${wsjtx_CXXSRCS} | ||||
| -  ${wsjtx_GENUISRCS} | ||||
| -  ${WSJTX_ICON_FILE} | ||||
| -  ${wsjtx_RESOURCES_RCC} | ||||
| -  ${wsjtx_VERSION_RESOURCES} | ||||
| -  ) | ||||
| - | ||||
| -if (WSJT_CREATE_WINMAIN) | ||||
| -  set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON) | ||||
| -endif (WSJT_CREATE_WINMAIN) | ||||
| - | ||||
| -set_target_properties (wsjtx PROPERTIES | ||||
| -  MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in" | ||||
| -  MACOSX_BUNDLE_INFO_STRING "${PROJECT_DESCRIPTION}" | ||||
| -  MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} | ||||
| -  MACOSX_BUNDLE_SHORT_VERSION_STRING "v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" | ||||
| -  MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${SCS_VERSION_STR}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_BUNDLE_NAME}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}" | ||||
| -  MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}" | ||||
| -  MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx" | ||||
| -  ) | ||||
| - | ||||
| -target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS}) | ||||
| -if (APPLE) | ||||
| -  target_link_libraries (wsjtx wsjt_fort) | ||||
| -else () | ||||
| -  target_link_libraries (wsjtx wsjt_fort_omp) | ||||
| -  if (OpenMP_C_FLAGS) | ||||
| -    set_target_properties (wsjtx PROPERTIES | ||||
| -      COMPILE_FLAGS "${OpenMP_C_FLAGS}" | ||||
| -      LINK_FLAGS "${OpenMP_C_FLAGS}" | ||||
| -      ) | ||||
| -  endif () | ||||
| -  set_target_properties (wsjtx PROPERTIES | ||||
| -    Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp | ||||
| -    ) | ||||
| -  if (WIN32) | ||||
| -    set_target_properties (wsjtx PROPERTIES | ||||
| -      LINK_FLAGS -Wl,--stack,0x1000000,--heap,0x20000000 | ||||
| -      ) | ||||
| -  endif () | ||||
| -endif () | ||||
| -target_link_libraries (wsjtx Qt5::SerialPort wsjt_cxx wsjt_qt wsjt_qtmm ${FFTW3_LIBRARIES} ${LIBM_LIBRARIES}) | ||||
| - | ||||
|  # make a library for WSJT-X UDP servers | ||||
|  # add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS}) | ||||
|  add_library (wsjtx_udp-static STATIC ${UDP_library_CXXSRCS}) | ||||
| @@ -1501,47 +1372,9 @@ | ||||
|  add_executable (wsjtx_app_version AppVersion/AppVersion.cpp ${wsjtx_app_version_VERSION_RESOURCES}) | ||||
|  target_link_libraries (wsjtx_app_version wsjt_qt) | ||||
|   | ||||
| -generate_version_info (message_aggregator_VERSION_RESOURCES | ||||
| -  NAME message_aggregator | ||||
| -  BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| -  ICON ${WSJTX_ICON_FILE} | ||||
| -  FILE_DESCRIPTION "Example WSJT-X UDP Message Protocol application" | ||||
| -  ) | ||||
| -add_resources (message_aggregator_RESOURCES /qss ${message_aggregator_STYLESHEETS}) | ||||
| -configure_file (UDPExamples/message_aggregator.qrc.in message_aggregator.qrc @ONLY) | ||||
| -qt5_add_resources (message_aggregator_RESOURCES_RCC | ||||
| -  ${CMAKE_CURRENT_BINARY_DIR}/message_aggregator.qrc | ||||
| -  contrib/QDarkStyleSheet/qdarkstyle/style.qrc | ||||
| -  ) | ||||
| -add_executable (message_aggregator | ||||
| -  ${message_aggregator_CXXSRCS} | ||||
| -  ${message_aggregator_RESOURCES_RCC} | ||||
| -  ${message_aggregator_VERSION_RESOURCES} | ||||
| -  ) | ||||
| -target_link_libraries (message_aggregator wsjt_qt Qt5::Widgets wsjtx_udp-static) | ||||
| - | ||||
| -if (WSJT_CREATE_WINMAIN) | ||||
| -  set_target_properties (message_aggregator PROPERTIES WIN32_EXECUTABLE ON) | ||||
| -endif (WSJT_CREATE_WINMAIN) | ||||
| - | ||||
| -if (UNIX) | ||||
| -  if (NOT WSJT_SKIP_MANPAGES) | ||||
| -    add_subdirectory (manpages) | ||||
| -    add_dependencies (wsjtx manpages) | ||||
| -  endif (NOT WSJT_SKIP_MANPAGES) | ||||
| -  if (NOT APPLE) | ||||
| -    add_subdirectory (debian) | ||||
| -    add_dependencies (wsjtx debian) | ||||
| -  endif (NOT APPLE) | ||||
| -endif (UNIX) | ||||
| - | ||||
|  # | ||||
|  # installation | ||||
|  # | ||||
| -install (TARGETS wsjtx | ||||
| -  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  BUNDLE DESTINATION . COMPONENT runtime | ||||
| -  ) | ||||
|   | ||||
|  # install (TARGETS wsjtx_udp EXPORT udp | ||||
|  #   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| @@ -1560,12 +1393,7 @@ | ||||
|  #   DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx | ||||
|  #   ) | ||||
|   | ||||
| -install (TARGETS udp_daemon message_aggregator wsjtx_app_version | ||||
| -  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
| -install (TARGETS jt9 wsprd fmtave fcal fmeasure | ||||
| +install (TARGETS wsjtx_app_version jt9 wsprd | ||||
|    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
|    BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
|    ) | ||||
| @@ -1578,38 +1406,6 @@ | ||||
|    ) | ||||
|  endif(WSJT_BUILD_UTILS)   | ||||
|   | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTL_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctl-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTLD_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTLCOM_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (FILES | ||||
| -  README | ||||
| -  COPYING | ||||
| -  AUTHORS | ||||
| -  THANKS | ||||
| -  NEWS | ||||
| -  BUGS | ||||
| -  DESTINATION ${CMAKE_INSTALL_DOCDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
|  install (FILES | ||||
|    cty.dat | ||||
|    cty.dat_copyright.txt | ||||
| @@ -1618,13 +1414,6 @@ | ||||
|    #COMPONENT runtime | ||||
|    ) | ||||
|   | ||||
| -install (DIRECTORY | ||||
| -  example_log_configurations | ||||
| -  DESTINATION ${CMAKE_INSTALL_DOCDIR} | ||||
| -  FILES_MATCHING REGEX "^.*[^~]$" | ||||
| -  #COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
|  # | ||||
|  # Mac installer files | ||||
|  # | ||||
| @@ -1676,22 +1465,6 @@ | ||||
|    "${CMAKE_CURRENT_BINARY_DIR}/wsjtx_config.h" | ||||
|    ) | ||||
|   | ||||
| - | ||||
| -if (NOT WIN32 AND NOT APPLE) | ||||
| -  # install a desktop file so wsjtx appears in the application start | ||||
| -  # menu with an icon | ||||
| -  install ( | ||||
| -    FILES wsjtx.desktop message_aggregator.desktop | ||||
| -    DESTINATION share/applications | ||||
| -    #COMPONENT runtime | ||||
| -    ) | ||||
| -  install ( | ||||
| -    FILES icons/Unix/wsjtx_icon.png | ||||
| -    DESTINATION share/pixmaps | ||||
| -    #COMPONENT runtime | ||||
| -    ) | ||||
| -endif (NOT WIN32 AND NOT APPLE) | ||||
| - | ||||
|  if (APPLE) | ||||
|    set (CMAKE_POSTFLIGHT_SCRIPT | ||||
|      "${wsjtx_BINARY_DIR}/postflight.sh") | ||||
|  option (WSJT_QDEBUG_TO_FILE "Redirect Qt debuging messages to a trace file.") | ||||
|  option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce transients." ON) | ||||
|  option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.") | ||||
| -option (WSJT_GENERATE_DOCS "Generate documentation files." ON) | ||||
| +option (WSJT_GENERATE_DOCS "Generate documentation files.") | ||||
|  option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.") | ||||
|  option (WSJT_TRACE_UDP "Debugging option that turns on UDP message protocol diagnostics.") | ||||
|  option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON) | ||||
| @@ -170,77 +170,7 @@ | ||||
|    ) | ||||
|   | ||||
|  set (wsjt_qt_CXXSRCS | ||||
| -  helper_functions.cpp | ||||
| -  qt_helpers.cpp | ||||
| -  widgets/MessageBox.cpp | ||||
| -  MetaDataRegistry.cpp | ||||
| -  Network/NetworkServerLookup.cpp | ||||
|    revision_utils.cpp | ||||
| -  L10nLoader.cpp | ||||
| -  WFPalette.cpp | ||||
| -  Radio.cpp | ||||
| -  RadioMetaType.cpp | ||||
| -  NonInheritingProcess.cpp | ||||
| -  models/IARURegions.cpp | ||||
| -  models/Bands.cpp | ||||
| -  models/Modes.cpp | ||||
| -  models/FrequencyList.cpp | ||||
| -  models/StationList.cpp | ||||
| -  widgets/FrequencyLineEdit.cpp | ||||
| -  widgets/FrequencyDeltaLineEdit.cpp | ||||
| -  item_delegates/CandidateKeyFilter.cpp | ||||
| -  item_delegates/ForeignKeyDelegate.cpp | ||||
| -  item_delegates/MessageItemDelegate.cpp | ||||
| -  validators/LiveFrequencyValidator.cpp | ||||
| -  GetUserId.cpp | ||||
| -  Audio/AudioDevice.cpp | ||||
| -  Transceiver/Transceiver.cpp | ||||
| -  Transceiver/TransceiverBase.cpp | ||||
| -  Transceiver/EmulateSplitTransceiver.cpp | ||||
| -  Transceiver/TransceiverFactory.cpp | ||||
| -  Transceiver/PollingTransceiver.cpp | ||||
| -  Transceiver/HamlibTransceiver.cpp | ||||
| -  Transceiver/HRDTransceiver.cpp | ||||
| -  Transceiver/DXLabSuiteCommanderTransceiver.cpp | ||||
| -  Network/NetworkMessage.cpp | ||||
| -  Network/MessageClient.cpp | ||||
| -  widgets/LettersSpinBox.cpp | ||||
| -  widgets/HintedSpinBox.cpp | ||||
| -  widgets/RestrictedSpinBox.cpp | ||||
| -  widgets/HelpTextWindow.cpp | ||||
| -  SampleDownloader.cpp | ||||
| -  SampleDownloader/DirectoryDelegate.cpp | ||||
| -  SampleDownloader/Directory.cpp | ||||
| -  SampleDownloader/FileNode.cpp | ||||
| -  SampleDownloader/RemoteFile.cpp | ||||
| -  DisplayManual.cpp | ||||
| -  MultiSettings.cpp | ||||
| -  validators/MaidenheadLocatorValidator.cpp | ||||
| -  validators/CallsignValidator.cpp | ||||
| -  widgets/SplashScreen.cpp | ||||
| -  EqualizationToolsDialog.cpp | ||||
| -  widgets/DoubleClickablePushButton.cpp | ||||
| -  widgets/DoubleClickableRadioButton.cpp | ||||
| -  Network/LotWUsers.cpp | ||||
| -  models/DecodeHighlightingModel.cpp | ||||
| -  widgets/DecodeHighlightingListView.cpp | ||||
| -  models/FoxLog.cpp | ||||
| -  widgets/AbstractLogWindow.cpp | ||||
| -  widgets/FoxLogWindow.cpp | ||||
| -  widgets/CabrilloLogWindow.cpp | ||||
| -  item_delegates/CallsignDelegate.cpp | ||||
| -  item_delegates/MaidenheadLocatorDelegate.cpp | ||||
| -  item_delegates/FrequencyDelegate.cpp | ||||
| -  item_delegates/FrequencyDeltaDelegate.cpp | ||||
| -  item_delegates/SQLiteDateTimeDelegate.cpp | ||||
| -  models/CabrilloLog.cpp | ||||
| -  logbook/AD1CCty.cpp | ||||
| -  logbook/WorkedBefore.cpp | ||||
| -  logbook/Multiplier.cpp | ||||
| -  Network/NetworkAccessManager.cpp | ||||
| -  widgets/LazyFillComboBox.cpp | ||||
| -  widgets/CheckableItemComboBox.cpp | ||||
| -  widgets/BandComboBox.cpp | ||||
|    ) | ||||
|   | ||||
|  set (wsjt_qtmm_CXXSRCS | ||||
| @@ -1089,9 +1019,6 @@ | ||||
|  if (WSJT_GENERATE_DOCS) | ||||
|    add_subdirectory (doc) | ||||
|  endif (WSJT_GENERATE_DOCS) | ||||
| -if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests) | ||||
| -  add_subdirectory (tests) | ||||
| -endif () | ||||
|   | ||||
|  # build a library of package functionality (without and optionally with OpenMP support) | ||||
|  add_library (wsjt_cxx STATIC ${wsjt_CSRCS} ${wsjt_CXXSRCS}) | ||||
| @@ -1357,10 +1284,7 @@ | ||||
|  add_library (wsjt_qt STATIC ${wsjt_qt_CXXSRCS} ${wsjt_qt_GENUISRCS} ${GENAXSRCS}) | ||||
|  # set wsjtx_udp exports to static variants | ||||
|  target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE) | ||||
| -target_link_libraries (wsjt_qt Hamlib::Hamlib Boost::log qcp Qt5::Widgets Qt5::Network Qt5::Sql) | ||||
| -if (WIN32) | ||||
| -  target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase) | ||||
| -endif (WIN32) | ||||
| +target_link_libraries (wsjt_qt Qt5::Core) | ||||
|   | ||||
|  # build a library of package Qt functionality used in Fortran utilities | ||||
|  add_library (fort_qt STATIC ${fort_qt_CXXSRCS}) | ||||
| @@ -1425,90 +1349,6 @@ | ||||
|    add_subdirectory (map65) | ||||
|  endif () | ||||
|   | ||||
| -# build the main application | ||||
| -generate_version_info (wsjtx_VERSION_RESOURCES | ||||
| -  NAME wsjtx | ||||
| -  BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| -  ICON ${WSJTX_ICON_FILE} | ||||
| -  ) | ||||
| - | ||||
| -add_executable (wsjtx MACOSX_BUNDLE | ||||
| -  ${wsjtx_CXXSRCS} | ||||
| -  ${wsjtx_GENUISRCS} | ||||
| -  ${WSJTX_ICON_FILE} | ||||
| -  ${wsjtx_RESOURCES_RCC} | ||||
| -  ${wsjtx_VERSION_RESOURCES} | ||||
| -  ) | ||||
| - | ||||
| -if (WSJT_CREATE_WINMAIN) | ||||
| -  set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON) | ||||
| -endif (WSJT_CREATE_WINMAIN) | ||||
| - | ||||
| -set_target_properties (wsjtx PROPERTIES | ||||
| -  MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in" | ||||
| -  MACOSX_BUNDLE_INFO_STRING "${PROJECT_DESCRIPTION}" | ||||
| -  MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} | ||||
| -  MACOSX_BUNDLE_SHORT_VERSION_STRING "v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" | ||||
| -  MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${SCS_VERSION_STR}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_BUNDLE_NAME}" | ||||
| -  MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}" | ||||
| -  MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}" | ||||
| -  MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx" | ||||
| -  ) | ||||
| - | ||||
| -target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS}) | ||||
| -if ((NOT ${OPENMP_FOUND}) OR APPLE) | ||||
| -  target_link_libraries (wsjtx wsjt_fort) | ||||
| -else () | ||||
| -  target_link_libraries (wsjtx wsjt_fort_omp) | ||||
| -  if (OpenMP_C_FLAGS) | ||||
| -    set_target_properties (wsjtx PROPERTIES | ||||
| -      COMPILE_FLAGS "${OpenMP_C_FLAGS}" | ||||
| -      LINK_FLAGS "${OpenMP_C_FLAGS}" | ||||
| -      ) | ||||
| -  endif () | ||||
| -  set_target_properties (wsjtx PROPERTIES | ||||
| -    Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp | ||||
| -    ) | ||||
| -  if (WIN32) | ||||
| -    set_target_properties (wsjtx PROPERTIES | ||||
| -      LINK_FLAGS -Wl,--stack,0x1000000,--heap,0x20000000 | ||||
| -      ) | ||||
| -  endif () | ||||
| -endif () | ||||
| -target_link_libraries (wsjtx Qt5::SerialPort wsjt_cxx wsjt_qt wsjt_qtmm ${FFTW3_LIBRARIES} ${LIBM_LIBRARIES}) | ||||
| - | ||||
| -# make a library for WSJT-X UDP servers | ||||
| -# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS}) | ||||
| -add_library (wsjtx_udp-static STATIC ${UDP_library_CXXSRCS}) | ||||
| -#target_include_directories (wsjtx_udp | ||||
| -#  INTERFACE | ||||
| -#  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx> | ||||
| -#  ) | ||||
| -target_include_directories (wsjtx_udp-static | ||||
| -  INTERFACE | ||||
| -  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx> | ||||
| -  ) | ||||
| -#set_target_properties (wsjtx_udp PROPERTIES | ||||
| -#  PUBLIC_HEADER "${UDP_library_HEADERS}" | ||||
| -#  ) | ||||
| -set_target_properties (wsjtx_udp-static PROPERTIES | ||||
| -  OUTPUT_NAME wsjtx_udp | ||||
| -  ) | ||||
| -target_compile_definitions (wsjtx_udp-static PUBLIC UDP_STATIC_DEFINE) | ||||
| -target_link_libraries (wsjtx_udp-static Qt5::Network Qt5::Gui) | ||||
| -generate_export_header (wsjtx_udp-static BASE_NAME udp) | ||||
| - | ||||
| -generate_version_info (udp_daemon_VERSION_RESOURCES | ||||
| -  NAME udp_daemon | ||||
| -  BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| -  ICON ${WSJTX_ICON_FILE} | ||||
| -  FILE_DESCRIPTION "Example WSJT-X UDP Message Protocol daemon" | ||||
| -  ) | ||||
| -add_executable (udp_daemon UDPExamples/UDPDaemon.cpp ${udp_daemon_VERSION_RESOURCES}) | ||||
| -target_link_libraries (udp_daemon wsjtx_udp-static) | ||||
| - | ||||
|  generate_version_info (wsjtx_app_version_VERSION_RESOURCES | ||||
|    NAME wsjtx_app_version | ||||
|    BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| @@ -1518,47 +1358,9 @@ | ||||
|  add_executable (wsjtx_app_version AppVersion/AppVersion.cpp ${wsjtx_app_version_VERSION_RESOURCES}) | ||||
|  target_link_libraries (wsjtx_app_version wsjt_qt) | ||||
|   | ||||
| -generate_version_info (message_aggregator_VERSION_RESOURCES | ||||
| -  NAME message_aggregator | ||||
| -  BUNDLE ${PROJECT_BUNDLE_NAME} | ||||
| -  ICON ${WSJTX_ICON_FILE} | ||||
| -  FILE_DESCRIPTION "Example WSJT-X UDP Message Protocol application" | ||||
| -  ) | ||||
| -add_resources (message_aggregator_RESOURCES /qss ${message_aggregator_STYLESHEETS}) | ||||
| -configure_file (UDPExamples/message_aggregator.qrc.in message_aggregator.qrc @ONLY) | ||||
| -qt5_add_resources (message_aggregator_RESOURCES_RCC | ||||
| -  ${CMAKE_CURRENT_BINARY_DIR}/message_aggregator.qrc | ||||
| -  contrib/QDarkStyleSheet/qdarkstyle/style.qrc | ||||
| -  ) | ||||
| -add_executable (message_aggregator | ||||
| -  ${message_aggregator_CXXSRCS} | ||||
| -  ${message_aggregator_RESOURCES_RCC} | ||||
| -  ${message_aggregator_VERSION_RESOURCES} | ||||
| -  ) | ||||
| -target_link_libraries (message_aggregator wsjt_qt Qt5::Widgets wsjtx_udp-static) | ||||
| - | ||||
| -if (WSJT_CREATE_WINMAIN) | ||||
| -  set_target_properties (message_aggregator PROPERTIES WIN32_EXECUTABLE ON) | ||||
| -endif (WSJT_CREATE_WINMAIN) | ||||
| - | ||||
| -if (UNIX) | ||||
| -  if (NOT WSJT_SKIP_MANPAGES) | ||||
| -    add_subdirectory (manpages) | ||||
| -    add_dependencies (wsjtx manpages) | ||||
| -  endif (NOT WSJT_SKIP_MANPAGES) | ||||
| -  if (NOT APPLE) | ||||
| -    add_subdirectory (debian) | ||||
| -    add_dependencies (wsjtx debian) | ||||
| -  endif (NOT APPLE) | ||||
| -endif (UNIX) | ||||
| - | ||||
|  # | ||||
|  # installation | ||||
|  # | ||||
| -install (TARGETS wsjtx | ||||
| -  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  BUNDLE DESTINATION . COMPONENT runtime | ||||
| -  ) | ||||
|   | ||||
|  # install (TARGETS wsjtx_udp EXPORT udp | ||||
|  #   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| @@ -1577,12 +1379,7 @@ | ||||
|  #   DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx | ||||
|  #   ) | ||||
|   | ||||
| -install (TARGETS udp_daemon message_aggregator wsjtx_app_version | ||||
| -  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
| -install (TARGETS jt9 wsprd fmtave fcal fmeasure | ||||
| +install (TARGETS wsjtx_app_version jt9 wsprd | ||||
|    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
|    BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime | ||||
|    ) | ||||
| @@ -1595,38 +1392,6 @@ | ||||
|    ) | ||||
|  endif(WSJT_BUILD_UTILS)   | ||||
|   | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTL_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctl-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTLD_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (PROGRAMS | ||||
| -  ${RIGCTLCOM_EXE} | ||||
| -  DESTINATION ${CMAKE_INSTALL_BINDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX} | ||||
| -  ) | ||||
| - | ||||
| -install (FILES | ||||
| -  README | ||||
| -  COPYING | ||||
| -  AUTHORS | ||||
| -  THANKS | ||||
| -  NEWS | ||||
| -  BUGS | ||||
| -  DESTINATION ${CMAKE_INSTALL_DOCDIR} | ||||
| -  #COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
|  install (FILES | ||||
|    cty.dat | ||||
|    cty.dat_copyright.txt | ||||
| @@ -1635,13 +1400,6 @@ | ||||
|    #COMPONENT runtime | ||||
|    ) | ||||
|   | ||||
| -install (DIRECTORY | ||||
| -  example_log_configurations | ||||
| -  DESTINATION ${CMAKE_INSTALL_DOCDIR} | ||||
| -  FILES_MATCHING REGEX "^.*[^~]$" | ||||
| -  #COMPONENT runtime | ||||
| -  ) | ||||
| - | ||||
|  # | ||||
|  # Mac installer files | ||||
|  # | ||||
| @@ -1693,22 +1451,6 @@ | ||||
|    "${CMAKE_CURRENT_BINARY_DIR}/wsjtx_config.h" | ||||
|    ) | ||||
|   | ||||
| - | ||||
| -if (NOT WIN32 AND NOT APPLE) | ||||
| -  # install a desktop file so wsjtx appears in the application start | ||||
| -  # menu with an icon | ||||
| -  install ( | ||||
| -    FILES wsjtx.desktop message_aggregator.desktop | ||||
| -    DESTINATION share/applications | ||||
| -    #COMPONENT runtime | ||||
| -    ) | ||||
| -  install ( | ||||
| -    FILES icons/Unix/wsjtx_icon.png | ||||
| -    DESTINATION share/pixmaps | ||||
| -    #COMPONENT runtime | ||||
| -    ) | ||||
| -endif (NOT WIN32 AND NOT APPLE) | ||||
| - | ||||
|  if (APPLE) | ||||
|    set (CMAKE_POSTFLIGHT_SCRIPT | ||||
|      "${wsjtx_BINARY_DIR}/postflight.sh") | ||||
|   | ||||
| @@ -38,7 +38,7 @@ case $ARCH in | ||||
|     ;; | ||||
| esac | ||||
|  | ||||
| wget https://www.sdrplay.com/software/$BINARY | ||||
| wget --no-http-keep-alive https://www.sdrplay.com/software/$BINARY | ||||
| sh $BINARY --noexec --target sdrplay | ||||
| patch --verbose -Np0 < /install-lib.$ARCH.patch | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,9 @@ function cmakebuild() { | ||||
|   if [[ ! -z "${2:-}" ]]; then | ||||
|     git checkout $2 | ||||
|   fi | ||||
|   if [[ -f ".gitmodules" ]]; then | ||||
|     git submodule update --init | ||||
|   fi | ||||
|   mkdir build | ||||
|   cd build | ||||
|   cmake ${CMAKE_ARGS:-} .. | ||||
| @@ -18,8 +21,8 @@ function cmakebuild() { | ||||
|  | ||||
| cd /tmp | ||||
|  | ||||
| STATIC_PACKAGES="libfftw3-bin python3 python3-setuptools netcat-openbsd libsndfile1 liblapack3 libusb-1.0-0 libqt5core5a libreadline8 libgfortran5 libgomp1 libasound2 libudev1 ca-certificates libpulse0 libfaad2 libopus0 libboost-program-options1.74.0 libboost-log1.74.0" | ||||
| BUILD_PACKAGES="wget git libsndfile1-dev libfftw3-dev cmake make gcc g++ liblapack-dev texinfo gfortran libusb-1.0-0-dev qtbase5-dev qtmultimedia5-dev qttools5-dev libqt5serialport5-dev qttools5-dev-tools asciidoctor asciidoc libasound2-dev libudev-dev libhamlib-dev patch xsltproc qt5-qmake libfaad-dev libopus-dev libboost-dev libboost-program-options-dev libboost-log-dev libboost-regex-dev libpulse-dev" | ||||
| STATIC_PACKAGES="libfftw3-bin python3 python3-setuptools netcat-openbsd libsndfile1 liblapack3 libusb-1.0-0 libqt5core5a libreadline8 libgfortran5 libgomp1 libasound2 libudev1 ca-certificates libpulse0 libfaad2 libopus0 libboost-program-options1.74.0 libboost-log1.74.0 libcurl4" | ||||
| BUILD_PACKAGES="wget git libsndfile1-dev libfftw3-dev cmake make gcc g++ liblapack-dev texinfo gfortran libusb-1.0-0-dev qtbase5-dev qtmultimedia5-dev qttools5-dev libqt5serialport5-dev qttools5-dev-tools asciidoctor asciidoc libasound2-dev libudev-dev libhamlib-dev patch xsltproc qt5-qmake libfaad-dev libopus-dev libboost-dev libboost-program-options-dev libboost-log-dev libboost-regex-dev libpulse-dev libcurl4-openssl-dev" | ||||
| apt-get update | ||||
| apt-get -y install auto-apt-proxy | ||||
| apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES | ||||
| @@ -51,15 +54,19 @@ rm /js8call-hamlib.patch | ||||
| cmakebuild ${JS8CALL_DIR} | ||||
| rm ${JS8CALL_TGZ} | ||||
|  | ||||
| WSJT_DIR=wsjtx-2.5.4 | ||||
| WSJT_DIR=wsjtx-2.6.1 | ||||
| WSJT_TGZ=${WSJT_DIR}.tgz | ||||
| wget http://physics.princeton.edu/pulsar/k1jt/${WSJT_TGZ} | ||||
| wget https://downloads.sourceforge.net/project/wsjt/${WSJT_DIR}/${WSJT_TGZ} | ||||
| tar xfz ${WSJT_TGZ} | ||||
| patch -Np0 -d ${WSJT_DIR} < /wsjtx-hamlib.patch | ||||
| mv /wsjtx.patch ${WSJT_DIR} | ||||
| cmakebuild ${WSJT_DIR} | ||||
| rm ${WSJT_TGZ} | ||||
|  | ||||
| git clone https://github.com/alexander-sholohov/msk144decoder.git | ||||
| # latest from main as of 2023-02-21 | ||||
| MAKEFLAGS="" cmakebuild msk144decoder fe2991681e455636e258e83c29fd4b2a72d16095 | ||||
|  | ||||
| git clone --depth 1 -b 1.6 https://github.com/wb2osz/direwolf.git | ||||
| cd direwolf | ||||
| # hamlib is present (necessary for the wsjt-x and js8call builds) and would be used, but there's no real need. | ||||
|   | ||||
| @@ -1265,6 +1265,7 @@ img.openwebrx-mirror-img | ||||
| #openwebrx-panel-digimodes[data-mode="fst4"]   #openwebrx-digimode-content-container, | ||||
| #openwebrx-panel-digimodes[data-mode="fst4w"]  #openwebrx-digimode-content-container, | ||||
| #openwebrx-panel-digimodes[data-mode="q65"]    #openwebrx-digimode-content-container, | ||||
| #openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-content-container, | ||||
| #openwebrx-panel-digimodes[data-mode="ft8"]    #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="wspr"]   #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="jt65"]   #openwebrx-digimode-select-channel, | ||||
| @@ -1275,7 +1276,8 @@ img.openwebrx-mirror-img | ||||
| #openwebrx-panel-digimodes[data-mode="js8"]    #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="fst4"]   #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="fst4w"]  #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="q65"]    #openwebrx-digimode-select-channel | ||||
| #openwebrx-panel-digimodes[data-mode="q65"]    #openwebrx-digimode-select-channel, | ||||
| #openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-select-channel | ||||
| { | ||||
|     display: none; | ||||
| } | ||||
| @@ -1290,7 +1292,8 @@ img.openwebrx-mirror-img | ||||
| #openwebrx-panel-digimodes[data-mode="js8"]    #openwebrx-digimode-canvas-container, | ||||
| #openwebrx-panel-digimodes[data-mode="fst4"]   #openwebrx-digimode-canvas-container, | ||||
| #openwebrx-panel-digimodes[data-mode="fst4w"]  #openwebrx-digimode-canvas-container, | ||||
| #openwebrx-panel-digimodes[data-mode="q65"]    #openwebrx-digimode-canvas-container | ||||
| #openwebrx-panel-digimodes[data-mode="q65"]    #openwebrx-digimode-canvas-container, | ||||
| #openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-canvas-container | ||||
| { | ||||
|     height: 200px; | ||||
|     margin: -10px; | ||||
|   | ||||
| @@ -331,7 +331,9 @@ ImaAdpcmCodec.prototype.reset = function() { | ||||
|     this.synchronized = 0; | ||||
|     this.syncWord = "SYNC"; | ||||
|     this.syncCounter = 0; | ||||
|     this.skip = 0; | ||||
|     this.phase = 0; | ||||
|     this.syncBuffer = new Uint8Array(4); | ||||
|     this.syncBufferIndex = 0; | ||||
| }; | ||||
|  | ||||
| ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ]; | ||||
| @@ -359,38 +361,45 @@ ImaAdpcmCodec.prototype.decode = function(data) { | ||||
|  | ||||
| ImaAdpcmCodec.prototype.decodeWithSync = function(data) { | ||||
|     var output = new Int16Array(data.length * 2); | ||||
|     var index = this.skip; | ||||
|     var oi = 0; | ||||
|     while (index < data.length) { | ||||
|         while (this.synchronized < 4 && index < data.length) { | ||||
|             if (data[index] === this.syncWord.charCodeAt(this.synchronized)) { | ||||
|                 this.synchronized++; | ||||
|             } else { | ||||
|                 this.synchronized = 0; | ||||
|             } | ||||
|             index++; | ||||
|             if (this.synchronized === 4) { | ||||
|                 if (index + 4 < data.length) { | ||||
|                     var syncData = new Int16Array(data.buffer.slice(index, index + 4)); | ||||
|     for (var index = 0; index < data.length; index++) { | ||||
|         switch (this.phase) { | ||||
|             case 0: | ||||
|                 // search for sync word | ||||
|                 if (data[index] !== this.syncWord.charCodeAt(this.synchronized++)) { | ||||
|                     // reset if data is unexpected | ||||
|                     this.synchronized = 0; | ||||
|                 } | ||||
|                 // if sync word has been found pass on to next phase | ||||
|                 if (this.synchronized === 4) { | ||||
|                     this.syncBufferIndex = 0; | ||||
|                     this.phase = 1; | ||||
|                 } | ||||
|                 break; | ||||
|             case 1: | ||||
|                 // read codec runtime data from stream | ||||
|                 this.syncBuffer[this.syncBufferIndex++] = data[index]; | ||||
|                 // if data is complete, apply and pass on to next phase | ||||
|                 if (this.syncBufferIndex === 4) { | ||||
|                     var syncData = new Int16Array(this.syncBuffer.buffer); | ||||
|                     this.stepIndex = syncData[0]; | ||||
|                     this.predictor = syncData[1]; | ||||
|                     this.syncCounter = 1000; | ||||
|                     this.phase = 2; | ||||
|                 } | ||||
|                 this.syncCounter = 1000; | ||||
|                 index += 4; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         while (index < data.length) { | ||||
|             if (this.syncCounter-- < 0) { | ||||
|                 this.synchronized = 0; | ||||
|             case 2: | ||||
|                 // decode actual audio data | ||||
|                 output[oi++] = this.decodeNibble(data[index] & 0x0F); | ||||
|                 output[oi++] = this.decodeNibble(data[index] >> 4); | ||||
|                 // if the next sync keyword is due, reset and return to phase 0 | ||||
|                 if (this.syncCounter-- === 0) { | ||||
|                     this.synchronized = 0; | ||||
|                     this.phase = 0; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|             output[oi++] = this.decodeNibble(data[index] & 0x0F); | ||||
|             output[oi++] = this.decodeNibble(data[index] >> 4); | ||||
|             index++; | ||||
|         } | ||||
|     } | ||||
|     this.skip = index - data.length; | ||||
|     return output.slice(0, oi); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -158,8 +158,8 @@ DemodulatorPanel.prototype.updatePanels = function() { | ||||
|     var modulation = this.getDemodulator().get_secondary_demod(); | ||||
|     $('#openwebrx-panel-digimodes').attr('data-mode', modulation); | ||||
|     toggle_panel("openwebrx-panel-digimodes", !!modulation); | ||||
|     toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4', 'fst4', 'fst4w', "q65"].indexOf(modulation) >= 0); | ||||
|     toggle_panel("openwebrx-panel-js8-message", modulation == "js8"); | ||||
|     toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4', 'fst4', 'fst4w', "q65", "msk144"].indexOf(modulation) >= 0); | ||||
|     toggle_panel("openwebrx-panel-js8-message", modulation === "js8"); | ||||
|     toggle_panel("openwebrx-panel-packet-message", modulation === "packet"); | ||||
|     toggle_panel("openwebrx-panel-pocsag-message", modulation === "pocsag"); | ||||
|  | ||||
|   | ||||
| @@ -50,7 +50,7 @@ MessagePanel.prototype.initClearButton = function() { | ||||
| function WsjtMessagePanel(el) { | ||||
|     MessagePanel.call(this, el); | ||||
|     this.initClearTimer(); | ||||
|     this.qsoModes = ['FT8', 'JT65', 'JT9', 'FT4', 'FST4', 'Q65']; | ||||
|     this.qsoModes = ['FT8', 'JT65', 'JT9', 'FT4', 'FST4', 'Q65', 'MSK144']; | ||||
|     this.beaconModes = ['WSPR', 'FST4W']; | ||||
|     this.modes = [].concat(this.qsoModes, this.beaconModes); | ||||
| } | ||||
|   | ||||
| @@ -581,6 +581,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient) | ||||
|             from csdr.chain.digimodes import AudioChopperDemodulator | ||||
|             from owrx.wsjt import WsjtParser | ||||
|             return AudioChopperDemodulator(mod, WsjtParser()) | ||||
|         elif mod == "msk144": | ||||
|             from csdr.chain.digimodes import Msk144Demodulator | ||||
|             return Msk144Demodulator() | ||||
|         elif mod == "js8": | ||||
|             from csdr.chain.digimodes import AudioChopperDemodulator | ||||
|             from owrx.js8 import Js8Parser | ||||
|   | ||||
| @@ -80,6 +80,7 @@ class FeatureDetector(object): | ||||
|         "wsjt-x": ["wsjtx"], | ||||
|         "wsjt-x-2-3": ["wsjtx_2_3"], | ||||
|         "wsjt-x-2-4": ["wsjtx_2_4"], | ||||
|         "msk144": ["msk144decoder"], | ||||
|         "packet": ["direwolf"], | ||||
|         "pocsag": ["digiham"], | ||||
|         "js8call": ["js8", "js8py"], | ||||
| @@ -428,7 +429,7 @@ class FeatureDetector(object): | ||||
|     def has_wsjtx(self): | ||||
|         """ | ||||
|         To decode FT8 and other digimodes, you need to install the WSJT-X software suite. Please check the | ||||
|         [WSJT-X homepage](https://physics.princeton.edu/pulsar/k1jt/wsjtx.html) for ready-made packages or instructions | ||||
|         [WSJT-X homepage](https://wsjt.sourceforge.io/) for ready-made packages or instructions | ||||
|         on how to build from source. | ||||
|         """ | ||||
|         return reduce(and_, map(self.command_is_runnable, ["jt9", "wsprd"]), True) | ||||
| @@ -459,6 +460,13 @@ class FeatureDetector(object): | ||||
|         """ | ||||
|         return self.has_wsjtx() and self._has_wsjtx_version(LooseVersion("2.4")) | ||||
|  | ||||
|     def has_msk144decoder(self): | ||||
|         """ | ||||
|         To decode the MSK144 digimode please install the "msk144decoder". See the | ||||
|         [project page](https://github.com/alexander-sholohov/msk144decoder) for more details. | ||||
|         """ | ||||
|         return self.command_is_runnable("msk144decoder") | ||||
|  | ||||
|     def has_js8(self): | ||||
|         """ | ||||
|         To decode JS8, you will need to install [JS8Call](http://js8call.com/) | ||||
|   | ||||
| @@ -120,6 +120,7 @@ class Modes(object): | ||||
|         WsjtMode("fst4", "FST4", requirements=["wsjt-x-2-3"]), | ||||
|         WsjtMode("fst4w", "FST4W", bandpass=Bandpass(1350, 1650), requirements=["wsjt-x-2-3"]), | ||||
|         WsjtMode("q65", "Q65", requirements=["wsjt-x-2-4"]), | ||||
|         DigitalMode("msk144", "MSK144", requirements=["msk144"], underlying=["usb"], service=True), | ||||
|         Js8Mode("js8", "JS8Call"), | ||||
|         DigitalMode( | ||||
|             "packet", | ||||
|   | ||||
| @@ -27,9 +27,9 @@ class PskReporter(Reporter): | ||||
|         Supports all valid MODE and SUBMODE values from the ADIF standard. | ||||
|  | ||||
|         Current version at the time of the last change: | ||||
|         https://www.adif.org/312/ADIF_312.htm#Mode_Enumeration | ||||
|         https://www.adif.org/314/ADIF_314.htm#Mode_Enumeration | ||||
|         """ | ||||
|         return ["FT8", "FT4", "JT9", "JT65", "FST4", "JS8", "Q65", "WSPR", "FST4W"] | ||||
|         return ["FT8", "FT4", "JT9", "JT65", "FST4", "JS8", "Q65", "WSPR", "FST4W", "MSK144"] | ||||
|  | ||||
|     def stop(self): | ||||
|         self.cancelTimer() | ||||
| @@ -105,27 +105,34 @@ class Uploader(object): | ||||
|         # filter out any erroneous encodes | ||||
|         encoded = [e for e in encoded if e is not None] | ||||
|  | ||||
|         def chunks(l, n): | ||||
|             """Yield successive n-sized chunks from l.""" | ||||
|             for i in range(0, len(l), n): | ||||
|                 yield l[i : i + n] | ||||
|         def chunks(block, max_size): | ||||
|             size = 0 | ||||
|             current = [] | ||||
|             for r in block: | ||||
|                 if size + len(r) > max_size: | ||||
|                     yield current | ||||
|                     current = [] | ||||
|                     size = 0 | ||||
|                 size += len(r) | ||||
|                 current.append(r) | ||||
|             yield current | ||||
|  | ||||
|         rHeader = self.getReceiverInformationHeader() | ||||
|         rInfo = self.getReceiverInformation() | ||||
|         sHeader = self.getSenderInformationHeader() | ||||
|  | ||||
|         packets = [] | ||||
|         # 50 seems to be a safe bet | ||||
|         for chunk in chunks(encoded, 50): | ||||
|         # 1200 bytes of sender data should keep the packet size below MTU for most cases | ||||
|         for chunk in chunks(encoded, 1200): | ||||
|             sInfo = self.getSenderInformation(chunk) | ||||
|             length = 16 + len(rHeader) + len(sHeader) + len(rInfo) + len(sInfo) | ||||
|             header = self.getHeader(length) | ||||
|             packets.append(header + rHeader + sHeader + rInfo + sInfo) | ||||
|             self.sequence = (self.sequence + len(chunk)) % (1 << 32) | ||||
|  | ||||
|         return packets | ||||
|  | ||||
|     def getHeader(self, length): | ||||
|         self.sequence += 1 | ||||
|         return bytes( | ||||
|             # protocol version | ||||
|             [0x00, 0x0A] | ||||
| @@ -142,7 +149,7 @@ class Uploader(object): | ||||
|         try: | ||||
|             return bytes( | ||||
|                 self.encodeString(spot["source"]["callsign"]) | ||||
|                 + list(int(spot["freq"]).to_bytes(4, "big")) | ||||
|                 + list(int(spot["freq"]).to_bytes(5, "big")) | ||||
|                 + list(int(spot["db"]).to_bytes(1, "big", signed=True)) | ||||
|                 + self.encodeString(spot["mode"]) | ||||
|                 + self.encodeString(spot["locator"]) | ||||
| @@ -208,7 +215,7 @@ class Uploader(object): | ||||
|             # senderCallsign | ||||
|             + [0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F] | ||||
|             # frequency | ||||
|             + [0x80, 0x05, 0x00, 0x04, 0x00, 0x00, 0x76, 0x8F] | ||||
|             + [0x80, 0x05, 0x00, 0x05, 0x00, 0x00, 0x76, 0x8F] | ||||
|             # sNR | ||||
|             + [0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x76, 0x8F] | ||||
|             # mode | ||||
|   | ||||
| @@ -122,6 +122,15 @@ class ServiceHandler(SdrSourceEventClient): | ||||
|         self.startupTimer.start() | ||||
|  | ||||
|     def updateServices(self): | ||||
|         def addService(dial, source): | ||||
|             mode = dial["mode"] | ||||
|             frequency = dial["frequency"] | ||||
|             try: | ||||
|                 service = self.setupService(mode, frequency, source) | ||||
|                 self.services.append(service) | ||||
|             except Exception: | ||||
|                 logger.exception("Error setting up service %s on frequency %d", mode, frequency) | ||||
|  | ||||
|         with self.lock: | ||||
|             logger.debug("re-scheduling services due to sdr changes") | ||||
|             self.stopServices() | ||||
| @@ -146,7 +155,7 @@ class ServiceHandler(SdrSourceEventClient): | ||||
|             groups = self.optimizeResampling(dials, sr) | ||||
|             if groups is None: | ||||
|                 for dial in dials: | ||||
|                     self.services.append(self.setupService(dial["mode"], dial["frequency"], self.source)) | ||||
|                     addService(dial, self.source) | ||||
|             else: | ||||
|                 for group in groups: | ||||
|                     if len(group) > 1: | ||||
| @@ -157,14 +166,14 @@ class ServiceHandler(SdrSourceEventClient): | ||||
|                         resampler = Resampler(resampler_props, self.source) | ||||
|  | ||||
|                         for dial in group: | ||||
|                             self.services.append(self.setupService(dial["mode"], dial["frequency"], resampler)) | ||||
|                             addService(dial, resampler) | ||||
|  | ||||
|                         # resampler goes in after the services since it must not be shutdown as long as the services are | ||||
|                         # still running | ||||
|                         self.services.append(resampler) | ||||
|                     else: | ||||
|                         dial = group[0] | ||||
|                         self.services.append(self.setupService(dial["mode"], dial["frequency"], self.source)) | ||||
|                         addService(dial, self.source) | ||||
|  | ||||
|     def get_min_max(self, group): | ||||
|         frequencies = sorted(group, key=lambda f: f["frequency"]) | ||||
| @@ -279,11 +288,13 @@ class ServiceHandler(SdrSourceEventClient): | ||||
|     def _getSecondaryDemodulator(self, mod) -> Optional[ServiceDemodulator]: | ||||
|         if isinstance(mod, ServiceDemodulatorChain): | ||||
|             return mod | ||||
|         # TODO add remaining modes | ||||
|         if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]: | ||||
|             from csdr.chain.digimodes import AudioChopperDemodulator | ||||
|             from owrx.wsjt import WsjtParser | ||||
|             return AudioChopperDemodulator(mod, WsjtParser()) | ||||
|         elif mod == "msk144": | ||||
|             from csdr.chain.digimodes import Msk144Demodulator | ||||
|             return Msk144Demodulator() | ||||
|         elif mod == "js8": | ||||
|             from csdr.chain.digimodes import AudioChopperDemodulator | ||||
|             from owrx.js8 import Js8Parser | ||||
| @@ -291,7 +302,8 @@ class ServiceHandler(SdrSourceEventClient): | ||||
|         elif mod == "packet": | ||||
|             from csdr.chain.digimodes import PacketDemodulator | ||||
|             return PacketDemodulator(service=True) | ||||
|         return None | ||||
|  | ||||
|         raise ValueError("unsupported service modulation: {}".format(mod)) | ||||
|  | ||||
|  | ||||
| class Services(object): | ||||
|   | ||||
							
								
								
									
										13
									
								
								owrx/wsjt.py
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								owrx/wsjt.py
									
									
									
									
									
								
							| @@ -245,6 +245,17 @@ class Q65Profile(WsjtProfile): | ||||
|         return ["jt9", "--q65", "-p", str(self.interval), "-b", self.mode.name, "-d", str(self.decoding_depth()), file] | ||||
|  | ||||
|  | ||||
| class Msk144Profile(WsjtProfile): | ||||
|     def getMode(self): | ||||
|         return "MSK144" | ||||
|  | ||||
|     def getInterval(self): | ||||
|         return 15 | ||||
|  | ||||
|     def decoder_commandline(self, file): | ||||
|         return None | ||||
|  | ||||
|  | ||||
| class WsjtParser(AudioChopperParser): | ||||
|     def parse(self, profile: WsjtProfile, freq: int, raw_msg: bytes): | ||||
|         try: | ||||
| @@ -366,6 +377,8 @@ class Jt9Decoder(Decoder): | ||||
|         # '0003  -4  0.4 1762 #  CQ R2ABM KO85' | ||||
|         # fst4 sample | ||||
|         # '**** -23  0.6 3023 `  <...> <...> R 591631 BI53PV' | ||||
|         # MSK144 sample | ||||
|         # '221602   8  0.4 1488 &  K1JT WA4CQG EM72' | ||||
|         msg, timestamp = self.parse_timestamp(msg) | ||||
|         wsjt_msg = msg[17:53].strip() | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user