summaryrefslogtreecommitdiffstats
path: root/prog/fourier/dft.c
blob: 598a7b3fb4fc5f0b58a4d637825c41891e055b9b (plain) (blame)
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
99
100
101
// v stdin piši S8 zvočne podatke z 8000 vzorci na sekundo
// frekvence:
// 2100 Hz	BAND
// 800 Hz	MONI
// 1000 Hz	CALL
// 1450 Hz	VFO/MR
// 1750 Hz	A/B
// DTMF:
// 	1209 Hz	1336 Hz	1477 Hz	1633 Hz
// 697	1	2	3	A
// 770	4	5	6	B
// 852	7	8	9	C
// 941	*	0	#	D
// ffmpeg -f alsa -ac 1 -i hw:5 -f s8 -ar 8000 - | ./a.out
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
#include <error.h>
#include <errno.h>
#include <sys/param.h> // for MIN, MAX
int main (void) {
	if (setvbuf(stdout, NULL, _IOFBF, 0))
		error_at_line(1, errno, __FILE__, __LINE__, "setvbuf");
#define SAMPLES 256
	int samples[SAMPLES] = { 0 };
	double povprečje = 0;
	int frekvence[] = {1209, 1336, 1477, 1633, 697, 770, 852, 941, 2100, 800, 1000, 1450, 1750};
	#define FREKVENC 13
	// int frekvence[] = {2100, 800, 1000, 1450, 1750, 1208, 1209, 1210, 1335, 1336, 1337, 1476, 1477, 1478, 1632, 1633, 1634, 696, 697, 698, 769, 770, 771, 851, 852, 853, 940, 941, 942};
/* #define FREKVENC 60
	int frekvence[FREKVENC+1];
	for (int i = 0; i < FREKVENC; i++)
		// frekvence[i] = 1000-(FREKVENC*10/2)+i*10;
		frekvence[i] = i*100; */
	complex sums[FREKVENC] = { 0 };
	unsigned sample = 0;
	int received = 0; 
	char znak = '\0';
	while ((received = getchar()) != EOF) {
		unsigned char intermed = received;
		char recvd = *(char *) &intermed;
		povprečje = (povprečje*SAMPLES+abs(recvd)-abs(samples[sample % SAMPLES]))/SAMPLES;
		if (!(sample % SAMPLES))
			printf("\033[2J\npovprečje: %f\n", povprečje);
		for (int frekvenca = 0; frekvenca < FREKVENC; frekvenca++) {
#define RATE 8000
			// sums[frekvenca] -= (complex) samples[sample % SAMPLES]*cpow(M_E, (complex) -2*M_PI*I*(complex) frekvence[frekvenca]/(complex) RATE);
			sums[frekvenca] += recvd*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*sample/RATE);
			sums[frekvenca] -= samples[sample % SAMPLES]*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*(sample-SAMPLES)/RATE);
			if (!(sample % SAMPLES)) {
				printf("%d\t", frekvence[frekvenca]);
				// for (int i = 0; i < pow(cabs(sums[frekvenca])/100, 2)/100; i++)
				for (int i = 0; i < cabs(sums[frekvenca])/256; i++)
					printf("#");
				printf("\n");
			}
		}
		if (!(sample % SAMPLES)) {
			int najv[3] = {0};
			double val[3] = {0};
			for (int i = 0; i < FREKVENC; i++)
				for (int j = 0; j < 3; j++)
					if (cabs(sums[i]) > val[j]) {
						for (int k = 2; k > j; k--) {
							najv[k] = najv[k-1];
							val[k] = val[k-1];
						}
						najv[j] = i;
						val[j] = cabs(sums[i]);
						break;
					}
			char trenutni = '\0';
			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]]);
				char znaki[4][4] = {{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}};
				int getidx (int freq) {
					int i;
					for (i = 0; i < 8; i++)
						if (freq == frekvence[i])
							return i%4;
					return -1;
				}
				if (getidx(manjša) == -1 || getidx(večja) == -1)
					trenutni = '\0';
				else
					trenutni = znaki[getidx(manjša)][getidx(večja)];
			}
			if (val[1] < val[0]/3 && najv[0] > 7) {
				char znaki[] = "PSZVM";
				trenutni = znaki[najv[0]-8];
			}
			if (znak == trenutni && znak)
				printf("tipka: %c\n", znak);
			znak = trenutni;
			fflush(stdout);
		}
		samples[sample++ % SAMPLES] = recvd;
	}
}