diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | fourier.c | 99 | ||||
-rwxr-xr-x | frekvence.php | 76 | ||||
-rw-r--r-- | makefile | 10 |
4 files changed, 186 insertions, 2 deletions
@@ -5,3 +5,6 @@ core .gdb_history ptt sio_record.c +frekvence.h +fourier +naprave diff --git a/fourier.c b/fourier.c new file mode 100644 index 0000000..def5c13 --- /dev/null +++ b/fourier.c @@ -0,0 +1,99 @@ +#include <complex.h> +#include <math.h> +#include <sys/param.h> // MIN/MAX +#include <stdio.h> // debug only +#include "frekvence.h" +#define SAMPLES 256 +#define FREKVENC (sizeof frekvence/sizeof frekvence[0]) +struct fourier { + void (* callback)(struct fourier *); + enum ton trenutni; + enum ton zadnji_klican; + unsigned count; + double samples[SAMPLES]; + unsigned sample; + complex sums[FREKVENC]; + double rate; + unsigned minimal_duration; +#ifdef USERDATA + USERDATA +#else + void * userdata; +#endif +}; +void add_sample (struct fourier * f, double received) { + for (unsigned frekvenca = 0; frekvenca < FREKVENC; frekvenca++) { + f->sums[frekvenca] += received*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*f->sample/f->rate); + f->sums[frekvenca] -= f->samples[f->sample % SAMPLES]*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*(f->sample-SAMPLES)/f->rate); + } + int najv[3] = { 0 }; + double val[3] = { 0 }; + for (unsigned i = 0; i < FREKVENC; i++) + for (int j = 0; j < 3; j++) { + double iabs = cabs(f->sums[i]); + if (iabs > val[j]) { + for (int k = 2; k > j; k--) { + najv[k] = najv[k-1]; + val[k] = val[k-1]; + } + najv[j] = i; + val[j] = iabs; + break; + } + } + enum ton trenutni = ni; + if (val[1] > val[0]/3 && val[2] < val[1]/3) { + int večja = MAX(frekvence[najv[0]], frekvence[najv[1]]); + int manjša = MIN(frekvence[najv[0]], frekvence[najv[1]]); + enum ton znaki[4][4] = + {{dtmf_1, dtmf_2, dtmf_3, dtmf_a}, + {dtmf_4, dtmf_5, dtmf_6, dtmf_b}, + {dtmf_7, dtmf_8, dtmf_9, dtmf_c}, + {dtmf_zvezdica, dtmf_0, dtmf_lojtra, dtmf_d}}; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" + int getidx (int freq) { + for (int i = 0; i < 8; i++) + if (freq == frekvence[i]) + return i%4; + return -1; + } +#pragma GCC diagnostic pop + if (getidx(manjša) == -1 || getidx(večja) == -1) + trenutni = ni; + else + trenutni = znaki[getidx(manjša)][getidx(večja)]; + } + if (val[1] < val[0]/3 && najv[0] > 7) + trenutni = band+najv[0]-band_tipka; + if (trenutni == f->trenutni) { + if (f->count++ == f->minimal_duration && f->zadnji_klican != f->trenutni) { + f->zadnji_klican = f->trenutni; + f->callback(f); + } + } else { + f->count = 0; + f->trenutni = trenutni; + } + f->samples[f->sample++ % SAMPLES] = received; +} +#if __INCLUDE_LEVEL__ == 0 +#include <stdio.h> +#include <string.h> +void callback (struct fourier * f) { + printf("%s\n", toni[f->trenutni]); +} +int main (void) { + struct fourier f; + memset(&f, 0, sizeof f); + f.callback = callback; + f.minimal_duration = SAMPLES; + f.rate = 8000; + int received = 0; + while ((received = getchar()) != EOF) { + unsigned char intermed = received; + char recvd = *(char *) &intermed; + add_sample(&f, recvd); + } +} +#endif diff --git a/frekvence.php b/frekvence.php new file mode 100755 index 0000000..c085d21 --- /dev/null +++ b/frekvence.php @@ -0,0 +1,76 @@ +#!/usr/bin/php +<?php +$i = <<<HEREDOC +1209 dtmf_c1 +1336 dtmf_c2 +1477 dtmf_c3 +1633 dtmf_c4 +697 dtmf_r1 +770 dtmf_r2 +852 dtmf_r3 +941 dtmf_r4 +2100 band_tipka +800 spodnja_tipka +1000 zgornja_tipka +1450 oranžna_tipka +1750 plava_tipka +HEREDOC; +// 1092 roger_prvi preveč mažeta 3. vrstico dtmfjev +// 869 roger_drugi če dodaš, moraš popraviti tudi v $t spodaj - ZAMIKI! +// 123 ctcss_123 nesmiselno zaznavati skupaj - ctcss je treba zaznavati posebej! +$f = []; +foreach (explode("\n", $i) as $l) { + if (trim($l) == "") + break; + $e = explode("\t", trim($l)); + $f[$e[0]] = $e[1]; +} +echo "static int frekvence[] = {" . PHP_EOL; +foreach ($f as $k => $v) + echo " $k, // $v" . PHP_EOL; +echo "};" . PHP_EOL; +echo "enum frekvenca {" . PHP_EOL; +foreach ($f as $k => $v) + echo " $v, // $k" . PHP_EOL; +echo "};" . PHP_EOL; +echo "static char * imena_frekvenc[] = {" . PHP_EOL; +foreach ($f as $k => $v) + echo " \"$v\", // $k" . PHP_EOL; +echo "};" . PHP_EOL; +$t = <<<HEREDOC +ni +dtmf_1 +dtmf_2 +dtmf_3 +dtmf_4 +dtmf_5 +dtmf_6 +dtmf_7 +dtmf_8 +dtmf_9 +dtmf_0 +dtmf_a +dtmf_b +dtmf_c +dtmf_d +dtmf_zvezdica +dtmf_lojtra +band +spodnja +zgornja +oranžna +plava +HEREDOC; +// roger1 +// roger2 +// ctcss +$t = explode("\n", trim($t)); +echo "enum ton {" . PHP_EOL; +foreach ($t as $ton) + echo " $ton," . PHP_EOL; +echo "};" . PHP_EOL; +echo "static char * toni[] = {" . PHP_EOL; +foreach ($t as $ton) + echo " \"$ton\"," . PHP_EOL; +echo "};" . PHP_EOL; +?> @@ -3,7 +3,7 @@ CC=cc MYCFLAGS=-O0 -Wall -Wextra -Wformat -pedantic -g -I. # -fsanitize=address MYLDFLAGS= -default: ptt naprave +default: ptt naprave fourier ptt: ptt.c $(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS) @@ -11,6 +11,12 @@ ptt: ptt.c naprave: naprave.c $(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS) -lsoundio +fourier: fourier.c frekvence.h + $(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS) -lm + +frekvence.h: frekvence.php + ./frekvence.php > frekvence.h + install: mkdir -p $(DESTDIR)/usr/bin/ cp ptt $(DESTDIR)/usr/bin/ @@ -18,7 +24,7 @@ install: distclean: clean clean: - rm -rf tmp + rm -rf tmp fourier frekvence.h valgrind: valgrind --error-exitcode=59 --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt $(CMD) |