aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/test_dtmf.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-11-20 19:51:24 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2017-12-03 08:46:05 +0100
commit9e75e64787e10556bf2075f241e23e41d8fd2b4c (patch)
tree5b8da262760a0ef4617cd3ee070f82db88c304cc /src/test/test_dtmf.c
parent44247ffb536ef25c1fc8c49c75b501d6f1808c52 (diff)
Add DTMF decoder to libdtmf
Note: This decoder has no user yet.
Diffstat (limited to 'src/test/test_dtmf.c')
-rw-r--r--src/test/test_dtmf.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/test/test_dtmf.c b/src/test/test_dtmf.c
new file mode 100644
index 0000000..8f56e5c
--- /dev/null
+++ b/src/test/test_dtmf.c
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+#include "../libdebug/debug.h"
+#include "../libsample/sample.h"
+#include "../libdtmf/dtmf_decode.h"
+#include "../libdtmf/dtmf_encode.h"
+
+#define level2db(level) (20 * log10(level))
+#define db2level(db) pow(10, (double)db / 20.0)
+
+#define SAMPLERATE 8000
+
+static double test_frequency[8] = { 697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0, 1633.0 };
+static const char *test_digits = "*#0123456789ABCD";
+
+static sample_t samples[SAMPLERATE];
+
+/* generate samples with two tones */
+static void generate_test_sample(double frequency1, double frequency2, double amplitude1, double amplitude2)
+{
+ int i;
+ double value;
+
+ for (i = 0; i < SAMPLERATE; i++) {
+ value = cos(2.0 * M_PI * frequency1 / (double)SAMPLERATE * i) * amplitude1;
+ value += cos(2.0 * M_PI * frequency2 / (double)SAMPLERATE * i) * amplitude2;
+ samples[i] = value;
+ }
+}
+
+static void check_level(sample_t *samples, const char *desc, double target, int when1, int when2)
+{
+ int i;
+ double amplitude = 0.0, diff;
+
+ for (i = when1; i < when2; i++) {
+ amplitude += samples[i];
+ }
+ amplitude = amplitude / (when2 - when1);
+ diff = fabs(amplitude - target);
+ printf("%s: amplitude between %d and %d ms is %.4f / %.4f db (expected %.4f)\n", desc, when1 * 1000 / SAMPLERATE, when2 * 1000 / SAMPLERATE, amplitude, level2db(amplitude), level2db(target));
+ if (diff < -0.1 || diff > 0.1)
+ printf("**** ERROR: we expected a diff close to 0.0\n");
+ else
+ printf("OK!\n");
+}
+
+static char got_digit;
+
+static void recv_digit(void *inst, char digit, dtmf_meas_t *meas)
+{
+ printf("decoded digit '%c' frequency %.1f %.1f amplitude %.1f %.1f dB\n", digit, meas->frequency_low, meas->frequency_high, level2db(meas->amplitude_low), level2db(meas->amplitude_high));
+ got_digit = digit;
+}
+
+int main(void)
+{
+ dtmf_dec_t dtmf_dec;
+ dtmf_enc_t dtmf_enc;
+ sample_t frequency1[SAMPLERATE], frequency2[SAMPLERATE], amplitude1[SAMPLERATE], amplitude2[SAMPLERATE];
+ int f, i;
+ double target;
+
+ dtmf_decode_init(&dtmf_dec, NULL, recv_digit, SAMPLERATE, db2level(0), db2level(-30.0));
+
+ for (f = 0; f < 8; f++) {
+ printf("Testing filter with frequency %.0f Hz:\n", test_frequency[f]);
+ generate_test_sample(test_frequency[f], 0.0, 1.0, 0.0);
+
+ dtmf_decode_filter(&dtmf_dec, samples, SAMPLERATE, frequency1, frequency2, amplitude1, amplitude2);
+
+ if (f == 0 || f == 3)
+ target = sqrt(0.5);
+ else if (f == 1 || f == 2)
+ target = 1.0;
+ else
+ target = 0.0;
+ check_level(amplitude1, "frequency level", target, 900 * SAMPLERATE / 1000, 1000 * SAMPLERATE / 1000);
+ if (f == 4 || f == 7)
+ target = sqrt(0.5);
+ else if (f == 5 || f == 6)
+ target = 1.0;
+ else
+ target = 0.0;
+ check_level(amplitude2, "frequency level", target, 900 * SAMPLERATE / 1000, 1000 * SAMPLERATE / 1000);
+
+ puts("");
+ }
+
+ dtmf_encode_init(&dtmf_enc, SAMPLERATE, 1.0);
+
+ for (i = 0; i < 16; i++) {
+ printf("Testing digit '%c' encoding and decoding:\n", test_digits[i]);
+ memset(samples, 0, sizeof(samples[0]) * SAMPLERATE);
+ dtmf_encode_set_tone(&dtmf_enc, test_digits[i]);
+ dtmf_encode(&dtmf_enc, samples + SAMPLERATE / 10, SAMPLERATE / 20);
+ got_digit = 0;
+ dtmf_decode(&dtmf_dec, samples, SAMPLERATE);
+ if (got_digit == 0)
+ printf("**** ERROR: we expected to decode digit '%c', but nothing was decoded\n", test_digits[i]);
+ else if (got_digit != test_digits[i])
+ printf("**** ERROR: we expected to decode digit '%c', but we decoded digit '%c'\n", test_digits[i], got_digit);
+ else
+ printf("OK!\n");
+ puts("");
+ }
+
+ dtmf_decode_exit(&dtmf_dec);
+
+ return 0;
+}
+