#include #include #include // MIN/MAX #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 }; // XXX refactor this to support roger_drugi decoding 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