{"id":51237230,"url":"https://github.com/mattackerman808/ft8-808","last_synced_at":"2026-06-28T21:31:55.218Z","repository":{"id":365528821,"uuid":"1271791472","full_name":"mattackerman808/ft8-808","owner":"mattackerman808","description":"Swift-native FT8 amateur-radio station for macOS — live decode, waterfall, rig control, and automated QSOs. GPL-free (MIT).","archived":false,"fork":false,"pushed_at":"2026-06-17T17:44:39.000Z","size":2202,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T19:26:05.601Z","etag":null,"topics":["amateur-radio","coreaudio","ft8","ham-radio","hamlib","macos","sdr","swift","wsjt-x"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattackerman808.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-17T02:38:37.000Z","updated_at":"2026-06-17T17:47:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mattackerman808/ft8-808","commit_stats":null,"previous_names":["mattackerman808/ft8-808"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mattackerman808/ft8-808","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattackerman808%2Fft8-808","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattackerman808%2Fft8-808/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattackerman808%2Fft8-808/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattackerman808%2Fft8-808/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattackerman808","download_url":"https://codeload.github.com/mattackerman808/ft8-808/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattackerman808%2Fft8-808/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34905180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amateur-radio","coreaudio","ft8","ham-radio","hamlib","macos","sdr","swift","wsjt-x"],"created_at":"2026-06-28T21:31:54.691Z","updated_at":"2026-06-28T21:31:55.127Z","avatar_url":"https://github.com/mattackerman808.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FT8-808\n\nA **Swift-native FT8 station for macOS** — live decode, waterfall, rig control, and\nfully automated QSOs. It ships as a **native macOS app** (GPU 3D/2D waterfall) and a\n**fast terminal UI**, both over one shared engine. The same job as\n[WSJT-X](https://github.com/WSJTX/wsjtx), built from the published protocol with a\nclean-room, GPL-free codebase.\n\n\u003e FT8-808 is an independent project. It does **not** read or port WSJT-X source; it\n\u003e relies on the openly published FT4/FT8 protocol spec and the MIT-licensed\n\u003e [`ft8_lib`](https://github.com/kgoba/ft8_lib). See [Licensing](#licensing).\n\nIt makes **real contacts on the air** — receive, decode, pick a station (or call CQ),\nauto-sequence the exchange through to `73`, log it to ADIF — from the mouse in the app or\nthe keyboard in the terminal client (`ft8term`, shown here):\n\n```\n [Q]uit  [T]une  [F]ind  [S]ettings\n cycle ████████████████████░░░░░░░  12.3/15s  slot even\n ───────────────────────────────────────────────────────────────────\n   ▁▂▃▅▇█  live waterfall / spectrum (vDSP FFT, noise-floor scaled)\n                          ▲  Rx/Tx 1370 Hz\n ───────────────────────────────────────────────────────────────────\n  dB   dt  freq  Band — entire passband │ Rx 570 Hz ±12\n ▎-13 +0.7 2409  EI9KF KB8BSN EL89       │  -14 +0.5  572  CQ AI5OS EM10\n ▎-10 +0.5  569  N6ACK AI5OS RR73        │  Tx        AI5OS N6ACK CM97\n ▎-18 +0.8  991  CQ WD8LOE EM63          │  ● PWR 92W  ALC 1.8  SWR 1.2\n ...                                     │  ▸ Tx3  AI5OS N6ACK R-13   now\n                                         │  ✓ QSO  AI5OS sent -10 rcvd -16\n   ↑↓/jk pick   ⏎ answer                 │  [C]Q  [E] TX  [O] slot  esc clear\n ───────────────────────────────────────────────────────────────────\n live: USB Audio CODEC   decoding…\n```\n\n## Features\n\n- **Live receive** — CoreAudio capture from the rig's USB codec, UTC-aligned 15 s\n  slots, full `ft8_lib` decode, with realistic SNR (WSJT-X-comparable, computed from\n  the waterfall — not a sync-score proxy).\n- **Waterfall / spectrum** — vDSP FFT with noise-floor-referenced scaling; the app renders\n  it as a live Metal **3D or 2D** waterfall you click to set Tx frequency.\n- **Dual band view** — entire passband on the left, your Rx-frequency traffic on the\n  right (the WSJT-X \"Band Activity / Rx Frequency\" split).\n- **Callsign highlighting** — your call green, worked-before (from your ADIF log) red,\n  per-token; even/odd slot markers down the band column.\n- **Rig control** — bundled Hamlib (no `brew install`): CAT frequency/mode and PTT.\n- **Transmit** — GFSK waveform synthesis, slot-aligned, keyed via CAT. Tune + auto-tune\n  drive calibration with live PWR/ALC/SWR meters.\n- **Automated QSOs** — pick a decode and the state machine sequences the whole exchange\n  (CQ → grid → report → R-report → RR73 → 73), then auto-completes.\n- **ADIF logging** — every QSO appended to `~/.config/ft8-808/ft8-808.adi`, importable\n  into LoTW / QRZ / Club Log.\n- **LoTW auto-upload** — optional: each logged QSO is signed and uploaded to ARRL\n  Logbook of The World via your installed [TrustedQSL](https://lotw.arrl.org/lotw-help/cmdline/)\n  (`tqsl`). Enable in **[S]ettings** (or `--lotw --lotw-location \"\u003cname\u003e\"`). On\n  launch (and on enabling) it catches up the whole log — anything logged while it\n  was off — and **U** uploads the whole log on demand. TQSL dedups, so nothing is\n  sent twice.\n- **Self-contained** — one `swift build`; Hamlib ships as a relocatable xcframework.\n\n## Install\n\nDownload the latest **signed + notarized `.pkg`** from\n[**Releases**](https://github.com/mattackerman808/ft8-808/releases) and double-click it.\nIt installs both front-ends:\n\n- **`FT8-808.app`** → `/Applications` — the native macOS app, and\n- **`ft8term`** → `/usr/local/bin` — the terminal client (on your `PATH`).\n\nThey share one config at `~/.config/ft8-808/config.json`, so you can use either\ninterchangeably. The package is notarized, so Gatekeeper clears it with no warning.\nUniversal (Apple Silicon + Intel), **macOS 13+**. You'll need a rig with a USB audio\ncodec + CAT; Hamlib is bundled (no `brew install`).\n\n## Build from source\n\nRequirements: **macOS 13+** and **Swift 6** (Xcode 16 / recent toolchain).\n\n```sh\ngit clone https://github.com/mattackerman808/ft8-808.git\ncd ft8-808\nswift build\nswift run ft8gui             # the native app\nswift run ft8term            # the terminal client\n```\n\n## Using the app (GUI)\n\nLaunch **FT8-808** (from `/Applications`, Spotlight, or `swift run ft8gui`). On the first\nrun, click the **⚙ gear** to set your callsign, grid, rig (CAT port + Hamlib model), and\naudio input/output. macOS asks for microphone access the first time it captures — that's\nyour rig's receive audio.\n\n**Tune the radio** — from the top bar:\n- **Band** menu — jump to a band's standard FT8 dial frequency.\n- **Scroll over the VFO digits** to tune; scrolling over the MHz / kHz / Hz part of the\n  readout steps that place. The **▲▼** steppers nudge ±1 kHz.\n\n**Work a station:**\n1. Flip **Enable TX** on (top bar) — the master transmit switch; it glows red when armed.\n2. **Click a decode** in the Passband or RX Frequency list. It loads the QSO — replying on\n   the station's frequency, in the opposite slot — and if you clicked early enough in your\n   own slot it goes out *that* cycle (\"pounce\"). Click another station to switch to it.\n3. Or hit **Call CQ** and let callers come to you.\n\nThe sequencer runs the whole exchange (reply → report → roger → `RR73`/`73`), logs the QSO\nto ADIF, and drops a green **✓ QSO** banner in the list. Then pick the next one.\n\nHandy bits: **Find Free** (on the RX/TX bar) drops you on a clear Tx frequency · the\n**Even/Odd** selector picks your transmit cycle · the **gauges** read live PWR/SWR/ALC · the\n**antenna icon** opens the Tuner (key a carrier, set drive, or auto-tune) · worked-before\ncalls show **red**, your own call **green**, and the bar under the RX/TX field tracks the\n15 s cycle.\n\n## Using the terminal client (TUI)\n\n`ft8term` is the same station, keyboard-driven — handy over SSH or on a headless shack box.\nFirst run, press **`S`** for Settings to set callsign, grid, rig, and audio — or pass flags:\n\n```sh\nft8term                      # if installed; or `swift run ft8term` from source\nft8term --call N0CALL --grid FN42 \\\n        --rig ts590sg,/dev/cu.usbserial-XXXX,115200 \\\n        --audio \"USB Audio CODEC\"\n```\n\n| Key | Action |\n|---|---|\n| `↑`/`↓` or `j`/`k` | pick a decode in the band column |\n| `⏎` | answer the selected station (replies on their freq, opposite slot) |\n| `C` | call CQ (press again to stop) |\n| `E` | enable / disable TX |\n| `O` | swap even/odd transmit slot |\n| `esc` | clear selection / abandon the active QSO |\n| `←`/`→`, `,`/`.`, `\u003c`/`\u003e` | move the Rx/Tx frequency cursor |\n| `F` | auto-pick a clear Tx frequency |\n| `T` | tune (key PTT + tone); `+`/`-` drive, `A` auto-tune |\n| `S` | settings · `Q` quit |\n\nDecode a recorded slot, WSJT-X style:\n\n```sh\nft8term path/to/slot.wav             # TUI batch mode (prints the final frame, exits)\nswift run ft8decode path/to/slot.wav # one-shot decoder (dev tool, build from source)\n```\n\n### Diagnostics\n\n```sh\nft8term --list-audio                 # audio devices (flags the rig codec)\nft8term --list-serial                # serial ports (flags the rig CAT port)\nft8term --list-rigs                  # Hamlib-supported rigs\nft8term --meter \"USB Audio CODEC\"    # probe the capture path + live level\nswift run ft8rig ...                 # standalone rig CAT/PTT diagnostic (dev tool)\n```\n\n## How it works\n\n15-second UTC-aligned TX/RX slots. 8-FSK at 6.25 baud, 6.25 Hz tone spacing. 79 symbols\n(58 data + 21 Costas sync). A 77-bit message + 14-bit CRC → LDPC(174,91) → tones. Decode =\nCostas sync → soft 8-FSK demod → LDPC. The protocol is fully specified in\n[*The FT4 and FT8 Communication Protocols*](https://wsjt.sourceforge.io/FT4_FT8_QEX.pdf)\n(Franke/Somerville/Taylor, QEX 2020) — enough for a clean-room build with no GPL code.\n\n**Architecture:** a headless `FT8808Engine` library holds all the radio logic; the\nfront-ends are thin clients over it — the `ft8gui` app and the `ft8term` TUI.\n\n| Target | Role |\n|---|---|\n| `CFT8` | vendored `ft8_lib` (MIT) + a C shim: decode pipeline, GFSK synth, SNR estimate |\n| `FT8Codec` | Swift wrapper — `decode`, `encode`, `synthesize` |\n| `FT8808Engine` | audio (raw AUHAL capture/playback), slot timing, spectrum, QSO sequencer, ADIF, rig protocol |\n| `CHamlib` / `HamlibRig` | bundled Hamlib xcframework + actor-based `RigController` |\n| `ft8gui` | native macOS app — SwiftUI + Metal 3D/2D waterfall over the engine |\n| `ft8term` / `ft8rig` / `ft8decode` | terminal client + diagnostics |\n\nSee [`docs/architecture.md`](docs/architecture.md), [`docs/roadmap.md`](docs/roadmap.md),\nand [`CLAUDE.md`](CLAUDE.md) (orientation for AI agents and new contributors — the\nhard-won macOS-audio and rig-control gotchas live there).\n\n## Licensing\n\n- **FT8-808's own code: MIT** (see [`LICENSE`](LICENSE)).\n- Bundled/linked deps keep their licenses — `ft8_lib` (MIT), Hamlib (LGPL-2.1+, dynamically\n  linked). Full third-party notices and LGPL compliance details in [`NOTICE.md`](NOTICE.md).\n- We use the **published protocol spec**, never WSJT-X (GPLv3) source.\n\n## References\n\n- FT4/FT8 protocol paper (QEX 2020): https://wsjt.sourceforge.io/FT4_FT8_QEX.pdf\n- `ft8_lib` (MIT C codec): https://github.com/kgoba/ft8_lib\n- Hamlib (rig control): https://github.com/Hamlib/Hamlib\n- WSJT-X (GPLv3 — behavioral reference only, no code reuse): https://github.com/WSJTX/wsjtx\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattackerman808%2Fft8-808","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattackerman808%2Fft8-808","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattackerman808%2Fft8-808/lists"}