Added colorbar to spectrogram for magnitude measurement.
[debian/gnuradio] / gr-utils / src / python / usrp_fft.py
index bdec44ce57c408d0898d44d853b13cd0eb6b5c95..4aa70adab9e3bb9085136ca26a046a9e6edc4e61 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007 Free Software Foundation, Inc.
+# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -28,7 +28,7 @@ from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form,
 from optparse import OptionParser
 import wx
 import sys
-
+import numpy
 
 def pick_subdevice(u):
     """
@@ -37,9 +37,9 @@ def pick_subdevice(u):
     If there's a daughterboard on B, select B.
     Otherwise, select A.
     """
-    if u.db[0][0].dbid() >= 0:       # dbid is < 0 if there's no d'board or a problem
+    if u.db(0, 0).dbid() >= 0:       # dbid is < 0 if there's no d'board or a problem
         return (0, 0)
-    if u.db[1][0].dbid() >= 0:
+    if u.db(0, 0).dbid() >= 0:
         return (1, 0)
     return (0, 0)
 
@@ -64,23 +64,41 @@ class app_top_block(stdgui2.std_top_block):
         parser.add_option("-f", "--freq", type="eng_float", default=None,
                           help="set frequency to FREQ", metavar="FREQ")
         parser.add_option("-g", "--gain", type="eng_float", default=None,
-                          help="set gain in dB (default is midpoint)")
+                          help="set gain in dB [default is midpoint]")
         parser.add_option("-W", "--waterfall", action="store_true", default=False,
                           help="Enable waterfall display")
         parser.add_option("-8", "--width-8", action="store_true", default=False,
                           help="Enable 8-bit samples across USB")
+        parser.add_option( "--no-hb", action="store_true", default=False,
+                          help="don't use halfband filter in usrp")
         parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
                           help="Enable oscilloscope display")
+       parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
+                         help="Set fftsink averaging factor, [default=%default]")
+       parser.add_option("", "--ref-scale", type="eng_float", default=13490.0,
+                         help="Set dBFS=0dB input value, [default=%default]")
+        parser.add_option("", "--fft-size", type="int", default=1024,
+                          help="Set FFT frame size, [default=%default]");
+
         (options, args) = parser.parse_args()
         if len(args) != 0:
             parser.print_help()
             sys.exit(1)
-
+       self.options = options
         self.show_debug_info = True
         
         # build the graph
+        if options.no_hb or (options.decim<8):
+          #Min decimation of this firmware is 4. 
+          #contains 4 Rx paths without halfbands and 0 tx paths.
+          self.fpga_filename="std_4rx_0tx.rbf"
+          self.u = usrp.source_c(which=options.which, decim_rate=options.decim, fpga_filename=self.fpga_filename)
+        else:
+          #Min decimation of standard firmware is 8. 
+          #standard fpga firmware "std_2rxhb_2tx.rbf" 
+          #contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+          self.u = usrp.source_c(which=options.which, decim_rate=options.decim)
 
-        self.u = usrp.source_c(which=options.which, decim_rate=options.decim)
         if options.rx_subdev_spec is None:
             options.rx_subdev_spec = pick_subdevice(self.u)
         self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
@@ -100,16 +118,19 @@ class app_top_block(stdgui2.std_top_block):
 
         if options.waterfall:
             self.scope = \
-              waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate)
+              waterfallsink2.waterfall_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate)
         elif options.oscilloscope:
             self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
         else:
-            self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, sample_rate=input_rate)
+            self.scope = fftsink2.fft_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate, 
+                                             ref_scale=options.ref_scale, ref_level=0.0, y_divs = 10,
+                                             avg_alpha=options.avg_alpha)
 
         self.connect(self.u, self.scope)
 
         self._build_gui(vbox)
-
+       self._setup_events()
+       
         # set initial values
 
         if options.gain is None:
@@ -233,7 +254,9 @@ class app_top_block(stdgui2.std_top_block):
             if self.show_debug_info:
                 self.myform['baseband'].set_value(r.baseband_freq)
                 self.myform['ddc'].set_value(r.dxc_freq)
-            return True
+           if not self.options.oscilloscope:
+               self.scope.win.set_baseband_freq(target_freq)
+           return True
 
         return False
 
@@ -252,6 +275,32 @@ class app_top_block(stdgui2.std_top_block):
             self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
         return ok
 
+    def _setup_events(self):
+       if not self.options.waterfall and not self.options.oscilloscope:
+           self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
+           
+    def evt_left_dclick(self, event):
+       (ux, uy) = self.scope.win.GetXY(event)
+       if event.CmdDown():
+           # Re-center on maximum power
+           points = self.scope.win._points
+           if self.scope.win.peak_hold:
+               if self.scope.win.peak_vals is not None:
+                   ind = numpy.argmax(self.scope.win.peak_vals)
+               else:
+                   ind = int(points.shape()[0]/2)
+           else:
+               ind = numpy.argmax(points[:,1])
+            (freq, pwr) = points[ind]
+           target_freq = freq/self.scope.win._scale_factor
+           print ind, freq, pwr
+            self.set_freq(target_freq)            
+       else:
+           # Re-center on clicked frequency
+           target_freq = ux/self.scope.win._scale_factor
+           self.set_freq(target_freq)
+           
+       
 def main ():
     app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1)
     app.MainLoop()