예제 #1
0
파일: ofdm.py 프로젝트: ariendj/gr-dab
	def __init__(self, dab_params, verbose=False, debug=False):
		"""
		Hierarchical block for OFDM modulation

		@param dab_params DAB parameter object (dab.parameters.dab_parameters)
		@param debug enables debug output to files
		"""

		dp = dab_params

		gr.hier_block2.__init__(self,"ofdm_mod",
		                        gr.io_signature2(2, 2, gr.sizeof_char*dp.num_carriers/4, gr.sizeof_char), # input signature
					gr.io_signature (1, 1, gr.sizeof_gr_complex)) # output signature


		# symbol mapping
		self.mapper = dab_swig.qpsk_mapper_vbc(dp.num_carriers)

		# add pilot symbol
		self.insert_pilot = dab_swig.ofdm_insert_pilot_vcc(dp.prn)

		# phase sum
		self.sum_phase = dab_swig.sum_phasor_trig_vcc(dp.num_carriers)

		# frequency interleaving
		self.interleave = dab_swig.frequency_interleaver_vcc(dp.frequency_interleaving_sequence_array)

		# add central carrier & move to middle
		self.move_and_insert_carrier = dab_swig.ofdm_move_and_insert_zero(dp.fft_length, dp.num_carriers)

		# ifft
		self.ifft = gr.fft_vcc(dp.fft_length, False, [], True)

		# cyclic prefixer
		self.prefixer = gr.ofdm_cyclic_prefixer(dp.fft_length, dp.symbol_length)

		# convert back to vectors
		self.s2v = gr.stream_to_vector(gr.sizeof_gr_complex, dp.symbol_length)

		# add null symbol
		self.insert_null = dab_swig.insert_null_symbol(dp.ns_length, dp.symbol_length)

		#
		# connect it all
		#

		# data
		self.connect((self,0), self.mapper, (self.insert_pilot,0), (self.sum_phase,0), self.interleave, self.move_and_insert_carrier, self.ifft, self.prefixer, self.s2v, (self.insert_null,0))
		self.connect(self.insert_null, self)

		# control signal (frame start)
		self.connect((self,1), (self.insert_pilot,1), (self.sum_phase,1), (self.insert_null,1))

		if debug:
			self.connect(self.mapper, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_mapper.dat"))
			self.connect(self.insert_pilot, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_insert_pilot.dat"))
			self.connect(self.sum_phase, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_sum_phase.dat"))
			self.connect(self.interleave, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_interleave.dat"))
			self.connect(self.move_and_insert_carrier, gr.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_move_and_insert_carrier.dat"))
			self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_ifft.dat"))
			self.connect(self.prefixer, gr.file_sink(gr.sizeof_gr_complex, "debug/generated_signal_prefixer.dat"))
			self.connect(self.insert_null, gr.file_sink(gr.sizeof_gr_complex, "debug/generated_signal.dat"))
예제 #2
0
    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]
        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)

        if (self._modulation.find("psk") >= 0):
            rotated_const = map(lambda pt: pt * rot,
                                psk.gray_constellation[arity])
        elif (self._modulation.find("qam") >= 0):
            rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
        #print rotated_const
        self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit,
                                             options.occupied_tones,
                                             options.fft_length)

        self.preambles = gr.ofdm_insert_preamble(self._fft_length,
                                                 padded_preambles)
        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
        self.cp_adder = gr.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"))
예제 #3
0
파일: ofdm.py 프로젝트: GREO/GNU-Radio
    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]
        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)
            
        if(self._modulation.find("psk") >= 0):
            rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity])
        elif(self._modulation.find("qam") >= 0):
            rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
        #print rotated_const
        self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit,
                                             options.occupied_tones, options.fft_length)
        
        self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles)
        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
        self.cp_adder = gr.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"))
