Example #1
0
    def __init__(self, dab_params, data_rate_n, protection):
        gr.hier_block2.__init__(self,
            "msc_encode",
            gr.io_signature(1, 1, gr.sizeof_char),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char)) # Output signature
        self.dp = dab_params
        self.n = data_rate_n
        self.msc_I = self.n * 192
        self.protect = protection

        # unpack
        self.unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST)

        # energy dispersal
        self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.msc_I), True)
        self.add_mod_2 = blocks.xor_bb()

        # convolutional encoder
        self.conv_pack = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST)
        self.conv_encoder = dab.conv_encoder_bb_make(self.msc_I / 8)
        self.conv_unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST)


        # calculate puncturing factors (EEP, table 33, 34)
        if (self.n > 1 or self.protect != 1):
            self.puncturing_L1 = [6 * self.n - 3, 2 * self.n - 3, 6 * self.n - 3, 4 * self.n - 3]
            self.puncturing_L2 = [3, 4 * self.n + 3, 3, 2 * self.n + 3]
            self.puncturing_PI1 = [24, 14, 8, 3]
            self.puncturing_PI2 = [23, 13, 7, 2]
            # calculate length of punctured codeword (11.3.2)
            self.msc_punctured_codeword_length = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors_ones[
                self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * \
                                                     self.dp.puncturing_vectors_ones[
                                                         self.puncturing_PI2[self.protect]] + 12
            self.assembled_msc_puncturing_sequence = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors[
                self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * self.dp.puncturing_vectors[
                self.puncturing_PI2[self.protect]] + self.dp.puncturing_tail_vector
            self.msc_conv_codeword_length = 4 * self.msc_I + 24  # 4*I + 24 ()
        # exception in table
        else:
            self.msc_punctured_codeword_length = 5 * 4 * self.dp.puncturing_vectors_ones[13] + 1 * 4 * \
                                                                                               self.dp.puncturing_vectors_ones[
                                                                                                   12] + 12
        # sanity check
        assert (6 * self.n == self.puncturing_L1[self.protect] + self.puncturing_L2[self.protect])

        # puncturing
        self.puncture = dab.puncture_bb_make(self.assembled_msc_puncturing_sequence)

        # time interleaving
        self.s2v_time_interleave = blocks.stream_to_vector_make(gr.sizeof_char, self.msc_punctured_codeword_length)
        self.time_interleaver = dab.time_interleave_bb_make(self.msc_punctured_codeword_length, self.dp.scrambling_vector)
        self.v2s_time_interleave = blocks.vector_to_stream_make(gr.sizeof_char, self.msc_punctured_codeword_length)

        # pack bits
        self.unpacked_to_packed_encoded = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST)

        # connect everything
        self.connect(self,
                     self.unpack,
                     self.add_mod_2,
                     self.conv_pack,
                     self.conv_encoder,
                     self.conv_unpack,
                     self.puncture,
                     self.s2v_time_interleave,
                     self.time_interleaver,
                     self.v2s_time_interleave,
                     self.unpacked_to_packed_encoded,
                     self)
        # connect prbs
        self.connect(self.prbs_src, (self.add_mod_2, 1))
Example #2
0
    def __init__(self, dab_params, address, size, protection, verbose=False, debug=False):
        gr.hier_block2.__init__(self,
                                "msc_decode",
                                # Input signature
                                gr.io_signature(1, 1, gr.sizeof_float * dab_params.num_carriers * 2),
                                # Output signature
                                gr.io_signature(1, 1, gr.sizeof_char))
        self.dp = dab_params
        self.address = address
        self.size = size
        self.protect = protection
        self.verbose = verbose
        self.debug = debug

        # calculate n factor (multiple of 8kbits etc.)
        self.n = self.size / self.dp.subch_size_multiple_n[self.protect]

        # calculate puncturing factors (EEP, table 33, 34)
        self.msc_I = self.n * 192
        if (self.n > 1 or self.protect != 1):
            self.puncturing_L1 = [6 * self.n - 3, 2 * self.n - 3, 6 * self.n - 3, 4 * self.n - 3]
            self.puncturing_L2 = [3, 4 * self.n + 3, 3, 2 * self.n + 3]
            self.puncturing_PI1 = [24, 14, 8, 3]
            self.puncturing_PI2 = [23, 13, 7, 2]
            # calculate length of punctured codeword (11.3.2)
            self.msc_punctured_codeword_length = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors_ones[
                self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * \
                                                     self.dp.puncturing_vectors_ones[
                                                         self.puncturing_PI2[self.protect]] + 12
            self.assembled_msc_puncturing_sequence = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors[
                self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * self.dp.puncturing_vectors[
                self.puncturing_PI2[self.protect]] + self.dp.puncturing_tail_vector
            self.msc_conv_codeword_length = 4*self.msc_I + 24 # 4*I + 24 ()
        # exception in table
        else:
            self.msc_punctured_codeword_length = 5 * 4 * self.dp.puncturing_vectors_ones[13] + 1 * 4 * \
                                                                                               self.dp.puncturing_vectors_ones[
                                                                                                   12] + 12
        #sanity check
        assert(6*self.n == self.puncturing_L1[self.protect] + self.puncturing_L2[self.protect])


        # MSC selection and block partitioning
        # select OFDM carriers with MSC
        self.select_msc_syms = grdab.select_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.num_msc_syms,
                                                  self.dp.num_fic_syms)
        # repartition MSC data in CIFs (left out due to heavy burden for scheduler and not really necessary)
        #self.repartition_msc_to_CIFs = grdab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers * 2,
        #                                                            self.dp.cif_bits, self.dp.num_msc_syms,
        #                                                            self.dp.num_cifs)
        #repartition MSC to CUs
        self.repartition_msc_to_cus = grdab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers*2, self.dp.msc_cu_size, self.dp.num_msc_syms, self.dp.num_cus * self.dp.num_cifs)

        # select CUs of one subchannel of each CIF and form logical frame vector
        self.select_subch = grdab.select_subch_vfvf_make(self.dp.msc_cu_size, self.dp.msc_cu_size * self.size, self.address, self.dp.num_cus)

        # time deinterleaving
        self.time_v2s = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.msc_cu_size * self.size)
        self.time_deinterleaver = grdab.time_deinterleave_ff_make(self.dp.msc_cu_size * self.size, self.dp.scrambling_vector)
        # unpuncture
        self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.msc_punctured_codeword_length)
        self.unpuncture = grdab.unpuncture_ff_make(self.assembled_msc_puncturing_sequence, 0)

        # convolutional decoding
        self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133])  # OK (dumped to text and verified partially)
        table = [
            0, 0, 0, 0,
            0, 0, 0, 1,
            0, 0, 1, 0,
            0, 0, 1, 1,
            0, 1, 0, 0,
            0, 1, 0, 1,
            0, 1, 1, 0,
            0, 1, 1, 1,
            1, 0, 0, 0,
            1, 0, 0, 1,
            1, 0, 1, 0,
            1, 0, 1, 1,
            1, 1, 0, 0,
            1, 1, 0, 1,
            1, 1, 1, 0,
            1, 1, 1, 1
        ]
        assert (len(table) / 4 == self.fsm.O())
        table = [(1 - 2 * x) / sqrt(2) for x in table]
        self.conv_decode = trellis.viterbi_combined_fb(self.fsm, self.msc_I + self.dp.conv_code_add_bits_input, 0, 0, 4, table, trellis.TRELLIS_EUCLIDEAN)
        self.conv_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I + self.dp.conv_code_add_bits_input)
        self.conv_prune = grdab.prune(gr.sizeof_char, self.msc_conv_codeword_length / 4, 0,
                                            self.dp.conv_code_add_bits_input)

        #energy descramble
        self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.msc_I), True)
        self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.msc_I)
        self.add_mod_2 = blocks.xor_bb()
        #self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I)

        #pack bits
        self.pack_bits = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST)

        # connect blocks
        self.connect((self, 0),
                     (self.select_msc_syms),
                     #(self.repartition_msc_to_CIFs, 0),
                     (self.repartition_msc_to_cus),
                     (self.select_subch, 0),
                     #(self.repartition_cus_to_logical_frame, 0),
                     self.time_v2s,
                     self.time_deinterleaver,
                     #self.conv_v2s,
                     self.unpuncture,
                     self.conv_decode,
                     #self.conv_s2v,
                     self.conv_prune,
                     #self.energy_v2s,
                     self.add_mod_2,
                     self.pack_bits,
                     #self.energy_s2v, #better output stream or vector??
                     (self))
        self.connect(self.prbs_src, (self.add_mod_2, 1))


