summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/spkmodem_decode/spkmodem-decode.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/util/spkmodem_decode/spkmodem-decode.c b/util/spkmodem_decode/spkmodem-decode.c
index 0f28bc6f..40581dd7 100644
--- a/util/spkmodem_decode/spkmodem-decode.c
+++ b/util/spkmodem_decode/spkmodem-decode.c
@@ -206,6 +206,9 @@ struct decoder_state {
int freq_max;
int freq_threshold;
int learn_frames;
+
+ /* previous sample used for edge detection */
+ signed short prev_sample;
};
static const char *argv0;
@@ -445,9 +448,11 @@ decode_pulse(struct decoder_state *st)
{
unsigned char old_ring, old_sep;
unsigned char new_pulse;
+ signed short sample;
int ringpos;
int sep_pos;
- signed short sample;
+ int diff_edge;
+ int diff_amp;
ringpos = st->ringpos;
sep_pos = st->sep_pos;
@@ -483,18 +488,33 @@ decode_pulse(struct decoder_state *st)
sample = read_sample(st);
/*
- * Convert the waveform sample into a pulse (0 or 1).
+ * Avoid startup edge. Since
+ * it's zero at startup, this
+ * may wrongly produce a pulse
+ */
+ if (st->sample_count == 0)
+ st->prev_sample = sample;
+
+ /*
+ * Detect edges instead of amplitude.
+ * This is more tolerant of weak microphones
+ * and speaker distortion..
*
- * The unsigned comparison creates a small dead zone near zero,
- * suppressing small amplitude noise from microphones or
- * cheap ADCs. Real PC speaker tones are far outside this
- * range, so they still produce clean pulses.
+ * However, we check both slope edges and
+ * amplitude, to mitagate noise.
*/
- if ((unsigned)(sample + THRESHOLD)
- > (unsigned)(2 * THRESHOLD))
+ diff_amp = sample;
+ diff_edge = sample - st->prev_sample;
+ if (diff_edge < 0)
+ diff_edge = -diff_edge;
+ if (diff_amp < 0)
+ diff_amp = -diff_amp;
+ if (diff_edge > THRESHOLD &&
+ diff_amp > THRESHOLD)
new_pulse = 1;
else
new_pulse = 0;
+ st->prev_sample = sample;
st->pulse[ringpos] = new_pulse;
st->freq_separator += new_pulse;