예제 #4
0
    def __init__(self, options, payload="", msgq_limit=2, pad_for_usrp=False):
        """
	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), gr.io_signature(1, 1, gr.sizeof_gr_complex)  # Input signature
        )  # Output signature

        self._fft_length = 64
        self._total_sub_carriers = 53
        self._data_subcarriers = 48
        self._cp_length = 16
        self._regime = options.regime
        self._symbol_length = self._fft_length + self._cp_length

        # assuming we have 100Ms/s going to the USRP2 and 80 samples per symbol
        # we can calculate the OFDM symboltime (in microseconds)
        # depending on the interpolation factor
        self._symbol_time = options.interp * (self._fft_length + self._cp_length) / 100

        win = []

        if self._regime == "1" or self._regime == "2":
            rotated_const = ofdm_packet_utils.bpsk(self)

        elif self._regime == "3" or self._regime == "4":
            rotated_const = ofdm_packet_utils.qpsk(self)

        elif self._regime == "5" or self._regime == "6":
            rotated_const = ofdm_packet_utils.qam16(self)

        elif self._regime == "7" or self._regime == "8":
            rotated_const = ofdm_packet_utils.qam64(self)

        # map groups of bits to complex symbols
        self._pkt_input = ftw.ofdm_mapper(rotated_const, msgq_limit, self._data_subcarriers, self._fft_length)

        # insert pilot symbols
        self.pilot = ftw.ofdm_pilot_cc(self._data_subcarriers)

        # move subcarriers to their designated place and insert DC
        self.cmap = ftw.ofdm_cmap_cc(self._fft_length, self._total_sub_carriers)

        # inverse fast fourier transform
        self.ifft = gr.fft_vcc(self._fft_length, False, win)

        # add cyclic prefix
        self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, self._symbol_length)

        # scale accordingly
        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))

        # we need to know the number of OFDM data symbols for preamble and zerogap
        info = ofdm_packet_utils.get_info(payload, options.regime, self._symbol_time)
        N_sym = info["N_sym"]

        # add training sequence
        self.preamble = ofdm_packet_utils.insert_preamble(self._symbol_length, N_sym)

        # append zero samples at the end (receiver needs that to decode)
        self.zerogap = ofdm_packet_utils.insert_zerogap(self._symbol_length, N_sym)

        # repeat the frame a number of times
        self.repeat = ftw.repetition(80, options.repetition, N_sym)

        self.s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self._symbol_length)
        self.v2s = gr.vector_to_stream(gr.sizeof_gr_complex, self._symbol_length)

        # swap real and immaginary component before sending (GNURadio/USRP2 bug!)
        if options.swapIQ == True:
            self.gr_complex_to_imag_0 = gr.complex_to_imag(1)
            self.gr_complex_to_real_0 = gr.complex_to_real(1)
            self.gr_float_to_complex_0 = gr.float_to_complex(1)
            self.connect((self.v2s, 0), (self.gr_complex_to_imag_0, 0))
            self.connect((self.v2s, 0), (self.gr_complex_to_real_0, 0))
            self.connect((self.gr_complex_to_real_0, 0), (self.gr_float_to_complex_0, 1))
            self.connect((self.gr_complex_to_imag_0, 0), (self.gr_float_to_complex_0, 0))
            self.connect((self.gr_float_to_complex_0, 0), (self))
        elif options.swapIQ == False:
            self.gr_complex_to_imag_0 = gr.complex_to_imag(1)
            self.gr_complex_to_real_0 = gr.complex_to_real(1)
            self.gr_float_to_complex_0 = gr.float_to_complex(1)
            self.connect((self.v2s, 0), (self.gr_complex_to_imag_0, 0))
            self.connect((self.v2s, 0), (self.gr_complex_to_real_0, 0))
            self.connect((self.gr_complex_to_imag_0, 0), (self.gr_float_to_complex_0, 1))
            self.connect((self.gr_complex_to_real_0, 0), (self.gr_float_to_complex_0, 0))
            self.connect((self.gr_float_to_complex_0, 0), (self))

            # connect the blocks
        self.connect((self._pkt_input, 0), (self.pilot, 0))
        self.connect((self._pkt_input, 1), (self.preamble, 1))
        self.connect((self.preamble, 1), (self.zerogap, 1))

        # if options.repetition == 1:
        # 	self.connect(self.pilot, self.cmap, self.ifft, self.cp_adder, self.scale, self.s2v, \
        # 	self.preamble, self.zerogap, self.v2s)

        # elif options.repetition > 1:
        self.connect(
            self.pilot,
            self.cmap,
            self.ifft,
            self.cp_adder,
            self.scale,
            self.s2v,
            self.preamble,
            self.zerogap,
            self.repeat,
            self.v2s,
        )
        # else:
        # 	print"Error: repetiton must be a integer number >= 1 \n"
        # 	sys.exit(1)

        if options.log:
            self.connect(
                (self._pkt_input), gr.file_sink(gr.sizeof_gr_complex * self._data_subcarriers, "ofdm_mapper.dat")
            )
            self.connect(
                self.pilot, gr.file_sink(gr.sizeof_gr_complex * (5 + self._data_subcarriers), "ofdm_pilot.dat")
            )
            self.connect(self.cmap, gr.file_sink(gr.sizeof_gr_complex * self._fft_length, "ofdm_cmap.dat"))
            self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex * self._fft_length, "ofdm_ifft.dat"))
            self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder.dat"))
            self.connect(self.scale, gr.file_sink(gr.sizeof_gr_complex, "ofdm_scale.dat"))
            self.connect(self.preamble, gr.file_sink(gr.sizeof_gr_complex * self._symbol_length, "ofdm_preamble.dat"))
            self.connect(self.zerogap, gr.file_sink(gr.sizeof_gr_complex * self._symbol_length, "ofdm_zerogap.dat"))