diff options
Diffstat (limited to 'util/spkmodem_decode/spkmodem-decode.c')
| -rw-r--r-- | util/spkmodem_decode/spkmodem-decode.c | 36 |
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; |
