1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <complex.h>
#include <math.h>
#include <sys/param.h> // 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 <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
|