-
Notifications
You must be signed in to change notification settings - Fork 1
/
dwim-gr.py
146 lines (105 loc) · 5.2 KB
/
dwim-gr.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python2
import find_start
import auto_correlate
import correlate
import make_prs
import parameters
import numpy
def delay(signal, delay):
print "delay", delay, len(signal)
if delay == 0:
return signal
sinc_vect = [0] * 201
for i in range(201):
sinc_vect[i] = numpy.sinc(100.0 - i - delay)
return numpy.convolve(signal, sinc_vect, 'same')
class block:
def init(self):
self.sample_rate = 2048000
self.step = 1
self.dp = parameters.dab_parameters(1, self.sample_rate)
self.prs = make_prs.modulate_prs(self.sample_rate, True)
self.frame_length = int(self.sample_rate * 96e-3)
self.prs_len=len(self.prs)
self.P = 0.2 * 3
self.I = 0.2 * 3
self.fract = 1000
self.integer_offset = 0
self.fract_offset = 0
self.state = get_samples
self.get_samples_count = self.frame_length
self.next_state = find_start
def work(self, input_items, output_items):
consumed = 0
while True:
if self.state == find_start:
#start = 0
#while start == 0:
# start = find_start.find_start(signal, self.sample_rate)
# signal = reader.read(f, count=self.frame_length)
rough_start = find_start.find_start(signal, self.sample_rate)
signal = signal[rough_start:]
fine_freq_offset = auto_correlate.auto_correlate(signal, self.dp, self.sample_rate)
fine_start, rough_freq_offset = correlate.find_rough_freq_offset(signal, -fine_freq_offset, self.prs, self.dp, self.sample_rate)
signal = signal[fine_start:]
start = rough_start + fine_start
freq_offset = rough_freq_offset - fine_freq_offset
self.shift_signal = numpy.exp(complex(0,-1)*numpy.arange(self.prs_len)*2*numpy.pi*freq_offset/float(self.sample_rate))
self.error_acc = 0
self.state = skip_samples
self.skip_samples_count = (start + self.frame_length * (self.step - 1), 0)
self.next_state = get_prs
elif self.state == get_prs:
self.state = get_samples
self.get_samples_count = self.frame_length
self.samples = []
self.next_state = process_prs
elif self.state == process_prs:
self.signal = self.samples * self.shift_signal
'''
fine_freq_offset = auto_correlate.auto_correlate(signal, self.dp, self.sample_rate)
fine_shift_signal = numpy.exp(complex(0,-1)*numpy.arange(len(signal))*2*numpy.pi*-fine_freq_offset/float(self.sample_rate))
signal = signal * fine_shift_signal
'''
error, cor, phase = correlate.estimate_prs_fine(signal[:len(self.prs)], self.prs)
absolute_start = self.integer_offset + self.fract_offset / 1000. + error
self.error_acc += error
estimated_frame_length = self.frame_length + self.I * self.error_acc + self.P * error
print estimated_frame_length
skip = estimated_frame_length*self.step-self.prs_len
self.state = skip_samples
self.skip_samples_count = (int(skip), int((skip - int(skip)) * 1000))
self.next_state = get_prs
elif self.state == get_samples:
n_input_items = len(input_items[0][consumed:])
to_consume = min(n_input_itmes, self.count - len(self.samples))
self.samples.append(input_items[0][consumed:consumed+to_consume])
consumed += to_consume
if len(self.samples) < self.count:
break
self.integer_offset += count
self.samples = delay(self.samples, float(self.fract_offset) / self.fract)
self.state = self.next_state
elif self.state == skip_samples:
assert fract_count < self.fract
current_integer_offset = self.integer_offset
current_fract_offset = self.fract_offset
integer_count = self.skip_samples_count[0]
fract_count = self.skip_samples_count[1]
target_integer_offset = self.integer_offset + integer_count + (current_fract_offset + fract_count) / self.fract
target_fract_offset = (current_fract_offset + fract_count) % self.fract
self.count = target_integer_offset - current_integer_offset
self.integer_offset = target_integer_offset
self.fract_offset = target_fract_offset
self.state = skip_samples_internal
elif self.state == skip_samples_internal:
n_input_items = len(input_items[0][consumed:])
to_consume = min(n_input_itmes, self.count)
self.count -= to_consume
consumed += to_consume
if self.count > 0:
break
self.state = self.next_state
#XXX: We always consume everything...
output_items[0] = input_items[0][:consumed]
return consumed