diff options
author | Anton Luka Šijanec <anton@sijanec.eu> | 2023-03-26 21:45:44 +0200 |
---|---|---|
committer | Anton Luka Šijanec <anton@sijanec.eu> | 2023-03-26 21:45:44 +0200 |
commit | 453dab565ae62b01534d7c41b6a47342d1a049d0 (patch) | |
tree | 6c50c8a32e2aae9f28ee11b5aada9d17c499fffb /fourier.c | |
parent | rm binary (diff) | |
download | soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar.gz soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar.bz2 soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar.lz soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar.xz soča-453dab565ae62b01534d7c41b6a47342d1a049d0.tar.zst soča-453dab565ae62b01534d7c41b6a47342d1a049d0.zip |
Diffstat (limited to 'fourier.c')
-rw-r--r-- | fourier.c | 99 |
1 files changed, 99 insertions, 0 deletions
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 |