Audio analysis · No upload

Morse audio to text

Drop a recording of morse code — a practice file, an SDR capture, a voice memo of a beacon — and read it back as text. The tone, the speed and the timing are measured from your file, never assumed; everything runs inside your browser, and the network meter below proves the zero live. This page downloads nothing at any point — not even a library.

Statusidle Files File Duration Sample rate Tone Unit Speed Network since file read
Decoded text

    
    

    

The strip is the decode made visible: the tone's envelope in decibels, the threshold it was read against, and every burst counted as a dit or a dah. The line under the transcript pairs each decoded character with its elements, so any letter can be checked against the recording.

How this decoder works

When you choose a file, the browser's File API hands this page the bytes in memory — no transfer happens, because the file is already on your machine — and your browser decodes the audio into raw samples itself. The measuring starts there. The samples are averaged to mono and cut into 4-millisecond frames; the loudest 32 milliseconds are autocorrelated to find the frequency of the keyed tone, anywhere from 100 to 3000 Hz; and a Goertzel filter — about a dozen lines of arithmetic in this page's own JavaScript — re-reads the whole recording at exactly that frequency, which is why hiss and hum elsewhere in the spectrum contribute almost nothing. Everything the readout prints is a measurement from your file: the tone in hertz, the timing unit in milliseconds, and the WPM, which is never asked for and never assumed.

The filtered envelope, in decibels, splits into two clusters — tone on and tone off — and the threshold between them is set from your recording, with hysteresis so ramped keying doesn't chatter. That yields runs of on and off; runs shorter than 8 milliseconds are merged away as clicks. The lengths of the tone bursts cluster into dits and dahs, the unit falls out of the measured centers, and the gaps are classified against multiples of that same unit: inside a letter, between letters, between words. The ITU table turns element patterns into text; a pattern outside the table is shown as dots and dashes, never guessed into the nearest letter. The strip draws the envelope, the threshold and every burst the decoder counted, and the alignment line pairs each decoded character with its elements — the evidence trail for every letter, readable without playing a thing.

The honest limits. This page reads one keyed tone at a time; speech, music and mixes where no single tone dominates produce a refusal, not a transcript — every refusal begins “could not find morse timing” and names its reason, and a refusal always means an empty transcript. Overlapping stations are never untangled: a balanced mix is refused outright, and when one station is far louder than the rest, the decode reads that dominant tone only. The keying has to switch by at least 6 decibels for the on/off gate to hold, and the working band is roughly 5–50 WPM. Files longer than ten minutes are refused by name, because the whole recording sits in your device's memory as raw samples. And this is a decoder only: it deliberately makes no sound, builds no tone and plays nothing back — the verify surface is the strip and the per-letter alignment, which show what a speaker never could: every burst it counted, against the threshold it counted them with.

Frequently asked questions

Is my recording uploaded anywhere?
No. Your browser opens the file with its File API and decodes the audio itself, and everything after that — the envelope, the threshold, the timing grammar — is JavaScript running inside this tab. The readout's network meter counts every request from the moment your file is read and stays at zero, and unlike the converter pages there is no one-time library download to footnote: this page fetches nothing at any point, so the zero has no exceptions. The methodology page shows how to verify it independently, including with your wifi switched off.
How does it know how fast the morse was sent?
It doesn't ask and it doesn't assume a standard: the speed is measured from your file, not assumed. The decoder collects the length of every tone burst it detected, clusters those lengths into short and long, and takes the timing unit from the measured centers — a dah is three units, so the two clusters give two independent estimates and the unit averages them. The WPM in the readout is 1200 divided by that unit in milliseconds, the PARIS standard, printed as a measurement. The letter and word gaps are then classified against that same measured unit, so a recording keyed in ordinary proportions reads without being told its speed. One honest limit: Farnsworth-spaced practice recordings stretch the gaps between letters far past the standard three units, and a stretched letter gap is indistinguishable from a word gap — the letters decode correctly, but extra word breaks appear in the transcript.
Why does it say “could not find morse timing”?
Because refusing is the honest answer when the recording doesn't carry what this page reads. Every refusal starts with “could not find morse timing” and names its reason: no steady tone in the recording, no single tone dominant enough to read (overlapping signals are refused, not untangled), no clear on/off keying (the tone must switch by at least 6 decibels), too few tone bursts to establish the speed, or an on/off pattern that doesn't follow morse structure. In each of those cases the transcript stays empty — noise in never becomes confident text out. The strip above the alignment line shows what was measured, so you can see what the decoder saw.
What can't this decoder read?
It reads one keyed tone at a time and cannot separate overlapping transmissions — a mix where no single tone dominates is refused rather than guessed, and when one station is far louder than the rest, the decode reads that dominant tone only. It does not decode a voice saying “dit dah”, and the working band is roughly 5–50 WPM. Files longer than ten minutes are refused by name, because the whole recording is held in your device's memory as raw samples. And a decoded pattern that isn't in the ITU table is shown as dots and dashes, never guessed into the nearest letter.
Which audio formats work here?
WAV and MP3 are the headline pair, and the full accept list — M4A/AAC, OGG and Opus, FLAC, AIFF and WebM audio — is simply every audio format your browser can decode itself. That is the whole selection rule: decoding is done by the browser's own audio engine, so this page never ships or downloads a decoder, and a format the browser cannot open is refused by name rather than attempted. Recordings from voice-memo apps, SDR captures and practice generators all arrive in one of these.

Related tools