diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 8e99860..9e8d676 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -15,21 +15,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Checkout horusdemodlib - uses: actions/checkout@v4 - with: - repository: "projecthorus/horusdemodlib" - ref: "master" - path: "horusdemodlib" - - - name: Build horusdemodlib - run: | - cd horusdemodlib - mkdir build - cd build - cmake .. -G "MinGW Makefiles" - mingw32-make - - uses: actions/setup-python@v5 with: python-version: '3.11' @@ -38,6 +23,9 @@ jobs: - name: Install pyAudio wheel run: pip install pyaudio + - name: Install horusdemodlib + run: pip install horusdemodlib + - name: Install other dependencies run: pip install -r requirements.txt @@ -48,7 +36,6 @@ jobs: shell: bash run: | mkdir -p dist - cp horusdemodlib/build/src/libhorus.dll . cp "C:\Program Files\Git\mingw64\bin\libgcc_s_seh-1.dll" . cp "C:\Program Files\Git\mingw64\bin\libstdc++-6.dll" . cp "C:\Program Files\Git\mingw64\bin\libwinpthread-1.dll" . @@ -71,21 +58,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Checkout horusdemodlib - uses: actions/checkout@v4 - with: - repository: "projecthorus/horusdemodlib" - ref: "master" - path: "horusdemodlib" - - - name: Build horusdemodlib - run: | - cd horusdemodlib - mkdir build - cd build - cmake .. - make - - uses: actions/setup-python@v5 with: python-version: '3.11' @@ -97,6 +69,9 @@ jobs: - name: Install pyAudio wheel run: pip install pyaudio + - name: Install horusdemodlib + run: pip install horusdemodlib + - name: Install other dependencies run: pip install -r requirements.txt @@ -107,7 +82,11 @@ jobs: shell: bash run: | mkdir -p dist - cp horusdemodlib/build/src/libhorus.dylib . + + - name: ake dummy file for use in appbundle + shell: bash + run: | + touch dummy.file - name: Run pyinstaller run: pyinstaller horus-gui_osx_runner.spec @@ -124,28 +103,13 @@ jobs: # Currently having issues with portaudio and these builds... build-osx-intel: - runs-on: [macos-13] + runs-on: [macos-15-intel] steps: - name: Checkout code uses: actions/checkout@v4 - - name: Checkout horusdemodlib - uses: actions/checkout@v4 - with: - repository: "projecthorus/horusdemodlib" - ref: "master" - path: "horusdemodlib" - - - name: Build horusdemodlib - run: | - cd horusdemodlib - mkdir build - cd build - cmake .. - make - - uses: actions/setup-python@v5 with: python-version: '3.11' @@ -157,6 +121,9 @@ jobs: - name: Install pyAudio wheel run: pip install pyaudio + - name: Install horusdemodlib + run: pip install horusdemodlib + - name: Install other dependencies run: pip install -r requirements.txt @@ -167,7 +134,11 @@ jobs: shell: bash run: | mkdir -p dist - cp horusdemodlib/build/src/libhorus.dylib . + + - name: Make dummy file for use in appbundle + shell: bash + run: | + touch dummy.file - name: Run pyinstaller run: pyinstaller horus-gui_osx_runner.spec diff --git a/README.md b/README.md index e9f45b3..91c0009 100755 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Telemetry demodulator for the following modems in use by Project Horus * Horus Binary Modes (4FSK) * v1 - Legacy 22 byte mode, Golay(23,12) FEC * v2 - 32-byte mode, Golay(23,12) FEC + * v3 - 32/48/64/96/128-byte mode with ASN.1 encoding, Golay(23,12) FEC * RTTY (7N1, 7N2 and 8N2, standard [UKHAS sentences](https://ukhas.org.uk/communication:protocol) with CRC16 only) This project serves as a graphical front-end to [horusdemodlib](https://github.com/projecthorus/horusdemodlib/wiki) a Python/C library of telemetry demodulators based off the [codec2](https://github.com/drowe67/codec2) FSK modem. The core modem used in this library is very well tested, and performs in line with incoherent FSK demodulator theory. The RTTY decoder is approximately [2dB better](http://www.rowetel.com/?p=5906) than dl-fldigi, and the Horus Binary modem approximately 7 dB better again. The Horus Binary v2 mode provides some additional flexibility over the v1 mode, allowing the addition of custom telemetry fields. @@ -44,17 +45,6 @@ Binary builds for some platforms are available on the releases page: https://git Please let me know if you have issues! -### Build HorusDemodLib - -```console -$ git clone https://github.com/projecthorus/horusdemodlib.git -$ cd horusdemodlib && mkdir build && cd build -$ cmake .. -$ make -$ sudo make install -$ sudo ldconfig -``` - ### Grab this Repo ```console $ git clone https://github.com/projecthorus/horus-gui.git @@ -70,7 +60,7 @@ $ source venv/bin/activate (venv) $ pip install pip -U (Optional - this updates pip) ``` -If not using a venv, you may need to replace `pip` with `pip3`, and `python` with `python3` below to ensure you are using Python3. Older linux distributions will likely have both Python 2.7 and Python 3 installed - this software only supports Python 3. On linux distros you may need to install `python3-venv`. +If not using a venv, you may need to replace `pip` with `pip3`, and `python` with `python3` below to ensure you are using Python3. Older linux distributions will likely have both Python 2.7 and Python 3 installed - this software only supports Python 3.9 or newer. On linux distros you may need to install `python3-venv`. ### Install Python Dependencies ```console @@ -126,14 +116,6 @@ $ (venv) python horus-gui.py As this repository is under regular development, you will likely need to update frequently. For those using the binary builds, this just means downloading a new file and running it. If you're running from source, this means updating both this repository, and horusdemodlib, on which it depends. ```console -$ cd ~/horusdemodlib -$ git pull -$ rm -rf build -$ cd horusdemodlib && mkdir build && cd build -$ cmake .. -$ make -$ make install - $ cd ~/horus-gui # git pull $ . venv/bin/activate (if using a venv) diff --git a/horus-gui.spec b/horus-gui.spec index 30c854b..df4c8f4 100644 --- a/horus-gui.spec +++ b/horus-gui.spec @@ -2,12 +2,12 @@ block_cipher = None - +from PyInstaller.utils.hooks import collect_data_files a = Analysis(['horus-gui.py'], pathex=['.'], binaries=[], - datas=[], - hiddenimports=['pkg_resources.py2_warn'], + datas=collect_data_files("horusbinaryv3"), + hiddenimports=['pkg_resources.py2_warn', '_cffi_backend'], hookspath=[], runtime_hooks=[], excludes=[], diff --git a/horus-gui_osx.spec b/horus-gui_osx.spec index cdd4921..7606620 100644 --- a/horus-gui_osx.spec +++ b/horus-gui_osx.spec @@ -2,12 +2,12 @@ block_cipher = None - +from PyInstaller.utils.hooks import collect_data_files a = Analysis(['horus-gui.py'], pathex=['.'], - binaries=[('../horusdemodlib/build/src/libhorus.dylib','.')], - datas=[], - hiddenimports=[], + binaries=[], + datas=collect_data_files("horusbinaryv3"), + hiddenimports=['pkg_resources.py2_warn', '_cffi_backend'], hookspath=[], runtime_hooks=[], excludes=[], diff --git a/horus-gui_osx_runner.spec b/horus-gui_osx_runner.spec index 2ac943e..ef113dc 100644 --- a/horus-gui_osx_runner.spec +++ b/horus-gui_osx_runner.spec @@ -2,12 +2,22 @@ block_cipher = None +from PyInstaller.utils.hooks import collect_data_files + +datas = collect_data_files("horusbinaryv3") +# For some reason the above line does add in the .asn1 file OK, but when the code starts +# it looks for it in '/Contents/Frameworks/horusdemodlib/../horusbinaryv3/HorusBinaryV3.asn1' +# which is very weird. +# The horusbinaryv3 dir does exist, but it doesn't make the horusdemodlib dir, so, we hack around that by +# adding a dummy file so pyinstaller makes the /Contents/Frameworks/horusdemodlib directory +# I hate this but it seems like it works. +datas += [('./dummy.file','horusdemodlib')] a = Analysis(['horus-gui.py'], pathex=['.'], - binaries=[('libhorus.dylib','.')], - datas=[], - hiddenimports=[], + binaries=[], + datas=datas, + hiddenimports=['pkg_resources.py2_warn', '_cffi_backend'], hookspath=[], runtime_hooks=[], excludes=[], diff --git a/horus-gui_win.spec b/horus-gui_win.spec index 9f55889..3246997 100755 --- a/horus-gui_win.spec +++ b/horus-gui_win.spec @@ -2,12 +2,12 @@ block_cipher = None - +from PyInstaller.utils.hooks import collect_data_files a = Analysis(['horus-gui.py'], pathex=['.'], - binaries=[('libhorus.dll','.'),('libgcc_s_seh-1.dll','.'),('libwinpthread-1.dll','.'),('libstdc++-6.dll','.')], - datas=[], - hiddenimports=['pkg_resources.py2_warn'], + binaries=[], + datas=collect_data_files("horusbinaryv3"), + hiddenimports=['pkg_resources.py2_warn', '_cffi_backend'], hookspath=[], runtime_hooks=[], excludes=[], diff --git a/horusgui/__init__.py b/horusgui/__init__.py index df12433..906d362 100755 --- a/horusgui/__init__.py +++ b/horusgui/__init__.py @@ -1 +1 @@ -__version__ = "0.4.2" +__version__ = "0.6.0" diff --git a/horusgui/config.py b/horusgui/config.py index 7054be7..3db536f 100644 --- a/horusgui/config.py +++ b/horusgui/config.py @@ -78,7 +78,7 @@ def read_config(widgets): global qt_settings, default_config # This is getting a bit ridiculous, need to re-think this approach. - OK_VERSIONS = [__version__,'0.3.19', '0.3.18', '0.3.17', '0.3.16', '0.3.15', '0.3.14', '0.3.13', '0.3.12', '0.3.11', '0.3.10', '0.3.9', '0.3.8', '0.3.7', '0.3.6', '0.3.5', '0.3.4', '0.3.1', '0.2.1'] + OK_VERSIONS = [__version__, '0.5.0-beta1', '0.4.2', '0.4.1', '0.4.0', '0.3.19', '0.3.18', '0.3.17', '0.3.16', '0.3.15', '0.3.14', '0.3.13', '0.3.12', '0.3.11', '0.3.10', '0.3.9', '0.3.8', '0.3.7', '0.3.6', '0.3.5', '0.3.4', '0.3.1', '0.2.1'] # Try and read in the version parameter from QSettings if qt_settings.value("version") not in OK_VERSIONS: diff --git a/horusgui/fft.py b/horusgui/fft.py index cf0cb70..f7d0cf7 100644 --- a/horusgui/fft.py +++ b/horusgui/fft.py @@ -50,7 +50,7 @@ def perform_fft(self): """ Perform a FFT on the first NFFT samples in the sample buffer, then shift the buffer along """ # Convert raw data to floats. - raw_data = np.fromstring( + raw_data = np.frombuffer( bytes(self.sample_buffer[: self.nfft * self.sample_width]), dtype=np.int16 ) raw_data = raw_data.astype(np.float64) / (2 ** 15) diff --git a/horusgui/gui.py b/horusgui/gui.py index 1daafa0..789b2e6 100644 --- a/horusgui/gui.py +++ b/horusgui/gui.py @@ -404,10 +404,11 @@ def initialize(self): w1_other.addWidget(self.widgets["loggingPathEntry"], 8, 1, 1, 1) w1_other.addWidget(self.widgets["selectLogDirButton"], 9, 0, 1, 2) w1_other.addWidget(self.widgets["otherHeaderLabel"], 10, 0, 1, 2) - w1_other.addWidget(self.widgets["inhibitCRCLabel"], 11, 0, 1, 1) - w1_other.addWidget(self.widgets["inhibitCRCSelector"], 11, 1, 1, 1) - w1_other.addWidget(self.widgets["fftSmoothingLabel"], 12, 0, 1, 1) - w1_other.addWidget(self.widgets["fftSmoothingSelector"], 12, 1, 1, 1) + # Inhibit this, need to remove it later + #w1_other.addWidget(self.widgets["inhibitCRCLabel"], 11, 0, 1, 1) + #w1_other.addWidget(self.widgets["inhibitCRCSelector"], 11, 1, 1, 1) + w1_other.addWidget(self.widgets["fftSmoothingLabel"], 11, 0, 1, 1) + w1_other.addWidget(self.widgets["fftSmoothingSelector"], 11, 1, 1, 1) w1_other.setRowStretch(13, 1) w1_other_widget.setLayout(w1_other) @@ -1134,6 +1135,10 @@ def handle_new_packet(self, frame): # RTTY packets are provided as a string, and can be displayed directly _packet = frame.data + # We now just inhibit trying to display anthing that fails CRC. + if frame.crc_pass == False: + return + _decoded = None # Grab SNR. diff --git a/horusgui/libhorus.dll b/horusgui/libhorus.dll deleted file mode 100644 index ccc36cc..0000000 Binary files a/horusgui/libhorus.dll and /dev/null differ diff --git a/horusgui/modem.py b/horusgui/modem.py index 9aac3ef..c0c8e1c 100644 --- a/horusgui/modem.py +++ b/horusgui/modem.py @@ -5,7 +5,7 @@ # Modem paramers and defaults HORUS_MODEM_LIST = { - "Horus Binary v1/v2": { + "Horus Binary v1/v2/v3": { "id": Mode.BINARY_V1, "baud_rates": [50, 100, 300], # Note: 25 Baud removed until issues in underlying modem are fixed. "default_baud_rate": 100, @@ -39,7 +39,7 @@ }, } -DEFAULT_MODEM = "Horus Binary v1/v2" +DEFAULT_MODEM = "Horus Binary v1/v2/v3" horusModem = None diff --git a/pyproject.toml b/pyproject.toml index 2a65012..3d83f03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "horusgui" -version = "0.4.2" +version = "0.6.0" description = "" authors = ["Mark Jessop "] @@ -11,7 +11,7 @@ crcmod = "^1.7" PyQt6 = "^6.7.0" pyqtgraph = "^0.12.3" pyaudio = "^0.2.11" -horusdemodlib = ">=0.4.0" +horusdemodlib = ">=0.6.0" [tool.poetry.dev-dependencies] @@ -30,7 +30,7 @@ dependencies = [ "PyQt6<7.0.0,>=6.9.0", "pyqtgraph<1.0.0,>=0.13.7", "pyaudio<1.0.0,>=0.2.14", - "horusdemodlib<1.0.0,>=0.3.15", + "horusdemodlib<1.0.0,>=0.6.0", "PyQt6", "audioop-lts; python_version>='3.13'", "crcmod", diff --git a/requirements.txt b/requirements.txt index 204d619..331e110 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,5 @@ crcmod PyQt6 pyqtgraph requests -horusdemodlib>=0.4.0 +horusdemodlib>=0.6.0 audioop-lts; python_version>='3.13' \ No newline at end of file