#debug
        if debug is True:
            #msc_select_syms
            self.sink_msc_select_syms = blocks.file_sink_make(gr.sizeof_float * self.dp.num_carriers * 2, "debug/msc_select_syms.dat")
            self.connect(self.select_msc_syms, self.sink_msc_select_syms)

            #msc repartition cus
            self.sink_repartition_msc_to_cus = blocks.file_sink_make(gr.sizeof_float * self.dp.msc_cu_size, "debug/msc_repartitioned_to_cus.dat")
            self.connect((self.repartition_msc_to_cus), self.sink_repartition_msc_to_cus)

            #data of one sub channel not decoded
            self.sink_select_subch = blocks.file_sink_make(gr.sizeof_float * self.dp.msc_cu_size * self.size, "debug/select_subch.dat")
            self.connect(self.select_subch, self.sink_select_subch)

            #sub channel time_deinterleaved
            self.sink_subch_time_deinterleaved = blocks.file_sink_make(gr.sizeof_float, "debug/subch_time_deinterleaved.dat")
            self.connect(self.time_deinterleaver, self.sink_subch_time_deinterleaved)

            #sub channel unpunctured
            self.sink_subch_unpunctured = blocks.file_sink_make(gr.sizeof_float, "debug/subch_unpunctured.dat")
            self.connect(self.unpuncture, self.sink_subch_unpunctured)

            # sub channel convolutional decoded
            self.sink_subch_decoded = blocks.file_sink_make(gr.sizeof_char, "debug/subch_decoded.dat")
            self.connect(self.conv_decode, self.sink_subch_decoded)

            # sub channel convolutional decoded
            self.sink_subch_pruned = blocks.file_sink_make(gr.sizeof_char, "debug/subch_pruned.dat")
            self.connect(self.conv_prune, self.sink_subch_pruned)

            # sub channel energy dispersal undone unpacked
            self.sink_subch_energy_disp_undone = blocks.file_sink_make(gr.sizeof_char, "debug/subch_energy_disp_undone_unpacked.dat")
            self.connect(self.add_mod_2, self.sink_subch_energy_disp_undone)

            # sub channel energy dispersal undone packed
            self.sink_subch_energy_disp_undone_packed = blocks.file_sink_make(gr.sizeof_char, "debug/subch_energy_disp_undone_packed.dat")
            self.connect(self.pack_bits, self.sink_subch_energy_disp_undone_packed)
