38 Commits

Author SHA1 Message Date
Leah Rowe
c666da8ecc util/spkmodem-decode: add CHAR_BIT define
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 02:33:40 +00:00
Leah Rowe
2d77f9649d spkmodem-decode: edge detection *and* amplitude
for pulses, we currently use amplitude detection.

edge detection is better, because weak / low gain
signals will be more reliable. if audio is coming
in on/from a system that does automatic gain
adjustment, this once again is more robust too.

microphones and speakers (which people often use
with spkmodem if nothing else available) often
clamp amplitude, to an extent that this software
may not detect those pulses reliably that way.

so we detect slope edges instead. this causes
very little performance penalty (use of abs(),
that's about it)

however, edge detection is inherently vulnerable
to noise, so we will also detect amplitude. this
acts as an effective noise filter, while still
improving pulse detection.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 02:21:20 +00:00
Leah Rowe
656c39e45c spkmodem-decode: reset calibration accumulators
in select_separator_tone, i never reset these
after computing their average.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:59:26 +00:00
Leah Rowe
9a1bf61bda util/spkmodem-decode: remove dead code
this check no longer applies (never triggers)

is_signal_valid already guarantees that the separator
tone is valid.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:58:09 +00:00
Leah Rowe
7f0e3d1877 spkmodem-decode: small cleanup in decode_pulse
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:53:11 +00:00
Leah Rowe
a385879203 spkmodem-decode: don't select sep tone on bad signal
otherwise, calibration could collect garbage data.
this improves noise mitigation.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:51:27 +00:00
Leah Rowe
e29ca3c0d3 spkmodem-decode: ignore invalid frames when setting bits
bits are currently assembled even on invalid frames. this
patch fixes that - the bug is also in the GNU version.

this reduces the chance of noise/calibration from creating
corrupt character output during operation.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:49:07 +00:00
Leah Rowe
1ec8bfbe91 spkmodem-decode: reset char if separator disappears
improves reliability in the case when audio cuts out,
mic glitches, laptop audio power saving, etc.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:47:40 +00:00
Leah Rowe
aada4848c1 spkmodem-decode: fix single-tone learning bug
enforce at least two tones. this mitigates the
chance of random noise being treated as a real
tone, and reduces the chance of broken
thresholds versus freq min/max e.g.
freq min 31, max 32 and threshold 31

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:45:17 +00:00
Leah Rowe
05f59ac7c6 spkmodem-decode: enforce calibrated seperator range
we weren't actually using what we calculated. this patch
fixes that, thus preventing random noise / microphone
clicks, random artifacts and such from being treated
as real frames (the purpose of is_valid_signal is
partly noise suppression).

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:42:41 +00:00
Leah Rowe
5bb99f636a spkmodem-decode: fix wrong sample count
in handle audio, i do the number of samples
per frame, and one more. e.g. 241 instead of
240. this bug is in the original GNU version
too. this patch fixes it.

this means that the output could slowly go
out of sync with calculated timings. the
patch fixes that. in practise, the decoder
is not that sensitive, and the code would
adjust anyway (automatic timing adjustment),
but ideally we want to not *cause* such
issues even if we mitigate them.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:37:02 +00:00
Leah Rowe
3c67487d14 Revert "util/spkmodem-decode: fix 3-frame timeout"
This reverts commit dbf0c3ccc2.
2026-03-13 01:32:54 +00:00
Leah Rowe
b4cce52ce0 util/spkmodem-decode: clarify frame count on check
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:31:33 +00:00
Leah Rowe
ee9045b807 util/spkmodem-decode: static asserts
assert integer sizes, important in this program because
we make several implicit assumptions about word sizes,
and integers need to be of a certain size.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:26:42 +00:00
Leah Rowe
4e48b173ae util/spkmodem-decode: annotate prototypes
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 01:23:27 +00:00
Leah Rowe
fcbd144306 util/spkmodem-decode: rename function for clarity
collect_separator should be select_separator, to bring
it in line with select_low_tone

this just makes the code a bit easier to read

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 00:57:15 +00:00
Leah Rowe
2cc06fcdbe util/spkmodem-decode: tidy up indentation
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 00:50:40 +00:00
Leah Rowe
a010665c1d fix typo in comment
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 00:29:41 +00:00
Leah Rowe
dbf0c3ccc2 util/spkmodem-decode: fix 3-frame timeout
i accidentally left this reset here during a
previous refactor.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-13 00:13:51 +00:00
Leah Rowe
36d914149d util/spkmodem-decode: rename auto_detect_tone
auto seems redundant. detect implies auto.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:58:59 +00:00
Leah Rowe
2bb17c61d0 spkmodem-decode: learn tone per frame, not sample
the fir filter produces stable frequencies per frame,
but learning per sample (within a frame) means we
record the same value roughly 240 times.

here, we are syncing up at just the right moment
instead, and only at that moment, this increasing
both performance and reliability.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:54:01 +00:00
Leah Rowe
63f4fa1f41 spkmodem-decode: fix learn_samples increment
oops!!!

another mistake during refactoring. right now it
doesn't increment before being checked, so learning
can go forever in an infinite loop

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:42:00 +00:00
Leah Rowe
769664779a spkmodem-decode: don't dump learn_samples in silence check
oops

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:40:56 +00:00
Leah Rowe
b59cc0f1ae util/spkmodem-decode: split up auto_detect_tone
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:38:10 +00:00
Leah Rowe
f396654ae8 util/spkmodem-decode: separate silence check
i conflated two separate tests in a previous change.

the silence check was defeated by still checking f
alongside it, which would be set, thus satisfying
the condition, and proceeding, which defeats the
purpose of the silence check (ignore false signal
that is actually noise) - so in the original patch
that i wrote, the extra checks actually do nothing.

this patch fixes that, and makes the logic a bit
clearer.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:26:47 +00:00
Leah Rowe
c4fefba877 util/spkmodem-decode: don't run decode in col_sep_tone
otherwise, it runs twice

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:21:18 +00:00
Leah Rowe
88ca9e6f03 util/spkmodem-decode: guard against silence in tone-detect
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:18:26 +00:00
Leah Rowe
3189e3e079 util/spkmodem-decode: split up handle_audio()
this enables the separated code to have reduced
indentation

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:14:03 +00:00
Leah Rowe
dd9e681eb9 util/spkmodem-decode: also auto-detect separator
the tone detection currently only tracks data, not
the separator. track both instead, for improved
detection reliability.

e.g.

separator tone ≈ 9
data low tone ≈ 18
data high tone ≈ 24

two fir windows produce e.g.
freq data 9 sep 0
then 18, 9
then 24, 9
18, 9

so we take min(data, separator)

that gives 9,9,9,9

now we have the separator cluster

however, if both windows are active during transitions,
you can also capture the higher clusters, which would
allow freq_max to grow

so when you learn e.g.:

freq min = 9
freq max 24

then the learned threshold would be:

(9 + 24) / 2 = 16

and now you know how to separate the tones

fir already suppresses noise so the pulse should
be reliable. so freq/sep only go non-zero when an
actual tone exists

this should now result in being able to sync with
spkmodem encoders with no prior knowledge of the
correct tone frequences. we just use maths.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 23:12:40 +00:00
Leah Rowe
5edd7c9fae util/spkmodem-decode: simplify valid_signal
since we have auto-detection now, we only need to know
that two signals exist, not that they are valid, since
the auto-detection now handles validation and fallback.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 22:53:17 +00:00
Leah Rowe
852a6ccf11 util/spkmodem-decode: automatic tone detection
a continuation of the previous patch. this waits for
currently one second, before defaulting to the hardcoded
value. otherwise, it tries to use whatever timing it
gets automatically.

this way, the program should now reconfigure its own
timing, without intervention by the user, if the timing
differs from sensible defaults.

this is because spkmodem is implementation-defined;
it's just however coreboot and/or GRUB happen to set
it up, and on the hardware in question.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 22:44:50 +00:00
Leah Rowe
569660ada9 util/spkmodem-decode: automatic tone calibration
current logic is hardcoded, as in the original spkmodem-recv.

with this change, small differences are observed and averaged,
then the detection thresholds are adjusted accordingly.

the existing macros serve as a baseline, but real signals
differ. with this change, we therefore account for possible
drift in timings, which can change in real-time; the old
code could possibly get out of sync beccause of that, which
may have resulted in corrupt characters on the screen. this
change therefore should make the output a bit more stable.

the detection window is continually adjusted, so that the
output timings don't drift.

the tolerances are automatically adjusted based on base
timings (see new define in patch)

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 22:16:23 +00:00
Leah Rowe
606c452bd8 util-spkmodem-decode: tidy up print_stats
make the frequencies clearer in printf

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:53:43 +00:00
Leah Rowe
995ac0bcd7 util/spkmodem-decode: do getopt first
much cleaner. do it right after zero-init memset.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:50:29 +00:00
Leah Rowe
912cd99f9f util/spkmodem-decode: init argv0 before pledge
otherwise, it'll be empty/undefined

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:49:54 +00:00
Leah Rowe
6204ff3ebf util/spkmodem-decode: frequency meter in debug
useful timing now displayed

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:43:23 +00:00
Leah Rowe
c8d078f9c7 util/spkmodem-recv: reset char precisely on timeout
instead of when it goes above, do it precisely on the
timeout. otherwise, if by sheer chance the signal
pauses and we reset the byte - sure, ok, but it's a
bit tight and we run the risk of advancing another
frame, depending on the timing.

this is a minor edge case, probably rarely ever
triggered in practise.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:33:46 +00:00
Leah Rowe
10e09d6402 rename util/spkmodem-recv to spkmodem-decode
it's no longer resembling the original util at all,
so a rename seems indicated. yes.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-03-12 21:24:16 +00:00