FT8 Decoding and Encoding in Python with test/loopback code
Project description
PyFT8 
All-Python FT8 Transceiver(WIP) GUI / Command Line Modem
This repository contains the source code for PyFT8, an all-Python open source FT8 transceiver that you can run as a basic GUI or from the command line to receive and transmit. Decoding performance (number of decodes) is about 70% of that achieved by WSJT-x in NORM mode, but (tbc) slightly above ft8_lib. At the time of writing (3-3-26) this new version 2.0.0 establishes the prior cli functionality plus an interesting GUI, on which I intend to build a transceiver function shortly.
Motivation
This started out as me thinking "How hard can it be, really?" after some frustration with Windows moving sound devices around and wanting to get a minimal decoder running that I can fully control.
I didn’t want to produce yet another port of the original Fortran / C into another language: instead I wanted to see how far I could get following audio -> spectrogram -> symbols -> bits -> error correction without resyncs and special treatments, writing my own code from scratch as far as possible. Also this has been, more than I expected, an exercise in writing Python ‘Pythonically’ for speed, which means absolutely not duplicating the big nested loops of Fortran and C. It also means writing code that is wide and short rather than thin and long, which suits my thinking style perfectly!
Installation
If you want to install this software without getting into the code, you can install from PyPI using pip install, using
pip install PyFT8
Once installed, you can use the following commands to run it.
| Usage | Command example | Notes |
|---|---|---|
| Basic Rx GUI | pyft8 -i "Keyword1, Keyword2" | Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC" |
| GUI with transmit | pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" | Keywords identify the input (-i) and output (-o) sound devices. The transmit parts are under development. |
| Command line Rx without a GUI | pyft8 -i "Keyword1, Keyword2" -n | |
| Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90" | Tx on next cycle. You supply the PTT control method. |
| Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90" | -w "Mywav.wav" can be omitted |
Otherwise, please download or browse the code, or fork the repo and play with it! If you do fork it, please check back here as I'm constantly (as of Jan 2026) rewriting and improving.
Performance Compared with FT8_lib and WSJT-x
The image below shows the number of decodes from PyFT8, WSJT-x V2.7.0 running in NORM mode, and FT8_lib, using the same 10 minutes of busy 20m audio that is used to test ft8_lib.
Limitations
In pursuit of tight code, I've concentrated on core standard messages, leaving out some of the less-used features. The receive part of the code doesn't (yet) have the full capability of the advanced decoders used in WSJT-x, and so gets fewer decodes than WSJT-x gets, depending on band conditions (on a quiet band with only good signals PyFT8 will get close to 100%).
Acknowledgements
This project implements a decoder for the FT8 digital mode. FT8 was developed by Joe Taylor, K1JT, Steve Franke, K9AN, and others as part of the WSJT-X project. Protocol details are based on information publicly described by the WSJT-X authors and in related open documentation.
Some constants and tables (e.g. Costas synchronization sequence, LDPC structure, message packing scheme) are derived from the publicly available WSJT-X source code and FT8 protocol descriptions. Original WSJT-X source is © the WSJT Development Group and distributed under the GNU General Public License v3 (GPL-3.0), hence the use of GPL-3.0 in this repository.
Also thanks to Robert Morris for basicft8(*1) - the first code I properly read when I was wondering whether to start this journey. (*1 note: applies to FT8 pre V2)
Useful resources:
WSJTx - focussed:
- WSJT-X on Sourceforge
- W4KEK WSJT-x git mirror (searchable)
Other FT8 decoding repos:
- weakmon
- FT8_lib
- 'ft8modem - a command-line software modem for FT8' including source code (C++ and Python) (bottom of page)
FT8 decoding explorations / explanations
- VK3JPK's FT8 notes including comprehensive Python source code
- G4JNT notes on LDPC coding process
FT8 decoding in hardware
- Optimizing the (Web-888) FT8 Skimmer Experience (see also RX-888 project )
- 'DX-FT8-Transceiver' source code, the firmware part of the DX-FT8 Transceiver project
FT8 encode/decode simulators:
Browser-based decoder/encoders
- ft8js - source github, uses FT8_lib
- ChromeFT8 Browser Extension, decoder adapted from ft8js
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyft8-2.0.0.tar.gz.
File metadata
- Download URL: pyft8-2.0.0.tar.gz
- Upload date:
- Size: 13.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95d1cad288f2caeb354a3eb8899a040a7dd487703d51708579f2df8894f1bd37
|
|
| MD5 |
dd6e92c20a037b9ec080ffcdf3e72e0d
|
|
| BLAKE2b-256 |
0dd688d20689bd53644acc6ee790c1cf4f727f52214b92e5c62d3714a6585ac5
|
File details
Details for the file pyft8-2.0.0-py3-none-any.whl.
File metadata
- Download URL: pyft8-2.0.0-py3-none-any.whl
- Upload date:
- Size: 31.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3eade191b0625bbad45e168bada0d586d73f6f105d208d54112f7331d4ffcbb8
|
|
| MD5 |
b5542603783256e34ff402c5fd5d6097
|
|
| BLAKE2b-256 |
6abf90fc67574599b3b39d6ff6dc5c48c58fb7c0621ba2b4e13b49bffe528e72
|