Example #3
0
    def __init__(self, dab_params, verbose=False, debug=False):
        """
		Hierarchical block for OFDM modulation

		@param dab_params DAB parameter object (grdab.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_v2s = blocks.vector_to_stream_make(gr.sizeof_char, 384)
        self.mapper_unpack = blocks.packed_to_unpacked_bb_make(
            1, gr.GR_MSB_FIRST)
        self.mapper = grdab.mapper_bc_make(dp.num_carriers)
        self.mapper_s2v = blocks.stream_to_vector_make(gr.sizeof_gr_complex,
                                                       1536)

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

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

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

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

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

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

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

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

        #
        # connect it all
        #

        # data
        self.connect((self, 0), self.mapper_v2s, self.mapper_unpack,
                     self.mapper, self.mapper_s2v, (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, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_mapper.dat"))
            self.connect(
                self.insert_pilot,
                blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers,
                                 "debug/generated_signal_insert_pilot.dat"))
            self.connect(
                self.sum_phase,
                blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers,
                                 "debug/generated_signal_sum_phase.dat"))
            self.connect(
                self.interleave,
                blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers,
                                 "debug/generated_signal_interleave.dat"))
            self.connect(
                self.move_and_insert_carrier,
                blocks.file_sink(
                    gr.sizeof_gr_complex * dp.fft_length,
                    "debug/generated_signal_move_and_insert_carrier.dat"))
            self.connect(
                self.ifft,
                blocks.file_sink(gr.sizeof_gr_complex * dp.fft_length,
                                 "debug/generated_signal_ifft.dat"))
            self.connect(
                self.prefixer,
                blocks.file_sink(gr.sizeof_gr_complex,
                                 "debug/generated_signal_prefixer.dat"))
            self.connect(
                self.insert_null,
                blocks.file_sink(gr.sizeof_gr_complex,
                                 "debug/generated_signal.dat"))
Example #4
0
    def __init__(self,
                 dab_params,
                 address,
                 size,
                 protection,
                 verbose=False,
                 debug=False):
        gr.hier_block2.__init__(
            self,
            "msc_decode",
            # Input signature
            gr.io_signature(1, 1,
                            gr.sizeof_float * dab_params.num_carriers * 2),
            # Output signature
            gr.io_signature(1, 1, gr.sizeof_char))
        self.dp = dab_params
        self.address = address
        self.size = size
        self.protect = protection
        self.verbose = verbose
        self.debug = debug

        # calculate n factor (multiple of 8kbits etc.)
        self.n = self.size / self.dp.subch_size_multiple_n[self.protect]

        # calculate puncturing factors (EEP, table 33, 34)
        self.msc_I = self.n * 192
        if (self.n > 1 or self.protect != 1):
            self.puncturing_L1 = [
                6 * self.n - 3, 2 * self.n - 3, 6 * self.n - 3, 4 * self.n - 3
            ]
            self.puncturing_L2 = [3, 4 * self.n + 3, 3, 2 * self.n + 3]
            self.puncturing_PI1 = [24, 14, 8, 3]
            self.puncturing_PI2 = [23, 13, 7, 2]
            # calculate length of punctured codeword (11.3.2)
            self.msc_punctured_codeword_length = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors_ones[
                self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * \
                                                     self.dp.puncturing_vectors_ones[
                                                         self.puncturing_PI2[self.protect]] + 12
            self.assembled_msc_puncturing_sequence = int(self.puncturing_L1[
                self.protect]) * 4 * self.dp.puncturing_vectors[
                    self.puncturing_PI1[self.protect]] + int(
                        self.puncturing_L2[self.protect]
                    ) * 4 * self.dp.puncturing_vectors[self.puncturing_PI2[
                        self.protect]] + self.dp.puncturing_tail_vector
            self.msc_conv_codeword_length = 4 * self.msc_I + 24  # 4*I + 24 ()
        # exception in table
        else:
            self.msc_punctured_codeword_length = 5 * 4 * self.dp.puncturing_vectors_ones[13] + 1 * 4 * \
                                                                                               self.dp.puncturing_vectors_ones[
                                                                                                   12] + 12
        #sanity check
        assert (6 * self.n == self.puncturing_L1[self.protect] +
                self.puncturing_L2[self.protect])

        # MSC selection and block partitioning
        # select OFDM carriers with MSC
        self.select_msc_syms = grdab.select_vectors(gr.sizeof_float,
                                                    self.dp.num_carriers * 2,
                                                    self.dp.num_msc_syms,
                                                    self.dp.num_fic_syms)
        # repartition MSC data in CIFs (left out due to heavy burden for scheduler and not really necessary)
        #self.repartition_msc_to_CIFs = grdab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers * 2,
        #                                                            self.dp.cif_bits, self.dp.num_msc_syms,
        #                                                            self.dp.num_cifs)
        #repartition MSC to CUs
        self.repartition_msc_to_cus = grdab.repartition_vectors_make(
            gr.sizeof_float, self.dp.num_carriers * 2, self.dp.msc_cu_size,
            self.dp.num_msc_syms, self.dp.num_cus * self.dp.num_cifs)

        # select CUs of one subchannel of each CIF and form logical frame vector
        self.select_subch = grdab.select_subch_vfvf_make(
            self.dp.msc_cu_size, self.dp.msc_cu_size * self.size, self.address,
            self.dp.num_cus)

        # time deinterleaving
        self.time_v2s = blocks.vector_to_stream_make(
            gr.sizeof_float, self.dp.msc_cu_size * self.size)
        self.time_deinterleaver = grdab.time_deinterleave_ff_make(
            self.dp.msc_cu_size * self.size, self.dp.scrambling_vector)
        # unpuncture
        self.conv_v2s = blocks.vector_to_stream(
            gr.sizeof_float, self.msc_punctured_codeword_length)
        self.unpuncture = grdab.unpuncture_ff_make(
            self.assembled_msc_puncturing_sequence, 0)

        # convolutional decoding
        self.fsm = trellis.fsm(
            1, 4, [0o133, 0o171, 0o145, 0o133
                   ])  # OK (dumped to text and verified partially)
        table = [
            0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1,
            0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0,
            1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1
        ]
        assert (len(table) / 4 == self.fsm.O())
        table = [(1 - 2 * x) / sqrt(2) for x in table]
        self.conv_decode = trellis.viterbi_combined_fb(
            self.fsm, self.msc_I + self.dp.conv_code_add_bits_input, 0, 0, 4,
            table, trellis.TRELLIS_EUCLIDEAN)
        self.conv_s2v = blocks.stream_to_vector(
            gr.sizeof_char, self.msc_I + self.dp.conv_code_add_bits_input)
        self.conv_prune = grdab.prune(gr.sizeof_char,
                                      self.msc_conv_codeword_length / 4, 0,
                                      self.dp.conv_code_add_bits_input)

        #energy descramble
        self.prbs_src = blocks.vector_source_b(self.dp.prbs(int(self.msc_I)),
                                               True)
        self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.msc_I)
        self.add_mod_2 = blocks.xor_bb()
        #self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I)

        #pack bits
        self.pack_bits = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST)

        # connect blocks
        self.connect(
            (self, 0),
            (self.select_msc_syms),
            #(self.repartition_msc_to_CIFs, 0),
            (self.repartition_msc_to_cus),
            (self.select_subch, 0),
            #(self.repartition_cus_to_logical_frame, 0),
            self.time_v2s,
            self.time_deinterleaver,
            #self.conv_v2s,
            self.unpuncture,
            self.conv_decode,
            #self.conv_s2v,
            self.conv_prune,
            #self.energy_v2s,
            self.add_mod_2,
            self.pack_bits,
            #self.energy_s2v, #better output stream or vector??
            (self))
        self.connect(self.prbs_src, (self.add_mod_2, 1))

        #debug
        if debug is True:
            #msc_select_syms
            self.sink_msc_select_syms = blocks.file_sink_make(
                gr.sizeof_float * self.dp.num_carriers * 2,
                "debug/msc_select_syms.dat")
            self.connect(self.select_msc_syms, self.sink_msc_select_syms)

            #msc repartition cus
            self.sink_repartition_msc_to_cus = blocks.file_sink_make(
                gr.sizeof_float * self.dp.msc_cu_size,
                "debug/msc_repartitioned_to_cus.dat")
            self.connect((self.repartition_msc_to_cus),
                         self.sink_repartition_msc_to_cus)

            #data of one sub channel not decoded
            self.sink_select_subch = blocks.file_sink_make(
                gr.sizeof_float * self.dp.msc_cu_size * self.size,
                "debug/select_subch.dat")
            self.connect(self.select_subch, self.sink_select_subch)

            #sub channel time_deinterleaved
            self.sink_subch_time_deinterleaved = blocks.file_sink_make(
                gr.sizeof_float, "debug/subch_time_deinterleaved.dat")
            self.connect(self.time_deinterleaver,
                         self.sink_subch_time_deinterleaved)

            #sub channel unpunctured
            self.sink_subch_unpunctured = blocks.file_sink_make(
                gr.sizeof_float, "debug/subch_unpunctured.dat")
            self.connect(self.unpuncture, self.sink_subch_unpunctured)

            # sub channel convolutional decoded
            self.sink_subch_decoded = blocks.file_sink_make(
                gr.sizeof_char, "debug/subch_decoded.dat")
            self.connect(self.conv_decode, self.sink_subch_decoded)

            # sub channel convolutional decoded
            self.sink_subch_pruned = blocks.file_sink_make(
                gr.sizeof_char, "debug/subch_pruned.dat")
            self.connect(self.conv_prune, self.sink_subch_pruned)

            # sub channel energy dispersal undone unpacked
            self.sink_subch_energy_disp_undone = blocks.file_sink_make(
                gr.sizeof_char, "debug/subch_energy_disp_undone_unpacked.dat")
            self.connect(self.add_mod_2, self.sink_subch_energy_disp_undone)

            # sub channel energy dispersal undone packed
            self.sink_subch_energy_disp_undone_packed = blocks.file_sink_make(
                gr.sizeof_char, "debug/subch_energy_disp_undone_packed.dat")
            self.connect(self.pack_bits,
                         self.sink_subch_energy_disp_undone_packed)
Example #5
0
	def __init__(self, dab_params, verbose=False, debug=False):
		"""
		Hierarchical block for OFDM modulation

		@param dab_params DAB parameter object (grdab.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_v2s = blocks.vector_to_stream_make(gr.sizeof_char, 384)
		self.mapper_unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST)
		self.mapper = grdab.mapper_bc_make(dp.num_carriers)
		self.mapper_s2v = blocks.stream_to_vector_make(gr.sizeof_gr_complex, 1536)

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

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

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

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

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

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

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

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

		#
		# connect it all
		#

		# data
		self.connect((self,0), self.mapper_v2s, self.mapper_unpack, self.mapper, self.mapper_s2v, (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, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_mapper.dat"))
			self.connect(self.insert_pilot, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_insert_pilot.dat"))
			self.connect(self.sum_phase, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_sum_phase.dat"))
			self.connect(self.interleave, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_interleave.dat"))
			self.connect(self.move_and_insert_carrier, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_move_and_insert_carrier.dat"))
			self.connect(self.ifft, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_ifft.dat"))
			self.connect(self.prefixer, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal_prefixer.dat"))
			self.connect(self.insert_null, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal.dat"))
Example #6
0
    def __init__(self,
                 dab_mode,
                 frequency,
                 bit_rate,
                 address,
                 size,
                 protection,
                 audio_bit_rate,
                 dabplus,
                 use_usrp,
                 src_path,
                 sink_path="None"):
        gr.top_block.__init__(self)

        self.dab_mode = dab_mode
        self.verbose = False
        self.sample_rate = 2e6
        self.dabplus = dabplus
        self.use_usrp = use_usrp
        self.src_path = src_path
        self.sink_path = sink_path
        gr.log.set_level("warn")

        ########################
        # source
        ########################
        if self.use_usrp:
            self.src = uhd.usrp_source("", uhd.io_type.COMPLEX_FLOAT32, 1)
            self.src.set_samp_rate(self.sample_rate)
            self.src.set_antenna("TX/RX")
        else:
            print "using file source"
            self.src = blocks.file_source_make(gr.sizeof_gr_complex,
                                               self.src_path, False)

        # set paramters to default mode
        self.softbits = True
        self.filter_input = True
        self.autocorrect_sample_rate = False
        self.resample_fixed = 1
        self.correct_ffe = True
        self.equalize_magnitude = True
        self.frequency = frequency
        self.dab_params = dab.parameters.dab_parameters(
            self.dab_mode, self.sample_rate, self.verbose)
        self.rx_params = dab.parameters.receiver_parameters(
            self.dab_mode, self.softbits, self.filter_input,
            self.autocorrect_sample_rate, self.resample_fixed, self.verbose,
            self.correct_ffe, self.equalize_magnitude)
        ########################
        # FFT and waterfall plot
        ########################
        self.fft_plot = qtgui.freq_sink_c_make(1024,
                                               fft.window.WIN_BLACKMAN_HARRIS,
                                               self.frequency, 2e6, "FFT")
        self.waterfall_plot = qtgui.waterfall_sink_c_make(
            1024, fft.window.WIN_BLACKMAN_HARRIS, self.frequency, 2e6,
            "Waterfall")
        #self.time_plot = qtgui.time_sink_c_make(1024, 2e6, "Time")

        ########################
        # OFDM demod
        ########################
        self.demod = dab.ofdm_demod(self.dab_params, self.rx_params,
                                    self.verbose)

        ########################
        # SNR measurement
        ########################
        self.v2s_snr = blocks.vector_to_stream_make(
            gr.sizeof_gr_complex, self.dab_params.num_carriers)
        self.snr_measurement = digital.mpsk_snr_est_cc_make(
            digital.SNR_EST_SIMPLE, 10000)
        self.constellation_plot = qtgui.const_sink_c_make(1024, "", 1)

        ########################
        # FIC decoder
        ########################
        self.fic_dec = dab.fic_decode(self.dab_params)

        ########################
        # MSC decoder
        ########################
        if self.dabplus:
            self.dabplus = dab.dabplus_audio_decoder_ff(
                self.dab_params, bit_rate, address, size, protection, True)
        else:
            self.msc_dec = dab.msc_decode(self.dab_params, address, size,
                                          protection)
            self.unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST)
            self.mp2_dec = dab.mp2_decode_bs_make(bit_rate / 8)
            self.s2f_left = blocks.short_to_float_make(1, 32767)
            self.s2f_right = blocks.short_to_float_make(1, 32767)
            self.gain_left = blocks.multiply_const_ff(1, 1)
            self.gain_right = blocks.multiply_const_ff(1, 1)

        ########################
        # audio sink
        ########################
        self.valve_left = dab.valve_ff_make(True)
        self.valve_right = dab.valve_ff_make(True)
        self.audio = audio.sink_make(audio_bit_rate)
        self.wav_sink = blocks.wavfile_sink_make("dab_audio.wav", 2,
                                                 audio_bit_rate)

        ########################
        # Connections
        ########################
        self.connect(self.src, self.fft_plot)
        self.connect(self.src, self.waterfall_plot)
        self.connect(self.src, self.demod, (self.fic_dec, 0))
        self.connect((self.demod, 1), (self.fic_dec, 1))
        if self.dabplus:
            self.connect((self.demod, 0), (self.dabplus, 0))
            self.connect((self.demod, 1), (self.dabplus, 1))
        else:
            self.connect((self.demod, 0), (self.msc_dec, 0), self.unpack,
                         self.mp2_dec)
            self.connect((self.demod, 1), (self.msc_dec, 1))
            self.connect((self.mp2_dec, 0), self.s2f_left, self.gain_left)
            self.connect((self.mp2_dec, 1), self.s2f_right, self.gain_right)
        self.connect((self.demod, 0), self.v2s_snr, self.snr_measurement,
                     self.constellation_plot)
        # connect audio to sound card and file sink
        if self.dabplus:
            self.connect((self.dabplus, 0), (self.audio, 0))
            self.connect((self.dabplus, 1), (self.audio, 1))
            self.connect((self.dabplus, 0), self.valve_left,
                         (self.wav_sink, 0))
            self.connect((self.dabplus, 1), self.valve_right,
                         (self.wav_sink, 1))
        else:
            self.connect(self.gain_left, (self.audio, 0))
            self.connect(self.gain_right, (self.audio, 1))
            self.connect(self.gain_left, self.valve_left, (self.wav_sink, 0))
            self.connect(self.gain_right, self.valve_right, (self.wav_sink, 1))

        # tune USRP frequency
        if self.use_usrp:
            self.set_freq(self.frequency)
            # set gain
            # if no gain was specified, use the mid-point in dB
            g = self.src.get_gain_range()
            self.rx_gain = float(g.start() + g.stop()) / 2
            self.src.set_gain(self.rx_gain)
Example #7
0
    def __init__(self, frequency, bit_rate, address, size, protection, use_usrp, src_path, record_audio = False, sink_path = "None"):
        gr.top_block.__init__(self)

        self.dab_mode = 1
        self.verbose = False
        self.sample_rate = 2e6
        self.use_usrp = use_usrp
        self.src_path = src_path
        self.record_audio = record_audio
        self.sink_path = sink_path

        ########################
        # source
        ########################
        if self.use_usrp:
            self.src = uhd.usrp_source("", uhd.io_type.COMPLEX_FLOAT32, 1)
            self.src.set_samp_rate(self.sample_rate)
            self.src.set_antenna("TX/RX")
        else:
            print "using file source"
            self.src = blocks.file_source_make(gr.sizeof_gr_complex, self.src_path, True)

        # set paramters to default mode
        self.softbits = True
        self.filter_input = True
        self.autocorrect_sample_rate = False
        self.resample_fixed = 1
        self.correct_ffe = True
        self.equalize_magnitude = True
        self.frequency = frequency
        self.dab_params = dab.parameters.dab_parameters(self.dab_mode, self.sample_rate, self.verbose)
        self.rx_params = dab.parameters.receiver_parameters(self.dab_mode, self.softbits,
                                                            self.filter_input,
                                                            self.autocorrect_sample_rate,
                                                            self.resample_fixed,
                                                            self.verbose, self.correct_ffe,
                                                            self.equalize_magnitude)

        ########################
        # OFDM demod
        ########################
        self.demod = dab.ofdm_demod(self.dab_params, self.rx_params, self.verbose)

        ########################
        # SNR measurement
        ########################
        self.v2s_snr = blocks.vector_to_stream_make(gr.sizeof_gr_complex, 1536)
        self.snr_measurement = digital.mpsk_snr_est_cc_make(digital.SNR_EST_SIMPLE, 10000)
        self.null_sink_snr = blocks.null_sink_make(gr.sizeof_gr_complex)

        ########################
        # FIC decoder
        ########################
        self.fic_dec = dab.fic_decode(self.dab_params)

        ########################
        # MSC decoder and audio sink
        ########################
        self.dabplus = dab.dabplus_audio_decoder_ff(self.dab_params, bit_rate, address, size, protection, True)
        self.audio = audio.sink_make(32000)

        ########################
        # Connections
        ########################
        self.connect(self.src, self.demod, (self.fic_dec, 0))
        self.connect((self.demod, 1), (self.fic_dec, 1))
        self.connect((self.demod, 0), (self.dabplus, 0))
        self.connect((self.demod, 1), (self.dabplus, 1))
        self.connect((self.demod, 0), self.v2s_snr, self.snr_measurement, self.null_sink_snr)
        # connect audio to sound card
        # left stereo channel
        self.connect((self.dabplus, 0), (self.audio, 0))
        # right stereo channel
        self.connect((self.dabplus, 1), (self.audio, 1))
        # connect file sink if recording is selected
        if self.record_audio:
            self.sink = blocks.wavfile_sink_make("dab_audio.wav", 2, 32000)
            self.connect((self.dabplus, 0), (self.sink, 0))
            self.connect((self.dabplus, 1), (self.sink, 1))

        # tune USRP frequency
        if self.use_usrp:
            self.set_freq(self.frequency)
            # set gain
            # if no gain was specified, use the mid-point in dB
            g = self.src.get_gain_range()
            self.rx_gain = float(g.start() + g.stop()) / 2
            self.src.set_gain(self.rx_gain)