Operator's manual

Frequently asked

How the decoder works, what the model can do, why the Beat-the-Bot matchup is set up the way it is, who built it, and what’s coming next. Tap any question; expand the technical version for the ham-radio and ML detail.

01·The basics
What is MORSE?

MORSE is a browser app that generates Morse code (CW) audio and decodes it with a small machine-learning model — all on your own device. You can dial in the speed and how much noise to bury the signal under, then watch the model copy it. There is also a game where you try to out-copy the model by ear.

What is CW / Morse code?

CW (“continuous wave”) is the on-off keying of a single tone into the dots and dashes of Morse code. It is one of the oldest modes in radio and is still used by amateur radio operators today because it gets through when voice cannot — a faint, narrow CW signal can be copied where a phone signal is just mush.

Do I need a radio or any special hardware?

No. MORSE generates the audio itself, right in the page. You do not need a radio, a key, or any software install. Live decoding from a microphone or a real receiver is on the roadmap, but everything today runs from synthesized clips.

02·How the decoding works
How does the decoder actually work?

The audio is turned into a simple picture of its energy over time, and a neural network reads that picture and predicts the sequence of characters. It was trained on huge amounts of synthetic CW at many speeds and noise levels, so it learns to copy through interference rather than relying on clean, perfectly-timed code.

The technical version

The network is CWNet — a CNN front end into a TCN and a bidirectional GRU, trained with a CTC objective (~808k parameters, exported to a 3.1 MB ONNX file). Input is a 4-channel envelope sampled at 500 Hz; output is per-frame log-probabilities over 42 classes (a CTC blank, A–Z, 0–9, and . , ? = /) at 250 Hz. A greedy CTC decode on the JavaScript side — gated by output entropy, blank ratio, and a run-length filter — collapses that into text.

The DSP that builds the envelope is hand-ported from the training pipeline (Python → TypeScript) so the browser sees exactly what the model was trained on.

How can machine learning run in a browser with no server?

The trained model is just a file the page downloads once, like an image. It then runs directly on your device using WebAssembly — a fast, low-level way for browsers to run compiled code. No request ever goes out to decode your audio, because there is nothing on the other end to ask.

The technical version

Inference runs through onnxruntime-web on the WASM backend, with multi-threading enabled. That requires the page to be cross-origin isolated (COOP/COEP headers), which is set both in dev and on the production host. The .onnx file is served as a static asset alongside the app.

How good is it, really?

It can copy CW down to roughly −12 dB signal-to-noise ratio — meaning the noise is several times stronger than the signal, well past the point where the code sounds like a steady tone to most ears. At easier signal levels it is essentially perfect; as you push the noise up, error rate climbs, and the decoder page shows you exactly where it breaks.

The technical version

SNR here is measured in the CW bandwidth of the synthesized clip. “−12 dB” is a headline figure for the favorable end of the speed range; very fast sending, deep fading (QSB), and short transmissions all make it harder. The decode page reports character error rate and a per-character diff so you can probe the failure modes yourself.

Is my audio or data sent anywhere?

No. Everything — generating the clip, running the model, grading the result — happens locally. There is no backend, no account, and no telemetry on the decode path. You can confirm it in your browser’s network tab: after the model file loads, decoding makes no network requests.

03·Accounts & the leaderboard
How does the leaderboard work?

Every time you finish a Beat-the-Bot round while signed in with a claimed callsign, your best copy percentage for that tier is saved. The leaderboard shows the top operators per tier — No-Code, Technician, General, Extra — plus an All board that ranks everyone together. You only see one row per operator per tier (your best), so the board is bests, not attempts.

Ranking is straightforward: highest copy percentage wins, with ties broken by when the best was set (earlier first). The bot is included only as a frozen per-tier baseline you can compare against; it does not occupy a leaderboard slot.

If you play without signing in, your scores live only in your browser and don't appear on the leaderboard. Sign in, claim a callsign, and your next personal-best is on the board the moment you set it.

What's the verified badge?

A small shield next to a callsign on the leaderboard means we've confirmed the person playing actually controls that callsign. Anyone signed in can claim any callsign; the badge is what tells you a claim has been verified against the operator's public QRZ bio.

To get one: go to your account page, click Get token, and we'll generate a one-time string starting with MORSE-VERIFY-. Paste it anywhere in your QRZ bio (qrz.com/db/YOURCALL), save, and click Check. We re-fetch your QRZ page and confirm the token is there. You then remove the token from your bio, save, and click Confirm — we re-fetch one more time, confirm it's gone, and flip the badge on. Two steps so your bio never has to keep our verification clutter. Tokens are good for 24 hours; you can re-mint any time.

Verification is optional — playing, claiming a callsign, and the leaderboard all work without it. The badge is just a higher signal-to-noise marker for other operators looking at the board.

04·Beat the Bot
What is Beat the Bot?

A game. Pick your license class — No-Code through Extra — and you get one callsign buried in static with a single listen to copy it. The callsign is keyed twice in the clip. A neural decoder works from a harder version of the same call, and after you submit your copy you see how each side did, scored character by character. The goal is to out-copy the machine despite starting from a cleaner signal.

Is it rigged? Does the bot get an unfair advantage?

The contest is intentionally asymmetric — but in your favor. Your clip is tuned to your tier: a No-Code clip is +10 dB at 13 WPM; an Extra clip is −6 dB at 28 WPM. The bot always decodes from the same hard clip — Extra difficulty — regardless of your tier. At Extra, you copy the same clip as the bot — no handicap. Below Extra, you start with a real noise and speed advantage.

What the bot has on its side is a processing advantage, not an access advantage: it decodes each of the two sends separately and merges the results, while you have to commit to a single copy in real time. That two-look merge is the interesting variable — and the game shows you exactly how the bot used it after every round. The question is not whether a machine can beat a human, but whether a neural decoder can overcome a noise and speed handicap by combining two noisy copies.

The technical version

The clip contains the call sent twice (e.g. “K1ABC K1ABC”). The decoder splits the envelope at the inter-send silence, runs inference on each half independently, greedy-decodes both, then combines them: if the two agree it takes the higher-confidence copy; if they disagree it Levenshtein-aligns them and fills missing characters from whichever look had them. This is post-decode ensembling, not coherent integration — summing per-frame log-probabilities before the CTC decode (for a true ~√2 SNR gain) is noted as future work.

The human is capped at one listen (MAX_LISTENS = 1). The clip asymmetry is deliberate and surfaced per-round: the SNR and WPM of both clips are shown in the result, and the “How the bot got two looks” detail explains the merge step.

05·The project
Who made this, and is it open source?

MORSE is a two-person project — we built the decoder and the game together, with different centers of gravity.

Mark PercivalKC4T

Creator & ML/DSP — started MORSE, trained CWNet, and built the morse-audio signal chain.

John SchultW4GIT

Engineering & UX — the frontend, plus the tooling and infrastructure holding the repo together.

The source is public on GitHub.

What’s next?
Accounts & leaderboardComing soon

Sign in, claim your call sign, and save your Beat-the-Bot results. A leaderboard ranks the top performances so you can see how you stack up against other operators — and licensed hams can optionally verify their call sign to earn a badge.

Live decodingPlanned

Feed a real microphone or receiver into the model and copy CW as it arrives, in streaming chunks. The pieces are specced in the code — not wired up yet.

Matchup & fairness tuningOngoing

Continued refinement of the Beat-the-Bot matchup and the fairness model behind it.

Your turn on the key

Enough reading — go pull something out of the noise.

Made within Atlantav2026.6.7