commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r9152 - gnuradio/branches/features/experimental-gui


From: jcorgan
Subject: [Commit-gnuradio] r9152 - gnuradio/branches/features/experimental-gui
Date: Sat, 2 Aug 2008 12:35:15 -0600 (MDT)

Author: jcorgan
Date: 2008-08-02 12:35:13 -0600 (Sat, 02 Aug 2008)
New Revision: 9152

Removed:
   gnuradio/branches/features/experimental-gui/fft_controller.py
Modified:
   gnuradio/branches/features/experimental-gui/fft_top_block.py
   gnuradio/branches/features/experimental-gui/usrp_fft.py
Log:
Collapse fft_controller into fft_top_block.

Deleted: gnuradio/branches/features/experimental-gui/fft_controller.py

Modified: gnuradio/branches/features/experimental-gui/fft_top_block.py
===================================================================
--- gnuradio/branches/features/experimental-gui/fft_top_block.py        
2008-08-02 17:10:02 UTC (rev 9151)
+++ gnuradio/branches/features/experimental-gui/fft_top_block.py        
2008-08-02 18:35:13 UTC (rev 9152)
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 #
 # Copyright 2008 Free Software Foundation, Inc.
 #
@@ -19,17 +20,48 @@
 # Boston, MA 02110-1301, USA.
 #
 
+"""
+GNU Radio top block and controller interface to create a stream
+of FFT frames at a specified rate from a USRP.
+"""
+
 from gnuradio import gr, blks2
+from prop_val import prop_val_interface
+import threading
 import simple_usrp
 
