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))
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)
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"))
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)
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"))
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)
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)