def gps_ca_chip(prn): """From IS-GPS-200L 3.3.2.3, Table 3-Ia """ g1 = max_len_seq(10, taps=[7])[0] g2 = max_len_seq(10, taps=[8, 7, 4, 2, 1])[0] return np.bitwise_xor( g1, np.roll(g2, ca_g2_delay[prn]) )
def test_mls_output(self): # define some alternate working taps alt_taps = { 2: [1], 3: [2], 4: [3], 5: [4, 3, 2], 6: [5, 4, 1], 7: [4], 8: [7, 5, 3] } # assume the other bit levels work, too slow to test higher orders... for nbits in range(2, 8): for state in [None, np.round(np.random.rand(nbits))]: for taps in [None, alt_taps[nbits]]: if state is not None and np.all(state == 0): state[0] = 1 # they can't all be zero orig_m = max_len_seq(nbits, state=state, taps=taps)[0] m = 2. * orig_m - 1. # convert to +/- 1 representation # First, make sure we got all 1's or -1 err_msg = "mls had non binary terms" assert_array_equal(np.abs(m), np.ones_like(m), err_msg=err_msg) # Test via circular cross-correlation, which is just mult. # in the frequency domain with one signal conjugated tester = np.real(ifft(fft(m) * np.conj(fft(m)))) out_len = 2**nbits - 1 # impulse amplitude == test_len err_msg = "mls impulse has incorrect value" assert_allclose(tester[0], out_len, err_msg=err_msg) # steady-state is -1 err_msg = "mls steady-state has incorrect value" assert_allclose(tester[1:], -1 * np.ones(out_len - 1), err_msg=err_msg) # let's do the split thing using a couple options for n in (1, 2**(nbits - 1)): m1, s1 = max_len_seq(nbits, state=state, taps=taps, length=n) m2, s2 = max_len_seq(nbits, state=s1, taps=taps, length=1) m3, s3 = max_len_seq(nbits, state=s2, taps=taps, length=out_len - n - 1) new_m = np.concatenate((m1, m2, m3)) assert_array_equal(orig_m, new_m)
def escreve_bits2(bit_string, filename): baudRate = 20 Fs = 24000 F1 = 800 F2 = 1200 t = np.arange(0, 1 / baudRate, 1 / Fs) mls = sig.max_len_seq(6) header = np.append([1, 1, 1, 1, 0, 0], mls[0]) header = np.append(header, [0, 0, 1, 1, 1, 1]) bit_string = np.append(header, bit_string) wave1 = np.cos(2 * np.pi * F1 * t) wave2 = np.cos(2 * np.pi * F2 * t) sine_output = np.array([0]) x = np.arange(0, (len(bit_string) / baudRate) + 1, 1 / Fs) x = x[0:len(bit_string) * len(t)] for i in range(len(bit_string)): if (bit_string[i] == '0'): sine_output = np.append(sine_output, wave1) else: sine_output = np.append(sine_output, wave2) sf.write(filename, sine_output, Fs)
def run(self, distance=0.0, ch_in=None, ch_out=None, oversampling=1): """ Run the calibration. Plays a maximum length sequence and cross correlate the signals to find the time delay. Parameters ---------- distance : float, optional Distance between the speaker and microphone ch_in : int, optional The input channel to use. If not specified, all channels are calibrated ch_out : int, optional The output channel to use. If not specified, all channels are calibrated """ if ch_out is None: ch_out = [0] # create the maximum length sequence mls = 0.95 * np.array(2 * signal.max_len_seq(self.mls_bits)[0] - 1, dtype=np.float32) # output signal s = np.zeros( (mls.shape[0] + int(self.pad_time * self.fs), sd.default.channels[1]), dtype=np.float32, ) # placeholder for delays delays = np.zeros((sd.default.channels[0], len(ch_out))) try: import matplotlib.pyplot as plt except ImportError: import warnings warnings.warn("Matplotlib is required for plotting") return for och in ch_out: # play and record the signal simultaneously s[:mls.shape[0], och] = 0.1 * mls rec_sig = sd.playrec(s, self.fs, channels=sd.default.channels[0], blocking=True) s[:, och] = 0 for ich in range(rec_sig.shape[1]): xcorr = signal.correlate(rec_sig[:, ich], mls, mode="valid") delays[ich, och] = np.argmax(xcorr) plt.plot(xcorr) plt.show() # subtract distance delays -= int(distance / self.c * self.fs) return delays
def seq_matrix(period, rotate): M_seq = np.array(max_len_seq(period)[0]) #M_seq = np.concatenate([M_seq,M_seq[:0]]) M_Matrix = np.copy(M_seq) for i in range(rotate - 1): M_seq = np.roll(M_seq, 1) M_Matrix = np.vstack((M_Matrix, M_seq)) M_Mat = torch.from_numpy(M_Matrix) return M_Mat
def overlay_code(s1_poly, s1_init, s2_init=None): # Section 3.2.2.1.2 # TODO: Convert s1_poly to taps list taps = [] init = [] for i in range(1, 11): if s1_poly & (2**i): taps.append(11 - i) for i in range(10, -1, -1): init.append(s1_init & (2**i) != 0) seq = max_len_seq(11, taps=np.array(taps), state=np.array(init))[0][:1800] if s2_init is not None: init2 = [] for i in range(10, -1, -1): init2.append(s2_init & (2**i) != 0) s2_seq = max_len_seq(11, taps=np.array([2]), state=np.array(init2))[0][:1800] seq = np.bitwise_xor(seq, s2_seq) return seq
def test_mls_inputs(self): # can't all be zero state assert_raises(ValueError, max_len_seq, 10, state=np.zeros(10)) # wrong size state assert_raises(ValueError, max_len_seq, 10, state=np.ones(3)) # wrong length assert_raises(ValueError, max_len_seq, 10, length=-1) assert_array_equal(max_len_seq(10, length=0)[0], []) # unknown taps assert_raises(ValueError, max_len_seq, 64) # bad taps assert_raises(ValueError, max_len_seq, 10, taps=[-1, 1])
def CreateSamples(_Filename, _NSamples): print("Creating Narma10 samples...") N10_Params = {} N10_Params['NSamples'] = _NSamples N10_Params['NElements'] = 800 N10_Params['NThetas'] = 400 # Narma10 I/O Inputs = np.zeros((N10_Params['NSamples'], N10_Params['NElements'])) Outputs = np.zeros((N10_Params['NSamples'], N10_Params['NElements'])) for i in range(0, N10_Params['NSamples']): Inputs[i, :], Outputs[i, :] = NARMA10(N10_Params['NElements']) # Mask: Use the Maximum Length Sequence with N > Number of Thetas MLS_word = np.int(np.log(N10_Params['NThetas']) / np.log(2)) Preprocessing_Mask = 2.0 * (np.hstack( [max_len_seq(MLS_word)[0], max_len_seq(MLS_word + 1)[0]])[:N10_Params['NThetas']]) - 1 Preprocessing_Mask *= 0.1 # Masked Inputs Masked_Inputs = np.zeros((N10_Params['NSamples'], N10_Params['NElements'] * N10_Params['NThetas'])) for i in range(0, N10_Params['NSamples']): for j in range(N10_Params['NElements']): Masked_Inputs[i, (j * N10_Params['NThetas']):(j + 1) * N10_Params['NThetas']] = np.multiply( Inputs[i, j], Preprocessing_Mask) with h5py.File(_Filename, 'w') as ofile: ofile.attrs['Header'] = str(N10_Params) ofile.create_dataset('Inputs', data=Inputs) ofile.create_dataset('Outputs', data=Outputs) ofile.create_dataset('Mask', data=Preprocessing_Mask) ofile.create_dataset('Masked Inputs', data=Masked_Inputs) return None
def test_mls_output(self): # define some alternate working taps alt_taps = {2: [1], 3: [2], 4: [3], 5: [4, 3, 2], 6: [5, 4, 1], 7: [4], 8: [7, 5, 3]} # assume the other bit levels work, too slow to test higher orders... for nbits in range(2, 8): for state in [None, np.round(np.random.rand(nbits))]: for taps in [None, alt_taps[nbits]]: if state is not None and np.all(state == 0): state[0] = 1 # they can't all be zero orig_m = max_len_seq(nbits, state=state, taps=taps)[0] m = 2. * orig_m - 1. # convert to +/- 1 representation # First, make sure we got all 1's or -1 err_msg = "mls had non binary terms" assert_array_equal(np.abs(m), np.ones_like(m), err_msg=err_msg) # Test via circular cross-correlation, which is just mult. # in the frequency domain with one signal conjugated tester = np.real(ifft(fft(m) * np.conj(fft(m)))) out_len = 2**nbits - 1 # impulse amplitude == test_len err_msg = "mls impulse has incorrect value" assert_allclose(tester[0], out_len, err_msg=err_msg) # steady-state is -1 err_msg = "mls steady-state has incorrect value" assert_allclose(tester[1:], -1 * np.ones(out_len - 1), err_msg=err_msg) # let's do the split thing using a couple options for n in (1, 2**(nbits - 1)): m1, s1 = max_len_seq(nbits, state=state, taps=taps, length=n) m2, s2 = max_len_seq(nbits, state=s1, taps=taps, length=1) m3, s3 = max_len_seq(nbits, state=s2, taps=taps, length=out_len - n - 1) new_m = np.concatenate((m1, m2, m3)) assert_array_equal(orig_m, new_m)
def escreve_bits4(bit_string, filename): baudRate = 20 Fs = 24000 F1 = 600 F2 = 800 F3 = 1000 F4 = 1200 t = np.arange(0, 1 / baudRate, 1 / Fs) mls = sig.max_len_seq(6) header = np.append([1, 1, 1, 1, 0, 0], mls[0]) header = np.append(header, [0, 0, 1, 1, 1, 1]) bit_string = np.append(header, bit_string) wave1 = np.cos(2 * np.pi * F1 * t) wave2 = np.cos(2 * np.pi * F2 * t) wave3 = np.cos(2 * np.pi * F3 * t) wave4 = np.cos(2 * np.pi * F4 * t) sine_output = np.array([0]) x = np.arange(0, (len(bit_string) / baudRate) + 1, 1 / Fs) x = x[0:len(bit_string) * len(t)] if (not (len(bit_string) % 2)): bit_string = np.append(bit_string, '0') for i in range(int(len(bit_string) / 2)): if (bit_string[2 * i] == '0' and bit_string[2 * i + 1] == '0'): sine_output = np.append(sine_output, wave1) elif (bit_string[2 * i] == '0' and bit_string[2 * i + 1] == '1'): sine_output = np.append(sine_output, wave2) elif (bit_string[2 * i] == '1' and bit_string[2 * i + 1] == '1'): sine_output = np.append(sine_output, wave3) else: sine_output = np.append(sine_output, wave4) sf.write(filename, sine_output, Fs)
def get_symbol(nbits, taps, width, type, clipboard): symbol, _ = signal.max_len_seq(nbits, taps=taps) symbol_size = len(symbol) str_symbol = str(list(symbol)) # Remove brackets str_symbol = str_symbol[1:-1] # Break into lines lines = chunks(str_symbol.split(), width) # Join it all up with new lines between lines out = "" if type == 'c': symbol = '\n '.join([' '.join(line) for line in lines]) out += f"// taps: {taps}\n" out += f"// nbits: {nbits}\n" out += f"// size: {symbol_size}\n" out += f"uint8_t symbol[{symbol_size}] = {{\n\t{symbol}\n}};" elif type == 'yaml': symbol = '\n '.join([' '.join(line) for line in lines]) out += f"# taps: {taps}\n" out += f"# nbits: {nbits}\n" out += f"# size: {symbol_size}\n" out += f"symbol: [{symbol}]" elif type == 'plain': out += str(list(symbol)) else: out += "Unknown type!" if not clipboard: print(out) else: pyperclip.copy(out) print("Result copied to clipboard")
square1=np.ones((1,int(Fs/baudRate))) square2=-np.ones((1,int(Fs/baudRate))) sine_output=np.array([0]) square_output=np.array([0]) bit_string=[0,0,1,0,1] x=np.arange(0,(len(bit_string)/baudRate)+1,1/Fs) x=x[0:len(bit_string)*len(t)] for i in range(len(bit_string)): if(bit_string[i]==1): sine_output=np.append(sine_output,wave1) square_output=np.append(square_output,square1) else: sine_output=np.append(sine_output,wave2) square_output=np.append(square_output,square2) ''' fig, axs = plt.subplots(2) fig.suptitle('FSK - F1:50Hz F2=200Hz') axs[0].plot(x, sine_output[0:len(x)]) axs[1].plot(x, square_output[0:len(x)]) plt.show() ''' mls=sig.max_len_seq(6) header=np.append([1,1,1,1,0,0],mls[0]) header=np.append(header,[0,0,1,1,1,1])
def generate_MLS(mlen): nbits = int(np.ceil(np.log2(mlen + 1))) #actual_mlen = 2**nbits-1 pseq = max_len_seq(nbits)[0] * 2 - 1 return pseq
def calc_stimulus_frame(self, N_first: int = 0, N_frame: int = 10, N_end: int = 10, init: bool = False) -> np.ndarray: """ Calculate a data frame of stimulus `x` with a length of `N_frame` samples, starting with index `N_first` Parameters ---------- N_first: int index of first data point N_frame: int number of samples to be generated init: bool when init == True, initialize stimulus settings Returns ------- x: ndarray an array with `N` stimulus data points """ if init or N_first == 0: '''intialize title string, y-axis label and some variables''' # use radians for angle internally self.rad_phi1 = self.ui.phi1 / 180 * pi self.rad_phi2 = self.ui.phi2 / 180 * pi # check whether some amplitude is complex and set array type for xf # correspondingly. if (self.ui.ledDC.isVisible and type(self.ui.DC) == complex) or\ (self.ui.ledAmp1.isVisible and type(self.ui.A1) == complex) or\ (self.ui.ledAmp2.isVisible and type(self.ui.A2) == complex): self.xf = np.zeros(N_frame, dtype=complex) else: self.xf = np.zeros(N_frame, dtype=float) self.H_str = r'$y[n]$' # default self.title_str = "" if self.ui.stim == "none": self.title_str = r'Zero Input Response' self.H_str = r'$h_0[n]$' # ------------------------------------------------------------------ elif self.ui.stim == "dirac": self.title_str = r'Impulse Response' self.H_str = r'$h[n]$' elif self.ui.stim == "sinc": self.title_str = r'Sinc Impulse' elif self.ui.stim == "gauss": self.title_str = r'Gaussian Impulse' elif self.ui.stim == "rect": self.title_str = r'Rect Impulse' # ------------------------------------------------------------------ elif self.ui.stim == "step": if self.ui.chk_step_err.isChecked(): self.title_str = r'Settling Error $\epsilon$' self.H_str = r'$h_{\epsilon, \infty} - h_{\epsilon}[n]$' else: self.title_str = r'Step Response' self.H_str = r'$h_{\epsilon}[n]$' # ------------------------------------------------------------------ elif self.ui.stim == "cos": self.title_str = r'Cosine Stimulus' elif self.ui.stim == "sine": self.title_str = r'Sinusoidal Stimulus' elif self.ui.stim == "exp": self.title_str = r'Complex Exponential Stimulus' elif self.ui.stim == "diric": self.title_str = r'Periodic Sinc Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "chirp": self.title_str = self.ui.chirp_type.capitalize() + ' Chirp Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "triang": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlim. Triangular Stimulus' else: self.title_str = r'Triangular Stimulus' elif self.ui.stim == "saw": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlim. Sawtooth Stimulus' else: self.title_str = r'Sawtooth Stimulus' elif self.ui.stim == "square": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlimited Rect. Stimulus' else: self.title_str = r'Rect. Stimulus' elif self.ui.stim == "comb": self.title_str = r'Bandlim. Comb Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "am": self.title_str = ( r'AM Stimulus: $A_1 \sin(2 \pi n f_1 + \varphi_1)' r'\cdot A_2 \sin(2 \pi n f_2 + \varphi_2)$') elif self.ui.stim == "pmfm": self.title_str = ( r'PM / FM Stimulus: $A_1 \sin(2 \pi n f_1' r'+ \varphi_1 + A_2 \sin(2 \pi n f_2 + \varphi_2))$') # ------------------------------------------------------------------ elif self.ui.stim == "formula": self.title_str = r'Formula Defined Stimulus' # ================================================================== if self.ui.noise == "gauss": self.title_str += r' + Gaussian Noise' elif self.ui.noise == "uniform": self.title_str += r' + Uniform Noise' elif self.ui.noise == "prbs": self.title_str += r' + PRBS Noise' elif self.ui.noise == "mls": self.title_str += r' + max. length sequence' elif self.ui.noise == "brownian": self.title_str += r' + Brownian Noise' # ================================================================== if self.ui.ledDC.isVisible and self.ui.DC != 0: self.title_str += r' + DC' # ---------------------------------------------------------------------- N_last = N_first + N_frame n = np.arange(N_first, N_last) # T_S = fb.fil[0]['T_S'] self.T1_idx = int(np.round(self.ui.T1)) # calculate stimuli x[n] ============================================== if self.ui.stim == "none": self.xf.fill(0) # ---------------------------------------------------------------------- elif self.ui.stim == "dirac": self.xf.fill(0) # = np.zeros(N_frame, dtype=A_type) if N_first <= self.T1_idx < N_last: self.xf[self.T1_idx - N_first] = self.ui.A1 # ---------------------------------------------------------------------- elif self.ui.stim == "sinc": self.xf = self.ui.A1 * sinc(2 * (n - self.ui.T1) * self.ui.f1)\ + self.ui.A2 * sinc(2 * (n - self.ui.T2) * self.ui.f2) # ---------------------------------------------------------------------- elif self.ui.stim == "gauss": self.xf = self.ui.A1 * sig.gausspulse( (n - self.ui.T1), fc=self.ui.f1, bw=self.ui.BW1) +\ self.ui.A2 * sig.gausspulse( (n - self.ui.T2), fc=self.ui.f2, bw=self.ui.BW2) # ---------------------------------------------------------------------- elif self.ui.stim == "rect": n_rise = int(self.T1_idx - np.floor(self.ui.TW1/2)) n_min = max(n_rise, 0) n_max = min(n_rise + self.ui.TW1, N_end) self.xf = self.ui.A1 * np.where((n >= n_min) & (n < n_max), 1, 0) # ---------------------------------------------------------------------- elif self.ui.stim == "step": if self.T1_idx < N_first: # step before current frame self.xf.fill(self.ui.A1) if N_first <= self.T1_idx < N_last: # step in current frame self.xf[0:self.T1_idx - N_first].fill(0) self.xf[self.T1_idx - N_first:].fill(self.ui.A1) elif self.T1_idx >= N_last: # step after current frame self.xf.fill(0) # ---------------------------------------------------------------------- elif self.ui.stim == "cos": self.xf =\ self.ui.A1 * np.cos(2*pi * n * self.ui.f1 + self.rad_phi1) +\ self.ui.A2 * np.cos(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "sine": self.xf =\ self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1) +\ self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "exp": self.xf =\ self.ui.A1 * np.exp(1j * (2 * pi * n * self.ui.f1 + self.rad_phi1)) +\ self.ui.A2 * np.exp(1j * (2 * pi * n * self.ui.f2 + self.rad_phi2)) # ---------------------------------------------------------------------- elif self.ui.stim == "diric": self.xf = self.ui.A1 * diric( (4 * pi * (n-self.ui.T1) * self.ui.f1 + self.rad_phi1*2) / self.ui.TW1, self.ui.TW1) # ---------------------------------------------------------------------- elif self.ui.stim == "chirp": if self.ui.T2 == 0: # sig.chirp is buggy, T_sim cannot be larger than T_end T_end = N_end # frequency sweep over complete interval else: T_end = self.ui.T2 # frequency sweep till T2 self.xf = self.ui.A1 * sig.chirp( n, self.ui.f1, T_end, self.ui.f2, method=self.ui.chirp_type, phi=self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "triang": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * triang_bl(2*pi * n * self.ui.f1 + self.rad_phi1) else: self.xf = self.ui.A1 * sig.sawtooth( 2*pi * n * self.ui.f1 + self.rad_phi1, width=0.5) # ---------------------------------------------------------------------- elif self.ui.stim == "saw": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * sawtooth_bl(2*pi * n * self.ui.f1 + self.rad_phi1) else: self.xf = self.ui.A1 * sig.sawtooth(2*pi * n * self.ui.f1 + self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "square": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * rect_bl( 2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1) else: self.xf = self.ui.A1 * sig.square( 2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1) # ---------------------------------------------------------------------- elif self.ui.stim == "comb": self.xf = self.ui.A1 * comb_bl(2 * pi * n * self.ui.f1 + self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "am": self.xf = self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1)\ * self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "pmfm": self.xf = self.ui.A1 * np.sin( 2 * pi * n * self.ui.f1 + self.rad_phi1 + self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2)) # ---------------------------------------------------------------------- elif self.ui.stim == "formula": param_dict = {"A1": self.ui.A1, "A2": self.ui.A2, "f1": self.ui.f1, "f2": self.ui.f2, "phi1": self.ui.phi1, "phi2": self.ui.phi2, "BW1": self.ui.BW1, "BW2": self.ui.BW2, "f_S": fb.fil[0]['f_S'], "n": n, "j": 1j} self.xf = safe_numexpr_eval(self.ui.stim_formula, (N_frame,), param_dict) else: logger.error('Unknown stimulus format "{0}"'.format(self.ui.stim)) return None # ---------------------------------------------------------------------- # Add noise to stimulus noi = 0 if self.ui.noise == "none": pass elif self.ui.noise == "gauss": noi = self.ui.noi * np.random.randn(N_frame) elif self.ui.noise == "uniform": noi = self.ui.noi * (np.random.rand(N_frame)-0.5) elif self.ui.noise == "prbs": noi = self.ui.noi * 2 * (np.random.randint(0, 2, N_frame)-0.5) elif self.ui.noise == "mls": # max_len_seq returns `sequence, state`. The state is not stored here, # hence, an identical sequence is created every time. noi = self.ui.noi * 2 * (sig.max_len_seq(int(np.ceil(np.log2(N_frame))), length=N_frame, state=None)[0] - 0.5) elif self.ui.noise == "brownian": # brownian noise noi = np.cumsum(self.ui.noi * np.random.randn(N_frame)) else: logger.error('Unknown kind of noise "{}"'.format(self.ui.noise)) if type(self.ui.noi) == complex: self.xf = self.xf.astype(complex) + noi else: self.xf += noi # Add DC to stimulus when visible / enabled if self.ui.ledDC.isVisible: if type(self.ui.DC) == complex: self.xf = self.xf.astype(complex) + self.ui.DC else: self.xf += self.ui.DC return self.xf[:N_frame]
##### By Barun Basnet ###### ##### Friday, July 26 ###### import numpy as np import matplotlib.pyplot as plt import math from scipy.signal import max_len_seq PN = max_len_seq(5)[0] #Maximum Length Sequence(MLS) code generation PN = (PN * 2) - 1 # +1 and -1 ######################################################## """ Manual Method (Without Library) A = np.array([1,1,1,1,1]) # No of LFSR = 5 size = 31 #2^D - 1 PN = [] # Storing generated Pseudo Noise sequence for i in range(size): print(A[-1]) PN.append(A[-1]) A = [A[-1] ^ A[-2], A[0], A[1], A[2], A[3]] # ^ XOR ### Making Function######### def PN_sequence(LFSR): A = [] # list to store initial value of LFSR for i in range(LFSR): A.append(1) size = 2**LFSR - 1 #2^D - 1 PN = [] # Storing generated Pseudo Noise sequence for j in range(size): PN.append(A[-1]) B = A.copy() # New list to store values of A
import numpy as np import soundfile from scipy.signal import max_len_seq # room parameters: 10m x 20m x 3m room_dim = (20, 10, 3) # x y z human_height = 1.6 corners = np.array([[0, 0], [0, room_dim[1]], [room_dim[0], room_dim[1]], [room_dim[0], 0]]).T # [x,y] absorption = 0.4 # specify signal source test_signal, test_fs = soundfile.read('data/guitar_16k.wav') # Maximum length sequence (MLS) nbits_mls = 12 mls_signal = max_len_seq(nbits_mls)[0] * 2 - 1 fs = 16000 soundfile.write('mls.wav', mls_signal.astype('float32'), fs) # locate IR36 source resolution = 10 azimuth = np.array(range(0, 360, resolution)) radius = np.array([1.5]) #np.array([[0.5, 1.5, 3.]]) # mics parameters (meters) mic_n = 8 # mics position on the device [[x], [y]] mic_position = np.array( [[0., -0.03813, -0.02898, 0.01197, 0.03591, 0.03281, 0.005, -0.02657], [0., 0.00358, 0.03204, 0.03638, 0.01332, -0.01977, -0.03797, -0.02758]]) # move mics to the center of the room
def generar_periodo(self, n_bits): senal = signal.max_len_seq(n_bits)[0] * 2 - 1 # +1 y -1 return list(senal.astype(dtype=numpy.float64))
# MLS uses binary convention: from scipy.signal import max_len_seq max_len_seq(4)[0] # array([1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0], dtype=int8) # MLS has a white spectrum (except for DC): import matplotlib.pyplot as plt from numpy.fft import fft, ifft, fftshift, fftfreq seq = max_len_seq(6)[0] * 2 - 1 # +1 and -1 spec = fft(seq) N = len(seq) plt.plot(fftshift(fftfreq(N)), fftshift(np.abs(spec)), '.-') plt.margins(0.1, 0.1) plt.grid(True) plt.show() # Circular autocorrelation of MLS is an impulse: acorrcirc = ifft(spec * np.conj(spec)).real plt.figure() plt.plot(np.arange(-N / 2 + 1, N / 2 + 1), fftshift(acorrcirc), '.-') plt.margins(0.1, 0.1) plt.grid(True) plt.show() # Linear autocorrelation of MLS is approximately an impulse: acorr = np.correlate(seq, seq, 'full') plt.figure()
from random import randint import math import matplotlib.pyplot as plt from matplotlib.pyplot import step, xlim, ylim, show import scipy # _Variables Declaration vader = 16 ########-----------------TRANSMISSION---------------------######## # _PN Sequence Generation pn_seq = max_len_seq(int(math.sqrt(vader)))[0].tolist() for _ in range(0,vader-1): if pn_seq[_] == 0: pn_seq[_] = -1 print "A Random PN-Sequence is Generated ------->", pn_seq # _Message Bits message = [] for _ in range(vader-1): anakin = randint(0,1) message.append(anakin) for _ in range(0,vader-1):
def transmitSignal(): signal = max_len_seq(int(np.log2(N)), length=N)[0] return signal
def main(id_, folder, params): # hash_file = os.path.join('cache', f'{get_hash(params)}.pkl') # try: # with open(hash_file, 'rb') as f: # return pickle.load(f) # except FileNotFoundError: # print("Unable to find in cache. Running...") # Set up logging global LOGGER LOGGER = logging.getLogger("{}".format(id_)) formatter = logging.Formatter( '%(asctime)s:%(levelname)s:%(name)s:%(message)s') if folder is not None: folder_name = '{}/{:04}.log'.format(folder, id_) else: folder_name = 'out.log' if params.get('logging_output', True): # Give the full log to a file handler = logging.FileHandler(folder_name, mode='w') LOGGER.setLevel(logging.DEBUG) elif params.get('command_line', False): # Give only important stuff to the terminal handler = logging.StreamHandler() LOGGER.setLevel(logging.WARN) else: # Give only important stuff to a file handler = logging.FileHandler(folder_name, mode='w') LOGGER.setLevel(logging.WARN) handler.setFormatter(formatter) LOGGER.addHandler(handler) # Take care of symbol generation if 'max_len_seq' in params: LOGGER.debug("Max Length Sequence: %s", params['max_len_seq']) symbol, state = signal.max_len_seq(params['max_len_seq']) elif 'symbol' in params: symbol = np.array(params['symbol']) LOGGER.debug("Symbol: %s (%s)", symbol, len(symbol)) symbol = symbol * 2 - 1 # Sync word parameters sync_word = np.array(params['sync_word']) sync_word_fuzz = params['sync_word_fuzz'] # Data # data = np.array([1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1]) data = np.array([]) if 'sample_file' in params and params['sample_file']['type'] == 'wl': # Don't bother with dealing with the sample period. # We will get that from the file. sample_factor = params['sample_factor'] samples, sample_period = get_samples_from_wl_file( params['sample_file'], sample_factor) else: # Sampling timing parameters sample_period = ureg(params['destination_sample_period']) chip_time = ureg(params['chip_time']) if chip_time < sample_period: LOGGER.error("Sample period must be smaller than chip time") exit() sample_factor = chip_time / sample_period if sample_factor % 1 != 0: LOGGER.error( "Sample period and on/off period must be evenly divisible: %s / %s = %s", chip_time, sample_period, sample_factor) exit() sample_factor = int(sample_factor) # Generate the samples (simulated or through a file) if 'sample_file' in params: # Resolve source and destination sample rates source_sample_period = ureg(params['source_sample_period']) samples = get_samples_from_spectrum_file(params['sample_file'], source_sample_period, sample_period) else: seed = params.get('seed', random.randrange(sys.maxsize)) LOGGER.warning("Seed is: %s", seed) rng = random.Random(seed) # Transmission timing parameters transmission_time = ureg(params['transmit_time']) samples_per_transmission = transmission_time / sample_period if samples_per_transmission % 1 != 0: LOGGER.error( "Sample period and transmission time must be evenly divisible: %s / %s = %s", transmission_time, sample_period, samples_per_transmission) exit() samples_per_transmission = int(samples_per_transmission) # Take care of carrier sensing if params.get('carrier_sensing'): cs = params['carrier_sensing'] cs['sigma'] = (ureg(cs['sigma']) / sample_period).magnitude cs['mu'] = (ureg(cs['mu']) / sample_period).magnitude samples = create_samples(symbol, sync_word, data, rng, sample_factor, samples_per_transmission, signal_params=params['signal'], noise_params=params['noise'], quantization=params.get('quantization'), cs_params=params.get( 'carrier_sensing', { 'mu': 0, 'sigma': 0 })) samples = list(samples) LOGGER.debug("Starting...") ### TODO: Temporary!!! # samples = samples[int(0 / sample_period.magnitude):int(150 / sample_period.magnitude)] original_samples = samples.copy() if params.get('filter', True): # print("Filtering nearby transmitters") samples = filter_nearby_transmitters(samples) result = decode_signal(samples, np.repeat(symbol, sample_factor), sample_factor, sync_word, sync_word_fuzz, params['correlation_buffer_size'], params['correlation_std_threshold'], params['low_pass_filter_size']) result = list(result) LOGGER.debug("Done...") def calc_threshold(data): ignore_values = 100 data = data[:-ignore_values] return data.std() * params['correlation_std_threshold'] + data.mean() def onpc(samples): corr_samples = np.correlate(np.repeat(symbol, sample_factor), samples) corr_samples = np.flip(corr_samples, 0) corr_samples = pd.Series(corr_samples) corr_samples = corr_samples / np.sum(symbol == 1) # Low pass filter corr_samples = corr_samples.rolling(window=30).mean() threshold = corr_samples.rolling(window=600).apply(calc_threshold) empty = np.empty(len(symbol) * sample_factor - 1) empty[:] = np.nan corr_samples = np.concatenate((empty, np.array(corr_samples))) threshold = np.concatenate((empty, np.array(threshold))) peak_indexes = np.where(corr_samples > threshold)[0] ys = corr_samples[peak_indexes] xs = peak_indexes return corr_samples, threshold, zip(xs, ys) test_samples, test_threshold, peaks = onpc(samples) test_samples_original, test_threshold_original, peaks_original = onpc( original_samples) global index global correlation global correlation_threshold_high global events if params.get('graph', False) or params.get('interactive', False): expected = [] for bit in sync_word: if bit == 0: expected.append(np.repeat(symbol, sample_factor) ^ 1) else: expected.append(np.repeat(symbol, sample_factor)) expected = np.concatenate(expected) if not params.get('interactive', False): import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt fig, (ax0, ax1, ax3, ax4, ax5) = plt.subplots(5, 1, figsize=(8, 6), sharex=True) ax0.plot(np.arange(len(original_samples)) * sample_period, original_samples, '.', markersize=.7) # Plot the raw samples ax1.plot(np.arange(len(samples)) * sample_period, samples, '.', markersize=.7) # ax1.axhline(median, color='red') # ax1.axhline(mean, color='green') # ax1.axhline(mean + 2*std, color='green') # # Plot the expected symbol sequence # ax2.plot(np.arange(len(expected)) * sample_period, expected) # ax2.set_xlim(ax1.get_xlim()) # ax2.set_xlabel('Time (ms)') scatter_data = [(x, y) for x, y, event in events if event == 'detected_peak_2'] if scatter_data: x, y = zip(*scatter_data) ax3.scatter(x * sample_period, y, marker='x', color='grey') scatter_data = [(x, y) for x, y, event in events if event == 'detected_peak'] if scatter_data: x, y = zip(*scatter_data) ax3.scatter(x * sample_period, y, marker='x', color='yellow') scatter_data = [(x, y) for x, y, event in events if event == 'detected_bit'] if scatter_data: x, y = zip(*scatter_data) ax3.scatter(x * sample_period, y, marker='x', color='red') ax3.plot(np.arange(len(correlation_threshold_high)) * sample_period, correlation_threshold_high, color='green', linewidth=1) # ax3.plot(correlation_threshold_low, color='orange', label='lower threshold') ax3.plot(np.arange(len(correlation)) * sample_period, correlation, label='correlation', linewidth=1) ax3.set_xlim(ax1.get_xlim()) ax3.set_xlabel('Time (s)') ax4.plot(np.arange(len(test_threshold)) * sample_period, test_threshold, color='green', linewidth=1) ax4.plot(np.arange(len(test_samples)) * sample_period, test_samples, linewidth=1) xs, ys = zip(*peaks) ax4.scatter(xs * sample_period, ys, marker='x', color='yellow') ax5.plot(np.arange(len(test_threshold_original)) * sample_period, test_threshold_original, color='green', linewidth=1) ax5.plot(np.arange(len(test_samples_original)) * sample_period, test_samples_original, linewidth=1) xs, ys = zip(*peaks_original) ax5.scatter(xs * sample_period, ys, marker='x', color='yellow') # plt.legend() plt.tight_layout() if params.get('graph', False): if 'sample_file' not in params: name = 'simulated' else: name = Path(params['sample_file']['name']).stem plt.savefig(f'decoded_signal-{id_}-{name}.pdf') plt.savefig(f'decoded_signal-{id_}-{name}.png', dpi=600) if params.get('interactive', False): plt.show() result = Result( original_samples=original_samples, samples=samples, sample_period=sample_period, correlation=copy.deepcopy(correlation), correlation_threshold_high=copy.deepcopy(correlation_threshold_high), detected_signal=copy.deepcopy(events), config=params) # Clear out global state index = 0 correlation = [] correlation_threshold_high = [] events = [] # with open(hash_file, 'wb') as f: # pickle.dump(result, f) return result
dest='verbosity', type=int, default=0, help="verbosity, 1 = True", action="store") parser.add_argument('--w', dest='write_file', type=int, default=0, help="Write to File, 1 = True", action="store") parser.add_argument('--file_name', dest='file_name', type=str, default="mseq.dat", help="Output file name", action="store") args = parser.parse_args() #--------END Command Line argument parser------------------------------------------------------ print (args.n) m = signal.max_len_seq(args.n) print ("Sequence Length: {:d}".format(len(m[0]))) if args.verbosity: print (m[0].tobytes()) if args.write_file: fp = '/'.join([os.getcwd(), args.file_name]) print (fp) with open(fp, 'w') as f: m[0].tofile(f) f.close()
def digmod_prbs_generator(modType, fs, symRate, prbsOrder=9, filt=rrc_filter, alpha=0.35): """Generates a baseband modulated signal with a given modulation type and root raised cosine filter using PRBS data.""" if symRate > fs: raise error.WfmBuilderError('Symbol Rate violates Nyquist.') saPerSym = int(fs / symRate) filterSymbolLength = 10 # Define bits per symbol and modulator function based on modType if modType.lower() == 'bpsk': bitsPerSym = 1 modulator = bpsk_modulator elif modType.lower() == 'qpsk': bitsPerSym = 2 modulator = qpsk_modulator elif modType.lower() == '8psk': bitsPerSym = 3 modulator = psk8_modulator elif modType.lower() == '16psk': bitsPerSym = 4 modulator = psk16_modulator elif modType.lower() == 'qam16': bitsPerSym = 4 modulator = qam16_modulator elif modType.lower() == 'qam32': bitsPerSym = 5 modulator = qam32_modulator elif modType.lower() == 'qam64': bitsPerSym = 6 modulator = qam64_modulator elif modType.lower() == 'qam128': bitsPerSym = 7 modulator = qam128_modulator elif modType.lower() == 'qam256': bitsPerSym = 8 modulator = qam256_modulator else: raise ValueError('Invalid modType chosen.') # Create pattern and repeat to ensure integer number of symbols. temp, state = max_len_seq(prbsOrder) bits = temp repeats = 1 while len(bits) % bitsPerSym: bits = np.tile(temp, repeats) repeats += 1 """Convert the pseudorandom bit sequence, which is a list of bits, into the binary values of symbols as strings, and then map symbols to locations in the complex plane.""" symbols = modulator(bits) """Perform a pseudo circular convolution on the symbols to mitigate zeroing of samples due to filter delay (i.e. PREpend the last few symbols and APpend the first few symbols).""" symbols = np.concatenate((symbols[-int(filterSymbolLength / 2):], symbols, symbols[:int(filterSymbolLength / 2)])) """Zero-fill each symbol rather than repeating the symbol value to fill. This is to ensure the filter operates on an impulse response rather than a zero-order hold response.""" iq = np.zeros(len(symbols) * saPerSym, dtype=np.complex) iq[::saPerSym] = symbols """Create pulse shaping filter. Taps should be an odd number to ensure there is a tap in the center of the filter.""" taps = filterSymbolLength * saPerSym + 1 time, modFilter = filt(int(taps), alpha, symRate, fs) # Apply filter and trim off zeroed samples to ensure EXACT wraparound. iq = np.convolve(iq, modFilter) iq = iq[taps - 1:-taps + 1] # Scale waveform data sFactor = abs(np.amax(iq)) iq = iq / sFactor * 0.707 return np.real(iq), np.imag(iq)
@author: ak1mo """ from b_sequences import BSeq as bprs from corellation import CorellationCalc as cor # Для генерации М-последовательностей from scipy.signal import max_len_seq # Параметры последовтельности length = 17 shifts = [1, 2] shifters = len(shifts) # Создание экземпляра класса B-последовательностей b_obj = bprs(length, shifts, shifters) # Создание ПСП bseq = b_obj.create_b_sequence() mseq = list(max_len_seq(4)[0]) # Расчёт сбалансированности и ПАКФ balance = b_obj.calculate_balance() pacf = cor.calculate_pacf(bseq[:]) print(list(mseq)) print(bseq) print(f'Сбалансированность 1/0: {balance}') print(f'Max = {max(pacf[1:])}, Min = {min(pacf)}.\n') cor.plot_corellation(pacf, f'ПАКФ B-последовательности_{length}, {shifts}')
def generate_max_len_seq(nbits, state): # length of PN = 4096 pn_row = max_len_seq(nbits=nbits, state=state, taps=[7,6,1], length=4096)[0] pn_row.tolist() return pn_row
def maximum_length_sequence(mlen): nbits = int(np.ceil(np.log2(mlen + 1))) #actual_mlen = 2**nbits-1 pseq = max_len_seq(nbits)[0] * 2 - 1 return pseq