summaryrefslogtreecommitdiff
path: root/util/spkmodem_decode/spkmodem-decode.c
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-13 01:23:27 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-13 01:23:27 +0000
commit4e48b173ae70df0064650ea626152c9007175001 (patch)
tree079b7e9d45d2571d2be315c19259ed0d94cc31b1 /util/spkmodem_decode/spkmodem-decode.c
parentfcbd144306a97bc1eafca3a71849620e190dc966 (diff)
util/spkmodem-decode: annotate prototypes
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/spkmodem_decode/spkmodem-decode.c')
-rw-r--r--util/spkmodem_decode/spkmodem-decode.c209
1 files changed, 114 insertions, 95 deletions
diff --git a/util/spkmodem_decode/spkmodem-decode.c b/util/spkmodem_decode/spkmodem-decode.c
index 44b8e084..a5283e51 100644
--- a/util/spkmodem_decode/spkmodem-decode.c
+++ b/util/spkmodem_decode/spkmodem-decode.c
@@ -209,25 +209,44 @@ struct decoder_state {
static const char *argv0;
+/*
+ * 16-bit little endian words are read
+ * continuously. we will swap them, if
+ * the host cpu is big endian.
+ */
static int host_is_big_endian(void);
+
+/* main loop */
static void handle_audio(struct decoder_state *st);
-static void detect_tone(struct decoder_state *st);
-static int silent_signal(struct decoder_state *st);
-static void select_low_tone(struct decoder_state *st);
+
+/* separate tone tolerances */
static void select_separator_tone(struct decoder_state *st);
-static int valid_signal(struct decoder_state *st);
+static int is_valid_signal(struct decoder_state *st);
+
+/* output to terminal */
+static int set_ascii_bit(struct decoder_state *st);
+static void print_char(struct decoder_state *st);
+static void reset_char(struct decoder_state *st);
+
+/* process samples/frames */
static void decode_pulse(struct decoder_state *st);
static signed short read_sample(struct decoder_state *st);
static void read_words(struct decoder_state *st);
-static int set_ascii_bit(struct decoder_state *st);
-static void print_char(struct decoder_state *st);
+
+/* continually adjust tone */
+static void detect_tone(struct decoder_state *st);
+static int silent_signal(struct decoder_state *st);
+static void select_low_tone(struct decoder_state *st);
+
+/* debug */
static void print_stats(struct decoder_state *st);
-static void reset_char(struct decoder_state *st);
+/* error handling / usage */
static void err(int errval, const char *msg, ...);
static void usage(void);
static const char *progname(void);
+/* portability (old systems) */
int getopt(int, char * const *, const char *);
extern char *optarg;
extern int optind;
@@ -318,70 +337,6 @@ handle_audio(struct decoder_state *st)
}
/*
- * Automatically detect spkmodem tone
- */
-static void
-detect_tone(struct decoder_state *st)
-{
- if (st->learn_frames >= LEARN_FRAMES)
- return;
-
- st->learn_frames++;
-
- if (silent_signal(st))
- return;
-
- select_low_tone(st);
-
- if (st->learn_frames != LEARN_FRAMES)
- return;
-
- st->freq_threshold =
- (st->freq_min + st->freq_max) / 2;
-
- if (st->debug)
- printf("auto threshold: %dHz\n",
- st->freq_threshold * FRAME_RATE);
-}
-
-/*
- * Ignore silence / near silence.
- * Both FIR windows will be near zero when no signal exists.
- */
-static int
-silent_signal(struct decoder_state *st)
-{
- return (st->freq_data <= 2 &&
- st->freq_separator <= 2);
-}
-
-/*
- * Choose the lowest active tone.
- * Separator frames carry tone in the separator window,
- * data frames carry tone in the data window.
- */
-static void
-select_low_tone(struct decoder_state *st)
-{
- int f;
-
- f = st->freq_data;
-
- if (f <= 0 || (st->freq_separator > 0 &&
- st->freq_separator < f))
- f = st->freq_separator;
-
- if (f <= 0)
- return;
-
- if (f < st->freq_min)
- st->freq_min = f;
-
- if (f > st->freq_max)
- st->freq_max = f;
-}
-
-/*
* collect separator tone statistics
* (and auto-adjust tolerances)
*/
@@ -390,7 +345,7 @@ select_separator_tone(struct decoder_state *st)
{
int avg;
- if (valid_signal(st))
+ if (is_valid_signal(st))
return;
if (st->sep_samples >= 50 && st->freq_separator <= 0)
@@ -418,13 +373,47 @@ select_separator_tone(struct decoder_state *st)
* from being misinterpreted as data.
*/
static int
-valid_signal(struct decoder_state *st)
+is_valid_signal(struct decoder_state *st)
{
return (st->freq_separator > 0 &&
st->freq_data > 0);
}
/*
+ * Each validated frame contributes one bit of modem data.
+ * Bits are accumulated MSB-first into the ASCII byte.
+ */
+static int
+set_ascii_bit(struct decoder_state *st)
+{
+ if (st->debug)
+ print_stats(st);
+ if (st->freq_data < st->freq_threshold)
+ st->ascii |= (1 << st->ascii_bit);
+
+ st->ascii_bit--;
+ return st->ascii_bit;
+}
+
+static void
+print_char(struct decoder_state *st)
+{
+ if (st->debug)
+ printf("<%c,%x>", st->ascii, st->ascii);
+ else
+ putchar(st->ascii);
+
+ reset_char(st);
+}
+
+static void
+reset_char(struct decoder_state *st)
+{
+ st->ascii = 0;
+ st->ascii_bit = 7;
+}
+
+/*
* Main demodulation step (moving-sum FIR filter).
*/
static void
@@ -547,30 +536,67 @@ read_words(struct decoder_state *st)
}
/*
- * Each validated frame contributes one bit of modem data.
- * Bits are accumulated MSB-first into the ASCII byte.
+ * Automatically detect spkmodem tone
*/
-static int
-set_ascii_bit(struct decoder_state *st)
+static void
+detect_tone(struct decoder_state *st)
{
+ if (st->learn_frames >= LEARN_FRAMES)
+ return;
+
+ st->learn_frames++;
+
+ if (silent_signal(st))
+ return;
+
+ select_low_tone(st);
+
+ if (st->learn_frames != LEARN_FRAMES)
+ return;
+
+ st->freq_threshold =
+ (st->freq_min + st->freq_max) / 2;
+
if (st->debug)
- print_stats(st);
- if (st->freq_data < st->freq_threshold)
- st->ascii |= (1 << st->ascii_bit);
+ printf("auto threshold: %dHz\n",
+ st->freq_threshold * FRAME_RATE);
+}
- st->ascii_bit--;
- return st->ascii_bit;
+/*
+ * Ignore silence / near silence.
+ * Both FIR windows will be near zero when no signal exists.
+ */
+static int
+silent_signal(struct decoder_state *st)
+{
+ return (st->freq_data <= 2 &&
+ st->freq_separator <= 2);
}
+/*
+ * Choose the lowest active tone.
+ * Separator frames carry tone in the separator window,
+ * data frames carry tone in the data window.
+ */
static void
-print_char(struct decoder_state *st)
+select_low_tone(struct decoder_state *st)
{
- if (st->debug)
- printf("<%c,%x>", st->ascii, st->ascii);
- else
- putchar(st->ascii);
+ int f;
- reset_char(st);
+ f = st->freq_data;
+
+ if (f <= 0 || (st->freq_separator > 0 &&
+ st->freq_separator < f))
+ f = st->freq_separator;
+
+ if (f <= 0)
+ return;
+
+ if (f < st->freq_min)
+ st->freq_min = f;
+
+ if (f > st->freq_max)
+ st->freq_max = f;
}
static void
@@ -607,13 +633,6 @@ print_stats(struct decoder_state *st)
}
static void
-reset_char(struct decoder_state *st)
-{
- st->ascii = 0;
- st->ascii_bit = 7;
-}
-
-static void
err(int errval, const char *msg, ...)
{
va_list ap;