Read the stations that never say a word

Most of what identifies itself on the air identifies itself in Morse.  A
repeater, a beacon, an unattended transmitter: four to six characters, over
in a second or two, and no speech anywhere in the capture.  Every one of
those was being thrown away, in three separate places.

The callsign book and the map were built inside the transcription branch,
on the reasoning that callsigns come out of transcripts.  They also come out
of Morse and out of APRS headers, neither of which involves a speech
recogniser -- so a receiver with none installed found none of them, and a CW
ident reached the sidecar and stopped there.  Both are now built whenever
classification is on, and all three sources go through one place.

The CW decoder only ran where the classifier had already said cw, ook or
carrier.  A two-second ident is a fraction of a capture named after whatever
filled the rest of it.  Every capture is offered to it now, once it has
finished; a decode does not relabel a capture that plainly holds speech.

And the decoder's own gates were written for a paragraph.  Three characters,
eight elements, and any repeated character refused -- which read VVV, DE, AR
and K correctly and then discarded them.  Short is the normal case now, on a
second bar: perfect timing, nothing undecoded, and the keyed tone at least
20 dB over its band.  That last is not decoration.  With four elements the
dot length is fitted to those very elements, so noise lands on the grid as
neatly as keying does; a third of a second of white noise decodes as a
perfectly timed V.  Over 200 noise blocks the loudest bin never rose 13 dB
above the median while keying at 3 dB SNR sits above 40.  One keyed element
is still refused: a single pulse is an E or a T whether a person sent it or
the squelch opened on a click.  288 non-Morse cases, no false positives.

Feeding that text to a callsign lookup made truncation matter.  A capture
opens when the squelch does, halfway through an element as often as not, and
half a character is not a smaller reading -- a K missing its first dash is
an A.  So the sliced character is dropped, and so is the rest of its word,
because what is left can read as a whole one: K1AA caught halfway through is
K1A, which is somebody else.  Across 1805 truncated captures that is 107
invented callsigns down to none, with 550 correct ones still found.

Phonetics, which is the other half of the ask.  A recogniser has never heard
of the alphabet -- it writes what the words sounded like:

  Whiskey-One-Alpha-Whiskey    hyphenated
  WhiskeyOneAlphaWhiskey       run together
  Whiskey1AlphaWhiskey         and half in digits
  wiskey one alfa whisky       spelled the way it sounded
  whiskey one alpha, uh, whiskey   with the hesitation written down

All read back to W1AW now.  A word is only taken apart when it is phonetic
all the way through, which is what keeps it off "kilometre" and "victorious".

Two bugs found on the way, both of which invented a callsign:

 - Nothing is joined across a slash any more.  The beacon W1AW/B came back
   as W1AWB, which belongs to nobody, and W1AW-4 came back as nothing at all.
 - Nor across a gap the sender chose.  A transcript's spacing is the
   recogniser's guess and may be closed up; a word gap in Morse is seven dot
   units, so "KU0W K" is a station signing off, not a longer callsign.

Also here:

 - saunterbrowse gives Morse a panel of its own, with the licence under it,
   searchable with / and readable with t.
 - --simulate no longer looks anything up or writes a map.  The demo band is
   invented but W1AW is the ARRL's own station, and it would have been
   pinned to the same map a real scan writes.
 - classify._psk_order took the logarithm of zero on a silent block.
 - The demo band has a repeater ident in it, and its Morse no longer runs
   one repeat into the next.
 - conftest refuses a real licence lookup from any test.

1161 tests, up from 1014.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PsWPTweCT6pwxKngvVxcg
This commit is contained in:
The Dust Council 2026-08-29 14:59:25 -07:00
parent f9f0d94000
commit b4718aa425
21 changed files with 1434 additions and 129 deletions

View file

