From 6e8f5922b826213c976cd36c7411fd315ef7f456 Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Thu, 6 Oct 2011 12:01:46 -0400
Subject: Added FFF version of pfb_arb_resampler to Python hier block (where
 only the rate is required).

---
 .../python/gnuradio/blks2impl/pfb_arb_resampler.py | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)

(limited to 'gnuradio-core/src/python/gnuradio/blks2impl')

diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
index 62f40582e6..3aadf700b6 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
@@ -73,3 +73,56 @@ class pfb_arb_resampler_ccf(gr.hier_block2):
 
     def set_rate(self, rate):
         self.pfb.set_rate(rate)
+
+
+class pfb_arb_resampler_fff(gr.hier_block2):
+    '''
+    Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+    The block takes a single float stream in and outputs a single float
+    stream out. As such, it requires no extra glue to handle the input/output
+    streams. This block is provided to be consistent with the interface to the
+    other PFB block.
+    '''
+    def __init__(self, rate, taps=None, flt_size=32, atten=100):
+	gr.hier_block2.__init__(self, "pfb_arb_resampler_fff",
+				gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+				gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+        
+        self._rate = rate
+        self._size = flt_size
+
+        if taps is not None:
+            self._taps = taps
+        else:
+            # Create a filter that covers the full bandwidth of the input signal
+            bw = 0.4
+            tb = 0.2
+            ripple = 0.1
+            #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten)
+            made = False
+            while not made:
+                try:
+                    self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten)
+                    made = True
+                except RuntimeError:
+                    ripple += 0.01
+                    made = False
+                    print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+                    # Build in an exit strategy; if we've come this far, it ain't working.
+                    if(ripple >= 1.0):
+                        raise RuntimeError("optfir could not generate an appropriate filter.")
+
+        self.pfb = gr.pfb_arb_resampler_fff(self._rate, self._taps, self._size)
+        #print "PFB has %d taps\n" % (len(self._taps),)
+        
+        self.connect(self, self.pfb)
+        self.connect(self.pfb, self)
+
+    # Note -- set_taps not implemented in base class yet
+    def set_taps(self, taps):
+        self.pfb.set_taps(taps)
+
+    def set_rate(self, rate):
+        self.pfb.set_rate(rate)
-- 
cgit v1.2.3


From 408868b41f0c81168199a531aab4db426f9e5d23 Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Thu, 6 Oct 2011 13:47:24 -0400
Subject: Formatting and normalizing freq limits.

---
 .../src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py | 136 ++++++++++++---------
 1 file changed, 81 insertions(+), 55 deletions(-)

(limited to 'gnuradio-core/src/python/gnuradio/blks2impl')

diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py
index 858b9cde6a..3a93a11d64 100755
--- a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py
@@ -28,8 +28,9 @@ class wfm_rcv_fmdet(gr.hier_block2):
         """
         Hierarchical block for demodulating a broadcast FM signal.
         
-        The input is the downconverted complex baseband signal (gr_complex).
-        The output is two streams of the demodulated audio (float) 0=Left, 1=Right.
+        The input is the downconverted complex baseband signal
+        (gr_complex).  The output is two streams of the demodulated
+        audio (float) 0=Left, 1=Right.
         
         @param demod_rate: input sample rate of complex baseband input.
         @type demod_rate: float
@@ -39,16 +40,15 @@ class wfm_rcv_fmdet(gr.hier_block2):
 	gr.hier_block2.__init__(self, "wfm_rcv_fmdet",
 				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
 				gr.io_signature(2, 2, gr.sizeof_float))      # Output signature
-        lowfreq = -125e3
-	highfreq = 125e3
+        lowfreq = -125e3/demod_rate
+	highfreq = 125e3/demod_rate
         audio_rate = demod_rate / audio_decimation
 
-
-        # We assign to self so that outsiders can grab the demodulator 
+        # We assign to self so that outsiders can grab the demodulator
         # if they need to.  E.g., to plot its output.
         #
         # input: complex; output: float
-            
+        
         self.fm_demod = gr.fmdet_cf (demod_rate, lowfreq, highfreq, 0.05)
 
         # input: float; output: float
@@ -62,25 +62,31 @@ class wfm_rcv_fmdet(gr.hier_block2):
                                            15000 ,
                                            width_of_transition_band,
                                            gr.firdes.WIN_HAMMING)
+
         # input: float; output: float
         self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
         if 1:
-            # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain
-            # We pick off the negative frequency half because we want to base band by it!
-            ##  NOTE  THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS
+            # Pick off the stereo carrier/2 with this filter. It
+            # attenuated 10 dB so apply 10 dB gain We pick off the
+            # negative frequency half because we want to base band by
+            # it!
+            ##  NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO
+            ##  DEEMPHASIS
 
             stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0,
-                                                                   demod_rate,
-                                                                   -19020,
-                                                                   -18980,
-                                                                   width_of_transition_band,
-                                                                   gr.firdes.WIN_HAMMING)
+                                                                       demod_rate,
+                                                                       -19020,
+                                                                       -18980,
+                                                                       width_of_transition_band,
+                                                                       gr.firdes.WIN_HAMMING)
             
             #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
             #print "stereo carrier filter ", stereo_carrier_filter_coeffs
             #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
 
-            # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain
+            # Pick off the double side band suppressed carrier
+            # Left-Right audio. It is attenuated 10 dB so apply 10 dB
+            # gain
 
             stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0,
                                                                      demod_rate,
@@ -90,101 +96,121 @@ class wfm_rcv_fmdet(gr.hier_block2):
                                                                      gr.firdes.WIN_HAMMING)
             #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
             #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
-            # construct overlap add filter system from coefficients for stereo carrier
 
-            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
-
-            # carrier is twice the picked off carrier so arrange to do a commplex multiply
+            # construct overlap add filter system from coefficients
+            # for stereo carrier
+            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation,
+                                                           stereo_carrier_filter_coeffs)
 
+            # carrier is twice the picked off carrier so arrange to do
+            # a commplex multiply
             self.stereo_carrier_generator = gr.multiply_cc();
 
             # Pick off the rds signal
-
             stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0,
-                                                                     demod_rate,
-                                                                     57000 - 1500,
-                                                                     57000 + 1500,
-                                                                     width_of_transition_band,
-                                                                     gr.firdes.WIN_HAMMING)
+                                                                   demod_rate,
+                                                                   57000 - 1500,
+                                                                   57000 + 1500,
+                                                                   width_of_transition_band,
+                                                                   gr.firdes.WIN_HAMMING)
             #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
             #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
             # construct overlap add filter system from coefficients for stereo carrier
 
-	    self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs)
-
-
-
-
-
-
+	    self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation,
+                                                       stereo_rds_filter_coeffs)
 	    self.rds_carrier_generator = gr.multiply_cc();
 	    self.rds_signal_generator = gr.multiply_cc();
 	    self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex);
 
-
-
             alpha = 5 * 0.25 * math.pi / (audio_rate)
             beta = alpha * alpha / 4.0
             max_freq = -2.0*math.pi*18990/audio_rate;
-            min_freq = -2.0*math.pi*19010/audio_rate;
+            min_freq = -2.0*math.pi*19010/audio_rate;          
+            self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,
+                                                                max_freq,
+                                                                min_freq);
+
+            #self.stereo_carrier_pll_recovery.squelch_enable(False)
+            ##pll_refout does not have squelch yet, so disabled for
+            #now
             
-            self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq);
-            #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now 
-            
-
-            # set up mixer (multiplier) to get the L-R signal at baseband
+            # set up mixer (multiplier) to get the L-R signal at
+            # baseband
 
             self.stereo_basebander = gr.multiply_cc();
 
-            # pick off the real component of the basebanded L-R signal.  The imaginary SHOULD be zero
+            # pick off the real component of the basebanded L-R
+            # signal.  The imaginary SHOULD be zero
 
             self.LmR_real = gr.complex_to_real();
             self.Make_Left = gr.add_ff();
             self.Make_Right = gr.sub_ff();
             
-            self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs)
+            self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation,
+                                                         stereo_dsbsc_filter_coeffs)
 
 
         if 1:
 
-            # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier
-            self.connect (self, self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0))
+            # send the real signal to complex filter to pick off the
+            # carrier and then to one side of a multiplier
+            self.connect (self, self.fm_demod, self.stereo_carrier_filter,
+                          self.stereo_carrier_pll_recovery, 
+                          (self.stereo_carrier_generator,0))
+
             # send the already filtered carrier to the otherside of the carrier
+            # the resulting signal from this multiplier is the carrier
+            # with correct phase but at -38000 Hz.
             self.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
-            # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz.
 
             # send the new carrier to one side of the mixer (multiplier)
             self.connect (self.stereo_carrier_generator, (self.stereo_basebander,0))
+
             # send the demphasized audio to the DSBSC pick off filter,  the complex
             # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
-            self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
             # the result is BASEBANDED DSBSC with phase zero!
+            self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
 
-            # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer
+            # Pick off the real part since the imaginary is
+            # theoretically zero and then to one side of a summer
             self.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
-            #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter
+
+            #take the same real part of the DSBSC baseband signal and
+            #send it to negative side of a subtracter
             self.connect (self.LmR_real,(self.Make_Right,1))
 
-	    # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone
+	    # Make rds carrier by taking the squared pilot tone and
+	    # multiplying by pilot tone
 	    self.connect (self.stereo_basebander,(self.rds_carrier_generator,0))
             self.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) 
-	    # take signal, filter off rds,  send into mixer 0 channel
+
+	    # take signal, filter off rds, send into mixer 0 channel
 	    self.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
-            # take rds_carrier_generator output and send into mixer 1 channel
+
+            # take rds_carrier_generator output and send into mixer 1
+            # channel
 	    self.connect (self.rds_carrier_generator,(self.rds_signal_generator,1))
-	    # send basebanded rds signal and send into "processor" which for now is a null sink
+
+	    # send basebanded rds signal and send into "processor"
+	    # which for now is a null sink
 	    self.connect (self.rds_signal_generator,self_rds_signal_processor)
 	    
 
         if 1:
-            # pick off the audio, L+R that is what we used to have and send it to the summer
+            # pick off the audio, L+R that is what we used to have and
+            # send it to the summer
             self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
-            # take the picked off L+R audio and send it to the PLUS side of the subtractor
+
+            # take the picked off L+R audio and send it to the PLUS
+            # side of the subtractor
             self.connect(self.audio_filter,(self.Make_Right, 0))
+
             # The result of  Make_Left  gets    (L+R) +  (L-R) and results in 2*L
             # The result of Make_Right gets  (L+R) - (L-R) and results in 2*R
             self.connect(self.Make_Left , self.deemph_Left, (self, 0))
             self.connect(self.Make_Right, self.deemph_Right, (self, 1))
+
         # NOTE: mono support will require variable number of outputs in hier_block2s
         # See ticket:174 in Trac database
         #else:
-- 
cgit v1.2.3


From 9e1810646ae9253ee8346cedbc0168a4956f7f1e Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Fri, 7 Oct 2011 17:39:33 -0400
Subject: uhd: adding uhd_rx_nogui app to uhd apps directory.

---
 .../src/python/gnuradio/blks2impl/fm_demod.py      |   2 +-
 gr-uhd/apps/Makefile.am                            |   3 +-
 gr-uhd/apps/uhd_rx_nogui.py                        | 233 +++++++++++++++++++++
 3 files changed, 236 insertions(+), 2 deletions(-)
 create mode 100755 gr-uhd/apps/uhd_rx_nogui.py

(limited to 'gnuradio-core/src/python/gnuradio/blks2impl')

diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py
index 1910b50117..55870513aa 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py
@@ -88,7 +88,7 @@ class demod_20k0f3e_cf(fm_demod_cf):
         fm_demod_cf.__init__(self, channel_rate, audio_decim,
                              5000,	# Deviation
                              3000,	# Audio passband frequency
-                             4000)	# Audio stopband frequency
+                             4500)	# Audio stopband frequency
 
 class demod_200kf3e_cf(fm_demod_cf):
     """
