def __init__(self,delay_num,delay_denom): gr.hier_block2.__init__(self,"moms_block", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(1,1,gr.sizeof_gr_complex)) cmplx_to_real = gr.complex_to_real() cmplx_to_img = gr.complex_to_imag() iirf_real = gr.iir_filter_ffd([1.5],[1, -0.5]) self.moms_real = moms_ff() self.moms_real.set_init_ip_fraction(delay_num,delay_denom) iirf_imag = gr.iir_filter_ffd([1.5],[1, -0.5]) self.moms_imag = moms_ff() self.moms_imag.set_init_ip_fraction(delay_num,delay_denom) float_to_cmplx = gr.float_to_complex() self.connect((self,0), (cmplx_to_real,0)) self.connect((self,0), (cmplx_to_img,0)) self.connect((cmplx_to_real,0), (iirf_real,0)) self.connect((cmplx_to_img,0), (iirf_imag,0)) self.connect((iirf_real,0), (self.moms_real,0)) self.connect((iirf_imag,0), (self.moms_imag,0)) self.connect((self.moms_real,0), (float_to_cmplx,0)) self.connect((self.moms_imag,0), (float_to_cmplx,1)) self.connect((float_to_cmplx,0), (self,0))
def __init__(self, audio_rate): gr.hier_block2.__init__( self, "standard_squelch", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature self.input_node = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.9524, -0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff( 1 / (0.01 * audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.3597, -0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1 / (0.01 * audio_rate)) self.sub = gr.sub_ff() self.add = gr.add_ff() self.gate = gr.threshold_ff(0.3, 0.43, 0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1 / (0.01 * audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.multiply_ff() self.connect(self, self.input_node) self.connect(self.input_node, (self.squelch_mult, 0)) self.connect(self.input_node, self.low_iir) self.connect(self.low_iir, (self.low_square, 0)) self.connect(self.low_iir, (self.low_square, 1)) self.connect(self.low_square, self.low_smooth, (self.sub, 0)) self.connect(self.low_smooth, (self.add, 0)) self.connect(self.input_node, self.hi_iir) self.connect(self.hi_iir, (self.hi_square, 0)) self.connect(self.hi_iir, (self.hi_square, 1)) self.connect(self.hi_square, self.hi_smooth, (self.sub, 1)) self.connect(self.hi_smooth, (self.add, 1)) self.connect(self.sub, (self.div, 0)) self.connect(self.add, (self.div, 1)) self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult, 1)) self.connect(self.squelch_mult, self)
def __init__(self, fg, fs, tau=75e-6): """ @param fg: flow graph @type fg: gr.flow_graph @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ w_p = 1/tau w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq a1 = (w_pp - 1)/(w_pp + 1) b0 = w_pp/(1 + w_pp) b1 = b0 btaps = [b0, b1] ataps = [1, a1] if 0: print "btaps =", btaps print "ataps =", ataps global plot1 plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) deemph = gr.iir_filter_ffd(btaps, ataps) gr.hier_block.__init__(self, fg, deemph, deemph)
def __init__(self, fs, tau=75e-6): """ @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ gr.hier_block2.__init__( self, "fm_deemph", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature # FIXME make this compute the right answer btaps = [1] ataps = [1] if 0: print "btaps =", btaps print "ataps =", ataps global plot2 plot2 = gru.gnuplot_freqz(gru.freqz(btaps, ataps), fs, True) preemph = gr.iir_filter_ffd(btaps, ataps) self.connect(self, preemph, self)
def __init__(self, fs, tau=75e-6): """ @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ gr.hier_block2.__init__(self, "fm_deemph", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature w_p = 1/tau w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq a1 = (w_pp - 1)/(w_pp + 1) b0 = w_pp/(1 + w_pp) b1 = b0 btaps = [b0, b1] ataps = [1, a1] if 0: print "btaps =", btaps print "ataps =", ataps global plot1 plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) deemph = gr.iir_filter_ffd(btaps, ataps) self.connect(self, deemph, self)
def __init__(self, fs, tau=75e-6): """ @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ gr.hier_block2.__init__( self, "fm_deemph", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature w_p = 1 / tau w_pp = math.tan(w_p / (fs * 2)) # prewarped analog freq a1 = (w_pp - 1) / (w_pp + 1) b0 = w_pp / (1 + w_pp) b1 = b0 btaps = [b0, b1] ataps = [1, a1] if 0: print "btaps =", btaps print "ataps =", ataps global plot1 plot1 = gru.gnuplot_freqz(gru.freqz(btaps, ataps), fs, True) deemph = gr.iir_filter_ffd(btaps, ataps) self.connect(self, deemph, self)
def __init__(self, fs, tau=75e-6): """ @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ gr.hier_block2.__init__(self, "fm_deemph", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature # FIXME make this compute the right answer btaps = [1] ataps = [1] if 0: print "btaps =", btaps print "ataps =", ataps global plot2 plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) preemph = gr.iir_filter_ffd(btaps, ataps) self.connect(self, preemph, self)
def __init__(self, audio_rate): gr.hier_block2.__init__(self, "standard_squelch", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature self.input_node = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.sub = gr.sub_ff(); self.add = gr.add_ff(); self.gate = gr.threshold_ff(0.3,0.43,0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.multiply_ff() self.connect (self, self.input_node) self.connect (self.input_node, (self.squelch_mult, 0)) self.connect (self.input_node,self.low_iir) self.connect (self.low_iir,(self.low_square,0)) self.connect (self.low_iir,(self.low_square,1)) self.connect (self.low_square,self.low_smooth,(self.sub,0)) self.connect (self.low_smooth, (self.add,0)) self.connect (self.input_node,self.hi_iir) self.connect (self.hi_iir,(self.hi_square,0)) self.connect (self.hi_iir,(self.hi_square,1)) self.connect (self.hi_square,self.hi_smooth,(self.sub,1)) self.connect (self.hi_smooth, (self.add,1)) self.connect (self.sub, (self.div, 0)) self.connect (self.add, (self.div, 1)) self.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) self.connect (self.squelch_mult, self)
def test_iir_direct_005(self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2, 11, 0) fbtaps = (0, -1, 3) expected_result = (2, 13, 21, 59, 58, 186, 68, 583) src = gr.vector_source_f(src_data) op = gr.iir_filter_ffd(fftaps, fbtaps) dst = gr.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data)
def test_iir_direct_004(self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2, 11) fbtaps = (0, -1) expected_result = (2, 13, 15, 26, 28, 39, 41, 52) src = gr.vector_source_f(src_data) op = gr.iir_filter_ffd(fftaps, fbtaps) dst = gr.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data)
def test_iir_direct_002(self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2, ) fbtaps = (0, ) expected_result = (2, 4, 6, 8, 10, 12, 14, 16) src = gr.vector_source_f(src_data) op = gr.iir_filter_ffd(fftaps, fbtaps) dst = gr.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data)
def __init__(self, fg, audio_rate): self.input_node = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.sub = gr.sub_ff(); self.add = gr.add_ff(); self.gate = gr.threshold_ff(0.3,0.43,0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.multiply_ff() fg.connect (self.input_node, (self.squelch_mult, 0)) fg.connect (self.input_node,self.low_iir) fg.connect (self.low_iir,(self.low_square,0)) fg.connect (self.low_iir,(self.low_square,1)) fg.connect (self.low_square,self.low_smooth,(self.sub,0)) fg.connect (self.low_smooth, (self.add,0)) fg.connect (self.input_node,self.hi_iir) fg.connect (self.hi_iir,(self.hi_square,0)) fg.connect (self.hi_iir,(self.hi_square,1)) fg.connect (self.hi_square,self.hi_smooth,(self.sub,1)) fg.connect (self.hi_smooth, (self.add,1)) fg.connect (self.sub, (self.div, 0)) fg.connect (self.add, (self.div, 1)) fg.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) gr.hier_block.__init__(self, fg, self.input_node, self.squelch_mult)
def test_iir_direct_004 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2, 11) fbtaps = (0, -1) expected_result = (2, 13, 15, 26, 28, 39, 41, 52) src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) dst = gr.vector_sink_f () self.tb.connect (src, op) self.tb.connect (op, dst) self.tb.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def test_iir_direct_005 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2, 11, 0) fbtaps = (0, -1, 3) expected_result = (2, 13, 21, 59, 58, 186, 68, 583) src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) dst = gr.vector_sink_f () self.tb.connect (src, op) self.tb.connect (op, dst) self.tb.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def test_iir_direct_002 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) fftaps = (2,) fbtaps = (0,) expected_result = (2, 4, 6, 8, 10, 12, 14, 16) src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) dst = gr.vector_sink_f () self.tb.connect (src, op) self.tb.connect (op, dst) self.tb.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def test_iir_direct_008 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) expected_result = (2,4,4,10,18,14,26,56) fftaps = (2,) fbtaps = (0, 1) src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) fftaps_data = (1) fbtaps = (0,0, -1,3) op.set_taps (fftaps, fbtaps) dst = gr.vector_sink_f () self.fg.connect (src, op) self.fg.connect (op, dst) self.fg.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def test_iir_direct_007 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) expected_result = (2,2,5,5,8,8,11,11) fftaps = [2, 1] fbtaps = [0, -1] src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) fftaps = [2,0,1] fbtaps = [0, -1] op.fftaps = fftaps op.fbtaps = fbtaps dst = gr.vector_sink_f () self.tb.connect (src, op) self.tb.connect (op, dst) self.tb.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def __init__(self, fg): self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([.004, 0], [0, .999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() fg.connect(self.split, (self.agc, 0)) fg.connect(self.split, (self.sqr, 0)) fg.connect(self.split, (self.sqr, 1)) fg.connect(self.sqr, self.int0) fg.connect(self.int0, self.log) fg.connect(self.log, self.offs) fg.connect(self.offs, self.gain) fg.connect(self.gain, (self.agc, 1)) gr.hier_block.__init__(self, fg, self.split, self.agc)
def __init__(self, fg): self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([0.004, 0], [0, 0.999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() fg.connect(self.split, (self.agc, 0)) fg.connect(self.split, (self.sqr, 0)) fg.connect(self.split, (self.sqr, 1)) fg.connect(self.sqr, self.int0) fg.connect(self.int0, self.log) fg.connect(self.log, self.offs) fg.connect(self.offs, self.gain) fg.connect(self.gain, (self.agc, 1)) gr.hier_block.__init__(self, fg, self.split, self.agc)
def __init__(self): gr.hier_block2.__init__(self, "agc", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([.004, 0], [0, .999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() self.connect(self, self.split) self.connect(self.split, (self.agc, 0)) self.connect(self.split, (self.sqr, 0)) self.connect(self.split, (self.sqr, 1)) self.connect(self.sqr, self.int0) self.connect(self.int0, self.log) self.connect(self.log, self.offs) self.connect(self.offs, self.gain) self.connect(self.gain, (self.agc, 1)) self.connect(self.agc, self)
def __init__(self, fg, fs, tau=75e-6): """ @param fg: flow graph @type fg: gr.flow_graph @param fs: sampling frequency in Hz @type fs: float @param tau: Time constant in seconds (75us in US, 50us in EUR) @type tau: float """ # FIXME make this compute the right answer btaps = [1] ataps = [1] if 0: print "btaps =", btaps print "ataps =", ataps global plot2 plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) preemph = gr.iir_filter_ffd(btaps, ataps) gr.hier_block.__init__(self, fg, preemph, preemph)
def __init__( self ): gr.hier_block2.__init__(self, "agc", gr.io_signature(1,1,gr.sizeof_float), gr.io_signature(1,1,gr.sizeof_float)) self.split = gr.multiply_const_ff( 1 ) self.sqr = gr.multiply_ff( ) self.int0 = gr.iir_filter_ffd( [.004, 0], [0, .999] ) self.offs = gr.add_const_ff( -30 ) self.gain = gr.multiply_const_ff( 70 ) self.log = gr.nlog10_ff( 10, 1 ) self.agc = gr.divide_ff( ) self.connect(self, self.split) self.connect(self.split, (self.agc, 0)) self.connect(self.split, (self.sqr, 0)) self.connect(self.split, (self.sqr, 1)) self.connect(self.sqr, self.int0) self.connect(self.int0, self.log) self.connect(self.log, self.offs) self.connect(self.offs, self.gain) self.connect(self.gain, (self.agc, 1)) self.connect(self.agc, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.tranwidth = tranwidth = 10000 self.tau = tau = 50e-6 self.gain = gain = 20 self.freq = freq = 100.0e6 self.decim = decim = 80 self.cutoff = cutoff = 100000 ################################################## # Blocks ################################################## self._tranwidth_text_box = forms.text_box( parent=self.GetWin(), value=self.tranwidth, callback=self.set_tranwidth, label="tranwidth", converter=forms.float_converter(), ) self.GridAdd(self._tranwidth_text_box, 1, 1, 1, 1) _tau_sizer = wx.BoxSizer(wx.VERTICAL) self._tau_text_box = forms.text_box( parent=self.GetWin(), sizer=_tau_sizer, value=self.tau, callback=self.set_tau, label="Zeitkonstante (Tau)", converter=forms.float_converter(), proportion=0, ) self._tau_slider = forms.slider( parent=self.GetWin(), sizer=_tau_sizer, value=self.tau, callback=self.set_tau, minimum=0, maximum=100e-6, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_tau_sizer) _gain_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, label="Gain [dB]", converter=forms.float_converter(), proportion=0, ) self._gain_slider = forms.slider( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, minimum=0, maximum=30, num_steps=60, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_gain_sizer) _freq_sizer = wx.BoxSizer(wx.VERTICAL) self._freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, label="Frequenz (UKW)", converter=forms.float_converter(), proportion=0, ) self._freq_slider = forms.slider( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, minimum=87.5e6, maximum=108e6, num_steps=205, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_freq_sizer, 0, 0, 1, 1) self._decim_text_box = forms.text_box( parent=self.GetWin(), value=self.decim, callback=self.set_decim, label="Decimation", converter=forms.float_converter(), ) self.GridAdd(self._decim_text_box, 1, 0, 1, 1) self._cutoff_text_box = forms.text_box( parent=self.GetWin(), value=self.cutoff, callback=self.set_cutoff, label="Cutoff", converter=forms.float_converter(), ) self.GridAdd(self._cutoff_text_box, 0, 1, 1, 1) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=64000000/decim, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="type=usrp1", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_subdev_spec("B:0", 0) self.uhd_usrp_source_0.set_samp_rate(64000000/decim) self.uhd_usrp_source_0.set_center_freq(freq, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.low_pass_filter_0_0 = gr.fir_filter_fff(1, firdes.low_pass( 1, 44100, 15000, tranwidth, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = gr.fir_filter_ccf(1, firdes.low_pass( 1, 64000000/decim, cutoff, tranwidth, firdes.WIN_HAMMING, 6.76)) self.gr_multiply_xx_0 = gr.multiply_vcc(1) self.gr_iir_filter_ffd_1 = gr.iir_filter_ffd(((1.0/(1+tau*2*800000), 1.0/(1+tau*2*800000))), ((1, -(1-tau*2*800000)/(1+tau*2*800000)))) self.gr_delay_0 = gr.delay(gr.sizeof_gr_complex*1, 1) self.gr_conjugate_cc_0 = gr.conjugate_cc() self.gr_complex_to_arg_0 = gr.complex_to_arg(1) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff( interpolation=44100, decimation=64000000/decim, taps=None, fractional_bw=None, ) self.audio_sink_0 = audio.sink(44100, "", True) ################################################## # Connections ################################################## self.connect((self.uhd_usrp_source_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_delay_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_delay_0, 0), (self.gr_conjugate_cc_0, 0)) self.connect((self.gr_conjugate_cc_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_complex_to_arg_0, 0)) self.connect((self.gr_complex_to_arg_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.gr_iir_filter_ffd_1, 0)) self.connect((self.gr_iir_filter_ffd_1, 0), (self.audio_sink_0, 0)) self.connect((self.gr_complex_to_arg_0, 0), (self.wxgui_fftsink2_0, 0))
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option("", "--address", type="string", default="addr=192.168.10.2", help="Address of UHD device, [default=%default]") parser.add_option("-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ") parser.add_option( "-s", "--samp-rate", type="eng_float", default=256e3, help="set sample rate (bandwidth) [default=%default]") parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option( "-O", "--audio-output", type="string", default="", help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse") (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq input_rate = options.samp_rate self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(input_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue( (self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = uhd.usrp_source(device_addr=options.address, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) self.src.set_samp_rate(input_rate) input_rate = self.src.get_samp_rate() self.src.set_center_freq(self.usrp_center, 0) self.tune_offset = 0 else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # save radio data to a file if SAVE_RADIO_TO_FILE: radio_file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, radio_file) # 2nd DDC xlate_taps = gr.firdes.low_pass ( \ 1.0, input_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING ) self.xlate = gr.freq_xlating_fir_filter_ccf ( \ fir_decim, xlate_taps, self.tune_offset, input_rate ) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.slider_fcutoff_hi.SetValue(0) self.slider_fcutoff_lo.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c(self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c(self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc(.5, .0625, (2. * math.pi * 7.5e3 / self.af_sample_rate), (2. * math.pi * 6.5e3 / self.af_sample_rate)) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() #AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([.004, 0], [0, .999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate), options.audio_output) if self.PLAY_FROM_USRP: self.tb.connect(self.src, self.xlate, self.fft) else: self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse) # and left click to re-tune self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option( "-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ" ) parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option("-d", "--decim", type="int", default=250, help="USRP decimation") parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=first one with a daughterboard)", ) (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq usb_rate = 64e6 / options.decim self.slider_range = usb_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(usb_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 / options.decim self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue((self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = usrp.source_s(decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.src) self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) self.src.tune(0, self.subdev, self.usrp_center) self.tune_offset = 0 # -self.usrp_center - self.src.rx_freq(0) else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # save radio data to a file if SAVE_RADIO_TO_FILE: file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, file) # 2nd DDC xlate_taps = gr.firdes.low_pass(1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING) self.xlate = gr.freq_xlating_fir_filter_ccf(fir_decim, xlate_taps, self.tune_offset, usb_rate) # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.slider_1.SetValue(0) self.slider_2.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c( self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240) ) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c( self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240), ) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc( 0.5, 0.0625, (2.0 * math.pi * 7.5e3 / self.af_sample_rate), (2.0 * math.pi * 6.5e3 / self.af_sample_rate) ) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() # AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([0.004, 0], [0, 0.999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate)) self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win) # and left click to re-tune em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def __init__(self, dab_params, rx_params, verbose=False, debug=False): """ Hierarchical block for OFDM demodulation @param dab_params DAB parameter object (dab.parameters.dab_parameters) @param rx_params RX parameter object (dab.parameters.receiver_parameters) @param debug enables debug output to files @param verbose whether to produce verbose messages """ self.dp = dp = dab_params self.rp = rp = rx_params self.verbose = verbose if self.rp.softbits: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature else: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.connect(self, self.input) # input filtering if self.rp.input_fft_filter: if verbose: print "--> RX filter enabled" lowpass_taps = gr.firdes_low_pass(1.0, # gain dp.sample_rate, # sampling rate rp.filt_bw, # cutoff frequency rp.filt_tb, # width of transition band gr.firdes.WIN_HAMMING) # Hamming window self.fft_filter = gr.fft_filter_ccc(1, lowpass_taps) # correct sample rate offset, if enabled if self.rp.autocorrect_sample_rate: if verbose: print "--> dynamic sample rate correction enabled" self.rate_detect_ns = detect_null.detect_null(dp.ns_length, False) self.rate_estimator = dab_swig.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) self.rate_prober = gr.probe_signal_f() self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober) # self.resample = gr.fractional_interpolator_cc(0, 1) self.resample = dab_swig.fractional_interpolator_triggered_update_cc(0,1) self.connect(self.rate_detect_ns, (self.resample,1)) self.updater = Timer(0.1,self.update_correction) # self.updater = threading.Thread(target=self.update_correction) self.run_interpolater_update_thread = True self.updater.setDaemon(True) self.updater.start() else: self.run_interpolater_update_thread = False if self.rp.sample_rate_correction_factor != 1: if verbose: print "--> static sample rate correction enabled" self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor) # timing and fine frequency synchronisation self.sync = ofdm_sync_dab2.ofdm_sync_dab(self.dp, self.rp, debug) # ofdm symbol sampler self.sampler = dab_swig.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap) # fft for symbol vectors self.fft = gr.fft_vcc(dp.fft_length, True, [], True) # coarse frequency synchronisation self.cfs = dab_swig.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length) # diff phasor self.phase_diff = dab_swig.diff_phasor_vcc(dp.num_carriers) # remove pilot symbol self.remove_pilot = dab_swig.ofdm_remove_first_symbol_vcc(dp.num_carriers) # magnitude equalisation if self.rp.equalize_magnitude: if verbose: print "--> magnitude equalization enabled" self.equalizer = dab_swig.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization) # frequency deinterleaving self.deinterleave = dab_swig.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array) # symbol demapping self.demapper = dab_swig.qpsk_demapper_vcb(dp.num_carriers) # # connect everything # if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1: self.connect(self.input, self.resample) self.input2 = self.resample else: self.input2 = self.input if self.rp.input_fft_filter: self.connect(self.input2, self.fft_filter, self.sync) else: self.connect(self.input2, self.sync) # data stream self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave) else: self.connect((self.remove_pilot,0), self.deinterleave) if self.rp.softbits: if verbose: print "--> using soft bits" self.softbit_interleaver = dab_swig.complex_to_interleaved_float_vcf(self.dp.num_carriers) self.connect(self.deinterleave, self.softbit_interleaver, (self,0)) else: self.connect(self.deinterleave, self.demapper, (self,0)) # control stream self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1)) else: self.connect((self.remove_pilot,1), (self,1)) # calculate an estimate of the SNR self.phase_var_decim = gr.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample) self.phase_var_arg = gr.complex_to_arg(dp.num_carriers) self.phase_var_v2s = gr.vector_to_stream(gr.sizeof_float, dp.num_carriers) self.phase_var_mod = dab_swig.modulo_ff(pi/2) self.phase_var_avg_mod = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.phase_var_sub_avg = gr.sub_ff() self.phase_var_sqr = gr.multiply_ff() self.phase_var_avg = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.probe_phase_var = gr.probe_signal_f() self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0)) self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1)) self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1)) self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var) # measure processing rate self.measure_rate = dab_swig.measure_processing_rate(gr.sizeof_gr_complex, 2000000) self.connect(self.input, self.measure_rate) # debugging if debug: self.connect(self.fft, gr.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat")) self.connect((self.cfs,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat")) self.connect(self.phase_diff, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat")) self.connect((self.remove_pilot,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat")) self.connect((self.remove_pilot,1), gr.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat")) self.connect(self.deinterleave, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat")) if self.rp.equalize_magnitude: self.connect(self.equalizer, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat")) if self.rp.softbits: self.connect(self.softbit_interleaver, gr.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat"))
def __init__(self, fg, fs, tau1=50e-6, f2): """ @param fg: flow graph @type fg: gr.flow_graph @param fs: sampling frequency in Hz @type fs: float @param tau1: Time constant in seconds (75us in US, 50us in EUR) @type tau1: float @param f2: cutoff frequency in Hz,choose f2 > f1 ( f1 is 2.12KHz in US, 3.2KHz in EUR) @type f2: float """ tau2=tau1/(2*math.pi*f2*tau1-1) w_1=1/tau1 w_2=1/tau2 w_p1=math.tan(w_1/(fs*2)) w_p2=math.tan(w_2/(fs*2)) b0=(w_p2+1)/(1+w_p1+w_p2) b1=(w_p2-1)/(1+w_p1+w_p2) a1=(w_p1+w_p2-1)/(w_p1+w_p2+1) btaps = [b0,b1] ataps = [1,a1] if 0: print "btaps =", btaps print "ataps =", ataps global plot2 plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) preemph = gr.iir_filter_ffd(10*btaps, ataps) gr.hier_block.__init__(self, fg, preemph, preemph)