def helper(self, v0, v1, fft_length, preamble): tb = self.tb src0 = blocks.vector_source_c(v0) src1 = blocks.vector_source_b(v1) s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_length) # print "len(v) = %d" % (len(v)) op = digital.ofdm_insert_preamble(fft_length, preamble) v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_length) dst0 = blocks.vector_sink_c() dst1 = blocks.vector_sink_b() tb.connect(src0, s2v, (op, 0)) tb.connect(src1, (op, 1)) tb.connect((op, 0), v2s, dst0) tb.connect((op, 1), dst1) tb.run() r0 = dst0.data() r0v = [] for i in range(len(r0) // fft_length): r0v.append(r0[i * fft_length:(i + 1) * fft_length]) r1 = dst1.data() self.assertEqual(len(r0v), len(r1)) return (r1, r0v)
def helper(self, v0, v1, fft_length, preamble): tb = self.tb src0 = blocks.vector_source_c(v0) src1 = blocks.vector_source_b(v1) s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_length) # print "len(v) = %d" % (len(v)) op = digital.ofdm_insert_preamble(fft_length, preamble) v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_length) dst0 = blocks.vector_sink_c() dst1 = blocks.vector_sink_b() tb.connect(src0, s2v, (op, 0)) tb.connect(src1, (op, 1)) tb.connect((op, 0), v2s, dst0) tb.connect((op, 1), dst1) tb.run() r0 = dst0.data() r0v = [] for i in range(len(r0)//fft_length): r0v.append(r0[i*fft_length:(i+1)*fft_length]) r1 = dst1.data() self.assertEqual(len(r0v), len(r1)) return (r1, r0v)
def __init__(self, options): """ @param options: parsed raw.ofdm_params """ self.params = ofdm_params(options) params = self.params gr.hier_block2.__init__( self, "ofdm_mod", gr.io_signature2(2, 2, gr.sizeof_gr_complex * params.data_tones, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature win = [] #[1 for i in range(self._fft_length)] # see gr_fft_vcc_fftw that it works differently if win = [1 1 1 ...] self.mapper = raw.ofdm_mapper(params.padded_carriers) self.preambles = digital.ofdm_insert_preamble(params.fft_length, params.padded_preambles) self.ifft = gr.fft_vcc(params.fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer( params.fft_length, params.fft_length + params.cp_length) self.scale = gr.multiply_const_cc(1.0 / math.sqrt(params.fft_length)) self.connect((self, 0), self.mapper, (self.preambles, 0)) self.connect((self, 1), (self.preambles, 1)) self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self) if options.log: self.connect( self.mapper, gr.file_sink(gr.sizeof_gr_complex * params.fft_length, "tx-map.dat")) self.connect( self.preambles, gr.file_sink(gr.sizeof_gr_complex * params.fft_length, "tx-pre.dat")) self.connect( self.ifft, gr.file_sink(gr.sizeof_gr_complex * params.fft_length, "tx-ifft.dat")) self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "tx-cp.dat"))
def __init__(self, options): """ @param options: parsed raw.ofdm_params """ self.params = ofdm_params(options) params = self.params gr.hier_block2.__init__(self, "ofdm_mod", gr.io_signature2(2, 2, gr.sizeof_gr_complex*params.data_tones, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature win = [] #[1 for i in range(self._fft_length)] # see gr_fft_vcc_fftw that it works differently if win = [1 1 1 ...] self.mapper = raw.ofdm_mapper(params.padded_carriers) self.preambles = digital.ofdm_insert_preamble(params.fft_length, params.padded_preambles) self.ifft = gr.fft_vcc(params.fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(params.fft_length, params.fft_length + params.cp_length) self.scale = gr.multiply_const_cc(1.0 / math.sqrt(params.fft_length)) self.connect((self,0), self.mapper, (self.preambles,0)) self.connect((self,1), (self.preambles,1)) self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self) if options.log: self.connect(self.mapper, gr.file_sink(gr.sizeof_gr_complex*params.fft_length, "tx-map.dat")) self.connect(self.preambles, gr.file_sink(gr.sizeof_gr_complex*params.fft_length, "tx-pre.dat")) self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*params.fft_length, "tx-ifft.dat")) self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "tx-cp.dat"))
def __init__(self, options, msgq_limit=2, pad_for_usrp=True): """ Hierarchical block for sending packets Packets to be sent are enqueued by calling send_pkt. The output is the complex modulated signal at baseband. Args: options: pass modulation options from higher layers (fft length, occupied tones, etc.) msgq_limit: maximum number of messages in message queue (int) pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples """ gr.hier_block2.__init__(self, "ofdm_mod", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._pad_for_usrp = pad_for_usrp self._modulation = options.modulation self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self._cp_length = options.cp_length win = [] #[1 for i in range(self._fft_length)] # Use freq domain to get doubled-up known symbol for correlation in time domain zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) ksfreq = known_symbols_4512_3[0:self._occupied_tones] for i in range(len(ksfreq)): if((zeros_on_left + i) & 1): ksfreq[i] = 0 # hard-coded known symbols preambles = (ksfreq,) padded_preambles = list() for pre in preambles: padded = self._fft_length*[0,] padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre padded_preambles.append(padded) symbol_length = options.fft_length + options.cp_length mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} arity = mods[self._modulation] rot = 1 if self._modulation == "qpsk": rot = (0.707+0.707j) # FIXME: pass the constellation objects instead of just the points if(self._modulation.find("psk") >= 0): constel = psk.psk_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) elif(self._modulation.find("qam") >= 0): constel = qam.qam_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) #print rotated_const self._pkt_input = digital.ofdm_mapper_bcv(rotated_const, msgq_limit, options.occupied_tones, options.fft_length) self.preambles = digital.ofdm_insert_preamble(self._fft_length, padded_preambles) self.ifft = fft.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = blocks.multiply_const_cc(1.0 / math.sqrt(self._fft_length)) self.connect((self._pkt_input, 0), (self.preambles, 0)) self.connect((self._pkt_input, 1), (self.preambles, 1)) self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self)
def __init__(self, options, msgq_limit=2, pad_for_usrp=True): """ Hierarchical block for sending packets Packets to be sent are enqueued by calling send_pkt. The output is the complex modulated signal at baseband. Args: options: pass modulation options from higher layers (fft length, occupied tones, etc.) msgq_limit: maximum number of messages in message queue (int) pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples """ gr.hier_block2.__init__(self, "ofdm_mod", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._pad_for_usrp = pad_for_usrp self._modulation = options.modulation self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self._cp_length = options.cp_length win = [] #[1 for i in range(self._fft_length)] # Use freq domain to get doubled-up known symbol for correlation in time domain zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) ksfreq = known_symbols_4512_3[0:self._occupied_tones] for i in range(len(ksfreq)): if((zeros_on_left + i) & 1): ksfreq[i] = 0 # hard-coded known symbols preambles = (ksfreq,) padded_preambles = list() for pre in preambles: padded = self._fft_length*[0,] padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre padded_preambles.append(padded) symbol_length = options.fft_length + options.cp_length mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} arity = mods[self._modulation] rot = 1 if self._modulation == "qpsk": rot = (0.707+0.707j) # FIXME: pass the constellation objects instead of just the points if(self._modulation.find("psk") >= 0): constel = psk.psk_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) elif(self._modulation.find("qam") >= 0): constel = qam.qam_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) #print rotated_const self._pkt_input = digital.ofdm_mapper_bcv(rotated_const, msgq_limit, options.occupied_tones, options.fft_length) self.preambles = digital.ofdm_insert_preamble(self._fft_length, padded_preambles) self.ifft = fft.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = blocks.multiply_const_cc(1.0 / math.sqrt(self._fft_length)) # self.connect((self._pkt_input, 0), (self.preambles, 0)) # self.connect((self._pkt_input, 1), (self.preambles, 1)) # self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self) self.nuller = blocks.null_sink(gr.sizeof_char) self.v2s = blocks.vector_to_stream(gr.sizeof_gr_complex*1,self._fft_length) self.connect((self._pkt_input, 0), self.v2s, self) self.connect((self._pkt_input, 1), self.nuller) if options.verbose: self._print_verbage() if options.log: self.connect(self._pkt_input, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat")) self.connect(self.preambles, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_preambles.dat")) self.connect(self.ifft, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_ifft_c.dat")) self.connect(self.cp_adder, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat"))