@ -540,7 +540,7 @@ Decode CW to text \[em] decode keyed carriers as Morse.
Setting name \fBdecode_morse\fR, default \fByes\fR.
.RS
.PP
Turn keyed carriers into readable text, with the sending speed. Morse is still in daily use by amateurs and by beacons, and this saves you learning to read it by ear. It costs almost nothing when there is no Morse about.
Turn keyed carriers into readable text, with the sending speed. Morse is still in daily use by amateurs and by beacons, and this saves you learning to read it by ear. It costs almost nothing when there is no Morse about. Every capture is tried once it has finished, whatever the modulation was called, because most of the Morse on the air is a repeater or a beacon giving its callsign in a burst of a second or two; a callsign read out of one goes to the same lookup and the same map as a spoken one.
.RE
.TP
.B --decode-data / --no-decode-data
@ -959,6 +959,54 @@ than a directory of placeholders.
.BR saunterbrowse (1)
reads these back, and lists any callsigns it finds in them with the licence
they belong to.
.PP
A callsign in a transcript is not written the way it is printed. A recogniser
has never heard of the phonetic alphabet: it writes what the words sounded
like, breaks the callsign wherever the speaker paused, joins the words back
up, hyphenates them, or drops a hesitation into the middle of the run. So
"KU 0W", "kilo uniform zero whiskey", "Whiskey\-One\-Alpha\-Whiskey",
"WhiskeyOneAlphaWhiskey" and "whiskey one alpha, uh, whiskey" are all read
back as the callsigns they are, and "alfa", "juliett" and "whisky" count
alongside the official spellings.
.PP
Nothing is joined across a slash: a suffix says where the station is, not
what it is called, so
.I W1AW/B
is W1AW.
.SH CW AND IDENTIFICATION
Every capture is offered to a CW decoder once it has finished, whatever the
classifier made of it. Most of the Morse on the air is not a conversation:
it is a repeater, a beacon or an unattended transmitter saying who it is and
stopping, which is four to six characters and over in a second or two. That
burst is a fraction of a capture named after whatever filled the rest of it,
so waiting for the label to say "CW" missed it.
.PP
Short is therefore the normal case rather than the awkward one. A decode of
two or three characters is believed on its timing alone \[em] every element
within a third of a unit of one or three, every character resolving to
something in the table, and the keyed tone standing at least 20 dB above the
rest of its band. That last one is what separates an ident from a blip: with
four elements the dot length is fitted to those very elements, so noise lands
on the grid as neatly as keying does, and only the tone tells them apart. One
keyed element is refused, because a single pulse is an E or a T whether a
person sent it or the squelch opened on a click.
.PP
The other half of a short decode is knowing what was cut off. A capture opens
when the squelch does, which is in the middle of an element as often as not,
and half a character is not a smaller reading of what was sent \[em] it is a
different one, and a K with its first dash missing is an A. So the character
at a sliced end is dropped, and so is the rest of the word it was in, because
what is left of that word can read as a whole one:
.I K1AA
caught halfway through is
.IR K1A ,
which belongs to somebody else. The full text is still reported; it is the
identification that is held to the stricter standard.
.PP
What survives goes to the same callsign lookup and the same map as a spoken
one. Word gaps in Morse are not joined across, because the sender chose them:
.I "KU0W K"
is a station signing off, not a callsign one letter longer.
.SH DECODING DATA
A great deal of what a scanner finds is not speech. Doorbells, tyre\-pressure
sensors, weather stations, remote controls, paging and packet radio all carry
@ -1032,8 +1080,11 @@ check: a burst of keying demodulated as FM audio is a buzz, and the speech
detector likes a buzz, but a frame whose own checksum came out right is not a
statistic.
.SH THE MAP
A callsign heard in a transcript is looked up in the FCC's published licence
data, which gives the licensee, the town, and coordinates. Those go into a
A callsign is looked up in the FCC's published licence data, which gives the
licensee, the town, and coordinates. They arrive from three directions and
all three end up in the same place: spoken and transcribed, sent in Morse, or
carried in the header of an APRS packet. None of the last two involves a
speech recogniser, so a machine with none installed still builds a map. Those go into a
KML file in the output directory \[em]
.I callsigns.kml
unless

