-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfm_demodulator.py
103 lines (69 loc) · 1.88 KB
/
fm_demodulator.py
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
102
103
import numpy as np
import matplotlib.pylab as plt
import time
# inspired by https://github.com/osmocom/rtl-sdr/blob/master/src/rtl_fm.c
# loading in the .wav
signal = np.memmap("SDRSharp_20170830_073822Z_145825000Hz_IQ.wav", offset=44)
result = np.zeros(len(signal)//2, dtype=np.float)
downsample = 128
def low_pass(signal):
# simple square window FIR
lowpassed = signal[:]
# needs to be go outside this function
now_r = 0
now_j = 0
i=0
i2=0
prev_index = 0
while (i < len(lowpassed)):
now_r += lowpassed[i]
now_j += lowpassed[i + 1]
i += 2
prev_index += 2
if (prev_index < downsample):
continue
lowpassed[i2] = now_r
lowpassed[i2 + 1] = now_j
prev_index = 0
now_r = 0
now_j = 0
i2 += 2
lp_len = i2
return lowpassed
def multiply(ar, aj, br, bj):
cr = ar * br - aj * bj
cj = aj * br + ar * bj
return cr, cj
def polar_discriminant(ar, aj, br, bj):
cr , cj = multiply(ar, aj, br, -bj)
#print(cr, cj)
angle = np.arctan2(cj, cr)
#print("angle", angle)
# return (angle / np.pi * (1<<14))
return (angle * 180.0 / np.pi)
def fm_demod(signal, result):
pre_r = 0
pre_j = 0
i = 0
pcm = 0
lp_len = len(signal)
# low-passing
lp = low_pass(signal)
#print(lp[0], lp[1], pre_r, pre_j)
pcm = polar_discriminant(lp[0], lp[1], pre_r, pre_j)
result[0] = pcm
for i in range(2, lp_len-1, 2):
# being lazy, only case 0 for now...
# case 0
pcm = polar_discriminant(lp[i], lp[i + 1], lp[i - 2], lp[i - 1])
result[i // 2] = pcm
pre_r = lp[lp_len - 2]
pre_j = lp[lp_len - 1]
result_len = lp_len // 2
#return(result)
time1 = time.time()
signal = -127.5 + signal
fm_demod(signal, result)
print(time.time() - time1)
plt.plot(result[::10])
plt.show()