From 453dab565ae62b01534d7c41b6a47342d1a049d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Sun, 26 Mar 2023 21:45:44 +0200 Subject: fourier --- .gitignore | 3 ++ fourier.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frekvence.php | 76 +++++++++++++++++++++++++++++++++++++++++++++ makefile | 10 ++++-- 4 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 fourier.c create mode 100755 frekvence.php diff --git a/.gitignore b/.gitignore index 366cd1f..cd15f56 100644 --- a/.gitignore +++ b/.gitignore @@ -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 +#include +#include // MIN/MAX +#include // 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 +#include +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 + $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 = << diff --git a/makefile b/makefile index 3a2b79f..32eed24 100644 --- a/makefile +++ b/makefile @@ -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) -- cgit v1.2.3