-class fft_top_block(gr.top_block):
+class _fft_thread(threading.Thread):
+    """
+    This background thread simply reads FFT frames from the message
+    queue and sets the top block 'fft' property to their string
+    representation. External code can add one or more listeners to
+    this property to receive notification when an FFT frame comes in.
+    """
+    def __init__(self, msgq, tb):
+       threading.Thread.__init__(self)
+        self._msgq = msgq
+        self._tb = tb
+        self._keep_running = True
+       self.setDaemon(1)
+
+    def run(self):
+       while self._keep_running:
+           msg = self._msgq.delete_head()
+           self._tb['fft'] = msg.to_string()
+
+    def stop(self):
+        self._keep_running = False
+
+
+class fft_top_block(gr.top_block, prop_val_interface, threading.Thread):
     """!
     GNU Radio top block to create a stream of FFT frames at a particular
-    frame rate from a USRP. The frames are enqueued in a gr.msg_queue for
-    external retrieval.
+    frame rate from a USRP.
+    
+    Provides controller interface to dynamically set USRP decimation rate,
+    daughterboard gain, receive center frequency, and averaging.
 
-    Provides functions to dynamically set USRP decimation rate, daughterboard
-    gain, receive center frequency, and averaging. 
+    Add a listener to property 'fft' to get frames.
     """
     def __init__(self, 
                 fft_size=512,
@@ -63,8 +95,13 @@
         @param average              Whether to implement FFT averaging [True, 
False] (default is False)
         """
         
+        # Initialize parent classes
        gr.top_block.__init__(self, "fft_top_block")
-       
+        prop_val_interface.__init__(self)
+
+        """
+        Create a hierarchical flow graph
+        """
        self._u = simple_usrp.source_c(which=which,
                                       decim=decim,
                                       width_8=width_8,
@@ -81,38 +118,79 @@
                                       avg_alpha=avg_alpha,
                                       average=average)
 
-       self._msgq = gr.msg_queue(2)
+       self._msgq = gr.msg_queue(2)  # OK to discard if bg thread can't keep up
        self._sink = gr.message_sink(gr.sizeof_float*fft_size, self._msgq, True)
        
        self.connect(self._u, self._fft, self._sink)
 
-    # "Setters", which are called externally to affect flowgraph operation
-    def set_gain(self, gain):
-       return self._u.set_gain(gain)
+        """
+        Create controller interface
+        """
+       # Listeners are invoked when a property is set on the top block
+       self.add_listener('decim',       self._set_decim)
+        self.add_listener('gain',        lambda x: self._u.set_gain(x))
+        self.add_listener('freq',        lambda x: self._u.set_freq(x))
+        self.add_listener('average',     lambda x: self._fft.set_average(x))
+        self.add_listener('avg_alpha',   lambda x: self._fft.set_avg_alpha(x))
+
+       # Providers are invoked when a property is read on the top block
+       self.set_provider('sample_rate', lambda : self._u.sample_rate())
+        self.set_provider('average',     lambda : self._fft.average())
+        self.set_provider('avg_alpha',   lambda : self._fft.avg_alpha())
        
-    def set_freq(self, freq):
-       return self._u.set_freq(freq)
-       
-    def set_decim(self, decim):
+        """
+        Create update thread.  Updates property 'fft' at desired frame rate
+        """
+       self._thread = _fft_thread(self._msgq, self)
+
+    def _set_decim(self, decim):
+        """!
+        Listens to property 'decim'. Changes decimation rate and updates 
'sample_rate'
+        property (which triggers listeners on that property).
+        """
        self._u.set_decim(decim)
        self._fft.set_sample_rate(self._u.sample_rate())
 
-    def set_avg_alpha(self, avg_alpha):
-       return self._fft.set_avg_alpha(avg_alpha)
-       
-    def set_average(self, average):
-       return self._fft.set_average(average)
+    def on_init(self):
+       """
+       This method gets called by the external GUI or other code to start the 
top block
+       operation.
+       """
+       # Start the queue runner background thread
+       self._thread.start()
 
-    # Getters, which are called externally to get information about the 
flowgraph
-    def queue(self):
-       return self._msgq
+       # Using gr.top_block.start() here keeps Python's SIGINT handler active,
+       # and we agree to handle SIGINT in our code if needed.  We must also 
call
+       # gr.top_block.stop() and .wait() to properly shut down GNU Radio
+       self.start()            
 
-    def sample_rate(self):
-        return self._u.sample_rate()
+    def on_exit(self):
+       """
+       This method gets called to shutdown the top block.  It stops the 
background
+       thread, then calls stop() and wait() on the top block.
+       """
+        self._thread.stop()
+        self.stop()
+       self.wait()
 
-    def average(self):
-        return self._fft.average()
 
-    def avg_alpha(self):
-        return self._fft.avg_alpha()
+if __name__ == "__main__":
+    """
+    Example usage of fft_top_block.  Opens a file and adds a file writer as a 
listener
+    to the 'fft' property.
+    """
 
+    # Create the top block (uses all default parameters, needs a USRP attached)
+    tb = fft_top_block()
+
+    # Write fft frames to a file
+    f = open("fft.dat", "w")
+    tb.add_listener('fft', lambda x: f.write(x))
+
+    # Start the top block and wait for a key, then stop the top block
+    tb.on_init()
+    try:
+        raw_input("Press any key to exit.\n")
+    except KeyboardInterrupt:
+       print "Application interrupted."
+    tb.on_exit()

Modified: gnuradio/branches/features/experimental-gui/usrp_fft.py
===================================================================
--- gnuradio/branches/features/experimental-gui/usrp_fft.py     2008-08-02 
17:10:02 UTC (rev 9151)
+++ gnuradio/branches/features/experimental-gui/usrp_fft.py     2008-08-02 
18:35:13 UTC (rev 9152)
@@ -24,8 +24,8 @@
 from gnuradio.eng_option import eng_option
 import sys
 
-# Import the controller object
-from fft_controller import fft_controller
+# Import the top block object
+from fft_top_block import fft_top_block
 
 # Import the GUI object
 from fft_gui import fft_gui
@@ -66,31 +66,30 @@
 
     # Applications have a 2-step initialization
     
-    # Step 1: Create the application controller.  It will create
-    # the top block it manipulates.  The controller implements
-    # a property/value interface to allow setting, getting, and
-    # listening properties that affect the application operation.
-    controller = fft_controller(fft_size=512,
-                                frame_rate=10,
-                                ref_scale=50,
-                                which=options.which,
-                                decim=options.decim,
-                                width_8=options.width_8,
-                                no_hb=options.no_hb,
-                                subdev_spec=options.rx_subdev_spec,
-                                gain=options.gain,
-                                freq=options.freq,
-                                antenna=options.antenna,
-                                avg_alpha=options.avg_alpha,
-                                average=False)
+    # Step 1: Create the application top block.
+    # The top block implements a controller interface
+    # to allow setting, getting, and listening to properties 
+    # that affect the application operation.
+    tb = fft_top_block(fft_size=512,
+                       frame_rate=10,
+                       ref_scale=50,
+                       which=options.which,
+                       decim=options.decim,
+                       width_8=options.width_8,
+                       no_hb=options.no_hb,
+                       subdev_spec=options.rx_subdev_spec,
+                       gain=options.gain,
+                       freq=options.freq,
+                       antenna=options.antenna,
+                       avg_alpha=options.avg_alpha,
+                       average=False)
 
-    # Step 2: Create the GUI and pass it the controller
+    # Step 2: Create the GUI and pass it the top block
     # to manipulate.  The GUI code doesn't know anything about GNU
     # Radio proper; it simply gets, sets, or listens to properties
-    # on the controller.  The 'GUI' can actually be a CLI batch
+    # on the top block.  The 'GUI' can actually be a CLI batch
     # program, an interactive shell, or anything that knows what to
-    # do with the controller properties.
+    # do with the the top block properties.
     #
-    gui = fft_gui(controller)
+    gui = fft_gui(tb, 'USRP FFT')
     gui.run()
-





reply via email to

[Prev in Thread] Current Thread [Next in Thread]