View file

@ -193,9 +193,17 @@ is every callsign heard in it, with the name and location on the licence.
Finding them is not a matter of one regular expression over the text as
written. A speech recogniser is poor at callsigns \[em] they are not words,
they are said one character at a time \[em] so it breaks them wherever the
speaker paused and writes the phonetic alphabet down verbatim. "KU 0W",
"K7 RA" and "kilo uniform zero whiskey" are all one callsign each, and all
three are read back correctly.
speaker paused and writes the phonetic alphabet down verbatim. It also joins
the words back up, hyphenates them, spells them the way they sounded, and
writes down the hesitation in the middle. "KU 0W", "K7 RA",
"kilo uniform zero whiskey", "Whiskey\-One\-Alpha\-Whiskey",
"WhiskeyOneAlphaWhiskey", "wiskey one alfa whisky" and
"whiskey one alpha, uh, whiskey" are all one callsign each, and all of them
are read back correctly.
.PP
A suffix is not part of the callsign. Nothing is joined across a slash, so
.I W1AW/B
is W1AW and not W1AWB, which belongs to nobody.
.PP
False positives are the thing to avoid: a browser that invents callsigns is
worse than one that finds none. So a run of words is only accepted when none
@ -295,6 +303,23 @@ lock-out list in your settings file. The width comes from the
setting, so a lock-out is a channel rather than a single point. Locking out a
frequency does not delete what has already been recorded on it \[em] the two
keys are separate on purpose, and pressing both is the usual thing to do.
.SH CALLSIGNS IN MORSE
Most stations on the air never say a word. A repeater, a beacon or an
unattended transmitter sends its callsign in Morse and stops, and what it
sent takes the place of the transcript at the top of the screen, with the
licence it belongs to underneath exactly as for speech. It is searchable with
.B /
like anything else.
.PP
Only the part of it that was not cut in half is looked at for a callsign. A
capture opens when the squelch does, which is partway through a word as often
as not, and what is left of that word can read as a whole one:
.I K1AA
caught halfway through is
.IR K1A ,
which belongs to somebody else.
.BR bandsaunter (1)
describes how that is decided. The full text is shown either way.
.SH DECODED DATA
Where a capture carried data rather than speech, what was decoded takes the
place of the transcript at the top of the screen: the kind of packet, and then

View file

