blob: d2d9a569f532e1c838395e4003f06d9e95db26e5 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001import numpy as np
2from IQ_Utils import L
3
4class SS_Decoder:
5 def __init__(self, params, signals):
6 # 10 Last samples used only on drawing.
7 self.PSS_corr_magSQR_output_frame_main = [0] * 10 * params.analysis_frame_len
8 self.SSS_corr_magSQR_output_frame_main = [0] * 10 * params.analysis_frame_len
9 # We have found PSS singal
10 self.PSS_peak_detected = 0
11 # We have found SSS signal
12 self.SSS_peak_detected = 0
13 # Index in our buffer, previous index
14 self.hold_PSS_max_idx = 0
15 self.hold_SSS_max_idx = 0
16 # Do Inverse Fast Fourier Transformation
17 self.doIFFT = 0
18 # Index on our index current.
19 self.PSS_Subframe_max_idx = 0
20 self.SSS_Subframe_max_idx = 0
21 self.params = params
22 self.signals = signals
23 self.PSS_Subframe_max_val = 0
24 self.SSS_Subframe_max_val = 0
25 # 3 Samples.
26 self.IQ_ThreeframeBuffer_main = [0] * 3 * params.analysis_frame_len
27
28 def pss_run(self, IQ_frame_main_norm):
29 params = self.params
30
31 # Keep feeding our 3 sample buffer, newest data to last
32 self.IQ_ThreeframeBuffer_main[:2*params.analysis_frame_len] = self.IQ_ThreeframeBuffer_main[params.analysis_frame_len:]
33 self.IQ_ThreeframeBuffer_main[2*params.analysis_frame_len:] = IQ_frame_main_norm
34 #if (params.is_NR==1):
35 if (0):
36 # Reset 4 symbols of extension
37 self.IQ_ThreeframeBuffer_main[3*params.analysis_frame_len-params.analysis_frame_overlap:] = [0] * params.analysis_frame_overlap
38
39 PSS_TD_seq = self.signals.PSS_TD_complex_pad_fftSize_wShift_ifft # Local
40
41 # Cross-correlation with our reference signal to find reference singal
42 IQ_ThreeframeBuffer_PSScorr_main = np.correlate(self.IQ_ThreeframeBuffer_main,PSS_TD_seq,'full')
43 #print [len(IQ_ThreeframeBuffer_PSScorr_main), len(self.IQ_ThreeframeBuffer_main), len(PSS_TD_seq)]
44
45 # Get middle sample.
46 IQ_frame_PSScorr_main = IQ_ThreeframeBuffer_PSScorr_main[params.analysis_frame_len:2*params.analysis_frame_len]
47
48 # Convert our sample to abs.
49 IQ_frame_ABS_PSScorr_main = np.absolute(IQ_frame_PSScorr_main)
50
51 # Keep feeding our 10 sample buffer (10ms one radioframe). Add current sample to last.
52 self.PSS_corr_magSQR_output_frame_main[:9*params.analysis_frame_len] = self.PSS_corr_magSQR_output_frame_main[params.analysis_frame_len:]
53 self.PSS_corr_magSQR_output_frame_main[9*params.analysis_frame_len:] = IQ_frame_ABS_PSScorr_main
54
55 self.PSS_Subframe_max_idx = np.argmax(IQ_frame_ABS_PSScorr_main) # Find maximun value from our data "Maximum Likehood"
56 self.PSS_Subframe_max_val = IQ_frame_ABS_PSScorr_main[self.PSS_Subframe_max_idx]
57
58 # Calculate average level
59 PSS_Subframe_mean = np.mean(IQ_frame_ABS_PSScorr_main)
60
61 # Find peak
62 if (params.is_TDD == 1):
63 PSS_threshold = 0.2
64 else:
65 PSS_threshold = 0.1
66
67 if ((self.PSS_Subframe_max_val > 2.0*PSS_Subframe_mean)and(self.PSS_Subframe_max_val > PSS_threshold)):
68 self.doIFFT = 1
69 self.PSS_peak_detected = 1
70
71 if (self.hold_PSS_max_idx == 0):
72 self.hold_PSS_max_idx = self.PSS_Subframe_max_idx
73
74
75 L.info( 'PSS peak idx: ' + str(self.PSS_Subframe_max_idx) )
76 L.info( 'PSS max: ' +str(self.PSS_Subframe_max_val) )
77
78 else:
79 self.doIFFT = 0
80 self.PSS_peak_detected = 0
81
82 def nr_sss_run(self, fetch_SSS_seq):
83 params = self.params
84
85 SSS_TD_seq = self.signals.SSS_TD_complex_pad_fftSize_wShift_ifft # Local
86
87 # Cross-correlation with our reference signal to find reference singal
88 IQ_ThreeframeBuffer_SSScorr_main = np.correlate(self.IQ_ThreeframeBuffer_main,SSS_TD_seq,'full')
89
90 # Get middle sample.
91 IQ_frame_SSScorr_main = IQ_ThreeframeBuffer_SSScorr_main[params.analysis_frame_len:2*params.analysis_frame_len]
92
93 # Convert our sample to abs.
94 IQ_frame_ABS_SSScorr_main = np.absolute(IQ_frame_SSScorr_main)
95
96 # Keep feeding our 10 sample buffer (10ms one radioframe). Add current sample to last.
97 self.SSS_corr_magSQR_output_frame_main[:9*params.analysis_frame_len] = self.SSS_corr_magSQR_output_frame_main[params.analysis_frame_len:]
98 self.SSS_corr_magSQR_output_frame_main[9*params.analysis_frame_len:] = IQ_frame_ABS_SSScorr_main
99
100 self.SSS_Subframe_max_idx = np.argmax(IQ_frame_ABS_SSScorr_main) # Find maximun value from our data "Maximum Likehood"
101 self.SSS_Subframe_max_val = IQ_frame_ABS_SSScorr_main[self.SSS_Subframe_max_idx]
102
103 # Calculate average level
104 SSS_Subframe_mean = np.mean(IQ_frame_ABS_SSScorr_main)
105
106 # Find peak
107 if (params.is_TDD == 1):
108 SSS_threshold = 0.2
109 else:
110 SSS_threshold = 0.1
111
112 if ((self.SSS_Subframe_max_val > 2.0*SSS_Subframe_mean)and(self.SSS_Subframe_max_val > SSS_threshold)):
113 self.SSS_peak_detected = 1
114 L.info( 'SSS peak idx: ' + str(self.SSS_Subframe_max_idx) )
115 L.info( 'SSS max: ' +str(self.SSS_Subframe_max_val) )
116 else:
117 self.SSS_peak_detected = 0
118 #Correlation Subframe
119 SSS_corr = np.sum(np.multiply(fetch_SSS_seq,self.signals.d_sss))
120 SSS_corr_abs_sqr = np.square(np.absolute(SSS_corr))
121 return 0
122
123 def lte_sss_run(self, fetch_SSS_seq):
124 # Deinterleave SSS
125 SSS_seq_2k = fetch_SSS_seq[::2]
126 SSS_seq_2kPlus1 = fetch_SSS_seq[1::2]
127
128 # ***** 2k processing part *****
129
130 # Pre-generate seq for correlation with SSS (2k)
131 s0c0_ = np.multiply(self.signals.s0_,self.signals.c0_) #For Subfame_0
132 s1c0_ = np.multiply(self.signals.s1_,self.signals.c0_) #For Subfame_5
133
134 # Correlation Subframe_0
135 SSS_corr_s0c0 = np.sum(np.multiply(SSS_seq_2k,s0c0_))
136 SSS_corr_abs_sqr_s0c0 = np.square(np.absolute(SSS_corr_s0c0))
137
138 # Correlation Subframe_5
139 SSS_corr_s1c0 = np.sum(np.multiply(SSS_seq_2k,s1c0_))
140 SSS_corr_abs_sqr_s1c0 = np.square(np.absolute(SSS_corr_s1c0))
141
142 #print [SSS_corr_abs_sqr_s0c0, SSS_corr_abs_sqr_s1c0]
143 #print ['SSS subframe',np.argmax([SSS_corr_abs_sqr_s0c0, SSS_corr_abs_sqr_s1c0])]
144
145 # ***** 2k+1 processing part *****
146
147 # Pre-generate seq for correlation with SSS (2k)
148 #For Subfame_0
149 s1c1_ = np.multiply(self.signals.s1_,self.signals.c1_)
150 s1c1z1m0 = np.multiply(s1c1_,self.signals.z1_m0)
151 #For Subfame_5
152 s0c1_ = np.multiply(self.signals.s0_,self.signals.c1_)
153 s0c1z1m1 = np.multiply(s0c1_,self.signals.z1_m1)
154
155 # Correlation Subframe_0
156 SSS_corr_s1c1z1m0 = np.sum(np.multiply(SSS_seq_2kPlus1,s1c1z1m0))
157 SSS_corr_abs_sqr_s1c1z1m0 = np.square(np.absolute(SSS_corr_s1c1z1m0))
158
159 # Correlation Subframe_5
160 SSS_corr_s0c1z1m1 = np.sum(np.multiply(SSS_seq_2kPlus1,s0c1z1m1))
161 SSS_corr_abs_sqr_s0c1z1m1 = np.square(np.absolute(SSS_corr_s0c1z1m1))
162
163 #print [SSS_corr_abs_sqr_s1c1z1m0, SSS_corr_abs_sqr_s0c1z1m1]
164
165 # Frame Timing Decision module
166 SSS_metric_Subframe0 = SSS_corr_abs_sqr_s0c0 + SSS_corr_abs_sqr_s1c1z1m0
167 SSS_metric_Subframe5 = SSS_corr_abs_sqr_s1c0 + SSS_corr_abs_sqr_s0c1z1m1
168 #print[SSS_metric_Subframe0,SSS_metric_Subframe5]
169
170 #ToDo: Revise threshold condition below
171 if (SSS_metric_Subframe0 > 10.0*SSS_metric_Subframe5):
172 start_half_frame = 0
173 #ToDo: Revise threshold condition below
174 if (SSS_metric_Subframe5 > 10.0*SSS_metric_Subframe0):
175 start_half_frame = 1
176
177# else:
178# start_half_frame = 1
179 #print "half_frame = " + str(start_half_frame)
180 half_subframe_offset = start_half_frame * 70
181
182 # SSS HACK!!! (Needed for LowRX)
183 if (start_half_frame == 1):
184 start_half_frame = 0
185 else:
186 start_half_frame = 1
187 self.SSS_peak_detected = 0
188 return half_subframe_offset