예제 #1
0
    def est_loopback_002(self):
        """
        Loopback randomizer/rs_encoder/interleaver to
	deinterleaver/rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
        interleaver_delay = 52
        expected_result = src_data[0:len(src_data) -
                                   (interleaver_delay *
                                    atsc.ATSC_MPEG_PKT_LENGTH)]

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
        inter = atsc.interleaver()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
        self.tb.connect(src, rand, rs_enc, inter, deinter, rs_dec, derand, dst)
        self.tb.run()
        result_data = dst.data()
        result_data = result_data[(interleaver_delay *
                                   atsc.ATSC_MPEG_PKT_LENGTH):len(result_data)]
        self.assertEqual(expected_result, result_data)
예제 #2
0
    def est_loopback_003(self):
        """
        Loopback randomizer/rs_encoder/interleaver/trellis_encoder
	via ds_to_softds to
	viterbi_decoder/deinterleaver/rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
        interleaver_delay = 52
        viterbi_delay = 12
        expected_result = src_data[0:len(src_data) - (
            (interleaver_delay + viterbi_delay) * atsc.ATSC_MPEG_PKT_LENGTH)]

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
        inter = atsc.interleaver()
        trellis = atsc.trellis_encoder()
        softds = atsc.ds_to_softds()
        viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
        self.tb.connect(src, rand, rs_enc, inter, trellis, softds, viterbi,
                        deinter, rs_dec, derand, dst)
        self.tb.run()
        result_data = dst.data()[((interleaver_delay + viterbi_delay) *
                                  atsc.ATSC_MPEG_PKT_LENGTH):len(dst.data())]
        self.assertEqual(expected_result, result_data)
예제 #3
0
    def est_loopback_003(self):
        """
        Loopback randomizer/rs_encoder/interleaver/trellis_encoder
	via ds_to_softds to
	viterbi_decoder/deinterleaver/rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
	interleaver_delay = 52
	viterbi_delay = 12
        expected_result = src_data[0:len(src_data)-((interleaver_delay+viterbi_delay)*atsc.ATSC_MPEG_PKT_LENGTH)]

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
        inter = atsc.interleaver()
	trellis = atsc.trellis_encoder()
	softds = atsc.ds_to_softds()
	viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
	self.tb.connect(src, rand, rs_enc, inter, trellis, softds, viterbi, deinter, rs_dec, derand, dst)
        self.tb.run ()
        result_data = dst.data ()[((interleaver_delay+viterbi_delay)*atsc.ATSC_MPEG_PKT_LENGTH):len(dst.data())]
        self.assertEqual (expected_result, result_data)
예제 #4
0
    def est_loopback_001(self):
        """
        Loopback randomizer/rs_encoder to rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
        expected_result = src_data

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
        self.tb.connect(src, rand, rs_enc, rs_dec, derand, dst)
        self.tb.run()
        result_data = dst.data()
        self.assertEqual(expected_result, result_data)