@ -381,6 +381,54 @@ than a directory of placeholders.
.BR saunterbrowse (1)
reads these back, and lists any callsigns it finds in them with the licence
they belong to.
.PP
A callsign in a transcript is not written the way it is printed. A recogniser
has never heard of the phonetic alphabet: it writes what the words sounded
like, breaks the callsign wherever the speaker paused, joins the words back
up, hyphenates them, or drops a hesitation into the middle of the run. So
"KU 0W", "kilo uniform zero whiskey", "Whiskey\-One\-Alpha\-Whiskey",
"WhiskeyOneAlphaWhiskey" and "whiskey one alpha, uh, whiskey" are all read
back as the callsigns they are, and "alfa", "juliett" and "whisky" count
alongside the official spellings.
.PP
Nothing is joined across a slash: a suffix says where the station is, not
what it is called, so
.I W1AW/B
is W1AW.
.SH CW AND IDENTIFICATION
Every capture is offered to a CW decoder once it has finished, whatever the
classifier made of it. Most of the Morse on the air is not a conversation:
it is a repeater, a beacon or an unattended transmitter saying who it is and
stopping, which is four to six characters and over in a second or two. That
burst is a fraction of a capture named after whatever filled the rest of it,
so waiting for the label to say "CW" missed it.
.PP
Short is therefore the normal case rather than the awkward one. A decode of
two or three characters is believed on its timing alone \[em] every element
within a third of a unit of one or three, every character resolving to
something in the table, and the keyed tone standing at least 20 dB above the
rest of its band. That last one is what separates an ident from a blip: with
four elements the dot length is fitted to those very elements, so noise lands
on the grid as neatly as keying does, and only the tone tells them apart. One
keyed element is refused, because a single pulse is an E or a T whether a
person sent it or the squelch opened on a click.
.PP
The other half of a short decode is knowing what was cut off. A capture opens
when the squelch does, which is in the middle of an element as often as not,
and half a character is not a smaller reading of what was sent \[em] it is a
different one, and a K with its first dash missing is an A. So the character
at a sliced end is dropped, and so is the rest of the word it was in, because
what is left of that word can read as a whole one:
.I K1AA
caught halfway through is
.IR K1A ,
which belongs to somebody else. The full text is still reported; it is the
identification that is held to the stricter standard.
.PP
What survives goes to the same callsign lookup and the same map as a spoken
one. Word gaps in Morse are not joined across, because the sender chose them:
.I "KU0W K"
is a station signing off, not a callsign one letter longer.
.SH DECODING DATA
A great deal of what a scanner finds is not speech. Doorbells, tyre\-pressure
sensors, weather stations, remote controls, paging and packet radio all carry
@ -454,8 +502,11 @@ check: a burst of keying demodulated as FM audio is a buzz, and the speech
detector likes a buzz, but a frame whose own checksum came out right is not a
statistic.
.SH THE MAP
A callsign heard in a transcript is looked up in the FCC's published licence
data, which gives the licensee, the town, and coordinates. Those go into a
A callsign is looked up in the FCC's published licence data, which gives the
licensee, the town, and coordinates. They arrive from three directions and
all three end up in the same place: spoken and transcribed, sent in Morse, or
carried in the header of an APRS packet. None of the last two involves a
speech recogniser, so a machine with none installed still builds a map. Those go into a
KML file in the output directory \[em]
.I callsigns.kml
unless

View file

@ -167,9 +167,17 @@ is every callsign heard in it, with the name and location on the licence.
Finding them is not a matter of one regular expression over the text as
written. A speech recogniser is poor at callsigns \[em] they are not words,
they are said one character at a time \[em] so it breaks them wherever the
speaker paused and writes the phonetic alphabet down verbatim. "KU 0W",
"K7 RA" and "kilo uniform zero whiskey" are all one callsign each, and all
three are read back correctly.
speaker paused and writes the phonetic alphabet down verbatim. It also joins
the words back up, hyphenates them, spells them the way they sounded, and
writes down the hesitation in the middle. "KU 0W", "K7 RA",
"kilo uniform zero whiskey", "Whiskey\-One\-Alpha\-Whiskey",
"WhiskeyOneAlphaWhiskey", "wiskey one alfa whisky" and
"whiskey one alpha, uh, whiskey" are all one callsign each, and all of them
are read back correctly.
.PP
A suffix is not part of the callsign. Nothing is joined across a slash, so
.I W1AW/B
is W1AW and not W1AWB, which belongs to nobody.
.PP
False positives are the thing to avoid: a browser that invents callsigns is
worse than one that finds none. So a run of words is only accepted when none
@ -283,6 +291,23 @@ lock-out list in your settings file. The width comes from the
setting, so a lock-out is a channel rather than a single point. Locking out a
frequency does not delete what has already been recorded on it \[em] the two
keys are separate on purpose, and pressing both is the usual thing to do.
.SH CALLSIGNS IN MORSE
Most stations on the air never say a word. A repeater, a beacon or an
unattended transmitter sends its callsign in Morse and stops, and what it
sent takes the place of the transcript at the top of the screen, with the
licence it belongs to underneath exactly as for speech. It is searchable with
.B /
like anything else.
.PP
Only the part of it that was not cut in half is looked at for a callsign. A
capture opens when the squelch does, which is partway through a word as often
as not, and what is left of that word can read as a whole one:
.I K1AA
caught halfway through is
.IR K1A ,
which belongs to somebody else.
.BR bandsaunter (1)
describes how that is decided. The full text is shown either way.
.SH DECODED DATA
Where a capture carried data rather than speech, what was decoded takes the
place of the transcript at the top of the screen: the kind of packet, and then