summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-12 22:59:06 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-12 23:12:40 +0000
commitdd9e681eb9a214fa628d64535f7466b78cfa36ec (patch)
treec2bf5e9933f3a113367fda3e81f601ff694c3cf0
parent5edd7c9fae55dbe11e3ad6d201bc6c8f39c0f683 (diff)
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>
-rw-r--r--util/spkmodem_decode/spkmodem-decode.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/util/spkmodem_decode/spkmodem-decode.c b/util/spkmodem_decode/spkmodem-decode.c
index 26b236f6..e5c0afd0 100644
--- a/util/spkmodem_decode/spkmodem-decode.c
+++ b/util/spkmodem_decode/spkmodem-decode.c
@@ -451,15 +451,30 @@ decode_pulse(struct decoder_state *st)
static void
auto_detect_tone(struct decoder_state *st)
{
+ int f;
+
+ /*
+ * Don't also run auto-detect during decode,
+ * otherwise it would run for every sample.
+ */
if (st->learn_samples >= LEARN_SAMPLES)
return;
- if (st->freq_data > 0) {
- if (st->freq_data < st->freq_min)
- st->freq_min = st->freq_data;
-
- if (st->freq_data > st->freq_max)
- st->freq_max = st->freq_data;
+ /*
+ * Check both FIR windows.
+ * Inside separator frames, the separator window contains tone,
+ * during data frames the data window does; a minimum of
+ * the two captures the lowest active tone cluster more reliably.
+ */
+ f = st->freq_data;
+ if (st->freq_separator > 0 && st->freq_separator < f)
+ f = st->freq_separator;
+ if (f > 0) {
+ if (f < st->freq_min)
+ st->freq_min = f;
+
+ if (f > st->freq_max)
+ st->freq_max = f;
}
st->learn_samples++;