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. @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) @param msgq_limit: maximum number of messages in message queue @type msgq_limit: int @param 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] # This fixed the bug, when the occupied tones are greater that the known symbols ksfreq = [0] * self._occupied_tones known_symbols_len = len(known_symbols_4512_3) for i in range(self._occupied_tones): ksfreq[i] = known_symbols_4512_3[i % known_symbols_len] 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 = {"qpsk": 4, "qam16": 16, "qam64": 64} arity = mods[self._modulation] rot = 1 #Create constellation objects for payload data. if(self._modulation.find("qpsk") >= 0): constel = dvbt_constellations.dvbt_qpsk_constellation(arity) elif(self._modulation.find("qam16") >= 0): constel = dvbt_constellations.dvbt_16qam_constellation(arity,False,mod_codes.GRAY_CODE) elif(self._modulation.find("qam64") >= 0): constel = dvbt_constellations.dvbt_64qam_constellation(arity,False,mod_codes.GRAY_CODE) rotated_const = constel.points() print rotated_const #Create constellation objects for pilot signals cs_constel = dvbt_constellations.dvbt_cs_pilots() tps_constel = dvbt_constellations.dvbt_tps_pilots() #print cs_constel.points() #print "\n" #print tps_constel.points() self._pkt_input = digital_swig.dvbt_ofdm_mapper_bcv(rotated_const,tps_constel.points(), cs_constel.points(), msgq_limit, options.occupied_tones, options.fft_length) self.preambles = digital_swig.ofdm_insert_preamble(self._fft_length, padded_preambles) self.ifft = gr.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital_swig.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = gr.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) if options.verbose: self._print_verbage() if options.log: self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat")) self.connect(self.preambles, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_preambles.dat")) self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_ifft_c.dat")) self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat"))
def __init__(self, options, callback=None): """ Hierarchical block for demodulating and deframing packets. The input is the complex modulated signal at baseband. Demodulated packets are sent to the handler. @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) @param callback: function of two args: ok, payload @type callback: ok: bool; payload: string """ gr.hier_block2.__init__(self, "ofdm_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(2, 2, gr.sizeof_gr_complex)) # Output signature self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY self._modulation = options.modulation self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self._cp_length = options.cp_length self._snr = options.snr self._show_vector_analyzer = options.show_vector_analyzer # 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] # This fixed the bug, when the occupied tones are greater that the known symbols ksfreq = [0] * self._occupied_tones known_symbols_len = len(known_symbols_4512_3) for i in range(self._occupied_tones): ksfreq[i] = known_symbols_4512_3[i % known_symbols_len] for i in range(len(ksfreq)): if((zeros_on_left + i) & 1): ksfreq[i] = 0 # hard-coded known symbols preambles = (ksfreq,) symbol_length = self._fft_length + self._cp_length self.ofdm_recv = ofdm_receiver(self._fft_length, self._cp_length, self._occupied_tones, self._snr, preambles, options.log) mods = {"qpsk": 4, "qam16": 16, "qam64": 64} arity = mods[self._modulation] rot = 1 # FIXME: pass the constellation objects instead of just the points if(self._modulation.find("qpsk") >= 0): constel = dvbt_constellations.dvbt_qpsk_constellation(arity) elif(self._modulation.find("qam16") >= 0): constel = dvbt_constellations.dvbt_16qam_constellation(arity,False,mod_codes.GRAY_CODE) elif(self._modulation.find("qam64") >= 0): constel = dvbt_constellations.dvbt_64qam_constellation(arity,False,mod_codes.GRAY_CODE) rotated_const = constel.points() print rotated_const phgain = 0.25 frgain = phgain*phgain / 4.0 #Create constellation objects for pilot signals cs_constel = dvbt_constellations.dvbt_cs_pilots() tps_constel = dvbt_constellations.dvbt_tps_pilots() self.ofdm_demod = digital_swig.dvbt_ofdm_frame_sink(rotated_const, tps_constel.points(), cs_constel.points(), range(arity), self._rcvd_pktq, self._occupied_tones, phgain, frgain) self.connect(self, self.ofdm_recv) self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0)) self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1)) # Vector analyzer output self.connect((self.ofdm_recv, 0), (self, 1)) #if(self._show_vector_analyzer == "yes"): # For qt # self.connect((self.ofdm_recv, 0), (self.ofdm_vector_analyzer_c, 0)) self.connect(self.ofdm_recv.chan_filt, self) if options.log: self.connect(self.ofdm_demod, gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones, "ofdm_frame_sink_c.dat")) else: self.connect(self.ofdm_demod, gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones)) if options.verbose: self._print_verbage() self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)