예제 #5
0
    def est_loopback_001(self):
        """
        Loopback randomizer/rs_encoder to rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
        expected_result = src_data

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
        self.tb.connect(src, rand, rs_enc, rs_dec, derand, dst)
        self.tb.run ()
        result_data = dst.data ()
        self.assertEqual (expected_result, result_data)
def main(args):

	nargs = len (args)
	if nargs == 1:
	   outfile = args[0]
	else:
	   sys.stderr.write ('usage: viterbi_out.py output_file\n')
	   sys.exit (1)

	fg = gr.flow_graph()

        src = gr.file_source(atsc.sizeof_atsc_soft_data_segment, "/tmp/atsc_pipe_5")
	viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
	depad = atsc.depad()
        dst = gr.file_sink(gr.sizeof_char,outfile)
	fg.connect(src, viterbi, deinter, rs_dec, derand, depad, dst)
        fg.run ()
예제 #7
0
def main(args):

	print os.getpid()

	nargs = len (args)
	if nargs == 1:
	   outfile = args[0]
	else:
	   sys.stderr.write ('usage: viterbi_out.py output_file\n')
	   sys.exit (1)

	tb = gr.top_block()

        src = blocks.file_source(atsc.sizeof_atsc_soft_data_segment, "/tmp/atsc_pipe_5")
	viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
	depad = atsc.depad()
        dst = blocks.file_sink(gr.sizeof_char,outfile)
	tb.connect(src, viterbi, deinter, rs_dec, derand, depad, dst)
        tb.run ()
예제 #8
0
def main(args):

	print os.getpid()

	nargs = len (args)
	if nargs == 1:
	   outfile = args[0]
	else:
	   sys.stderr.write ('usage: viterbi_out.py output_file\n')
	   sys.exit (1)

	tb = gr.top_block()

        src = gr.file_source(atsc.sizeof_atsc_soft_data_segment, "/tmp/atsc_pipe_5")
	viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
	depad = atsc.depad()
        dst = gr.file_sink(gr.sizeof_char,outfile)
	tb.connect(src, viterbi, deinter, rs_dec, derand, depad, dst)
        tb.run ()
예제 #9
0
    def est_loopback_002(self):
        """
        Loopback randomizer/rs_encoder/interleaver to
	deinterleaver/rs_decoder/derandomizer
        """
        src_data = make_transport_stream()
	interleaver_delay = 52
        expected_result = src_data[0:len(src_data)-(interleaver_delay*atsc.ATSC_MPEG_PKT_LENGTH)]

        src = vector_source_ts(src_data)
        rand = atsc.randomizer()
        rs_enc = atsc.rs_encoder()
	inter = atsc.interleaver()
	deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
        dst = vector_sink_ts()
        self.tb.connect(src, rand, rs_enc, inter, deinter, rs_dec, derand, dst)
        self.tb.run ()
        result_data = dst.data ()
	result_data = result_data[(interleaver_delay*atsc.ATSC_MPEG_PKT_LENGTH):len(result_data)]
        self.assertEqual (expected_result, result_data)
예제 #10
0
    def __init__(self,
                 if_rate,        # Incoming sample rate
                 symbol_rate,    # Original symbol rate
                 excess_bw,      # RRC excess bandwidth, typically 0.35-0.5
                 costas_alpha,   # Costas loop 1st order gain, typically 0.01-0.2
                 costas_beta,    # Costas loop 2nd order gain, typically alpha^2/4.0
                 costas_max,     # Costas loop max frequency offset in radians/sample
                 mm_gain_mu,     # M&M loop 1st order gain, typically 0.001-0.2
                 mm_gain_omega,  # M&M loop 2nd order gain, typically alpha^2/4.0
                 mm_omega_limit, # M&M loop max timing error
                 ):
        
        gr.hier_block2.__init__(self, "receive_path",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature(0, 0, 0))                    # Output signature

        self._if_rate = if_rate
        self._sps = int(self._if_rate/symbol_rate)
        print "IF sample rate:", n2s(self._if_rate)
        print "Symbol rate:", n2s(symbol_rate)
        print "Samples/symbol:", self._sps
        print "RRC bandwidth:", excess_bw
        
        # Create AGC to scale input to unity
        self._agc = gr.agc_cc(1e-5, 1.0, 1.0, 1.0)

	# Create RRC with specified excess bandwidth
	taps = gr.firdes.root_raised_cosine(1.0,          # Gain
					    self._sps,    # Sampling rate
					    1.0,          # Symbol rate
					    excess_bw,    # Roll-off factor
					    11*self._sps) # Number of taps

	self._rrc = gr.fir_filter_ccf(1, taps)
        
        # Create a Costas loop frequency/phase recovery block

        print "Costas alpha:", costas_alpha
        print "Costas beta:", costas_beta
        print "Costas max:", costas_max
        
        self._costas = gr.costas_loop_cc(costas_alpha,  # PLL first order gain
                                         costas_beta,   # PLL second order gain
                                         costas_max,    # Max frequency offset rad/sample
                                         -costas_max,   # Min frequency offset rad/sample
                                         2)             # BPSK

        # Create a M&M bit synchronization retiming block
        mm_mu = 0.5
        mm_omega = self._sps

        print "MM gain mu:", mm_gain_mu
        print "MM gain omega:", mm_gain_omega
        print "MM omega limit:", mm_omega_limit
        
        self._mm = gr.clock_recovery_mm_cc(mm_omega,       # Initial samples/symbol
                                           mm_gain_omega,  # Second order gain
                                           mm_mu,          # Initial symbol phase
                                           mm_gain_mu,     # First order gain
                                           mm_omega_limit) # Maximum timing offset

        # Add an SNR probe on the demodulated constellation
        self._snr_probe = gr.probe_mpsk_snr_c(10.0/symbol_rate)
        self.connect(self._mm, self._snr_probe)
        
        # Slice the resulting constellation into bits.
        # Get inphase channel and make decision about 0
        self._c2r = gr.complex_to_real()
        self._slicer = gr.binary_slicer_fb() 
        
        # Descramble BERT sequence.  A channel error will create 3 incorrect bits
        self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler
        self._decoder = atsc.rs_decoder() #reed-solomon decoder

        # Measure BER by the density of 0s in the stream
        self._ber = gr.probe_density_b(1.0/symbol_rate)

        self.connect(self, self._agc, self._rrc, self._costas, self._mm, 
                     self._c2r, self._slicer, self._descrambler, self._ber)
예제 #11
0
def graph (args):

	print os.getpid()

	nargs = len(args)
    	if nargs == 2:
		infile = args[0]
        	outfile = args[1]
    	else:
        	raise ValueError('usage: interp.py input_file output_file.ts\n')

	input_rate = 19.2e6
	IF_freq = 5.75e6

	tb = gr.top_block()

	# Read from input file
	srcf = blocks.file_source(gr.sizeof_short, infile)

	# Convert interleaved shorts (I,Q,I,Q) to complex
	is2c = blocks.interleaved_short_to_complex()

	# 1/2 as wide because we're designing lp filter
	symbol_rate = atsc.ATSC_SYMBOL_RATE/2.
	NTAPS = 279
	tt = filter.firdes.root_raised_cosine (1.0, input_rate / 3, symbol_rate, .1152, NTAPS)
	rrc = filter.fir_filter_ccf(1, tt)

	# Interpolate Filter our 6MHz wide signal centered at 0
	ilp_coeffs = filter.firdes.low_pass(1, input_rate, 3.2e6, .5e6, filter.firdes.WIN_HAMMING)
	ilp = filter.interp_fir_filter_ccf(3, ilp_coeffs)

	# Move the center frequency to 5.75MHz ( this wont be needed soon )
	duc_coeffs = filter.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING )
    	duc = filter.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, -5.75e6, 19.2e6 )

	# fpll input is float
	c2f = blocks.complex_to_float()

	# Phase locked loop
	fpll = atsc.fpll()

	# Clean fpll output
	lp_coeffs2 = filter.firdes.low_pass (1.0,
			   input_rate,
			   5.75e6,
                           120e3,
                           filter.firdes.WIN_HAMMING);
	lp_filter = filter.fir_filter_fff (1, lp_coeffs2)

	# Remove pilot ( at DC now )
	iir = filter.single_pole_iir_filter_ff(1e-5)
	remove_dc = blocks.sub_ff()

	# Bit Timing Loop, Field Sync Checker and Equalizer
	btl = atsc.bit_timing_loop()
	fsc = atsc.fs_checker()
	eq = atsc.equalizer()
	fsd = atsc.field_sync_demux()

	# Viterbi
	viterbi = atsc.viterbi_decoder()
        deinter = atsc.deinterleaver()
        rs_dec = atsc.rs_decoder()
        derand = atsc.derandomizer()
	depad = atsc.depad()

	# Write to output file
	outf = blocks.file_sink(gr.sizeof_char,outfile)

	# Connect it all together
	tb.connect( srcf, is2c, rrc, ilp, duc, c2f, fpll, lp_filter)
	tb.connect( lp_filter, iir )
	tb.connect( lp_filter, (remove_dc, 0) )
	tb.connect( iir, (remove_dc, 1) )
	tb.connect( remove_dc, btl )
	tb.connect( (btl, 0), (fsc, 0), (eq, 0), (fsd,0) )
	tb.connect( (btl, 1), (fsc, 1), (eq, 1), (fsd,1) )
	tb.connect( fsd, viterbi, deinter, rs_dec, derand, depad, outf )

	tb.run()
예제 #12
0
def graph(args):

    nargs = len(args)
    if nargs == 2:
        infile = args[0]
        outfile = args[1]
    else:
        raise ValueError('usage: interp.py input_file output_file\n')

    tb = gr.top_block()

    # Convert to a from shorts to a stream of complex numbers.
    srcf = blocks.file_source(gr.sizeof_short, infile)
    s2ss = blocks.stream_to_streams(gr.sizeof_short, 2)
    s2f1 = blocks.short_to_float()
    s2f2 = blocks.short_to_float()
    src0 = blocks.float_to_complex()
    tb.connect(srcf, s2ss)
    tb.connect((s2ss, 0), s2f1, (src0, 0))
    tb.connect((s2ss, 1), s2f2, (src0, 1))

    # Low pass filter it and increase sample rate by a factor of 3.
    lp_coeffs = filter.firdes.low_pass(3, 19.2e6, 3.2e6, .5e6,
                                       filter.firdes.WIN_HAMMING)
    lp = filter.interp_fir_filter_ccf(3, lp_coeffs)
    tb.connect(src0, lp)

    # Upconvert it.
    duc_coeffs = filter.firdes.low_pass(1, 19.2e6, 9e6, 1e6,
                                        filter.firdes.WIN_HAMMING)
    duc = filter.freq_xlating_fir_filter_ccf(1, duc_coeffs, 5.75e6, 19.2e6)
    # Discard the imaginary component.
    c2f = blocks.complex_to_float()
    tb.connect(lp, duc, c2f)

    # Frequency Phase Lock Loop
    input_rate = 19.2e6
    IF_freq = 5.75e6
    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE / 2.
    NTAPS = 279
    tt = filter.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115,
                                          NTAPS)
    # heterodyne the low pass coefficients up to the specified bandpass
    # center frequency.  Note that when we do this, the filter bandwidth
    # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
    # matches the diagram in the ATSC spec.
    arg = 2. * math.pi * IF_freq / input_rate
    t = []
    for i in range(len(tt)):
        t += [tt[i] * 2. * math.cos(arg * i)]
    rrc = filter.fir_filter_fff(1, t)

    fpll = atsc.fpll()

    pilot_freq = IF_freq - 3e6 + 0.31e6
    lower_edge = 6e6 - 0.31e6
    upper_edge = IF_freq - 3e6 + pilot_freq
    transition_width = upper_edge - lower_edge
    lp_coeffs = filter.firdes.low_pass(1.0, input_rate,
                                       (lower_edge + upper_edge) * 0.5,
                                       transition_width,
                                       filter.firdes.WIN_HAMMING)

    lp_filter = filter.fir_filter_fff(1, lp_coeffs)

    alpha = 1e-5
    iir = filter.single_pole_iir_filter_ff(alpha)
    remove_dc = blocks.sub_ff()

    tb.connect(c2f, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc, 0))
    tb.connect(iir, (remove_dc, 1))

    # Bit Timing Loop, Field Sync Checker and Equalizer

    btl = atsc.bit_timing_loop()
    fsc = atsc.fs_checker()
    eq = atsc.equalizer()
    fsd = atsc.field_sync_demux()

    tb.connect(remove_dc, btl)
    tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0))
    tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1))

    # Viterbi

    viterbi = atsc.viterbi_decoder()
    deinter = atsc.deinterleaver()
    rs_dec = atsc.rs_decoder()
    derand = atsc.derandomizer()
    depad = atsc.depad()
    dst = blocks.file_sink(gr.sizeof_char, outfile)
    tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst)

    dst2 = blocks.file_sink(gr.sizeof_gr_complex, "atsc_complex.data")
    tb.connect(src0, dst2)

    tb.run()
예제 #13
0
def graph (args):

    nargs = len(args)
    if nargs == 2:
	infile = args[0]
        outfile = args[1]
    else:
        raise ValueError('usage: interp.py input_file output_file\n')

    tb = gr.top_block ()

    # Convert to a from shorts to a stream of complex numbers.
    srcf = gr.file_source (gr.sizeof_short,infile)
    s2ss = gr.stream_to_streams(gr.sizeof_short,2)
    s2f1 = gr.short_to_float()
    s2f2 = gr.short_to_float()
    src0 = gr.float_to_complex()
    tb.connect(srcf, s2ss)
    tb.connect((s2ss, 0), s2f1, (src0, 0))
    tb.connect((s2ss, 1), s2f2, (src0, 1))

    # Low pass filter it and increase sample rate by a factor of 3.
    lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING )
    lp = gr.interp_fir_filter_ccf ( 3, lp_coeffs )
    tb.connect(src0, lp)

    # Upconvert it.
    duc_coeffs = gr.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING )
    duc = gr.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, 5.75e6, 19.2e6 )
    # Discard the imaginary component.
    c2f = gr.complex_to_float()
    tb.connect(lp, duc, c2f)

    # Frequency Phase Lock Loop
    input_rate = 19.2e6
    IF_freq = 5.75e6
    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE/2.
    NTAPS = 279
    tt = gr.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS)
    # heterodyne the low pass coefficients up to the specified bandpass
    # center frequency.  Note that when we do this, the filter bandwidth
    # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
    # matches the diagram in the ATSC spec.
    arg = 2. * math.pi * IF_freq / input_rate
    t=[]
    for i in range(len(tt)):
        t += [tt[i] * 2. * math.cos(arg * i)]
    rrc = gr.fir_filter_fff(1, t)

    fpll = atsc.fpll()

    pilot_freq = IF_freq - 3e6 + 0.31e6
    lower_edge = 6e6 - 0.31e6
    upper_edge = IF_freq - 3e6 + pilot_freq
    transition_width = upper_edge - lower_edge
    lp_coeffs = gr.firdes.low_pass (1.0,
                                    input_rate,
                                    (lower_edge + upper_edge) * 0.5,
                                    transition_width,
                                    gr.firdes.WIN_HAMMING);
    
    lp_filter = gr.fir_filter_fff (1,lp_coeffs)
    
    alpha = 1e-5
    iir = gr.single_pole_iir_filter_ff(alpha)
    remove_dc = gr.sub_ff()

    tb.connect(c2f, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc,0))
    tb.connect(iir, (remove_dc,1))
    
    # Bit Timing Loop, Field Sync Checker and Equalizer

    btl = atsc.bit_timing_loop()
    fsc = atsc.fs_checker()
    eq = atsc.equalizer()
    fsd = atsc.field_sync_demux()

    tb.connect(remove_dc, btl)
    tb.connect((btl, 0),(fsc, 0),(eq, 0),(fsd, 0))
    tb.connect((btl, 1),(fsc, 1),(eq, 1),(fsd, 1))

    # Viterbi

    viterbi = atsc.viterbi_decoder()
    deinter = atsc.deinterleaver()
    rs_dec = atsc.rs_decoder()
    derand = atsc.derandomizer()
    depad = atsc.depad()
    dst = gr.file_sink(gr.sizeof_char, outfile)
    tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst)

    dst2 = gr.file_sink(gr.sizeof_gr_complex, "atsc_complex.data")
    tb.connect(src0, dst2)

    tb.run ()
예제 #14
0
def graph(args):

    print os.getpid()

    nargs = len(args)
    if nargs == 2:
        infile = args[0]
        outfile = args[1]
    else:
        raise ValueError('usage: interp.py input_file output_file.ts\n')

    input_rate = 19.2e6
    IF_freq = 5.75e6

    tb = gr.top_block()

    # Read from input file
    srcf = blocks.file_source(gr.sizeof_short, infile)

    # Convert interleaved shorts (I,Q,I,Q) to complex
    is2c = blocks.interleaved_short_to_complex()

    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE / 2.
    NTAPS = 279
    tt = filter.firdes.root_raised_cosine(1.0, input_rate / 3, symbol_rate,
                                          .1152, NTAPS)
    rrc = filter.fir_filter_ccf(1, tt)

    # Interpolate Filter our 6MHz wide signal centered at 0
    ilp_coeffs = filter.firdes.low_pass(1, input_rate, 3.2e6, .5e6,
                                        filter.firdes.WIN_HAMMING)
    ilp = filter.interp_fir_filter_ccf(3, ilp_coeffs)

    # Move the center frequency to 5.75MHz ( this won't be needed soon )
    duc_coeffs = filter.firdes.low_pass(1, 19.2e6, 9e6, 1e6,
                                        filter.firdes.WIN_HAMMING)
    duc = filter.freq_xlating_fir_filter_ccf(1, duc_coeffs, -5.75e6, 19.2e6)

    # fpll input is float
    c2f = blocks.complex_to_float()

    # Phase locked loop
    fpll = atsc.fpll()

    # Clean fpll output
    lp_coeffs2 = filter.firdes.low_pass(1.0, input_rate, 5.75e6, 120e3,
                                        filter.firdes.WIN_HAMMING)
    lp_filter = filter.fir_filter_fff(1, lp_coeffs2)

    # Remove pilot ( at DC now )
    iir = filter.single_pole_iir_filter_ff(1e-5)
    remove_dc = blocks.sub_ff()

    # Bit Timing Loop, Field Sync Checker and Equalizer
    btl = atsc.bit_timing_loop()
    fsc = atsc.fs_checker()
    eq = atsc.equalizer()
    fsd = atsc.field_sync_demux()

    # Viterbi
    viterbi = atsc.viterbi_decoder()
    deinter = atsc.deinterleaver()
    rs_dec = atsc.rs_decoder()
    derand = atsc.derandomizer()
    depad = atsc.depad()

    # Write to output file
    outf = blocks.file_sink(gr.sizeof_char, outfile)

    # Connect it all together
    tb.connect(srcf, is2c, rrc, ilp, duc, c2f, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc, 0))
    tb.connect(iir, (remove_dc, 1))
    tb.connect(remove_dc, btl)
    tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0))
    tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1))
    tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, outf)

    tb.run()