rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [diff] [blame] | 1 | import numpy as np
|
| 2 | from IQ_Utils import L
|
| 3 |
|
| 4 | class 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 |