diff --git a/gr-uhd/apps/Makefile.am b/gr-uhd/apps/Makefile.am
index c1ee0ff054..c30a143c2e 100644
--- a/gr-uhd/apps/Makefile.am
+++ b/gr-uhd/apps/Makefile.am
@@ -32,4 +32,5 @@ bin_SCRIPTS = \
 	uhd_fft.py 		\
 	uhd_rx_cfile.py		\
 	uhd_siggen.py		\
-	uhd_siggen_gui.py
+	uhd_siggen_gui.py	\
+	uhd_rx_nogui.py
diff --git a/gr-uhd/apps/uhd_rx_nogui.py b/gr-uhd/apps/uhd_rx_nogui.py
new file mode 100755
index 0000000000..6f860b820a
--- /dev/null
+++ b/gr-uhd/apps/uhd_rx_nogui.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2011 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, uhd, optfir, audio, blks2
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+"""
+This example application demonstrates receiving and demodulating 
+different types of signals using the USRP. 
+
+A receive chain is built up of the following signal processing
+blocks:
+
+USRP  - Daughter board source generating complex baseband signal.
+CHAN  - Low pass filter to select channel bandwidth
+RFSQL - RF squelch zeroing output when input power below threshold
+AGC   - Automatic gain control leveling signal at [-1.0, +1.0]
+DEMOD - Demodulation block appropriate to selected signal type.
+        This converts the complex baseband to real audio frequencies,
+	and applies an appropriate low pass decimating filter.
+CTCSS - Optional tone squelch zeroing output when tone is not present.
+RSAMP - Resampler block to convert audio sample rate to user specified
+        sound card output rate.
+AUDIO - Audio sink for playing final output to speakers.
+
+The following are required command line parameters:
+
+-f FREQ		USRP receive frequency
+-m MOD		Modulation type, select from AM, FM, or WFM
+
+The following are optional command line parameters:
+
+-R SUBDEV       Daughter board specification, defaults to first found
+-c FREQ         Calibration offset.  Gets added to receive frequency.
+                Defaults to 0.0 Hz.
+-g GAIN         Daughterboard gain setting. Defaults to mid-range.
+-o RATE         Sound card output rate. Defaults to 32000. Useful if
+                your sound card only accepts particular sample rates.
+-r RFSQL	RF squelch in db. Defaults to -50.0.
+-p FREQ		CTCSS frequency.  Opens squelch when tone is present.
+
+Once the program is running, ctrl-break (Ctrl-C) stops operation.
+
+Please see fm_demod.py and am_demod.py for details of the demodulation
+blocks.
+"""
+
+# (device_rate, channel_rate, audio_rate, channel_pass, channel_stop, demod)
+demod_params = {
+		'AM'  : (256e3,  16e3, 16e3,  5000,   8000, blks2.demod_10k0a3e_cf),
+		'FM'  : (256e3,  32e3,  8e3,  8000,   9000, blks2.demod_20k0f3e_cf),
+		'WFM' : (320e3, 320e3, 32e3, 80000, 115000, blks2.demod_200kf3e_cf)
+	       }
+
+class uhd_src(gr.hier_block2):
+    """
+    Create a UHD source object supplying complex floats.
+    
+    Selects user supplied subdevice or chooses first available one.
+
+    Calibration value is the offset from the tuned frequency to 
+    the actual frequency.       
+    """
+    def __init__(self, address, samp_rate, gain=None, calibration=0.0):
+	gr.hier_block2.__init__(self, "uhd_src",
+				gr.io_signature(0, 0, 0),                    # Input signature
+				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+        self._src = uhd.usrp_source(device_addr=address,
+                                    io_type=uhd.io_type.COMPLEX_FLOAT32,
+                                    num_channels=1)
+
+        self._src.set_samp_rate(samp_rate)
+	dev_rate = self._src.get_samp_rate()
+        self._samp_rate = samp_rate
+        
+        # Resampler to get to exactly samp_rate no matter what dev_rate is
+        self._rrate = samp_rate / dev_rate
+        self._resamp = blks2.pfb_arb_resampler_ccf(self._rrate)
+        
+	# If no gain specified, set to midrange
+	if gain is None:
+	    g = self._src.get_gain_range()
+	    gain = (g.start()+g.stop())/2.0
+            print "Using gain: ", gain
+        self._src.set_gain(gain)
+            
+        self._cal = calibration
+	self.connect(self._src, self._resamp, self)
+
+    def tune(self, freq):
+        r = self._src.set_center_freq(freq+self._cal, 0)
+
+    def rate(self):
+        return self._samp_rate
+        
+class app_top_block(gr.top_block):
+    def __init__(self, options):
+	gr.top_block.__init__(self)
+	self.options = options
+
+	(dev_rate, channel_rate, audio_rate,
+	 channel_pass, channel_stop, demod) = demod_params[options.modulation]
+
+        DEV = uhd_src(options.address,          # UHD device address
+                      dev_rate,         	# device sample rate
+                      options.gain, 	    	# Receiver gain
+                      options.calibration)      # Frequency offset
+	DEV.tune(options.frequency)
+
+	if_rate = DEV.rate()
+        channel_decim = int(if_rate // channel_rate)
+	audio_decim = int(channel_rate // audio_rate)
+
+	CHAN_taps = optfir.low_pass(1.0,          # Filter gain
+                                    if_rate, 	  # Sample rate
+                                    channel_pass, # One sided modulation bandwidth
+                                    channel_stop, # One sided channel bandwidth
+                                    0.1, 	  # Passband ripple
+                                    60) 	  # Stopband attenuation
+
+	CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate
+	                                      CHAN_taps,     # Filter taps
+					      0.0, 	     # Offset frequency
+					      if_rate)	     # Sample rate
+
+	RFSQL = gr.pwr_squelch_cc(options.rf_squelch,    # Power threshold
+	                          125.0/channel_rate, 	 # Time constant
+				  int(channel_rate/20),  # 50ms rise/fall
+				  False)		 # Zero, not gate output
+
+	AGC = gr.agc_cc(1.0/channel_rate,  # Time constant
+			1.0,     	   # Reference power 
+			1.0,               # Initial gain
+			1.0)		   # Maximum gain
+
+	DEMOD = demod(channel_rate, audio_decim)
+
+	# From RF to audio
+        #self.connect(DEV, CHAN, RFSQL, AGC, DEMOD)
+        self.connect(DEV, CHAN, DEMOD)
+
+	# Optionally add CTCSS and RSAMP if needed
+	tail = DEMOD
+	if options.ctcss != None and options.ctcss > 60.0:
+	    CTCSS = gr.ctcss_squelch_ff(audio_rate,    # Sample rate
+				        options.ctcss) # Squelch tone
+	    self.connect(DEMOD, CTCSS)
+	    tail = CTCSS
+
+	if options.output_rate != audio_rate:
+	    out_lcm = gru.lcm(audio_rate, options.output_rate)
+	    out_interp = int(out_lcm // audio_rate)
+	    out_decim = int(out_lcm // options.output_rate)
+	    RSAMP = blks2.rational_resampler_fff(out_interp, out_decim)
+	    self.connect(tail, RSAMP)
+	    tail = RSAMP 
+
+	# Send to audio output device
+        AUDIO = audio.sink(int(options.output_rate),
+                           options.audio_output)
+	self.connect(tail, AUDIO)
+	
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-a", "--address", type="string",
+                      default="addr=192.168.10.2",
+                      help="Address of UHD device, [default=%default]")
+    parser.add_option("-A", "--antenna", type="string", default=None,
+                      help="select Rx Antenna where appropriate [default=%default]")
+    parser.add_option("-f", "--frequency", type="eng_float",
+                      default=None, metavar="Hz",
+                      help="set receive frequency to Hz [default=%default]")
+    parser.add_option("-c",   "--calibration", type="eng_float",
+                      default=0.0, metavar="Hz",
+                      help="set frequency offset to Hz [default=%default]")
+    parser.add_option("-g", "--gain", type="int",
+                      metavar="dB", default=None,
+                      help="set RF gain [default is midpoint]")
+    parser.add_option("-m", "--modulation", type="choice", choices=('AM','FM','WFM'),
+                      metavar="TYPE", default=None,
+                      help="set modulation type (AM,FM) [default=%default]")
+    parser.add_option("-o", "--output-rate", type="eng_float",
+                      default=32000, metavar="RATE",
+                      help="set audio output rate to RATE [default=%default]")
+    parser.add_option("-r", "--rf-squelch", type="eng_float",
+                      default=-50.0, metavar="dB",
+                      help="set RF squelch to dB [default=%default]")
+    parser.add_option("-p", "--ctcss", type="float",
+                      default=None, metavar="FREQ",
+		      help="set CTCSS squelch to FREQ [default=%default]")
+    parser.add_option("-O", "--audio-output", type="string", default="",
+                      help="pcm device name.  E.g., hw:0,0 or surround51 or /dev/dsp")
+    (options, args) = parser.parse_args()
+
+    if options.frequency is None:
+	sys.stderr.write("Must supply receive frequency with -f.\n")
+	sys.exit(1)
+
+    if options.modulation is None:
+        sys.stderr.write("Must supply a modulation type (AM, FM, WFM).\n")
+        sys.exit(1)
+        
+    tb = app_top_block(options)
+    try:
+        tb.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == "__main__":
+    main()
-- 
cgit v1.2.3