commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r6483 - in grc/tags: . grc_0.69 grc_0.69/examples grc_


From: jblum
Subject: [Commit-gnuradio] r6483 - in grc/tags: . grc_0.69 grc_0.69/examples grc_0.69/notes grc_0.69/src grc_0.69/src/Graphics grc_0.69/src/SignalBlockDefs
Date: Wed, 19 Sep 2007 19:49:24 -0600 (MDT)

Author: jblum
Date: 2007-09-19 19:49:24 -0600 (Wed, 19 Sep 2007)
New Revision: 6483

Added:
   grc/tags/grc_0.69/
   grc/tags/grc_0.69/examples/
   grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml
   grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt
   grc/tags/grc_0.69/notes/release_notes.txt
   grc/tags/grc_0.69/notes/todo.txt
   grc/tags/grc_0.69/readme.txt
   grc/tags/grc_0.69/src/ActionHandler.py
   grc/tags/grc_0.69/src/Constants.py
   grc/tags/grc_0.69/src/ExecFlowGraph.py
   grc/tags/grc_0.69/src/Graphics/Dialogs.py
   grc/tags/grc_0.69/src/Graphics/FlowGraph.py
   grc/tags/grc_0.69/src/Graphics/MainWindow.py
   grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py
   grc/tags/grc_0.69/src/Preferences.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py
   grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py
   grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py
Removed:
   grc/tags/grc_0.69/examples/
   grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml
   grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt
   grc/tags/grc_0.69/notes/notes.txt
   grc/tags/grc_0.69/readme.txt
   grc/tags/grc_0.69/src/ActionHandler.py
   grc/tags/grc_0.69/src/Constants.py
   grc/tags/grc_0.69/src/ExecFlowGraph.py
   grc/tags/grc_0.69/src/Graphics/Dialogs.py
   grc/tags/grc_0.69/src/Graphics/FlowGraph.py
   grc/tags/grc_0.69/src/Graphics/MainWindow.py
   grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py
   grc/tags/grc_0.69/src/Preferences.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py
   grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py
   grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py
   grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py
Log:
tag grc 0.69

Copied: grc/tags/grc_0.69 (from rev 6211, grc/trunk)

Copied: grc/tags/grc_0.69/examples (from rev 6374, grc/trunk/examples)

Deleted: grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml

Copied: grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml (from rev 6449, 
grc/trunk/examples/packet_mod_demod.grc.xml)
===================================================================
--- grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml                         
(rev 0)
+++ grc/tags/grc_0.69/examples/packet_mod_demod.grc.xml 2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,215 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow_graph>
+  <timestamp>1189898583.51</timestamp>
+  <hostname>tiggle</hostname>
+  <version>0.69 beta</version>
+  <valid>True</valid>
+  <window_width>1600</window_width>
+  <window_height>1200</window_height>
+  <vars>
+    <var>
+      <key>samp_rate</key>
+      <value>100e3</value>
+      <min/>
+      <max/>
+      <step/>
+    </var>
+    <var>
+      <key>freq</key>
+      <value>500</value>
+      <min>0</min>
+      <max>1000</max>
+      <step>10.0</step>
+    </var>
+    <var>
+      <key>amp</key>
+      <value>1</value>
+      <min>0</min>
+      <max>2</max>
+      <step>0.02</step>
+    </var>
+    <var>
+      <key>off</key>
+      <value>0</value>
+      <min>-1</min>
+      <max>1</max>
+      <step>0.02</step>
+    </var>
+  </vars>
+  <signal_blocks>
+    <signal_block>
+      <tag>Note</tag>
+      <id>Note0</id>
+      <x_coordinate>408</x_coordinate>
+      <y_coordinate>270</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>A demonstration of the packet framework.</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Packet Demodulator</tag>
+      <id>Packet Demodulator0</id>
+      <x_coordinate>535</x_coordinate>
+      <y_coordinate>427</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param/>
+        <param>-1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink0</id>
+      <x_coordinate>219</x_coordinate>
+      <y_coordinate>402</y_coordinate>
+      <rotation>180</rotation>
+      <params>
+        <param>1</param>
+        <param>Output</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Signal Source</tag>
+      <id>Signal Source0</id>
+      <x_coordinate>26</x_coordinate>
+      <y_coordinate>354</y_coordinate>
+      <rotation>90</rotation>
+      <params>
+        <param>1</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>$freq</param>
+        <param>$amp</param>
+        <param>$off</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Scope Sink</tag>
+      <id>Scope Sink1</id>
+      <x_coordinate>125</x_coordinate>
+      <y_coordinate>178</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>Input</param>
+        <param>$samp_rate</param>
+        <param>1</param>
+        <param>0</param>
+        <param>0.001</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>GMSK Modulator</tag>
+      <id>GMSK Modulator0</id>
+      <x_coordinate>399</x_coordinate>
+      <y_coordinate>36</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>2</param>
+        <param>0.35</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>About</tag>
+      <id>About0</id>
+      <x_coordinate>480</x_coordinate>
+      <y_coordinate>176</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>Packet Mod/Demod</param>
+        <param>Josh Blum</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>GMSK Demodulator</tag>
+      <id>GMSK Demodulator0</id>
+      <x_coordinate>871</x_coordinate>
+      <y_coordinate>189</y_coordinate>
+      <rotation>270</rotation>
+      <params>
+        <param>2</param>
+        <param>0.05</param>
+        <param>0.5</param>
+        <param>0.005</param>
+        <param>0</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Throttle</tag>
+      <id>Throttle0</id>
+      <x_coordinate>703</x_coordinate>
+      <y_coordinate>36</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>0</param>
+        <param>$samp_rate*25</param>
+        <param>1</param>
+      </params>
+    </signal_block>
+    <signal_block>
+      <tag>Packet Modulator</tag>
+      <id>Packet Modulator0</id>
+      <x_coordinate>129</x_coordinate>
+      <y_coordinate>19</y_coordinate>
+      <rotation>0</rotation>
+      <params>
+        <param>1</param>
+        <param>2</param>
+        <param>1</param>
+        <param>512</param>
+        <param/>
+        <param>0</param>
+      </params>
+    </signal_block>
+  </signal_blocks>
+  <connections>
+    <connection>
+      <input_signal_block_id>Scope Sink1</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Scope Sink0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Packet Demodulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Packet Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Signal Source0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>GMSK Modulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Packet Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Packet Demodulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>GMSK Demodulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>Throttle0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>GMSK Modulator0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+    <connection>
+      <input_signal_block_id>GMSK Demodulator0</input_signal_block_id>
+      <input_socket_index>0</input_socket_index>
+      <output_signal_block_id>Throttle0</output_signal_block_id>
+      <output_socket_index>0</output_socket_index>
+    </connection>
+  </connections>
+</flow_graph>

Deleted: grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt

Copied: grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt (from rev 6478, 
grc/trunk/notes/creating_a_signal_block_def.txt)
===================================================================
--- grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt                     
        (rev 0)
+++ grc/tags/grc_0.69/notes/creating_a_signal_block_def.txt     2007-09-20 
01:49:24 UTC (rev 6483)
@@ -0,0 +1,213 @@
+###################################################################
+#      How to create a signal block definition - Josh Blum
+###################################################################
+#      Signal blocks in GRC are defined in python code. Each block gets its 
own method:
+def MySignalBlockDef(sb):
+       #       import any packages here and equate the actual gr constructor
+       #
+       #       This is good practice:
+       #       If a package or a block is not implemented in your version of 
GNU Radio, 
+       #       an ImportError or AttributeError will be caught,
+       #       and GRC can ignore this block. 
+       from gnuradio import blks
+       fcn = blks.some_hier_block
+       #       add input and output sockets
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Float())
+       #       add signal block parameters
+       sb.add_param('Sample Rate', Float(default_samp_rate))
+       sb.add_param('Decimation', Int(default_decim))
+       #       set a documentation string (optional)
+       sb.set_docs('''This is my block.''')
+       #       create a method to build the actual GNU Radio block.
+       #       The first parameter of this method must be the flow graph.
+       #       The proceeding parmeters coorespond to the parameters above.
+       def make(fg, samp_rate, decim):
+               #       create the signal block using fcn, and call every 
parameter's parse method
+               block = fcn(samp_rate.parse(), decim.parse())
+               #       add callbacks: callbacks are special methods of the 
signal block
+               #       that let us change parameters after the block is 
created.
+               #       If one of the parameters was based on a variable and 
had a callback method,
+               #       one could dynamically change the block's parameter(s) 
by changing the variable.
+               #       The first argument is the method, the second is the 
unparsed data type:
+               fg.add_callback(block.set_samp_rate, samp_rate)
+               return block #  return the block
+       #       end the definition by returning a tuple: graphical block, the 
make method
+       return sb, make
+#      This is a very basic framework. You can do anything with your signal 
block definition!
+#      Just make sure all methods return the right things and that the number 
of parameters matches up.
+
+###################################################################
+#      Add your block to the tree:
+###################################################################
+       Edit SignalBlockDefs/SignalBlockTree.py. 
+       Find your desired category and add the tuple to the tree:
+       ("My Signal Block's Name", MySignalBlockDef),
+       
+###################################################################
+#      Basic and Vector Data Types
+###################################################################
+
+Complex
+Float
+Int
+Short
+Byte
+
+ComplexVector
+FloatVector
+IntVector
+ShortVector
+ByteVector
+
+'''
+All of these data types share the same contructor, like so:
+Float(default_value, min, max)
+The default_value can be anything, it will be stored in the data type as a 
string.
+Preferably, the default value will be a numeric python object, 
+or a string representing a vector or a expression. 
+For the basic data types, the min and max parameters determine what values are 
considered valid.
+For the vector data types, the min and max parameters determine what vector 
lengths are considered valid.
+The min and the max must be floats or ints. 
+Also, do not use min and max for Complex, as this does not make sence and will 
always be invalid.
+'''
+
+
+###################################################################
+#      Enum and Bool Data Types
+###################################################################
+
+'''
+The Enum data types takes a finite list of choices. 
+The data type stores the index of the choice. 
+Parsing an Enum data type will return the choice at the stored index.
+'''
+
+example_enum = Enum([
+               ('Name of choice0', data0),
+               ('Name of choice1', data1),
+               ('Name of choice2', data2),
+       ], default_index)
+       
+'''
+The Bool data type is a special type of Enum, 
+with a choice for True and a choice for false.
+'''
+
+example_bool = Bool(true='Choose Yes', false='Choose No', default=True)
+
+
+###################################################################
+#      Variable Data Type
+###################################################################
+
+'''
+The variable data type can represent any of the basic or vector data types.
+By using this data type, one can change the data type of a socket or a 
parameter.
+A variable data type takes an Enum as its parameter. 
+This Enum must parse to one of the basic or vector data types.
+'''
+
+example_enum_of_data_types = Enum([
+               ('Float Out', Float()),
+               ('Complex Out', Complex()),
+       ])
+sb.add_param('Choose Output Type', example_enum_of_data_types) #allow the user 
to choose the data type
+sb.add_output_socket('out', Variable(example_enum_of_data_types))#the output 
socket is now variable
+
+'''
+Now to do something more complicated: 
+Suppose we want to use an Enum to control more than one variable, 
+but the variables need to be different types.
+The Enum can hold a tuple or a list for each choice.
+The Variable's index parameter specifies the index of this tuple.
+Essentially, the tuple can be filled with anything; however,
+the indecies that the Variable references must be basic or vector data types.
+'''
+
+example_enum_of_data_types = Enum([
+               ('Float -> Complex', (gr.block_fc, Float(), Complex())),
+               ('Short -> Float', (gr.block_sf, Short(), Float())),
+       ])
+sb.add_param('Choose IO Types', example_enum_of_data_types)    #allow the user 
to choose the data type
+sb.add_input_socket('out', Variable(example_enum_of_data_types, index=1))#the 
input socket uses 1st index
+sb.add_output_socket('out', Variable(example_enum_of_data_types, index=2))#the 
output socket uses 2nd index
+
+'''
+In the case above, the 0th index of the tuple holds a specific gr block.
+Again, specifying the actual gr block is good practice:
+If a package or a block is not implemented in your version of GNU Radio, 
+an ImportError or AttributeError will be caught,
+and GRC can ignore this block. 
+The gr block can be retrieved in the make method by calling type.parse()[0],
+(since parse will return the tuple, and [0] gets the 0th element).
+'''
+
+###################################################################
+#      Misc Data Types
+###################################################################
+
+String
+FileOpen
+FileSave
+
+'''
+A String data type can take on any value and will always be valid. 
+The String data type is good for specifying names and titles.
+
+The FileOpen data type stores a file path as a string. 
+It will only be valid if its string represents a file path to an existing file.
+
+The FileSave data type stores a file path as a string. 
+It will only be valid if its string represents a file path with existing 
directories.
+'''
+
+###################################################################
+#      Special socket options
+###################################################################
+
+'''
+The methods add_input_socket and add_output_socket have two additional 
parameters: optional and vlen.
+The "optional" parameter is a boolean value which is "False" by default. 
+If the value is "True", the socket will pass validation even if it is left 
unconnected.
+
+The "vlen" parameter is an Int data type which is None by default. 
+If the value is an Int, the socket's data type will be vectorized when the Int 
is greater than 1.
+(Vectorized means that a Complex data type will become ComplexVector and so 
on...)
+'''
+
+#Usage
+sb.add_input_socket(cname, data_type, optional=False, vlen=None)
+
+###################################################################
+#      Special param options
+###################################################################
+
+'''
+The method add param has four additional parameters: show_label, type, I/O 
controllers
+
+The "show_label" parameter is a boolean value which is "True" by default.
+If the value is "False", this block's parameter will not be drawn into the 
block's label.
+It saves space on the flow graph by not drawing redundant parameters.
+A parameter is redundant when its effect is seen on the block.
+Ex: A Enum controlling the output data type changes the color of the output 
socket. 
+
+The "type" parameter is a boolean value which is "False" by default.
+If the value is "True", Up and Down hotkeys will increment and decrement the 
value.
+Warning: The "type" parameter should only be used with the Enum data type.
+Useful for changing a block's data type with hotkeys.
+
+The "I/O_socket_controller" parameter is a boolean value which is "False" by 
default.
+If the value is "True", this block's parameter will control the number of 
input or output sockets (respectivly).
+Warning: The "I/O_socket_controller" parameter should only be used with the 
Integer data types (Int, Short, Byte).
+Useful for block with a dynamic number of inputs, like Add and Interleave.
+'''
+
+#Usage
+add_param(cname, data_type, show_label=True, type=False, 
output_sockets_controller=False, input_sockets_controller=False)
+
+###################################################################
+#      Final Notes
+###################################################################
+
+Please look through the src/SignalBlockDefs/*.py to see how all these 
components work together...

Deleted: grc/tags/grc_0.69/notes/notes.txt

Copied: grc/tags/grc_0.69/notes/release_notes.txt (from rev 6478, 
grc/trunk/notes/release_notes.txt)
===================================================================
--- grc/tags/grc_0.69/notes/release_notes.txt                           (rev 0)
+++ grc/tags/grc_0.69/notes/release_notes.txt   2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,19 @@
+This release: GRC 0.69, September 19th 2007
+
+Last release: GRC 0.65, March 20th 2007
+
+Compatibility: 
+       gnuradio trunk r6477 and subsequent revisions within a reasonable 
time-period
+       gnuradio 3.1 branch
+
+Fixes and New Features:
+       -rx on usrp side b works
+       -usrp flex rf options
+       -usrp dual source and sink
+       -selector/deselector block
+       -packet modulator and demodulator
+       -misc block fixes and additions
+       -tabbed windows
+       -execute a flow graph without graphics
+       -new math expressions, with filter functions
+

Copied: grc/tags/grc_0.69/notes/todo.txt (from rev 6482, 
grc/trunk/notes/todo.txt)
===================================================================
--- grc/tags/grc_0.69/notes/todo.txt                            (rev 0)
+++ grc/tags/grc_0.69/notes/todo.txt    2007-09-20 01:49:24 UTC (rev 6483)
@@ -0,0 +1,51 @@
+############   Blocks to Add:  ####################
+-ofdm (blks2)
+-cpm (blks2)
+-filterbank (blks2)
+-usrp quad souce, set z == 1 to ignore Q inputs 
+-multi-channel scope
+
+############   Known Problems: ####################
+-packet threads block on close
+-core abort with bad params to filter functions
+-blocks need to fix themselves when they go out of bounds, like in a resize
+-socket controllers should be intelligent on shrinkage
+-usrp transmit dies in lock/unlock
+-audio dies lock/unlock
+-channel model needs hier2
+
+############   Features to Add:        ####################
+-startup tips
+-math expr from file
+-save working directory after close
+-create sub-flow graphs to be used in larger flow graphs
+-include dtd in saved flow graphs
+-fm demod example with expansion of wfm_recv block
+
+############   wxPython Features:      ####################
+-dump wx running graph to png?
+-scroll box for graphs
+-dropdowns in wx graphics, for variable settings
+                 self.scaling_chooser = wx.Choice(self, -1, choices=['Linear 
Hz', 'Logarithmic Hz', 'LogHz'])
+        self.scaling_chooser.SetSelection(0) #default is linear hz
+        self.Bind(wx.EVT_CHOICE, self.scale, self.scaling_chooser)
+        selection = event.GetSelection()
+
+############   User Prefs:     ####################
+--save scrollbar positions (hidden pref)
+
+############   Uninteresting Features: ####################
+-add the concept of a current working directory
+-auto param to usrp diagnose dialog
+-use popen3 once it works in cygwin
+-arrow like images for socket, to replace in/out strings
+-min/max in DataTypes can be other data types
+-press enter to close params
+
+############   Get GTK Stock IDs:      ####################
+gtk.stock_list_ids()
+
+############   connect packet mod to demod:    ####################    
+gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+gr.unpack_k_bits_bb(self.bits_per_symbol())
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/readme.txt

Copied: grc/tags/grc_0.69/readme.txt (from rev 6478, grc/trunk/readme.txt)
===================================================================
--- grc/tags/grc_0.69/readme.txt                                (rev 0)
+++ grc/tags/grc_0.69/readme.txt        2007-09-20 01:49:24 UTC (rev 6483)
@@ -0,0 +1,14 @@
+Hello!
+
+Thank you for downloading GNU Radio Companion.
+This program is free software. 
+A GPL license is distributed with this program.
+This license covers all the source code/python files. 
+You will also find a "creative common license" for the grc icon.
+
+Intructions for GRC are available at:
+http://gnuradio.org/trac/wiki/GNURadioCompanion
+
+If you have questions, problems, suggestions, or want to contribute,
+please email me at jblum at jhu dot edu
+

Deleted: grc/tags/grc_0.69/src/ActionHandler.py

Copied: grc/tags/grc_0.69/src/ActionHandler.py (from rev 6460, 
grc/trunk/src/ActionHandler.py)
===================================================================
--- grc/tags/grc_0.69/src/ActionHandler.py                              (rev 0)
+++ grc/tags/grc_0.69/src/ActionHandler.py      2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,383 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden ActionHandler
+#ActionHandler builds the interface and handles most of the user inputs.       
        
address@hidden Josh Blum
+
+import os, sys
+from Constants import *
+from Actions import *
+import pygtk
+pygtk.require('2.0')
+import gtk
+import Graphics
+import Preferences
+from threading import Thread
+import Messages
+import ParseXML
+import random
+
+class ActionHandler:
+       """
+       The action handler will setup all the major window components,
+       and handle button presses and flow graph operations from the GUI.
+       """
+       
+       def __init__(self, file_paths): 
+               """!
+               ActionHandler constructor.
+               Create the main window, setup the message handler, import the 
preferences, 
+               and connect all of the action handlers. Finally, enter the gtk 
main loop and block.
+               @param file_paths a list of flow graph file passed from command 
line            
+               """                             
+               if PY_GTK_ICON: 
gtk.window_set_default_icon_from_file(PY_GTK_ICON)
+               for action in ACTIONS_LIST: action.connect('activate', 
self._handle_actions)
+               ### create the main window and setup the Messages       ###
+               self.main_window = Graphics.MainWindow(self.handle_states)
+               Preferences.load(self.main_window)
+               self.get_flow_graph = self.main_window.get_flow_graph
+               self.get_page = self.main_window.get_page
+               Messages.register_messenger(self.main_window.add_report_line)
+               Messages.register_messenger(sys.stdout.write)
+               Messages.send_init()
+               self.main_window.connect('delete_event', self._quit)
+               self.main_window.connect('key_press_event', 
self._handle_key_press)
+               #flow graph settings            
+               self.init_file_paths = file_paths
+               self.handle_states(APPLICATION_INITIALIZE)
+               # enter the mainloop            
+               gtk.gdk.threads_init()
+               gtk.gdk.threads_enter()
+               gtk.main()
+               gtk.gdk.threads_leave()         
+               
+       def _handle_key_press(self, widget, event):
+               """
+               Handle key presses from the keyboard.           
+               Translate key combos into actions.      
+               Key combinations that do not include special keys, such as ctrl 
or Fcn*,
+               Also, require that the flow graph has mouse focus when choosing 
to handle keys.
+               @return true if the flow graph is in active use
+               """
+               keyname = gtk.gdk.keyval_name(event.keyval)
+               #print 'Key "%s" (%d) was pressed' % (keyname, event.keyval)
+               #if event.state & gtk.gdk.CONTROL_MASK: print "Control was 
being held down"
+               #if event.state & gtk.gdk.MOD1_MASK: print "Alt was being held 
down"
+               #if event.state & gtk.gdk.SHIFT_MASK: print "Shift was being 
held down"         
+               ####################    save/open/new/undo/redo 
############################### 
+               if event.state & gtk.gdk.CONTROL_MASK and keyname == 's':
+                       self.handle_states(FLOW_GRAPH_SAVE)
+               elif event.state & gtk.gdk.CONTROL_MASK and keyname == 'z':
+                       self.handle_states(FLOW_GRAPH_UNDO)
+               elif event.state & gtk.gdk.CONTROL_MASK and (keyname in ('y', 
'Z')):
+                       self.handle_states(FLOW_GRAPH_REDO)
+               elif event.state & gtk.gdk.CONTROL_MASK and keyname == 'o':
+                       self.handle_states(FLOW_GRAPH_OPEN)
+               elif event.state & gtk.gdk.CONTROL_MASK and keyname == 'n':
+                       self.handle_states(FLOW_GRAPH_NEW)
+               ####################    Delete  ###############################
+               elif self.get_flow_graph().get_focus_flag() and keyname == 
'Delete':    #mouse focus
+                       self.handle_states(ELEMENT_DELETE)
+               ####################    Rotate  ###############################
+               elif self.get_flow_graph().get_focus_flag() and keyname == 
'Right': #mouse focus
+                       self.handle_states(SIGNAL_BLOCK_ROTATE_RIGHT)
+               elif self.get_flow_graph().get_focus_flag() and keyname == 
'Left': #mouse focus
+                       self.handle_states(SIGNAL_BLOCK_ROTATE_LEFT)
+               ####################    Data Type       
###############################
+               elif self.get_flow_graph().get_focus_flag() and keyname == 
'Down': #mouse focus
+                       self.handle_states(SIGNAL_BLOCK_INC_TYPE)
+               elif self.get_flow_graph().get_focus_flag() and keyname == 
'Up': #mouse focus
+                       self.handle_states(SIGNAL_BLOCK_DEC_TYPE)
+               ####################    Socket Controllers      
###############################         
+               elif self.get_flow_graph().get_focus_flag() and keyname in 
('equal','plus', 'KP_Add'): #mouse focus
+                       self.handle_states(SOCKET_CONTROLLER_INC)
+               elif self.get_flow_graph().get_focus_flag() and keyname in 
('minus', 'KP_Subtract'): #mouse focus
+                       self.handle_states(SOCKET_CONTROLLER_DEC)               
+               ####################    Exec/Stop/Print 
###############################
+               elif keyname == 'F5':
+                       self.handle_states(FLOW_GRAPH_EXEC)
+               elif keyname == 'F7':
+                       self.handle_states(FLOW_GRAPH_STOP)
+               elif keyname == 'Print':
+                       self.handle_states(FLOW_GRAPH_SCREEN_CAPTURE)
+               #propagate this if the fg is not in focus or nothing is selected
+               return self.get_flow_graph().get_focus_flag() and 
self.get_flow_graph().is_selected()
+        
+       def _quit(self, window, event):
+               """!
+               Handle the delete event from the main window.
+               Generated by pressing X to close, alt+f4, or right click+close. 
+               This method in turns calls the state handler to quit.
+               @return true            
+               """
+               self.handle_states(APPLICATION_QUIT)
+               return True     
+       
+       def _handle_actions(self, event):               
+               """
+               Handle all of the activate signals from the gtk actions. 
+               The action signals derive from clicking on a    toolbar or menu 
bar button. 
+               Forward the action to the state handler.
+               """
+               self.handle_states(event.get_name())            
+               
+       def handle_states(self, state=''):
+               """!
+               Handle the state changes in the GUI.            
+               Handle all of the state changes that arise from the action 
handler or other Graphics and 
+               inputs in the application. The state passed to the 
handle_states method is a string descriping 
+               the change. A series of if/elif statements handle the state by 
greying out action buttons, causing 
+               changes in the flow graph, saving/opening files...      The 
handle_states method is passed to the
+               contructors of many of the classes used in this application 
enabling them to report any state change.
+               @param state a string describing the state change
+               """
+               
##############################################################################################
+               #       Initalize/Quit
+               
##############################################################################################
+               if state == APPLICATION_INITIALIZE:     
+                       for action in ACTIONS_LIST: action.set_sensitive(False) 
#set all actions disabled
+                       # enable a select few actions 
+                       Graphics.enable_usrp_diagnostics()      #try to enable 
usrp diagnostics
+                       for action in (
+                               APPLICATION_QUIT, FLOW_GRAPH_NEW, 
FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS, FLOW_GRAPH_CLOSE,
+                               ABOUT_WINDOW_DISPLAY, 
DATA_TYPES_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY, MATH_EXPR_WINDOW_DISPLAY,
+                               FLOW_GRAPH_WINDOW_RESIZE, PREFS_WINDOW_DISPLAY, 
FLOW_GRAPH_SCREEN_CAPTURE,
+                       ): get_action_from_name(action).set_sensitive(True)     
        
+                       if not self.init_file_paths and 
Preferences.restore_files(): self.init_file_paths = Preferences.files_open()
+                       if not self.init_file_paths: self.init_file_paths = ['']
+                       for file_path in self.init_file_paths: 
self.main_window.new_page(file_path) #load pages from file paths
+                       if not self.get_page(): self.main_window.new_page() 
#ensure that at least a blank page exists
+               elif state == APPLICATION_QUIT:
+                       if self.main_window.close_pages():
+                               Preferences.save(self.main_window)
+                               gtk.main_quit()
+                               exit(0)
+               
##############################################################################################
+               #       Selections
+               
##############################################################################################
+               elif state == SIGNAL_BLOCK_SELECT or state == SOCKET_SELECT:
+                       for action in (ELEMENT_DELETE, 
SIGNAL_BLOCK_PARAM_MODIFY, SIGNAL_BLOCK_ROTATE_RIGHT, 
SIGNAL_BLOCK_ROTATE_LEFT): 
+                               get_action_from_name(action).set_sensitive(True)
+               elif state == CONNECTION_SELECT:
+                       get_action_from_name(ELEMENT_DELETE).set_sensitive(True)
+                       for action in (SIGNAL_BLOCK_PARAM_MODIFY, 
SIGNAL_BLOCK_ROTATE_RIGHT, SIGNAL_BLOCK_ROTATE_LEFT): 
+                               
get_action_from_name(action).set_sensitive(False)
+               elif state == NOTHING_SELECT:
+                       for action in (ELEMENT_DELETE, 
SIGNAL_BLOCK_PARAM_MODIFY, SIGNAL_BLOCK_ROTATE_RIGHT, 
SIGNAL_BLOCK_ROTATE_LEFT): 
+                               
get_action_from_name(action).set_sensitive(False)
+                       self.get_flow_graph().unselect()
+               
##############################################################################################
+               #       Move/Rotate/Delete/Create
+               
##############################################################################################
          
+               elif state == SIGNAL_BLOCK_MOVE:                        
+                       
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+                       self.get_page().set_saved(False)
+               elif state == SIGNAL_BLOCK_ROTATE_LEFT:
+                       if self.get_flow_graph().rotate_selected(DIR_LEFT):     
                        
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)                
+               elif state == SIGNAL_BLOCK_ROTATE_RIGHT:
+                       if self.get_flow_graph().rotate_selected(DIR_RIGHT):    
                        
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)                
+               elif state == ELEMENT_DELETE:
+                       if self.get_flow_graph().delete_selected():             
                
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
                                
+                               self.handle_states(NOTHING_SELECT)
+                               self.get_page().set_saved(False)
+               elif state == CONNECTION_CREATE or state == 
SIGNAL_BLOCK_CREATE:                        
+                       
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+                       self.handle_states(NOTHING_SELECT)      
+                       self.get_page().set_saved(False)
+               elif state == SIGNAL_BLOCK_INC_TYPE:
+                       if 
self.get_flow_graph().type_controller_modify_selected(1):
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)
+               elif state == SIGNAL_BLOCK_DEC_TYPE:
+                       if 
self.get_flow_graph().type_controller_modify_selected(-1):
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)        
+               elif state == SOCKET_CONTROLLER_INC:
+                       if 
self.get_flow_graph().socket_controller_modify_selected(1):
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)
+               elif state == SOCKET_CONTROLLER_DEC:
+                       if 
self.get_flow_graph().socket_controller_modify_selected(-1):
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)                
+               
##############################################################################################
+               #       Window stuff
+               
##############################################################################################
+               elif state == USRP_DIAGNOSTICS_DISPLAY:
+                       Graphics.USRPDiagnosticsDialog()                
+               elif state == PREFS_WINDOW_DISPLAY:
+                       Graphics.PreferencesDialog()
+                       self.get_flow_graph().update()
+               elif state == ABOUT_WINDOW_DISPLAY:
+                       Graphics.AboutDialog()
+               elif state == DATA_TYPES_WINDOW_DISPLAY:
+                       Graphics.DataTypesDialog()
+               elif state == HOTKEYS_WINDOW_DISPLAY:
+                       Graphics.HotKeysDialog()
+               elif state == MATH_EXPR_WINDOW_DISPLAY:
+                       Graphics.MathExprDialog()
+               elif state == FLOW_GRAPH_WINDOW_RESIZE:
+                       dimensions = 
Graphics.FlowGraphWindowSizeDialog(self.get_flow_graph().get_size_request()).run()
+                       if dimensions:
+                               
self.get_flow_graph().set_size_request(*dimensions)
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
                                        
+                               self.get_page().set_saved(False)
+               
##############################################################################################
+               #       Variable and Param Modifications
+               
##############################################################################################
+               elif state == SIGNAL_BLOCK_PARAM_MODIFY:
+                       if self.get_flow_graph().param_modify_selected():
+                               
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                               self.get_page().set_saved(False)                
+               elif state == VARIABLE_MODIFY:
+                       
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                       self.get_page().set_saved(False)        
+                       self.get_flow_graph().update()
+               elif state == VARIABLE_REORDER:
+                       
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
        
+                       self.get_page().set_saved(False)        
+               
##############################################################################################
+               #       Undo/Redo
+               
##############################################################################################
+               elif state == FLOW_GRAPH_UNDO:          
+                       nested_data = 
self.get_page().get_state_cache().get_prev_state()
+                       if nested_data  != None:                
+                               self.handle_states(NOTHING_SELECT)
+                               
self.get_flow_graph().from_nested_data(nested_data)
+                               self.get_page().set_saved(False)
+               elif state == FLOW_GRAPH_REDO:                                  
        
+                       nested_data = 
self.get_page().get_state_cache().get_next_state()
+                       if nested_data  != None:                
+                               self.handle_states(NOTHING_SELECT)
+                               
self.get_flow_graph().from_nested_data(nested_data)
+                               self.get_page().set_saved(False)
+               
##############################################################################################
+               #       New/Open/Save/Close
+               
##############################################################################################
+               elif state == FLOW_GRAPH_NEW:
+                       self.main_window.new_page()
+               elif state == FLOW_GRAPH_OPEN:
+                       file_path = 
Graphics.OpenFlowGraphFileDialog(self.get_flow_graph() and 
self.get_page().get_file_path() or '').run()
+                       if file_path != None: 
self.main_window.new_page(file_path)
+               elif state == FLOW_GRAPH_CLOSE:
+                       self.main_window.close_page()           
+               elif state == FLOW_GRAPH_SAVE:
+                       if not self.get_page().get_file_path(): 
self.handle_states(FLOW_GRAPH_SAVE_AS)
+                       else:
+                               try:
+                                       
ParseXML.to_file(ParseXML.to_xml(self.get_flow_graph().to_nested_data()), 
self.get_page().get_file_path())
+                                       self.get_page().set_saved(True)         
+                               except IOError: 
+                                       
Messages.send_fail_save(self.get_page().get_file_path())
+                                       self.get_page().set_saved(False)
+               elif state == FLOW_GRAPH_SAVE_AS:
+                       file_path = 
Graphics.SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
+                       if file_path != None:                   
+                               self.get_page().set_file_path(file_path)
+                               self.handle_states(FLOW_GRAPH_SAVE)     
+               elif state == FLOW_GRAPH_SCREEN_CAPTURE:
+                       file_path = 
Graphics.SaveImageFileDialog(self.get_page().get_file_path()).run()
+                       if file_path != None: 
+                               pixmap = self.get_flow_graph().pixmap
+                               width, height = pixmap.get_size()
+                               pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 
0, 8, width, height)
+                               pixbuf.get_from_drawable(pixmap, 
pixmap.get_colormap(), 0, 0, 0, 0, width, height)
+                               pixbuf.save(file_path, 
IMAGE_FILE_EXTENSION[1:])                                                
+               
##############################################################################################
+               #       Run/Stop
+               
##############################################################################################
          
+               elif state == FLOW_GRAPH_EXEC:
+                       if not self.get_page().get_pid_file():
+                               if not self.get_page().get_saved() or not 
self.get_page().get_file_path(): 
+                                       self.handle_states(FLOW_GRAPH_SAVE) 
#only save if file path missing or not saved
+                               if self.get_page().get_saved() and 
self.get_page().get_file_path(): 
+                                       ExecFlowGraphThread(self)       #only 
exec if file path and saved
+               elif state == FLOW_GRAPH_STOP:
+                       MUTEX.lock()
+                       if self.get_page().get_pid_file(): 
+                               try: 
os.kill(int(open(self.get_page().get_pid_file(), 'r').read()), 9)
+                               except: print "could not kill pid file: 
%s"%self.get_page().get_pid_file()
+                       MUTEX.unlock()
+               elif state == '': #pass and run the global actions
+                       pass
+               else: print '!!! State "%s" not handled !!!'%state
+               
##############################################################################################
+               #       Global Actions for all States
+               
##############################################################################################
+               #set the exec button if the flow graph is valid and is not 
already running
+               MUTEX.lock()
+               
get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(self.get_flow_graph().is_valid()
 and not self.get_page().get_pid_file())
+               
get_action_from_name(FLOW_GRAPH_STOP).set_sensitive(self.get_page().get_pid_file()
 != '')       
+               MUTEX.unlock()
+               #saved status           
+               get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(not 
self.get_page().get_saved())
+               self.main_window.update()                               
+                               
+class ExecFlowGraphThread(Thread):
+       """Execute the flow graph as a new process and wait on it to finish."""
+       def __init__ (self, action_handler):
+               """!
+               ExecFlowGraphThread constructor.
+               @param action_handler an instance of an ActionHandler
+               """
+               Thread.__init__(self)
+               self.handle_states = action_handler.handle_states
+               self.flow_graph = action_handler.get_flow_graph()
+               #store page and dont use main window calls in run
+               self.page = action_handler.get_page()
+               #random id so multiple flow graphs can run w/o files 
intersecting
+               rand_id = random.randint(10000, 99999) 
+               #set files              
+               self.file_path = self.page.get_file_path()
+               self.report_file = '/tmp/grc-%d-%d.report'%(os.getpid(), 
rand_id)
+               self.pid_file = '/tmp/grc-%d-%d.pid'%(os.getpid(), rand_id)     
        
+               self.page.set_pid_file(self.pid_file)
+               get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(False)
+               get_action_from_name(FLOW_GRAPH_STOP).set_sensitive(True)
+               Messages.send_start_exec(self.page.get_file_path())
+               self.start()
+               
+       def run(self):  
+               """Execute the flow graph."""
+               cmd = '%s "%s" --pid_file="%s" 2> "%s"'%(
+                       DEFAULT_FLOW_GRAPH_EXEC, 
+                       self.file_path, 
+                       self.pid_file, 
+                       self.report_file,
+               )
+               os.system(cmd)  
+               try:                                            
+                       report = open(self.report_file, 'r')    
+                       #       read all the lines of the report file into a 
list       #
+                       Messages.send_end_exec(report.readlines())
+                       report.close()  
+                       os.remove(self.report_file)
+               except IOError: print "could not read report file: 
%s"%self.report_file
+               try: os.remove(self.pid_file)
+               except: print "could not remove pid file: %s"%self.pid_file
+               MUTEX.lock()
+               self.page.set_pid_file('')
+               MUTEX.unlock()
+               self.handle_states()
+               

Deleted: grc/tags/grc_0.69/src/Constants.py

Copied: grc/tags/grc_0.69/src/Constants.py (from rev 6478, 
grc/trunk/src/Constants.py)
===================================================================
--- grc/tags/grc_0.69/src/Constants.py                          (rev 0)
+++ grc/tags/grc_0.69/src/Constants.py  2007-09-20 01:49:24 UTC (rev 6483)
@@ -0,0 +1,209 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Constants
+#Global constants
address@hidden Josh Blum
+
+import sys, os
+import mutex
+
+##mutex used when running a flow graph.
+MUTEX = mutex.mutex()  
+def lock(mutex):
+       while not mutex.testandset(): pass      #try to lock repeatedly until 
lock is aquired
+MUTEX.lock = lambda: lock(MUTEX)
+
+######################################################################################################
+## Global Titles @{
+######################################################################################################
+
+##The current version of this code
+VERSION = '0.69'
+
+##The name to appear in the main window for a flow graph that has not been 
saved to file.
+NEW_FLOGRAPH_TITLE = 'untitled'
+
+##The prefix title on the main window.
+MAIN_WINDOW_PREFIX = "GRC"
address@hidden
+
+######################################################################################################
+## Signal block connector lengths
+######################################################################################################
+
+##The length that a connection must extend from the socket until the length 
depends on the index of the socket.
+CONNECTOR_EXTENSION_INITIAL_LENGTH = 11
+
+##The length that a connection must extend from the initial length times the 
index of the socket, after this length, the connection may have a bend.
+CONNECTOR_EXTENSION_LENGTH = 11
+
+######################################################################################################
+## Signal block rotations
+######################################################################################################
+
+##List of possible angles (in degrees) that a signal block and its parameters 
can be rotated to.
+POSSIBLE_ROTATIONS = (0, 90, 180, 270)
+
+##direction of rotation left.
+DIR_LEFT = 'left'
+
+##direction of rotation right.
+DIR_RIGHT = 'right'
+
+######################################################################################################
+## Dimension constraints for the various windows (in pixels)
+######################################################################################################
+
+##main window constraints      @{
+DEFAULT_MAIN_WINDOW_WIDTH = 750
+
+DEFAULT_MAIN_WINDOW_HEIGHT = 550
address@hidden
+
+##flow graph window constraints        @{
+MIN_WINDOW_WIDTH = 600
+MAX_WINDOW_WIDTH = 2400
+
+MIN_WINDOW_HEIGHT = 400
+MAX_WINDOW_HEIGHT = 1800
address@hidden
+
+##dialog constraints   @{
+MIN_DIALOG_WIDTH = 400
+MIN_DIALOG_HEIGHT = 500
address@hidden
+
+##misc window constraints      @{
+REPORTS_WINDOW_HEIGHT = 80
+
+SIGNAL_BLOCK_SELECTION_WINDOW_WIDTH = 250
+SIGNAL_BLOCK_SELECTION_WINDOW_HEIGHT = 250
+
+VARIABLE_MODIFICATION_WINDOW_WIDTH = 250
+VARIABLE_MODIFICATION_WINDOW_HEIGHT = 150
address@hidden
+
+######################################################################################################
+## Constraints for the sliders in the runnable flow graph @{
+######################################################################################################
+
+##The number of tics for a slider.
+DEFAULT_SLIDER_STEPS = 100
+
+##The max width that a row of sliders can use.
+MAX_SLIDERS_WIDTH = 600
+
+##Slider width in pixels
+DEFAULT_SLIDER_WIDTH = 200
+##Slider width in pixels
+MAX_SLIDER_WIDTH = 300
+##Slider width in pixels
+MIN_SLIDER_WIDTH = 100
+
+##The height in pixels.
+SLIDER_HEIGHT = 20
address@hidden
+
+######################################################################################################
+## Constraints on displayable labels and sockets @{
+######################################################################################################
+
+LABEL_SEPARATION = 4
+LABEL_PADDING_WIDTH=20
+LABEL_PADDING_HEIGHT=10
+
+SOCKET_SEPARATION = 20
+SOCKET_HEIGHT = 17
+SOCKET_WIDTH = 27
+SOCKET_BORDER_SEPARATION = 10
+
+PARAM_FONT = 'Sans 8'
+SIGNAL_BLOCK_FONT = 'Sans 9 Bold'
+SOCKET_FONT = 'Sans 8'
address@hidden
+
+######################################################################################################
+## Dragging, scrolling, and redrawing constants for the flow graph window in 
pixels @{
+######################################################################################################
+
+##How close can the mouse get to the window border before mouse events are 
ignored.
+BORDER_PROXIMITY_SENSITIVITY = 10
+
+##How close the mouse can get to the edge of the visible window before 
scrolling is invoked.
+SCROLL_PROXIMITY_SENSITIVITY = 30
+
+##When the window has to be scrolled, move it this distance in the required 
direction.
+SCROLL_DISTANCE = 15
+
+##The redrawing sensitivity, how many motion detection events must occur 
before a redraw?
+MOTION_DETECT_REDRAWING_SENSITIVITY = 3
+
+##How close the mouse click can be to a connection and register a connection 
select.
+CONNECTION_SELECT_SENSITIVITY = 5
address@hidden
+
+######################################################################################################
+#      A state is recorded for each change to the flow graph, the size 
dictates how many states we can record 
+######################################################################################################
+
+##The size of the state saving cache in the flow graph (for undo/redo 
functionality)
+STATE_CACHE_SIZE = 42
+
+######################################################################################################
+## Constansts dealing with File Paths @{
+######################################################################################################
+
+##Location of the python src directory.
+SRC_DIR = os.path.abspath(os.path.dirname(__file__))
+
+##Location of external data files.
+DATA_DIR = os.path.abspath(SRC_DIR+'/../data/')
+
+##The setting for a blank flow graph.
+INITIAL_FLOW_GRAPH_FILE = 
os.path.abspath(DATA_DIR+'/initial_flow_graph.grc.xml')
+
+##The default file extension for flow graphs.
+FLOW_GRAPH_FILE_EXTENSION = '.grc.xml'
+
+##The default file extension for saving flow graph snap shots.
+IMAGE_FILE_EXTENSION = '.png'
+
+##The default path for the open/save dialogs.
+DEFAULT_FILE_PATH = os.path.expanduser('~')+'/'
+
+##The default icon for the gtk windows.
+PY_GTK_ICON = os.path.abspath(DATA_DIR+'/grc-icon-256.png')
+
+##The default icon for the wx windows.
+WX_APP_ICON = os.path.abspath(DATA_DIR+'/grc-icon-32.png')
+#>>> platform dependency! wx under cygwin has issues with icon paths   #
+if sys.platform == 'cygwin': WX_APP_ICON = None
+
+##The default binary to execute python files.
+PYEXEC = 'python'
+#>>> platform dependency! MacOS requires pythonw to run wx apps        #
+if sys.platform == 'darwin': PYEXEC = 'pythonw'
+
+##The default command to run a flow graph file.
+DEFAULT_FLOW_GRAPH_EXEC = '%s %s/ExecFlowGraphGUI.py'%(PYEXEC, SRC_DIR)
+
+##The default user preferences file.
+PREFERENCES_FILE_PATH = os.path.abspath(DEFAULT_FILE_PATH + '/.grc.xml')
address@hidden
+

Deleted: grc/tags/grc_0.69/src/ExecFlowGraph.py

Copied: grc/tags/grc_0.69/src/ExecFlowGraph.py (from rev 6347, 
grc/trunk/src/ExecFlowGraph.py)
===================================================================
--- grc/tags/grc_0.69/src/ExecFlowGraph.py                              (rev 0)
+++ grc/tags/grc_0.69/src/ExecFlowGraph.py      2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,196 @@
+#! /usr/bin/env python
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden ExecFlowGraph 
+#Use an xml input file to build and run a gnu radio flow graph without 
graphics.
address@hidden Josh Blum
+
+import ParseXML
+import Variables
+from Elements import SignalBlock
+from gnuradio import gr
+import os
+from Constants import FLOW_GRAPH_FILE_EXTENSION,MUTEX
+from optparse import OptionParser
+
+##############################################################################################
+#      Flow Graph Builder
+##############################################################################################
 
+class FlowGraphBuilder(gr.top_block):
+       """ Parse the input file to build the gnuradio flow graph.
+               Register the variables, handle signal block callbacks.  """
+               
+       def __init__(self, file_path):          
+               gr.top_block.__init__(self, file_path)  
+               #internal data structures               
+               self.callbacks = list()
+               self.callbacks_locked = list()
+               self.callbacks_cond = list()
+               self.var_keys = list()          
+               self.started = False
+               #build the flow graph
+               
self._parse_nested_data(ParseXML.from_xml(ParseXML.from_file(file_path)))       
+               
+       def _start(self):
+               """Start the flow graph."""
+               self.start()
+               self.started = True
+               
+       def _stop(self):
+               """Stop the flow graph."""
+               self.stop()
+               self.started = False
+                       
+       def add_window(self, *args):
+               """Empty method for adding a window in the GUI flow graph."""
+               pass
+               
+       def get_panel(self):
+               """Empty method for getting the wx panel in the GUI flow 
graph.""" 
+               print """
+Graphical Sinks are not supported in ExecFlowGraph.py:
+ use ExecFlowGraphGUI.py [-d] or remove the Graphical Sink.
+Exiting!"""
+               exit(-1)
+               
+       def add_callback(self, function, *data_type_params):
+               """
+               Register a callback function with its associated data.
+               @param function the callback function
+               @param data_type_params a list of data types
+               """
+               self.callbacks.append((function, data_type_params))
+               
+       def add_callback_locked(self, function, *data_type_params):
+               """
+               Register a "locked" callback function with its associated data.
+               These callbacks will be called inside of a lock/unlock sequence.
+               @param function the callback function
+               @param data_type_params a list of data types
+               """
+               self.callbacks_locked.append((function, data_type_params))
+               
+       def add_callback_cond(self, function, *data_type_params):
+               """
+               Register a "conditional" callback function with its associated 
data.
+               These callbacks will be called inside of a lock/unlock sequence
+               only if at least one locked callback has been registered.
+               @param function the callback function
+               @param data_type_params a list of data types
+               """
+               self.callbacks_cond.append((function, data_type_params))
+               
+       def _parse_callback(self, function, *data_type_params):
+               """
+               Parse a single callback. Call function on the data types.
+               @param function the callback function
+               @param data_type_params a list of data types
+               """
+               #print "***\nBegin A callback\n%s\n\n***"%function
+               try: function(*map(lambda param: param.parse(), 
data_type_params))
+               except Exception, e: print "***\n\nerror parsing a callback -> 
ignoring\n%s...\n\n***"%e
+               #print "***\nEnd A callback\n***"               
+               
+       def parse_callbacks(self):
+               """For each call back, parse all of the data and 
+               call the registered callback function on that data."""
+               #MUTEX.lock()
+               #print "***\n\nCallback Time BEGIN\n\n***"
+               if self.started:                        
+                       if self.callbacks:      #parse regular callbacks
+                               for function, data_type_params in 
self.callbacks:
+                                       self._parse_callback(function, 
*data_type_params)
+                       if self.callbacks_locked:       #parse locked callbacks 
and conditional callbacks                               
+                               self.lock() 
+                               for function, data_type_params in 
self.callbacks_locked + self.callbacks_cond:
+                                       self._parse_callback(function, 
*data_type_params)
+                               self.unlock()
+               #print "***\n\nCallback Time END\n\n***"
+               #MUTEX.unlock()
+               
+       def _parse_nested_data(self, nested_data):
+               """!
+               Parse nested data from a flow graph file and build the 
graphics. 
+               @param nested_data the nested flow graph data
+               """
+               find_data = ParseXML.find_data
+               flow_graph = find_data([nested_data], 'flow_graph')     
+               vars = find_data(flow_graph, 'vars')
+               signal_blocks = find_data(flow_graph, 'signal_blocks')
+               connections = find_data(flow_graph, 'connections')
+               self.var_keys = Variables.from_nested_data(vars)
+               signal_blocks_dict = dict()                             
+               for signal_block in signal_blocks:                      
+                       signal_block,runnable_signal_block = 
SignalBlock.from_nested_data(None, signal_block, SignalBlock)                   
   
+                       data_type_params = list()
+                       data_type_params.append(self)#put the flow graph in the 
front of the list
+                       for param in signal_block.get_params(): #load the list 
of arguments to the runnable block               
+                               data_type_params.append(param.get_data_type())  
                
+                       signal_blocks_dict[signal_block.get_id()] = 
runnable_signal_block(*data_type_params)
+               for connection in connections:
+                       connection = find_data([connection], 'connection')
+                       input_signal_block_id = find_data(connection, 
'input_signal_block_id')
+                       input_socket_index = int(find_data(connection, 
'input_socket_index'))
+                       output_signal_block_id = find_data(connection, 
'output_signal_block_id')
+                       output_socket_index = int(find_data(connection, 
'output_socket_index')) 
+                       input_signal_block = 
signal_blocks_dict[input_signal_block_id]
+                       output_signal_block = 
signal_blocks_dict[output_signal_block_id]                        
+                       self.connect(#  use this flow graph's connect method    
#
+                               (output_signal_block, output_socket_index),
+                               (input_signal_block, input_socket_index))
+                               
+##############################################################################################
+#      Option Parser for running a flow graph
+##############################################################################################
                         
+class FlowGraphOptionParser(OptionParser):
+       """This flow graph option parser provides a basic help, 
+       and ensures that a flow graph is passed on the command line."""
+       
+       def __init__(self):
+               """Create the base option parser and add usage and basic 
options."""                    
+               usage = "usage: %prog [options] 
flow_graph"+FLOW_GRAPH_FILE_EXTENSION
+               OptionParser.__init__(self, usage=usage)                
+               self.add_option("-p", "--pid_file", action="store", 
type="string", dest="pid_file", help="record process id")   
+               
+       def parse_args(self):
+               """Call the base parse_args, handle the basic options,
+               and ensure a flow graph was passed in args. Return the 
(options, args)."""
+               (options, args) = OptionParser.parse_args(self)
+               if options.pid_file:
+                       try: open(options.pid_file, 'w').write('%d\n' % 
os.getpid())
+                       except: 
+                               print '\nCould not create pid file: 
"%s".\nExiting!'%options.pid_file
+                               exit(-1)
+               if not len(args): 
+                       self.print_help()
+                       exit(-1)
+               return options, args
+
+##############################################################################################
+#      Main
+##############################################################################################
                                 
+if __name__ == '__main__':     
+       parser = FlowGraphOptionParser()
+       (options, args) = parser.parse_args()   
+       fg = FlowGraphBuilder(args[0])
+       fg.start()
+       raw_input('Flow Graph Running...\nPress Enter to Exit: ')
+       fg.stop()       
+       exit(0)
+                       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/Graphics/Dialogs.py

Copied: grc/tags/grc_0.69/src/Graphics/Dialogs.py (from rev 6449, 
grc/trunk/src/Graphics/Dialogs.py)
===================================================================
--- grc/tags/grc_0.69/src/Graphics/Dialogs.py                           (rev 0)
+++ grc/tags/grc_0.69/src/Graphics/Dialogs.py   2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,286 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Graphics.Dialogs
+#Misc dialogs.
address@hidden Josh Blum
+
+import Colors
+import pygtk
+pygtk.require('2.0')
+import gtk
+from DataTypes import *
+from Constants import *
+from Elements import GraphicalParam
+import Preferences
+
+class TextDisplay(gtk.TextView):
+       """A non editable gtk text view."""
+       
+       def __init__(self, text=''):
+               """!
+               TextDisplay constructor.
+               @param text the text to display (string)
+               """
+               text_buffer = gtk.TextBuffer()
+               text_buffer.set_text(text)      
+               self.set_text = text_buffer.set_text            
+               self.insert = lambda line: 
text_buffer.insert(text_buffer.get_end_iter(), line)
+               gtk.TextView.__init__(self, text_buffer)
+               self.set_editable(False)
+               self.set_cursor_visible(False)
+               self.set_wrap_mode(gtk.WRAP_WORD)
+
+######################################################################################################
+class PreferencesDialog(gtk.Dialog):
+       """A dialog box to display the preferences."""
+       
+       def __init__(self):
+               """PreferencesDialog constructor."""
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               self.set_title("Preferences")   
+               self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
+               notebook = gtk.Notebook()
+               for title,notes,params in Preferences.PREFS_LIST:               
        
+                       if title:                               
+                               vbox = gtk.VBox()
+                               vbox.pack_start(gtk.Label(), False)     #blank 
label for spacing
+                               for param, key in params: 
vbox.pack_start(param.get_input_object(), False)              
+                               if notes: vbox.pack_start(TextDisplay(notes), 
False, padding=5)
+                               notebook.append_page(vbox, gtk.Label(title))    
        
+               self.vbox.pack_start(notebook, True)
+               self.show_all()
+               self.run()
+               self.destroy()
+
+######################################################################################################
+class FlowGraphWindowSizeDialog(gtk.Dialog):
+       """A dialog box to set the window size, width and heigh in pixels."""
+       
+       def __init__(self, dimensions):
+               """!
+               FlowGraphWindowSizeDialog constructor.
+               @param dimensions the (width,height) tuple from the flow graph
+               """
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               self.set_title("Set the Window Size")           
+               #       the helpful dimension constraints label #
+               window_size_label = gtk.Label()
+               window_size_label.set_markup("""<i>
+Minimum window (width/height) in pixels is (%d/%d).
+Maximum window (width/height) in pixels is (%d/%d).
+</i>"""%(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MAX_WINDOW_WIDTH, 
MAX_WINDOW_HEIGHT))
+               self.vbox.pack_end(window_size_label, False)                    
                
+               self.original_dimensions = width,height = dimensions    
+               self.width = Int(width, min=MIN_WINDOW_WIDTH, 
max=MAX_WINDOW_WIDTH)
+               self.height = Int(height, min=MIN_WINDOW_HEIGHT, 
max=MAX_WINDOW_HEIGHT)
+               self.vbox.pack_start(GraphicalParam('width (pixels)', 
self.width).get_input_object(), False)
+               self.vbox.pack_start(GraphicalParam('height (pixels)', 
self.height).get_input_object(), False)  
+               self.show_all()
+               
+       def run(self):
+               """!
+               Get the new dimensions.
+               @return the new dimensions (width,height) or None if invalid.
+               """
+               self.dimensions = None                  
+               gtk.Dialog.run(self)
+               if self.width.is_valid() and self.height.is_valid():
+                       self.dimensions = (self.width.parse(), 
self.height.parse())
+               self.destroy()
+               if self.original_dimensions == self.dimensions: return None     
# do not return dimensions if no change
+               return self.dimensions          
+
+######################################################################################################
+def MessageDialogHelper(type, buttons, title=None, markup=None):
+       """!
+       Create a modal message dialog and run it.
+       @param type the type of message: gtk.MESSAGE_INFO, gtk.MESSAGE_WARNING, 
gtk.MESSAGE_QUESTION or gtk.MESSAGE_ERROR
+       @param buttons the predefined set of buttons to use: gtk.BUTTONS_NONE, 
gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, 
gtk.BUTTONS_OK_CANCEL
+       @param tittle the title of the window (string)
+       @param markup the message text with pango markup
+       @return the gtk response from run()
+       """
+       message_dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, type, 
buttons)
+       if title != None: message_dialog.set_title(title)
+       if markup != None: message_dialog.set_markup(markup)
+       response = message_dialog.run()
+       message_dialog.destroy()
+       return response
+               
+######################################################################################################
+class AboutDialog(gtk.AboutDialog):
+       """A cute little about dialog."""
+       
+       def __init__(self):
+               """AboutDialog constructor."""
+               gtk.AboutDialog.__init__(self)
+               self.set_version(VERSION)
+               self.set_name(MAIN_WINDOW_PREFIX)       
+               self.set_license(__doc__)
+               self.set_copyright('Copyright 2007 Free Software Foundation, 
Inc.')
+               
self.set_website('http://gnuradio.org/trac/wiki/GNURadioCompanion')
+               self.set_comments("""\
+Thank you to all those from the mailing list who tested GNU Radio Companion 
and offered advice.
+--
+Special Thanks:
+A. Brinton Cooper -> starting the project
+CER Technology Fellowship Grant -> initial funding
+William R. Kenan Jr. Fund -> usrp & computers
+Patrick Strasser -> the GRC icon
+Achilleas Anastasopoulos -> trellis support
+--""")
+               self.run()
+               self.destroy()
+                                       
+######################################################################################################
                 
+class DataTypesDialog(gtk.Dialog):
+       """Display each data type with its associated color."""
+       
+       def __init__(self):
+               """DataTypesDialog constructor."""
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               self.set_title('Data Types')
+               self.set_size_request(170, -1)
+               markup = ''
+               for color_spec in (
+                       'Regular Types:',
+                       ('Complex', Colors.COMPLEX_COLOR_SPEC),
+                       ('Float', Colors.FLOAT_COLOR_SPEC),
+                       ('Int', Colors.INT_COLOR_SPEC),
+                       ('Short', Colors.SHORT_COLOR_SPEC),                     
                                                        
+                       ('Byte', Colors.BYTE_COLOR_SPEC),
+                       'Vector Types:',
+                       ('Complex Vector', Colors.COMPLEX_VECTOR_COLOR_SPEC),
+                       ('Float Vector', Colors.FLOAT_VECTOR_COLOR_SPEC),
+                       ('Int Vector', Colors.INT_VECTOR_COLOR_SPEC),
+                       ('Short Vector', Colors.SHORT_VECTOR_COLOR_SPEC),       
                                                                        
+                       ('Byte Vector', Colors.BYTE_VECTOR_COLOR_SPEC),
+               ):
+                       width = 20 #width in monospace characters
+                       if type(color_spec) == type(str()): markup = 
'%s\n\n<b>%s</b>'%(markup, color_spec.center(width, ' '))
+                       else:   
+                               tag,spec = color_spec                           
        
+                               markup = '%s\n<span 
background="%s">%s</span>'%(markup, spec, tag.center(width, ' '))
+               label = gtk.Label()
+               label.set_markup('<tt>%s</tt>\n'%markup[1:])    #strip 1st 
newline, append newline
+               self.vbox.pack_start(label, False)
+               self.show_all()
+               self.run()
+               self.destroy()                  
+                       
+######################################################################################################
                 
+class HotKeysDialog(gtk.Dialog):
+       """Display each action with the associated hotkey."""
+       
+       def __init__(self):
+               """HotKeysDialog constructor."""
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               self.set_title('Hot Keys')
+               markup = ''
+               for action, hotkey in (
+                       ('New Flow Graph', 'Ctrl + n'),
+                       ('Open Flow Graph', 'Ctrl + o'),
+                       ('Save Flow Graph', 'Ctrl + s'),
+                       ('Undo Change', 'Ctrl + z'),
+                       ('Redo Change', 'Ctrl + y'),
+                       ('Redo Change', 'Ctrl + Z'),
+                       ('Delete Block', 'Delete'),
+                       ('Rotate Block', 'Right'),
+                       ('Rotate Block', 'Left'),
+                       ('Modify Data Type', 'Up'),
+                       ('Modify Data Type', 'Down'),
+                       ('Add a Socket', '+'),
+                       ('Remove a Socket', '-'),
+                       ('Close Dialog', 'Esc'),
+                       ('Flow Graph Run', 'F5'),
+                       ('Flow Graph Stop', 'F7'),
+                       ('Screen Shot', 'PrintScreen'),
+               ): markup = '%s\n<b>%s:</b>%s'%(markup, action, 
hotkey.rjust(25-len(action),' '))
+               label = gtk.Label()
+               label.set_markup('<tt>%s</tt>\n'%markup)        #append newline
+               self.vbox.pack_start(label, False)
+               self.show_all()
+               self.run()
+               self.destroy()          
+               
+######################################################################################################
                 
+class MathExprDialog(gtk.Dialog):
+       """A dialog to test math expressions for the parser."""
+       
+       ##the help message
+       HELP_MSG = """\
+<b>Operators - Complex   <i>(complex arguments)</i></b> 
+       + - * / ^       
+<b>Trigonometric Functions   <i>(complex arguments, radians)</i></b> 
+       sin(z) cos(z) tan(z) asin(z) acos(z) atan(z) 
+       sinh(z) cosh(z) tanh(z) asinh(z) acosh(z) atanh(z)      
+<b>Complex Components   <i>(complex arguments)</i></b>
+       mag(z*) real(z*) imag(z*) conj(z*) arg(z)
+<b>Misc Functions   <i>(complex arguments)</i></b> 
+       abs(z*) pow(b, p) sqrt(z) log10(z) log(z, [b=e]) ln(z) exp(z) 
+<b>Misc Functions   <i>(floating point arguments)</i></b> 
+       floor(f) ceil(f) radians(deg) degrees(rad) mod(f1, f2) atan2(y, x) 
sgn(f) min(f*) max(f*)
+<b>Filter Taps Generators   <i>(floating point arguments, rates and 
frequencies in Hz)</i></b> 
+       low_pass(gain, samp_rate, cutoff_freq, width, [window=hamming], 
[beta=6.76])
+       high_pass(gain, samp_rate, cutoff_freq, width, [window=hamming], 
[beta=6.76])   
+       band_pass(gain, samp_rate, low_cutoff_freq, high_cutoff_freq, width, 
[window=hamming], [beta=6.76])
+       complex_band_pass(gain, samp_rate, low_cutoff_freq, high_cutoff_freq, 
width, [window=hamming], [beta=6.76])
+       band_reject(gain, samp_rate, low_cutoff_freq, high_cutoff_freq, width, 
[window=hamming], [beta=6.76])   
+       gaussian(gain, spb, bt, int ntaps)
+       hilbert(int ntaps, [window=rectangular], [beta=6.76])
+       root_raised_cosine(gain, samp_rate, symbol_rate, alpha, int ntaps) 
+       window(window, int ntaps, beta) 
+<b>Window Types for Filters</b>
+       hamming hann blackman rectangular kaiser
+<b>Other Constants</b>
+       pi e j  
+<b>Using Vectors</b>
+       () (num1,) (num2, num2, ...)    
+<b>Test Your Expressions Below:</b>\
+"""
+
+       def __init__(self):
+               """MathExprDialog constrcutor. Create a new gtk Dialog with a 
close button, an extry box, and an output text box."""            
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               #       Create the title and label      #
+               self.set_title('Mathematical Expressions')
+               label = gtk.Label()
+               label.set_markup(self.HELP_MSG)
+               self.vbox.pack_start(label, False)              
+               self.set_size_request(800, 600)
+               #       create a text box for parser output     #
+               self.text_box = TextDisplay()
+               self.text_box.set_text('')                      
+               # create the entry box and give it the change handler #
+               self.param = GraphicalParam('Expression', RawExpr(''))
+               self.input_obj = 
self.param.get_input_object(self._handle_changed)
+               self.vbox.pack_start(self.input_obj, False)                     
+               # add the scrolled window for the text box #
+               scrolled_window = gtk.ScrolledWindow()
+               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
+               scrolled_window.add_with_viewport(self.text_box)
+               self.vbox.pack_start(scrolled_window, True)     
+               self.show_all()
+               self.run()
+               self.destroy()
+               
+       def _handle_changed(self, param=None):
+               """Handle changed in the param's entry box by updating the text 
box."""
+               self.text_box.set_text(str(self.param.get_data_type())) 
+               
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/Graphics/FlowGraph.py

Copied: grc/tags/grc_0.69/src/Graphics/FlowGraph.py (from rev 6460, 
grc/trunk/src/Graphics/FlowGraph.py)
===================================================================
--- grc/tags/grc_0.69/src/Graphics/FlowGraph.py                         (rev 0)
+++ grc/tags/grc_0.69/src/Graphics/FlowGraph.py 2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,502 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Graphics.FlowGraph
+#A flow graph structure for storing signal blocks and their connections.
address@hidden Josh Blum
+
+from Constants import *
+from Actions import *
+from Colors import BACKGROUND_COLOR, TXT_COLOR
+from Elements import GraphicalSignalBlock,GraphicalConnection
+from Elements import Utils
+from Elements.Connection import ConnectionException
+import Variables
+import pygtk
+pygtk.require('2.0')
+import gtk
+import time,socket #for tagging saved files
+import SignalBlockDefs
+from SignalBlockParamsDialog import SignalBlockParamsDialog
+import random
+import Messages
+import Preferences
+import ParseXML
+import Messages
+
+class FlowGraph(gtk.DrawingArea):
+       """
+       FlowGraph is the data structure to store graphical signal blocks, 
+       graphical inputs and outputs, 
+       and the connections between inputs and outputs.
+       """     
+               
+       def __init__(self, handle_states, variable_modification_window):
+               """!
+               FlowGraph contructor.
+               Create a list for signal blocks and connections. Connect mouse 
handlers.
+               @param handle_states the callback function
+               @param variable_modification_window var mod window also for 
callbacks
+               """     
+               #setup
+               self.elements = list()
+               self.remove_element = lambda e: self.elements.remove(e)
+               self.gc = None
+               self.handle_states = handle_states
+               self.variable_modification_window = variable_modification_window
+               gtk.DrawingArea.__init__(self)
+               self.connect('expose-event', self._handle_window_expose)
+               self.connect('motion-notify-event', self._handle_mouse_motion)
+               self.connect('button-press-event', 
self._handle_mouse_button_press)  
+               self.connect('button-release-event', 
self._handle_mouse_button_release)         
+               self.set_events(
+                       gtk.gdk.BUTTON_PRESS_MASK | \
+                       gtk.gdk.POINTER_MOTION_MASK | \
+                       gtk.gdk.BUTTON_RELEASE_MASK | \
+                       gtk.gdk.LEAVE_NOTIFY_MASK | \
+                       gtk.gdk.ENTER_NOTIFY_MASK
+               )       
+               #       setup the focus flag    #               
+               self.focus_flag = False
+               self.get_focus_flag = lambda: self.focus_flag           
+               self.connect("leave-notify-event", self._handle_focus_event, 
False)
+               self.connect("enter-notify-event", self._handle_focus_event, 
True)              
+               #       important vars dealing with mouse event tracking        
#       
+               self.has_moved = False
+               self.mouse_pressed = False
+               self.coordinate = (0,0)
+               self.selected_element = None
+               self.is_selected = lambda: self.selected_element != None
+               self.count = 0
+               self.pixmap = None
+               
+###########################################################################
+#      Flow Graph Access Methods
+###########################################################################    
+       
+       def _handle_focus_event(self, widget, event, focus_flag):
+               """Record the focus state of the flow graph window."""
+               self.focus_flag = focus_flag
+                               
+       def add_signal_block(self, tag):        
+               """!
+               Add a signal block of the given tag to this flow graph.
+               @param tag the signal block tag
+               """
+               index = 0
+               while True:
+                       id = tag+str(index)
+                       index = index + 1       
+                       if not [
+                               None for element in self.elements if 
Utils.is_signal_block(element) and id == element.get_id()
+                       ]:              #make sure that the id is not used by 
another signal block
+                               rot = 0
+                               vAdj = 
self.get_parent().get_vadjustment().get_value()
+                               hAdj = 
self.get_parent().get_hadjustment().get_value()
+                               x = random.randint(100,400)+int(hAdj)   
+                               y = random.randint(100,400)+int(vAdj)   
+                               self.elements.append(
+                                       SignalBlockDefs.get_signal_block(self, 
(x, y), rot, tag, id, GraphicalSignalBlock)[0]
+                               )
+                               self.handle_states(SIGNAL_BLOCK_CREATE) 
+                               self.update()
+                               return          
+       
+       def type_controller_modify_selected(self, direction):
+               """
+               !Change the registered type controller for the selected signal 
block.
+               @param direction +1 or -1
+               @return true for success
+               """
+               if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
+               if Utils.is_signal_block(self.selected_element): return 
self.selected_element.modify_type_controller(direction)
+               return False
+               
+       def socket_controller_modify_selected(self, direction):
+               """!
+               Change socket controller for the selected signal block.
+               @param direction +1 or -1
+               @return true for success
+               """
+               if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
+               if Utils.is_signal_block(self.selected_element): return 
self.selected_element.modify_socket_controller(direction)
+               return False
+
+       def param_modify_selected(self):
+               """!
+               Create and show a param modification dialog for the selected 
element (socket and signal block only).
+               @return true if parameters were changed
+               """
+               if Utils.is_socket(self.selected_element): 
self.selected_element = self.selected_element.get_parent()
+               if Utils.is_signal_block(self.selected_element):
+                       signal_block_params_dialog = 
SignalBlockParamsDialog(self.selected_element)
+                       changed = signal_block_params_dialog.run()      
+                       self.update()   
+                       return changed #changes were made?
+               return False    
+               
+       def connect_sockets(self, s1, s2):
+               """!
+               Connect input and output sockets. Ignore state change if 
creation of connection fails.
+               @param s1 a socket
+               @param s2 another socket
+               """
+               try:            
+                       connection = GraphicalConnection(self, s1, s2)
+                       self.elements.append(connection)
+                       self.selected_element = None
+                       self.handle_states(CONNECTION_CREATE)   
+                       self.update()   
+               except ConnectionException: 
+                       Messages.send_fail_connection() 
+                       self.handle_states(NOTHING_SELECT)      
+       
+       def move_selected(self, delta_coordinate):
+               """!
+               Move the element and by the change in coordinates.
+               @param delta_coordinate the change in coordinates
+               """
+               if self.selected_element != None:                               
        
+                       self.selected_element.move(delta_coordinate)    
+                       self.has_moved = True   
+                       self.draw()
+                       
+       def rotate_selected(self, direction):
+               """!
+               Rotate the selected element by 90 degrees. Only rotate 
SignalBlocks and Sockets.
+               @param direction DIR_LEFT or DIR_RIGHT
+               @return         true if rotated, otherwise false. 
+               """
+               if self.selected_element != None and 
(Utils.is_signal_block(self.selected_element) or 
Utils.is_socket(self.selected_element)):                                  
+                       self.selected_element.rotate(direction) 
+                       self.draw()
+                       return True
+               return False    
+       
+       def delete_selected(self):
+               """!
+               If an element is selected, remove it and its attached parts 
from the element list.
+               @return true if the element was deleted, otherwise false.
+               """
+               if self.selected_element != None:
+                       if Utils.is_socket(self.selected_element):      # found 
a socket, set to parent signal block
+                               self.selected_element = 
self.selected_element.get_parent()                                              
+                       if Utils.is_signal_block(self.selected_element):        
# delete a signal block
+                               connections = 
self.selected_element.get_connections()
+                               for connection in connections: 
connection.disconnect()
+                               self.remove_element(self.selected_element)
+                       elif Utils.is_connection(self.selected_element):        
# delete a connection
+                               self.selected_element.disconnect()              
                        
+                       self.selected_element = None                            
+                       self.update()   
+                       return True
+               return False
+               
+       def unselect(self):
+               """If an element is selected, un-highlight it and set selected 
to None."""
+               if self.selected_element != None: 
+                       self.selected_element.set_highlighted(False)            
        
+                       self.selected_element = None    
+                       self.update()   
+                                       
+       def what_is_selected(self, coor):               
+               """!
+               What is selected?
+               At the given coordinate, return the first element found to be 
selected  
+               - iterate though the elements backwards since top elements are 
at the end of the list   
+               - if an element is selected, place it at the end of the list so 
that is is drawn last, 
+                       and hence on top.
+               @param coor the coordinate of the mouse click
+               @return the selected element or None
+               """              
+               #       check the elements      #                       
+               for element in reversed(self.elements):
+                       if element.what_is_selected(coor) != None:
+                               self.elements.remove(element)
+                               self.elements.append(element)
+                               return element.what_is_selected(coor)           
+               return None
+               
+       def draw(self, drawable=None):          
+               """Draw the background and then all of the Elements in this 
FlowGraph on the pixmap, 
+               then draw the pixmap to the drawable window of this 
FlowGraph."""
+               if self.gc != None:                             
+                       #       draw the background     #               
+                       W,H = self.get_size_request()
+                       self.gc.foreground = BACKGROUND_COLOR
+                       self.pixmap.draw_rectangle(self.gc, True, 0, 0, W, H)   
+                       if Preferences.show_grid():                             
+                               grid_size = Preferences.get_grid_size()         
                
+                               points = list()
+                               for i in range(W/grid_size):
+                                       for j in range(H/grid_size): 
+                                               
points.append((i*grid_size,j*grid_size))                                        
+                               self.gc.foreground = TXT_COLOR                  
                
+                               self.pixmap.draw_points(self.gc, points)        
+                       #       draw the foreground     #
+                       for element in filter(Utils.is_signal_block, 
self.elements) + filter(Utils.is_connection, self.elements): 
+                               element.draw(self.pixmap)       # draw signal 
blocks first, then connections on the top                 
+                       if self.mouse_pressed and self.selected_element != None:
+                               self.selected_element.draw(self.pixmap)
+                       self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 
0, 0, -1, -1)      
+                       
+       def is_valid(self):
+               """!
+               Is the flow graph valid, ie: are all elements valid?
+               @return true if flow graph is valid
+               """             
+               for element in self.elements: 
+                       if not element.is_valid(): return False
+               return True
+               #return all([element.is_valid() for element in self.elements])  
#python 2.5 and higher
+               
+       def update(self):
+               """Call update on all elements."""      
+               for element in self.elements: element.update()  
+               self.draw()
+               
+       
##########################################################################
+       ##      Handlers
+       
##########################################################################      
+               
+       def _handle_mouse_button_press(self, widget, event):
+               """ A mouse button is pressed. Record the state of the mouse, 
find the selected element,
+               set the Element highlighted, handle the state change, and 
redraw the FlowGraph."""              
+               #       unselect anything in the vars mod window        #
+               self.variable_modification_window.unselect_all()
+               if event.button == 1:
+                       if self.selected_element != None: 
self.selected_element.set_highlighted(False)
+                       self.count = 0
+                       self.mouse_pressed = True
+                       self.coordinate = (event.x, event.y)
+                       old_selection = self.selected_element
+                       self.selected_element = self.what_is_selected((event.x, 
event.y))
+                       #       handle the state change with the new selection  
#
+                       if Utils.is_connection(self.selected_element): 
self.handle_states(CONNECTION_SELECT)    
+                       elif Utils.is_socket(self.selected_element): 
self.handle_states(SOCKET_SELECT)  
+                       elif Utils.is_signal_block(self.selected_element): 
self.handle_states(SIGNAL_BLOCK_SELECT)      
+                       elif self.selected_element == None: 
self.handle_states(NOTHING_SELECT)                                          
+                       #       this selection and the last were Sockets, try 
to connect them   #
+                       if Utils.is_socket(old_selection) and 
Utils.is_socket(self.selected_element) and\
+                               old_selection is not self.selected_element: 
#cannot be the same socket
+                               self.connect_sockets(old_selection, 
self.selected_element)                                              
+                       if self.selected_element != None: 
self.selected_element.set_highlighted(True)                                     
                              
+                       #       double click detected, bring up params dialog 
if possible       #
+                       if event.type == gtk.gdk._2BUTTON_PRESS and 
Utils.is_signal_block(self.selected_element):
+                               self.mouse_pressed = False
+                               self.handle_states(SIGNAL_BLOCK_PARAM_MODIFY)   
                        
+                       self.draw()
+               return True
+               
+       def _handle_mouse_button_release(self, widget, event):
+               """A mouse button is released, record the state."""
+               if event.button == 1:
+                       self.mouse_pressed = False
+                       if self.has_moved:
+                               if Preferences.snap_to_grid():
+                                       grid_size = Preferences.get_grid_size()
+                                       X,Y = 
self.selected_element.get_coordinate()
+                                       deltaX = X%grid_size
+                                       if deltaX < grid_size/2: deltaX = -1 * 
deltaX
+                                       else: deltaX = grid_size - deltaX
+                                       deltaY = Y%grid_size
+                                       if deltaY < grid_size/2: deltaY = -1 * 
deltaY
+                                       else: deltaY = grid_size - deltaY
+                                       self.move_selected((deltaX,deltaY))
+                               self.handle_states(SIGNAL_BLOCK_MOVE)
+                               self.has_moved = False
+               return True
+               
+       def _handle_mouse_motion(self, widget, event):          
+               """The mouse has moved. If mouse_pressed is true, react to the 
motions: 
+               -       if an Element is highlighted, this will move the 
Element by redrawing it at the new position."""
+               fgW,fgH = self.get_size_request()
+               self.count = (1 + 
self.count)%MOTION_DETECT_REDRAWING_SENSITIVITY
+               #       to perform a movement, the mouse must be pressed, an 
element selected, count of zero.   #
+               if self.mouse_pressed and\
+                       self.count == 0 and\
+                       self.selected_element != None:
+                       #       The event coordinates must be within 10 pixels 
away from the bounds of the flow graph.  #
+                       x = event.x
+                       if x <= BORDER_PROXIMITY_SENSITIVITY:
+                               x = BORDER_PROXIMITY_SENSITIVITY
+                       if      x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
+                               x = fgW - BORDER_PROXIMITY_SENSITIVITY          
                        
+                       y = event.y
+                       if y <= BORDER_PROXIMITY_SENSITIVITY:
+                               y = BORDER_PROXIMITY_SENSITIVITY
+                       if      y >= fgH - BORDER_PROXIMITY_SENSITIVITY:        
+                               y = fgH - BORDER_PROXIMITY_SENSITIVITY  
+                       #       get the change in coordinates   #               
+                       X,Y = self.coordinate
+                       deltaX = int(x - X)
+                       deltaY = int(y - Y)                                     
                                                
+                       vAdj = self.get_parent().get_vadjustment().get_value()
+                       hAdj = self.get_parent().get_hadjustment().get_value()
+                       width = self.get_parent().get_hadjustment().page_size
+                       height = self.get_parent().get_vadjustment().page_size
+                       # scroll horizontal if we moved near the border #
+                       if x-hAdj > width-SCROLL_PROXIMITY_SENSITIVITY and\
+                               hAdj+SCROLL_DISTANCE < fgW - width:
+                               
self.get_parent().get_hadjustment().set_value(hAdj+SCROLL_DISTANCE)
+                       elif x-hAdj < SCROLL_PROXIMITY_SENSITIVITY:
+                               
self.get_parent().get_hadjustment().set_value(hAdj-SCROLL_DISTANCE)
+                       # scroll vertical if we moved near the border   #
+                       if y-vAdj > height-SCROLL_PROXIMITY_SENSITIVITY and\
+                               vAdj+SCROLL_DISTANCE < fgH - height:
+                               
self.get_parent().get_vadjustment().set_value(vAdj+SCROLL_DISTANCE)
+                       elif y-vAdj < SCROLL_PROXIMITY_SENSITIVITY:
+                               
self.get_parent().get_vadjustment().set_value(vAdj-SCROLL_DISTANCE)
+                       # move the selected element and record the new 
coordinate       #                       
+                       self.move_selected((deltaX, deltaY))    
+                       self.coordinate = (x, y)        
+                                       
+       def _handle_window_expose(self, widget, event): 
+               """Called when the window initially appears or is resized: 
create a new pixmap, draw the flow graph."""
+               self.gc = self.window.new_gc()
+               width, height = self.get_size_request()
+               if self.pixmap == None or (width, height) != 
self.pixmap.get_size():            
+                       self.pixmap = gtk.gdk.Pixmap(self.window, width, 
height, -1)
+               self.draw()
+
+##########################################################################
+##
+##                     Export the Flow Graph
+##
+##########################################################################     
                                        
+       def to_nested_data(self):
+               """!
+               Dump all the values in this flow graph into a nested data 
format.
+               @return nested data representing a flow graph
+               """
+               vars_list = list()
+               signal_blocks_list = list()
+               connections_list = list()
+               W,H = self.get_size_request()
+               nested_data = ('flow_graph', [
+                       ('timestamp', str(time.time())),
+                       ('hostname', socket.gethostname()),
+                       ('version', VERSION),
+                       ('valid', str(self.is_valid())),
+                       ('window_width', str(W)),
+                       ('window_height', str(H)),
+                       ('vars', vars_list),
+                       ('signal_blocks', signal_blocks_list),
+                       ('connections', connections_list)
+               ])      
+       
##########################################################################
+       ##      Export the Variables
+       
##########################################################################      
+               for key in self.variable_modification_window.to_key_list():
+                       row = (key,) + Variables.get_values(key)
+                       vars_list.append(('var', [
+                               ('key', row[0]), 
+                               ('value', row[1]),
+                               ('min', row[2]),
+                               ('max', row[3]),
+                               ('step', row[4]),
+                       ]))
+       
##########################################################################
+       ##      Export the Signal Blocks
+       
##########################################################################
+               for element in filter(Utils.is_signal_block, self.elements):
+                       params_list = list()
+                       signal_blocks_list.append(('signal_block', [
+                               ('tag', element.get_tag()), 
+                               ('id', element.get_id()),
+                               ('x_coordinate', 
str(element.get_coordinate()[0])),
+                               ('y_coordinate', 
str(element.get_coordinate()[1])),
+                               ('rotation', str(element.get_rotation())),
+                               ('params', params_list)
+                       ]))
+                       for param in element.get_params():
+                               params_list.append(('param', 
str(param.get_data_type().get_data()))     )       
+       
##########################################################################
+       ##      Export the Connections
+       
##########################################################################
+               for element in filter(Utils.is_connection, self.elements):
+                       connections_list.append(('connection', [
+                               ('input_signal_block_id', 
str(element.get_input_socket().get_parent().get_id())), 
+                               ('input_socket_index', 
str(element.get_input_socket().get_index())),
+                               ('output_signal_block_id', 
str(element.get_output_socket().get_parent().get_id())), 
+                               ('output_socket_index', 
str(element.get_output_socket().get_index()))
+                       ]))
+               #print 'To',nested_data
+               return nested_data
+
+##########################################################################
+##     
+##                     Import the Flow Graph
+##
+##########################################################################     
        
+       def from_nested_data(self, nested_data):
+               """!
+               Set all the values in this flow graph using the nested data.
+               @param nested_data nested data representing a flow graph
+               """
+               #print 'From',nested_data
+               #TODO: use a non-destructive method to clear the elements list
+               self.elements = list()  #clear the elements
+               find_data = ParseXML.find_data
+               flow_graph = find_data([nested_data], 'flow_graph')
+               #       window width and height are optional    #
+               window_width = find_data(flow_graph, 'window_width')
+               if window_width == None: window_width = MAX_WINDOW_WIDTH
+               window_height = find_data(flow_graph, 'window_height')
+               if window_height == None: window_height = MAX_WINDOW_HEIGHT
+               self.set_size_request(int(window_width),int(window_height))
+               vars = find_data(flow_graph, 'vars')
+               signal_blocks = find_data(flow_graph, 'signal_blocks')
+               connections = find_data(flow_graph, 'connections')
+       
##########################################################################
+       ##      Import the Variables
+       
##########################################################################
+               keys = Variables.from_nested_data(vars)
+               self.variable_modification_window.from_key_list(keys)
+       
##########################################################################
+       ##      Import the Signal Blocks
+       
##########################################################################
+               for signal_block in signal_blocks:
+                       signal_block = 
GraphicalSignalBlock.from_nested_data(self, signal_block, 
GraphicalSignalBlock)[0]       #index 0 for just signal block  
+                       if signal_block: self.elements.append(signal_block)     
                
+       
##########################################################################
+       ##      Import the Connections
+       
##########################################################################
+               for connection in connections:
+                       connection = find_data([connection], 'connection')
+                       input_signal_block_id = find_data(connection, 
'input_signal_block_id')
+                       input_socket_index = int(find_data(connection, 
'input_socket_index'))
+                       output_signal_block_id = find_data(connection, 
'output_signal_block_id')
+                       output_socket_index = int(find_data(connection, 
'output_socket_index'))
+                       input_socket = output_socket = None                     
                                                        
+                       for element in filter(Utils.is_signal_block, 
self.elements):
+                               if element.get_id() == input_signal_block_id: 
input_socket = element.get_input_socket(input_socket_index)
+                               if element.get_id() == output_signal_block_id: 
output_socket = element.get_output_socket(output_socket_index)
+                       try: self.elements.append(GraphicalConnection(self, 
input_socket, output_socket))
+                       except ConnectionException: 
+                               Messages.send_error_load('Could not connect 
"%s" input[%d] and "%s" output[%d].'%(
+                                               input_signal_block_id, 
+                                               input_socket_index, 
+                                               output_signal_block_id, 
+                                               output_socket_index,
+                                       )
+                               )       
+               self.selected_element = None            
+               self.update()
+               # done importing the flow graph #
+

Deleted: grc/tags/grc_0.69/src/Graphics/MainWindow.py

Copied: grc/tags/grc_0.69/src/Graphics/MainWindow.py (from rev 6460, 
grc/trunk/src/Graphics/MainWindow.py)
===================================================================
--- grc/tags/grc_0.69/src/Graphics/MainWindow.py                                
(rev 0)
+++ grc/tags/grc_0.69/src/Graphics/MainWindow.py        2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,411 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Graphics.MainWindow
+#The main window, containing all windows, tool bars, and menu bars.
address@hidden Josh Blum
+
+from Constants import *
+from Actions import *
+import pygtk
+pygtk.require('2.0')
+import gtk
+import Bars
+from FlowGraph import FlowGraph
+from SignalBlockSelectionWindow import SignalBlockSelectionWindow
+from VariableModificationWindow import VariableModificationWindow
+from Dialogs import TextDisplay,MessageDialogHelper
+from StateCache import StateCache
+import Preferences
+import Messages
+import ParseXML
+import os
+
+############################################################
+##     Notebook Page
+############################################################
+
+class Page(gtk.HBox):
+       """A page in the notebook."""
+       
+       def __init__(self, main_window, file_path=''):
+               """
+               Page constructor.
+               @param main_window main window
+               @param file_path path to a flow graph file
+               """             
+               #import the file
+               self.main_window = main_window
+               initial_state = ParseXML.from_xml(ParseXML.from_file(file_path 
or INITIAL_FLOW_GRAPH_FILE))
+               
self.main_window.get_flow_graph().from_nested_data(initial_state)
+               self.state_cache = 
StateCache(self.main_window.get_flow_graph().to_nested_data())
+               self.set_pid_file('')
+               self.set_file_path(file_path)           
+               self.set_saved(True)    
+               #import success, initialize page                
+               gtk.HBox.__init__(self, False, 0)
+               self.show()             
+               #tab box to hold label and close button
+               self.tab = gtk.HBox(False, 0)                   
+               #setup tab label
+               self.label = gtk.Label()
+               self.tab.pack_start(self.label, True, False, 0)
+               #setup button image
+               image = gtk.Image()
+               image.set_from_stock('gtk-close', gtk.ICON_SIZE_MENU)
+               #setup image box
+               image_box = gtk.HBox(False, 0)
+               image_box.pack_start(image, True, False, 0)
+               #setup the button
+               button = gtk.Button()
+               button.connect("clicked", self._handle_button)
+               button.set_relief(gtk.RELIEF_NONE)
+               button.add(image_box)
+               #button size            
+               w, h = gtk.icon_size_lookup_for_settings(button.get_settings(), 
gtk.ICON_SIZE_MENU)
+               button.set_size_request(w+6, h+6)
+               self.tab.pack_start(button)             
+               self.tab.show_all()
+               
+       def _handle_button(self, button):
+               """
+               The button was clicked.
+               Make the current page selected, then close.
+               @param the button
+               """
+               self.main_window.page_to_be_closed = self
+               self.main_window.handle_states(FLOW_GRAPH_CLOSE)
+               
+       def set_text(self, text):
+               """
+               Set the text in this label.
+               @param text the new text
+               """
+               self.label.set_text(text)
+               
+       def get_tab(self):
+               """
+               Get the gtk widget for this page's tab.
+               @return gtk widget 
+               """
+               return self.tab
+               
+       def get_pid_file(self):
+               """!
+               Get the pid file for the flow graph.
+               @return the pid file or ''
+               """
+               return self.pid_file
+       
+       def set_pid_file(self, pid_file=''):
+               """!
+               Set the pid file, '' for no pid file.
+               @param pid_file file path string
+               """
+               self.pid_file = pid_file
+       
+       def get_file_path(self):
+               """!
+               Get the file path for the flow graph.
+               @return the file path or ''
+               """
+               return self.file_path
+       
+       def set_file_path(self, file_path=''):
+               """!
+               Set the file path, '' for no file path.
+               @param file_path file path string
+               """
+               if file_path: self.file_path = os.path.abspath(file_path)
+               else: self.file_path = ''
+       
+       def get_saved(self):
+               """!
+               Get the saved status for the flow graph.
+               @return true if saved
+               """
+               return self.saved
+       
+       def set_saved(self, saved=True):
+               """!
+               Set the saved status.
+               @param saved boolean status
+               """
+               self.saved = saved 
+       
+       def get_state_cache(self):
+               """!
+               Get the state cache for the flow graph.
+               @return the state cache
+               """
+               return self.state_cache
+               
+############################################################
+##     Main window
+############################################################           
+               
+class MainWindow(gtk.Window):
+       """The topmost window with menus, the tool bar, and other major 
windows."""
+       
+       def __init__(self, handle_states):
+               """!
+               MainWindow contructor.
+               @param handle_states the callback function
+               """     
+               #setup window
+               self.handle_states = handle_states
+               gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)          
+               vbox = gtk.VBox()
+               hbox = gtk.HBox()
+               self.add(vbox)
+               #create the menu bar    and toolbar     
+               vbox.pack_start(Bars.MenuBar(), False)  
+               vbox.pack_start(Bars.Toolbar(), False)                  
+               # create variable modification window   #
+               self.variable_modification_window = 
VariableModificationWindow(self.handle_states)
+               self.flow_graph = FlowGraph(self.handle_states, 
self.variable_modification_window)              
+               #setup scrolled window
+               self.scrolled_window = gtk.ScrolledWindow()
+               self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, 
MIN_WINDOW_HEIGHT)      
+               self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
+               self.scrolled_window.add_with_viewport(self.flow_graph)
+               # create the notebook #         
+               self.notebook = gtk.Notebook()
+               self.page_to_be_closed = None
+               self.current_page = None
+               self.notebook.set_show_border(False)
+               self.notebook.set_scrollable(True)      #scroll arrows for page 
tabs
+               self.notebook.connect("switch-page", self._handle_page_change)
+               fg_and_report_box = gtk.VBox(False, 0)
+               fg_and_report_box.pack_start(self.notebook, False, False, 0)
+               fg_and_report_box.pack_start(self.scrolled_window)
+               hbox.pack_start(fg_and_report_box)
+               vbox.pack_start(hbox)           
+               #create the side windows
+               side_box = gtk.VBox()
+               hbox.pack_start(side_box, False)
+               side_box.pack_start(self.variable_modification_window, False)   
        #dont allow resize
+               
side_box.pack_start(SignalBlockSelectionWindow(self.get_flow_graph)) #all 
resize, selection window can have more space
+               #create the reports window              
+               self.text_display = TextDisplay()
+               #house the reports in a scrolled window
+               self.reports_scrolled_window = gtk.ScrolledWindow()
+               self.reports_scrolled_window.set_size_request(-1, 
REPORTS_WINDOW_HEIGHT)
+               self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 
gtk.POLICY_AUTOMATIC)
+               
self.reports_scrolled_window.add_with_viewport(self.text_display)       
+               fg_and_report_box.pack_end(self.reports_scrolled_window, False) 
#dont allow resize, fg should get all the space
+               # show all but the main window container and the reports window 
+               vbox.show_all()                 
+               self.show_reports_window(False) 
+               # load preferences and show the main window 
+               Preferences.load(self)
+               self.show()#show after resize in preferences
+
+       ############################################################
+       ##      Event Handlers
+       ############################################################
+               
+       def _quit(self, window, event):
+               """!
+               Handle the delete event from the main window.
+               Generated by pressing X to close, alt+f4, or right click+close. 
+               This method in turns calls the state handler to quit.
+               @return true            
+               """
+               self.handle_states(APPLICATION_QUIT)
+               return True     
+               
+       def _handle_page_change(self, notebook, page, page_num):
+               """!
+               Handle a page change. When the user clicks on a new tab,
+               reload the flow graph to update the vars window and 
+               call handle states (select nothing) to update the buttons.
+               @param notebook the notebook
+               @param page new page
+               @param page_num new page number
+               """             
+               self.current_page = self.notebook.get_nth_page(page_num)
+               state = self.get_page().get_state_cache().get_current_state()
+               self.get_flow_graph().from_nested_data(state)
+               self.handle_states(NOTHING_SELECT) 
+               
+       ############################################################
+       ##      Report Window
+       ############################################################
+       
+       def add_report_line(self, line):
+               """!
+               Place line plus a newline at the end of the text buffer, then 
scroll its window all the way down.
+               @param line the new text
+               """
+               self.text_display.insert(line)          
+               vadj = self.reports_scrolled_window.get_vadjustment()
+               vadj.set_value(vadj.upper)
+                                               
+       def show_reports_window(self, show):
+               """!
+               Show the reports window when show is True.
+               Hide the reports window when show is False.
+               @param show boolean flag
+               """
+               if show: self.reports_scrolled_window.show()
+               else: self.reports_scrolled_window.hide()
+               
+       ############################################################
+       ##      Pages: create and close
+       ############################################################
+       
+       def new_page(self, file_path=''):
+               """!
+               Create a new notebook page.
+               Set the tab to be selected.
+               @param file_path optional file to load into the flow graph
+               """
+               if file_path and file_path in self._get_files(): #already open
+                       page = 
self.notebook.get_nth_page(self._get_files().index(file_path))
+                       self._set_page(page)
+                       return          
+               try: #try to load from file
+                       if file_path: Messages.send_start_load(file_path)
+                       page = Page(self, file_path)
+                       if file_path: Messages.send_end_load()
+               except Exception, e: 
+                       Messages.send_fail_load(e)
+                       return  
+               self.notebook.append_page(page, page.get_tab())
+               self._set_page(page)
+               
+       def close_pages(self):
+               """
+               Close all the pages in this notebook.           
+               @return true if all closed
+               """
+               files = filter(lambda file: file, self._get_files()) #filter 
blank files
+               for page in self._get_pages():
+                       self.page_to_be_closed = page
+                       self.close_page(False)
+               if self.notebook.get_n_pages(): return False
+               Preferences.save_files_open(files)
+               return True
+                       
+       def close_page(self, ensure=True):
+               """
+               Close the current page.
+               If ensure: ensure there is at least one page in the notebook,
+               call new page if get page is none.
+               @param ensure boolean
+               """
+               if not self.page_to_be_closed: self.page_to_be_closed = 
self.get_page()
+               #show the page if it has an executing flow graph or is unsaved
+               if self.page_to_be_closed.get_pid_file() or not 
self.page_to_be_closed.get_saved():
+                       self._set_page(self.page_to_be_closed)
+               #unsaved? ask the user
+               if not self.page_to_be_closed.get_saved() and 
self._save_changes(): 
+                       self.handle_states(FLOW_GRAPH_SAVE) #try to save
+                       if not self.page_to_be_closed.get_saved(): #still 
unsaved?
+                               self.page_to_be_closed = None   #set the page 
to be closed back to None
+                               return
+               #stop the flow graph if executing
+               if self.page_to_be_closed.get_pid_file(): 
self.handle_states(FLOW_GRAPH_STOP)
+               #remove the page
+               
self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
+               if ensure and self.notebook.get_n_pages() == 0: self.new_page() 
#no pages, make a new one
+               self.page_to_be_closed = None   #set the page to be closed back 
to None
+       
+       ############################################################
+       ##      Misc
+       ############################################################
+
+       def update(self):
+               """!
+               Set the title of the main window.
+               Set the titles on the page tabs.
+               Show/hide the reports window.
+               @param title the window title
+               """     
+               if self.get_page():
+                       title = ''.join((
+                                       MAIN_WINDOW_PREFIX,
+                                       ' - Editing: ',
+                                       (self.get_page().get_file_path() or 
NEW_FLOGRAPH_TITLE),
+                                       (self.get_page().get_saved() and ' ' or 
'*'), #blank must be non empty
+                               )
+                       )
+               else: title = MAIN_WINDOW_PREFIX + ' - Editor '
+               gtk.Window.set_title(self, title)       
+               #set tab titles
+               for page in self._get_pages():
+                       page.set_text(''.join((
+                                               
(os.path.split(page.get_file_path())[1] or NEW_FLOGRAPH_TITLE),
+                                               (page.get_saved() and ' ' or 
'*'), #blank must be non empty
+                                       )
+                               )
+                       )
+               #reports window
+               Preferences.show_reports_window(self)
+                       
+       def get_flow_graph(self):
+               """
+               Get the flow graph in this main window.
+               @return the flow graph
+               """
+               return self.flow_graph
+               
+       def get_page(self):
+               """!
+               Get the selected page.
+               @return the selected page
+               """
+               return self.current_page
+
+       ############################################################
+       ##      Helpers
+       ############################################################
+
+       def _set_page(self, page):
+               """
+               Set the current page.
+               @param page the page widget
+               """
+               self.current_page = page
+               
self.notebook.set_current_page(self.notebook.page_num(self.current_page))       
                
+
+       def _save_changes(self):
+               """!
+               Save changes to flow graph?             
+               @return true if yes
+               """
+               return MessageDialogHelper(
+                       gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved 
Changes!', 
+                       'Would you like to save changes before closing?'
+               ) == gtk.RESPONSE_YES
+               
+       def _get_files(self):
+               """
+               Get the file names for all the pages, in order.
+               @return list of file paths
+               """
+               return map(lambda page: page.get_file_path(), self._get_pages())
+
+       def _get_pages(self):
+               """
+               Get a list of all pages in the notebook.
+               @return list of pages
+               """
+               return [self.notebook.get_nth_page(page_num) for page_num in 
range(self.notebook.get_n_pages())]        
+

Deleted: grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py

Copied: grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py (from rev 6449, 
grc/trunk/src/Graphics/USRPDiagnostics.py)
===================================================================
--- grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py                           
(rev 0)
+++ grc/tags/grc_0.69/src/Graphics/USRPDiagnostics.py   2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,105 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Graphics.USRPDiagnostics
+#A dialog for querying USRP subdevices. USRP interfacing methods encapsulated 
here.
address@hidden Josh Blum
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+from Actions import USRP_DIAGNOSTICS_DISPLAY,get_action_from_name
+from Elements import GraphicalParam
+from DataTypes import *
+from Dialogs import TextDisplay
+
+def enable_usrp_diagnostics():
+       """Enable the action for USRP diganostics if gnuradio.usrp can be 
imported."""
+       try: 
+               from gnuradio import usrp
+               
get_action_from_name(USRP_DIAGNOSTICS_DISPLAY).set_sensitive(True)
+       except ImportError: print "USRP support missing -> USRP diagnostics 
disabled..."        
+
+class USRPDiagnosticsDialog(gtk.Dialog):
+       """
+       The main dialog window for USRP Dignostics. 
+       The USRP parameters and feedback will be located inside this dialog.
+       """
+       
+       def __init__(self):
+               """USRPDiagnosticsDialog contructor.
+               Create a new gtk Dialog with a close button, USRP input 
paramaters, and output labels."""               
+               gtk.Dialog.__init__(self, buttons=('gtk-close', 
gtk.RESPONSE_CLOSE))
+               #       Create the title label  #
+               self.set_title('USRP Diagnostics')
+               self.USRP_number = Int(0, min=0)
+               self.USRP_type = Enum([('Receive', 'rx'), ('Transmit', 'tx'),])
+               self.USRP_subdev = Enum([
+                               ('Side A:0', (0, 0)), 
+                               ('Side B:0', (1, 0)),
+                               ('Side A:1', (0, 1)), 
+                               ('Side B:1', (1, 1)),
+                       ]
+               )
+               self.vbox.pack_start(GraphicalParam('Unit Number', 
self.USRP_number).get_input_object(), False)
+               self.vbox.pack_start(GraphicalParam('Transmit/Receive', 
self.USRP_type).get_input_object(), False)
+               self.vbox.pack_start(GraphicalParam('Side:Subdevice', 
self.USRP_subdev).get_input_object(), False)
+               self.diagnose_button = gtk.Button('Query')
+               self.diagnose_button.connect('clicked', self._diagnose_usrp)
+               self.vbox.pack_start(self.diagnose_button, False)               
+               #       Create a text box for USRP queries      #
+               self.query_buffer = TextDisplay()
+               self.query_buffer.set_text('Press "Query" to retrieve USRP 
information...')                     
+               self.vbox.pack_start(self.query_buffer) 
+               self.show_all() 
+               self.run()
+               self.destroy()
+               
+       def _diagnose_usrp(self, widget=None):
+               """Query the USRP device and copy the results into the query 
text box."""
+               from gnuradio import usrp
+               type = self.USRP_type.parse()
+               if type == 'rx':        #for the rx query, use the source and 
rx methods
+                       make = usrp.source_c
+                       get_mux = usrp.determine_rx_mux_value
+               elif type == 'tx':      #for the tx query, use the sink and tx 
methods
+                       make = usrp.sink_c
+                       get_mux = usrp.determine_tx_mux_value
+               try:            
+                       u = make(self.USRP_number.parse())
+                       subdev_spec = self.USRP_subdev.parse()  
+                       subdev = usrp.selected_subdev(u, subdev_spec)#get the 
subdev
+                       msg = ">>> USRP Query\n"
+                       msg = "%s\nName:\n\t%s\n"%(msg,str(subdev.name()))
+                       msg = "%s\nAutomated Mux:\n\t0x%08x\n"%(msg, 
0xFFFFFFFFL & long(get_mux(u, subdev_spec))) #ensure that the value is 
displayed as: 8 nibbles, unsigned, hex
+                       msg = "%s\nConverter 
Rate:\n\t%s\n"%(msg,u.converter_rate())
+                       msg = "%s\nUses Quadrature:\n\t%s\n"%(msg, 
str(subdev.is_quadrature()))
+                       gain_min, gain_max, gain_step = subdev.gain_range()
+                       msg = "%s\nGain Range (min, max, step 
size):\n\t%s\n\t%s\n\t%s\n"%(msg, gain_min, gain_max, gain_step)
+                       freq_min, freq_max, freq_step = subdev.freq_range()
+                       msg = "%s\nFreq Range (min, max, step 
size):\n\t%s\n\t%s\n\t%s\n"%(msg, freq_min, freq_max, freq_step)
+                       self.query_buffer.set_text(msg)
+               except Exception, e:    #display the error message
+                       self.query_buffer.set_text('''\
+>>> Error\n%s
+
+If the USRP cannot be found, make sure that the USRP is plugged-in and restart 
this program. \
+If the problem persists, there may be a problem with you gnuradio installation 
or USB 2.0.
+'''%str(e))            
+               
+               
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/Preferences.py

Copied: grc/tags/grc_0.69/src/Preferences.py (from rev 6375, 
grc/trunk/src/Preferences.py)
===================================================================
--- grc/tags/grc_0.69/src/Preferences.py                                (rev 0)
+++ grc/tags/grc_0.69/src/Preferences.py        2007-09-20 01:49:24 UTC (rev 
6483)
@@ -0,0 +1,194 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden Preferences
+#Holds global preferences stored as GraphicalParams.
address@hidden Josh Blum
+
+from DataTypes import Bool,Enum,Int,String
+from Elements import GraphicalParam, Param
+import time,socket #for tagging saved files
+from Constants import *
+import ParseXML
+import Messages
+
+PARAM_CHECKING_PREF = GraphicalParam('Parameter Checking', Bool(true='Verify 
Parameters', false='Ignore Invalid Params', default=True))
+CONNECTION_CHECKING_PREF = GraphicalParam('Connection Checking', 
Bool(true='Match Data Types', false='Ignore Data Types', default=True))
+SOCKET_CHECKING_PREF = GraphicalParam('Socket Checking', Bool(true='Require 
Connections', false='Allow Open Sockets', default=True))
+FILES_OPEN_PREF = Param('Files Open', String())
+RESTORE_FILES_PREF = GraphicalParam('Restore Files', Bool(true='Restore 
Previous Files', false='Restore Nothing', default=True))
+SNAP_TO_GRID_PREF = GraphicalParam('Snap to Grid', Bool(true='On', 
false='Off', default=False))
+GRID_SIZE_PREF = GraphicalParam('Grid Size (pixels)', Enum([
+       ('10 pixels', 10), 
+       ('20 pixels', 20), 
+       ('30 pixels', 30),
+       ('40 pixels', 40),
+       ('50 pixels', 50),
+       ('60 pixels', 60),
+       ('70 pixels', 70),
+       ('80 pixels', 80),
+       ('90 pixels', 90),
+       ('100 pixels', 100),], 2))
+SHOW_GRID_PREF = GraphicalParam('Grid Points', Bool(true='Show Grid', 
false='Hide Grid', default=False))
+REPORTS_WIN_SHOW_PREF = GraphicalParam('Reports Window', Bool(true='Show 
Reports Window', false='Hide Reports Window', default=True))
+MAIN_WINDOW_WIDTH_PREF = Param('Main Window Width', 
Int(DEFAULT_MAIN_WINDOW_WIDTH))
+MAIN_WINDOW_HEIGHT_PREF = Param('Main Window Height', 
Int(DEFAULT_MAIN_WINDOW_HEIGHT))
+
+###########################################################################
+#      List of Preferences
+###########################################################################
+
+PREFS_LIST = [ #(title, notes, list of preferences)
+       ("Verification", '''\
+Verification ensures that:
+       signal block parameters pass validation,
+       data types on either side of a connection match,
+       and input/output sockets connect.
+       
+You may disable any one of these validation checks. \
+However, the resulting flow graph may fail execution. \
+''', [ 
+                       (PARAM_CHECKING_PREF, 'param_check'),
+                       (CONNECTION_CHECKING_PREF, 'connection_check'),
+                       (SOCKET_CHECKING_PREF, 'socket_check'),
+               ]
+       ),
+       ("Grid Options", '''\
+Snap to Grid forces the upper right corner of the signal block to align with a 
grid point. \
+''', [
+                       (SNAP_TO_GRID_PREF, 'snap_to_grid'),
+                       (GRID_SIZE_PREF, 'grid_size'),
+                       (SHOW_GRID_PREF, 'show_grid'),
+               ]
+       ),
+       ("Misc Options", '', [
+                       (REPORTS_WIN_SHOW_PREF, 'show_reports_window'),
+                       (RESTORE_FILES_PREF, 'restore_files'),
+               ]
+       ),      
+       ('', '', [      #put hidden prefs here
+                       (FILES_OPEN_PREF, 'files_open'),
+                       (MAIN_WINDOW_WIDTH_PREF, 'window_width'),
+                       (MAIN_WINDOW_HEIGHT_PREF, 'window_height'),
+               ]
+       ),      
+]
+       
+PREFS_DICT = dict((key, param) for param, key in reduce(lambda l1, l2: l1 + 
l2, zip(*PREFS_LIST)[2]))
+
+###########################################################################
+#      Preference Access Methods
+###########################################################################
+
+def _get_value(param):
+       """!
+       Get the value of the given parameter.
+       If the param is valid, return the parsed value of the param, otherwise 
return a blank string.   
+       @param param the parameter
+       @return the value of the parameter
+       """
+       if param.get_data_type().is_valid(): return 
param.get_data_type().parse()
+       else: return ''
+       
+def _to_nested():
+       """!
+       Convert the param's data to nested format.
+       @return the nested format
+       """
+       prefs = [('pref', [('key', key), ('value', 
param.get_data_type().get_data())]) for key,param in PREFS_DICT.iteritems()]
+       nested_data = ('preferences', [
+                       ('timestamp', str(time.time())),
+                       ('hostname', socket.gethostname()),
+                       ('version', VERSION),                                   
                                                
+                       ('prefs', prefs),
+               ]
+       )       
+       return nested_data
+       
+def _from_nested(nested_data):
+       """!
+       Parse the nested data to retrieve each preference.
+       @param nested_data the nested data
+       """
+       find_data = ParseXML.find_data
+       preferences = find_data([nested_data], 'preferences')
+       prefs = find_data(preferences, 'prefs')
+       for pref in prefs:
+               pref = find_data([pref], 'pref')
+               key = find_data(pref, 'key')
+               value = find_data(pref, 'value')
+               try: PREFS_DICT[key].get_data_type().set_data(value)
+               except: pass
+               
+def load(window=None):
+       """!
+       Load the preferences from the preferences file.
+       @param window optional flow graph window
+       """
+       try: 
+               
_from_nested(ParseXML.from_xml(ParseXML.from_file(PREFERENCES_FILE_PATH)))
+               if window: window.resize(_get_value(MAIN_WINDOW_WIDTH_PREF), 
_get_value(MAIN_WINDOW_HEIGHT_PREF))
+       except: Messages.send_fail_load_preferences()           
+
+def save(window=None):
+       """!
+       Save the preferences to the preferences file.
+       @param window optional flow graph window
+       """
+       if window:
+               width,height = window.get_size()
+               MAIN_WINDOW_WIDTH_PREF.get_data_type().set_data(width)
+               MAIN_WINDOW_HEIGHT_PREF.get_data_type().set_data(height)
+       try: ParseXML.to_file(ParseXML.to_xml(_to_nested()), 
PREFERENCES_FILE_PATH)             
+       except IOError: Messages.send_fail_save_preferences()
+               
+###########################################################################
+#      Special methods for specific program functionalities
+###########################################################################
+       
+def restore_files():
+       return _get_value(RESTORE_FILES_PREF)   
+       
+def files_open():
+       return _get_value(FILES_OPEN_PREF).split('\n')
+       
+def save_files_open(files):
+       FILES_OPEN_PREF.get_data_type().set_data('\n'.join(files))
+       
+def check_connections():
+       return _get_value(CONNECTION_CHECKING_PREF)
+       
+def check_sockets():
+       return _get_value(SOCKET_CHECKING_PREF)
+
+def check_params():
+       return _get_value(PARAM_CHECKING_PREF)
+       
+def show_reports_window(window):
+       return window.show_reports_window(_get_value(REPORTS_WIN_SHOW_PREF))
+       
+def get_grid_size():
+       return _get_value(GRID_SIZE_PREF)       
+       
+def snap_to_grid():
+       return _get_value(SNAP_TO_GRID_PREF)
+       
+def show_grid():
+       return _get_value(SHOW_GRID_PREF)
+               
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py (from rev 6347, 
grc/trunk/src/SignalBlockDefs/Filters.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py                            
(rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/Filters.py    2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,489 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.Filters
+#Taps generators are from gr.firdes. Most FIR filters are implemented and a 
few misc ones.
address@hidden Josh Blum
+
+from DataTypes import *
+from gnuradio import gr,gru,blks2
+from SignalBlockConstants import default_samp_rate,all_choices
+
+###########################################################################
+#      Generic filters with taps parameters
+###########################################################################
+def FIRFilter(sb):
+       filters = Enum([
+               ('Complex->Complex (Complex Taps)', (gr.fir_filter_ccc, 
gr.interp_fir_filter_ccc, Complex(), Complex(), ComplexVector())),      
+               ('Complex->Complex (Float Taps)', (gr.fir_filter_ccf, 
gr.interp_fir_filter_ccf, Complex(), Complex(), FloatVector())),  
+               ('Float->Complex (Complex Taps)', (gr.fir_filter_fcc, 
gr.interp_fir_filter_fcc, Float(), Complex(), ComplexVector())),  
+               ('Float->Float (Float Taps)', (gr.fir_filter_fff, 
gr.interp_fir_filter_fff, Float(), Float(), FloatVector())),  
+               ('Float->Short (Float Taps)', (gr.fir_filter_fsf, 
gr.interp_fir_filter_fsf, Float(), Short(), FloatVector())),  
+               ('Short->Complex (Complex Taps)', (gr.fir_filter_scc, 
gr.interp_fir_filter_scc, Short(), Complex(), ComplexVector())),          
+       ])
+       sb.add_input_socket('in', Variable(filters, index=2))
+       sb.add_output_socket('out', Variable(filters, index=3))
+       sb.add_param('Filter Type', filters, False, type=True)
+       sb.add_param('Type', Enum([('Decimating', 0), ('Interpolating', 1)]))   
#this parses into an index for the filters Enum
+       sb.add_param('Decimation', Int(1, min=1))       
+       sb.add_param('Taps', Variable(filters, index=4, min=1), variable=True)  
+       sb.set_docs('''\
+The decimation parameter becomes interpolation if the filter type is set to 
interpolation. ''')
+       def make(fg, filter_type, type, decim, taps):
+               block = filter_type.parse()[type.parse()](decim.parse(), 
taps.parse())
+               fg.add_callback(block.set_taps, taps)
+               return block
+       return sb,make
+       
+def FreqXlatingFIRFilter(sb):  
+       filters = Enum([
+               ('Complex', (gr.freq_xlating_fir_filter_ccc, 
gr.freq_xlating_fir_filter_ccf, Complex())),       
+               ('Float', (gr.freq_xlating_fir_filter_fcc, 
gr.freq_xlating_fir_filter_fcf, Float())),
+               ('Short', (gr.freq_xlating_fir_filter_scc, 
gr.freq_xlating_fir_filter_scf, Short())),                   
+       ])
+       taps = Enum([
+               ('Complex', (0, ComplexVector())),
+               ('Float', (1, FloatVector())),
+       ])
+       sb.add_input_socket('in', Variable(filters, index=2))
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Input Type', filters, False, type=True)
+       sb.add_param('Taps Type', taps) #this parses into an index for the 
filters Enum
+       sb.add_param('Samp Rate', Float(default_samp_rate))
+       sb.add_param('Center Freq', Float(), variable=True)
+       sb.add_param('Decimation', Int(1, min=1))       
+       sb.add_param('Taps', Variable(taps, index=1, min=1), variable=True)
+       def make(fg, filter_type, taps_type, samp_rate, center_freq, decim, 
taps):
+               block = 
filter_type.parse()[taps_type.parse()[0]](decim.parse(), taps.parse(), 
center_freq.parse(), samp_rate.parse())
+               fg.add_callback(block.set_taps, taps)
+               fg.add_callback(block.set_center_freq, center_freq)
+               return block
+       return sb,make
+       
+def FFTFilter(sb):
+       filters = Enum([
+               ('Complex', (gr.fft_filter_ccc, Complex(), ComplexVector())),   
+               ('Float', (gr.fft_filter_fff, Float(), FloatVector())),         
        
+       ])      
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=1))
+       sb.add_param('Type', filters, False, type=True)
+       sb.add_param('Decimation', Int(1, min=1))       
+       sb.add_param('Taps', Variable(filters, index=2, min=1), variable=True)
+       sb.set_docs('''The type selection controls the data type of the input, 
output, and taps.''')
+       def make(fg, type, decim, taps):
+               block = type.parse()[0](decim.parse(), taps.parse())
+               fg.add_callback(block.set_taps, taps)
+               return block
+       return sb,make
+       
+def RationalResampler(sb):
+       filters = Enum([
+               ('Complex->Complex (Complex Taps)', 
(gr.rational_resampler_base_ccc, Complex(), Complex(), ComplexVector())),
+               ('Complex->Complex (Float Taps)', 
(gr.rational_resampler_base_ccf, Complex(), Complex(), FloatVector())),
+               ('Float->Complex (Complex Taps)', 
(gr.rational_resampler_base_fcc, Float(), Complex(), ComplexVector())),
+               ('Float->Float (Float Taps)', (gr.rational_resampler_base_fff, 
Float(), Float(), FloatVector())),
+               ('Float->Short (Float Taps)', (gr.rational_resampler_base_fsf, 
Float(), Short(), FloatVector())),
+               ('Short->Complex (Complex Taps)', 
(gr.rational_resampler_base_scc, Short(), Complex(), ComplexVector())),
+       ])      
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=2))
+       sb.add_param('Filter Type', filters, False, type=True)
+       sb.add_param('Interpolation', Int(1, min=1))    
+       sb.add_param('Decimation', Int(1, min=1))       
+       sb.add_param('Taps', Variable(filters, index=3, min=1), variable=True)
+       def make(fg, filter_type, interp, decim, taps):
+               block = filter_type.parse()[0](interp.parse(), decim.parse(), 
taps.parse())
+               fg.add_callback(block.set_taps, taps)
+               return block
+       return sb,make
+
+def IIRFiler(sb):
+       fcn = gr.iir_filter_ffd
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Float())
+       sb.add_param('FF Taps', FloatVector())
+       sb.add_param('FB Taps', FloatVector())
+       return sb, lambda fg, fftaps, fbtaps: fcn(fftaps.parse(), 
fbtaps.parse())
+
+def FilterDelay(sb):
+       fcn = gr.filter_delay_fc
+       sb.add_input_socket('in1', Float())
+       sb.add_input_socket('in2', Float(), optional=True)
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Taps', FloatVector())
+       sb.set_docs('''\
+The block takes one or two float stream and outputs a complex stream. \
+If only one float stream is input, \
+the real output is a delayed version of this input and the imaginary output is 
the filtered output. \
+If two floats are connected to the input, \
+then the real output is the delayed version of the first input, \
+the imaginary output is the filtered output. \
+The delay in the real path accounts for the group delay introduced by the 
filter in the imaginary path.\
+''')
+       return sb, lambda fg, taps: fcn(taps.parse())
+       
+def ChannelModel(sb):
+       fcn = blks2.channel_model
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Noise Voltage', Float(0.0), variable=True)
+       sb.add_param('Freq Offset', Float(0.0), variable=True)
+       sb.add_param('Epsilon', Float(1.0))
+       sb.add_param('Taps', ComplexVector('1.0,0.0'), variable=True)
+       sb.set_docs('''\
+Creates a channel model that includes:
+       - AWGN noise power in terms of noise voltage
+       - A frequency offest in the channel in ratio
+       - A timing offset ratio to model clock difference (epsilon)
+       - Multipath taps
+''')
+       def make(fg, noise_voltage, frequency_offset, epsilon, taps):
+               block = fcn(noise_voltage.parse(), frequency_offset.parse(), 
epsilon.parse(), taps.parse())
+               fg.add_callback(block.set_noise_voltage, noise_voltage)
+               fg.add_callback(block.set_frequency_offset, frequency_offset)
+               fg.add_callback(block.set_taps, taps)
+               return block
+       return sb, make
+
+###########################################################################
+#      Special filters using taps generators
+###########################################################################
+def make_filter(fg, filter_type, decimation, taps_maker, taps_args):
+       filter = filter_type.parse()[0]
+       decimation = decimation.parse() 
+       taps = taps_maker(*map(lambda data:data.parse(), taps_args))            
+       block = filter(decimation, taps)
+       fg.add_callback(lambda *args: block.set_taps(taps_maker(*args)), 
*taps_args)
+       return block    
+
+window_choices = [
+       ('Hamming', gr.firdes.WIN_HAMMING),
+       ('Hann', gr.firdes.WIN_HANN),
+       ('Blackman', gr.firdes.WIN_BLACKMAN),
+       ('Rectangular', gr.firdes.WIN_RECTANGULAR),
+       ('Kaiser', gr.firdes.WIN_KAISER),
+]
+filter_choices = [
+       ('FFT: Float->Float', (gr.fft_filter_fff, Float(), Float())),
+       ('FIR: Complex->Complex', (gr.fir_filter_ccf, Complex(), Complex())),
+       ('FIR: Float->Float', (gr.fir_filter_fff, Float(), Float())),
+       ('FIR: Float->Short', (gr.fir_filter_fsf, Float(), Short())),
+       ('Interp FIR: Complex->Complex', (gr.interp_fir_filter_ccf, Complex(), 
Complex())),
+       ('Interp FIR: Float->Float', (gr.interp_fir_filter_fff, Float(), 
Float())),
+       ('Interp FIR: Float->Short', (gr.interp_fir_filter_fsf, Float(), 
Short())),
+]
+                       
+def LowPassFilter(sb):
+       taps_maker = gr.firdes.low_pass
+       pass_filter_helper(sb, taps_maker)
+       def make(fg, filter_type, gain, samp_freq, cutoff_freq, 
transition_width, decimation, window, beta):
+               taps_args = (gain, samp_freq, cutoff_freq, transition_width, 
window, beta)              
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+
+def HighPassFilter(sb):
+       taps_maker = gr.firdes.high_pass
+       pass_filter_helper(sb, taps_maker)
+       def make(fg, filter_type, gain, samp_freq, cutoff_freq, 
transition_width, decimation, window, beta):
+               taps_args = (gain, samp_freq, cutoff_freq, transition_width, 
window, beta)              
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+
+def BandPassFilter(sb):
+       taps_maker = gr.firdes.band_pass
+       pass_filter_helper(sb, taps_maker)
+       def make(fg, filter_type, gain, samp_freq, low_cutoff_freq, 
high_cutoff_freq, transition_width, decimation, window, beta):
+               taps_args = (gain, samp_freq, low_cutoff_freq, 
high_cutoff_freq, transition_width, window, beta)                
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+
+def BandRejectFilter(sb):
+       taps_maker = gr.firdes.band_reject
+       pass_filter_helper(sb, taps_maker)
+       def make(fg, filter_type, gain, samp_freq, low_cutoff_freq, 
high_cutoff_freq, transition_width, decimation, window, beta):
+               taps_args = (gain, samp_freq, low_cutoff_freq, 
high_cutoff_freq, transition_width, window, beta)                
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+
+def pass_filter_helper(sb, taps_maker):
+       filters = Enum(filter_choices, 2)
+       windows = Enum(window_choices, 1)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=2))
+       sb.add_param('Filter Type', filters, type=True)
+       sb.add_param('Gain', Float(1), variable=True)
+       sb.add_param('Sampling Rate', Float(default_samp_rate), variable=True)
+       if taps_maker in (gr.firdes.low_pass, gr.firdes.high_pass): 
+               sb.add_param('Cutoff Freq', Float(1000), variable=True)
+       elif taps_maker in (gr.firdes.band_pass, gr.firdes.band_reject):
+               sb.add_param('Low Cutoff Freq', Float(500), variable=True)
+               sb.add_param('High Cutoff Freq', Float(1500), variable=True)
+       sb.add_param('Transition Width', Float(100), variable=True)             
+       sb.add_param('Decimation', Int(1, min=1))
+       sb.add_param('Window Type', windows)
+       sb.add_param('Beta', Float(6.76), variable=True)
+       sb.set_docs('''\
+The decimation parameter becomes interpolation if the filter type is set to 
interpolation.''')
+
+def Window(sb):
+       taps_maker = gr.firdes.window
+       filters = Enum(filter_choices, 2)
+       windows = Enum(window_choices, 1)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=2)) 
+       sb.add_param('Filter Type', filters, type=True)
+       sb.add_param('Decimation', Int(1, min=1))
+       sb.add_param('Window Type', windows)
+       sb.add_param('Num Taps', Int(20, min=0), variable=True)
+       sb.add_param('Beta', Float(6.76), variable=True)
+       def make(fg, filter_type, decimation, window, ntaps, beta):
+               taps_args = (window, ntaps, beta)
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+
+def RootRaisedCosine(sb):
+       taps_maker = gr.firdes.root_raised_cosine
+       filters = Enum(filter_choices, 2)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=2))
+       sb.add_param('Filter Type', filters, type=True)         
+       sb.add_param('Decimation', Int(1, min=1))
+       sb.add_param('Gain', Float(1), variable=True)
+       sb.add_param('Sampling Rate', Float(default_samp_rate), variable=True)
+       sb.add_param('Symbol Rate', Float(100), variable=True)
+       sb.add_param('Alpha', Float(6.76), variable=True)
+       sb.add_param('Num Taps', Int(20, min=0), variable=True)         
+       def make(fg, filter_type, decimation, gain, samp_freq, symbol_rate, 
alpha, ntaps):              
+               taps_args = (gain, samp_freq, symbol_rate, alpha, ntaps)
+               return make_filter(fg, filter_type, decimation, taps_maker, 
taps_args)
+       return sb, make
+       
+###########################################################################
+#      Other filters
+###########################################################################
+def Hilbert(sb):
+       fcn = gr.hilbert_fc
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Num Taps', Int(10, min=0))
+       return sb, lambda fg, num_taps: fcn(num_taps.parse())
+       
+def Goertzel(sb):   
+       fcn = gr.goertzel_fc  
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Rate', Int())
+       sb.add_param('Length', Int())
+       sb.add_param('Frequency', Float())   
+       return sb, lambda fg, rate, len, freq: 
fcn(rate.parse(),len.parse(),freq.parse()) 
+       
+def PowerSquelch(sb):
+       fcn = gr.simple_squelch_cc
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Threshold (dB)', Float(30), variable=True)
+       sb.add_param('Alpha', Float(.5), variable=True)
+       sb.set_docs('''Power levels below the threshold are not passed 
through.''')
+       def make(fg, threshold, alpha):
+               block = fcn(threshold.parse(), alpha.parse())
+               fg.add_callback(block.set_threshold, threshold)
+               fg.add_callback(block.set_alpha, alpha)
+               return block
+       return sb, make
+       
+def SinglePoleIIRFilter(sb):
+       vlen = Int(1, min=1)
+       type = Enum([
+               ('Float', (gr.single_pole_iir_filter_ff, Float())),
+               ('Complex', (gr.single_pole_iir_filter_cc, Complex())),
+       ])
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_output_socket('out', Variable(type, index=1), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Alpha', Float(1), variable=True)
+       sb.add_param('Vector Length', vlen)
+       def make(fg, type, alpha, vlen):
+               block = type.parse()[0](alpha.parse(), vlen.parse())
+               fg.add_callback(block.set_taps, alpha)
+               return block
+       return sb, make
+       
+def AutomaticGainControl(sb):
+       type = Enum([('Complex', (gr.agc_cc, Complex())), ('Float', (gr.agc_ff, 
Float())),], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_output_socket('out', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Rate', Float(1e-4))
+       sb.add_param('Reference', Float(1))
+       sb.add_param('Gain', Float(1))
+       sb.add_param('Max Gain', Float(0))      
+       return sb, lambda fg, type, rate, ref, gain, max_gain: \
+               type.parse()[0](rate.parse(), ref.parse(), gain.parse(), 
max_gain.parse())              
+               
+def AutomaticGainControl2(sb):
+       type = Enum([('Complex', (gr.agc2_cc, Complex())), ('Float', 
(gr.agc2_ff, Float())),], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_output_socket('out', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Attack Rate', Float(1e-1))
+       sb.add_param('Decay Rate', Float(1e-2))
+       sb.add_param('Reference', Float(1))
+       sb.add_param('Gain', Float(1))
+       sb.add_param('Max Gain', Float(0))      
+       return sb, lambda fg, type, attack_rate, decay_rate, ref, gain, 
max_gain: \
+               type.parse()[0](attack_rate.parse(), decay_rate.parse(), 
ref.parse(), gain.parse(), max_gain.parse())
+               
+def FeedForwardAGC(sb):
+       fcn = gr.feedforward_agc_cc
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Num Samples', Int(100, min=1))
+       sb.add_param('Reference', Float(0))
+       sb.set_docs('''Non-causal AGC which computes required gain based on max 
absolute value over nsamples.''')
+       return sb, lambda fg, nsamps, ref: fcn(nsamps.parse(), ref.parse())     
+       
+def CMAFilter(sb):
+       fcn = gr.cma_equalizer_cc
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Complex())
+       sb.add_param('Num Taps', Int(10, min=0))
+       sb.add_param('Modulus', Float())
+       sb.add_param('Mu', Float())
+       sb.set_docs('''Constant Modulus Adaptive Filter.''')
+       return sb, lambda fg, num_taps, mod, mu: fcn(num_taps.parse(), 
mod.parse(), mu.parse())
+       
+def ClockRecovery(sb):
+       type = Enum([
+               ('Complex', (gr.clock_recovery_mm_cc, Complex())),
+               ('Float', (gr.clock_recovery_mm_ff, Float())),
+       ])
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_output_socket('out', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Omega', Float(), variable=True)
+       sb.add_param('Gain Omega', Float(), variable=True)
+       sb.add_param('Mu', Float(), variable=True)
+       sb.add_param('Gain Mu', Float(), variable=True)
+       sb.add_param('Omega Relative Limit', Float())
+       sb.set_docs('''Mueller & Mueller clock recovery.''')
+       def make(fg, type, omega, gain_omega, mu, gain_mu, omega_rel_limit): 
+               block = type.parse()[0](omega.parse(), gain_omega.parse(), 
mu.parse(), gain_mu.parse(), omega_rel_limit.parse())
+               fg.add_callback(block.set_gain_mu, gain_mu)
+               fg.add_callback(block.set_gain_omega, gain_omega)
+               fg.add_callback(block.set_mu, mu)
+               fg.add_callback(block.set_omega, omega)
+               return block
+       return sb,make  
+       
+def FFT(sb):
+       taps_maker = gr.firdes.window
+       type = Enum([
+               ('Complex', (gr.fft_vcc, ComplexVector())),
+               ('Float', (gr.fft_vfc, FloatVector())),
+       ])
+       sb.add_input_socket('vin', Variable(type, index=1))
+       sb.add_output_socket('vout', ComplexVector())
+       sb.add_param('Input Type', type, False, type=True)
+       sb.add_param('FFT Size', Int(512, min=1))
+       sb.add_param('Window', Enum(window_choices, 1)) 
+       sb.add_param('Beta', Float(6.76))
+       return sb, lambda fg, type, size, window, beta: \
+               type.parse()[0](size.parse(), True, taps_maker(window.parse(), 
size.parse(), beta.parse()))
+
+def IFFT(sb):
+       fcn = gr.fft_vcc
+       taps_maker = gr.firdes.window
+       sb.add_input_socket('vin', ComplexVector())
+       sb.add_output_socket('vout', ComplexVector())
+       sb.add_param('FFT Size', Int(512, min=1))
+       sb.add_param('Window', Enum(window_choices, 1), type=True)      
+       sb.add_param('Beta', Float(6.76))
+       return sb, lambda fg, size, window, beta: \
+               fcn(size.parse(), False, taps_maker(window.parse(), 
size.parse(), beta.parse()))
+                                                                               
                                        
+def Upsample(sb):
+       taps_maker = gr.firdes.window
+       type = Enum([
+               ('Complex', (gr.rational_resampler_base_ccf, Complex())),
+               ('Float', (gr.rational_resampler_base_fff, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))      
+       sb.add_output_socket('out', Variable(type, index=1))    
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Interpolation (L)', Int(1, min=1))        
+       sb.set_docs('''\
+Add L-1 zeros between each sample in f(k). 
+>>> Implements a gr.rational_resampler_base_**f(decim=1,  taps=[1.0])''')
+       return sb, lambda fg, type, interp: type.parse()[0](interp.parse(), 1, 
[1.0])
+
+def Downsample(sb):
+       fcn = gr.keep_one_in_n
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))
+       sb.add_output_socket('out', Variable(type))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Decimation (M)', Int(1, min=1), variable=True)
+       sb.set_docs('''\
+Reduce the sample rate by keeping every Mth sample.
+>>> Implements the gr.keep_one_in_n block.''')
+       def make(fg, type, decimation):
+               type = type.parse()
+               block = fcn(type.get_num_bytes(), decimation.parse())
+               fg.add_callback(block.set_n, decimation)
+               return block
+       return sb, make
+
+def FractionalResampler(sb):
+       lcm = gru.lcm 
+       filters = Enum([
+               ('Complex', (blks2.rational_resampler_ccc, Complex())),
+               ('Float', (blks2.rational_resampler_fff, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=1))
+       sb.add_param('Type', filters, False, type=True)
+       sb.add_param('Input Rate', Int(100e3))
+       sb.add_param('Output Rate', Int(100e3))
+       sb.add_param('Fractional Bandwidth', Float(0.4, min=0.0, max=0.5))
+       sb.set_docs('''\
+Rational Resampler with a low pass FIR filter. \
+The fractional bandwidth must be a number between 0 and 0.5. \
+The fractional bandwidth controls the transition width of the low pass filter. 
''')
+       def make(fg, filter_type, inrate, outrate, fractional_bw):
+               in_rate = inrate.parse()
+               out_rate = outrate.parse()
+               interp = int(lcm(in_rate, out_rate)/in_rate)
+               decim = int(lcm(in_rate, out_rate)/out_rate)
+               return filter_type.parse()[0](interp, decim, taps=None, 
fractional_bw=fractional_bw.parse())
+       return sb, make
+       
+def FractionalInterpolator(sb):
+       filters = Enum([
+               ('Complex', (gr.fractional_interpolator_cc, Complex())),
+               ('Float', (gr.fractional_interpolator_ff, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(filters, index=1))
+       sb.add_output_socket('out', Variable(filters, index=1))
+       sb.add_param('Type', filters, False, type=True)
+       sb.add_param('Phase Shift', Float())
+       sb.add_param('Interp Ratio', Float())   
+       def make(fg, filter_type, phase_shit, interp_ratio):
+               return filter_type.parse()[0](phase_shift.parse(), 
interp_ratio.parse())
+       return sb, make
+       

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py (from rev 6476, 
grc/trunk/src/SignalBlockDefs/GraphicalSinks.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py                     
        (rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/GraphicalSinks.py     2007-09-20 
01:49:24 UTC (rev 6483)
@@ -0,0 +1,192 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.GraphicalSinks
+#Various graphical sinks.
address@hidden Josh Blum
+
+from DataTypes import *
+from gnuradio import gr
+from SignalBlockConstants import default_samp_rate
+
+number_display_pritority = 0
+fft_display_priority = 1
+scope_display_priority = 2
+constellation_display_pritority = 3
+waterfall_display_priority = 4
+
+def FFTSink(sb):
+       from gnuradio.wxgui import fftsink2
+       type = Enum([
+               ('Complex', (fftsink2.fft_sink_c, Complex())),
+               ('Float', (fftsink2.fft_sink_f, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Title', String('FFT'))    
+       sb.add_param('Sampling Rate', Int(default_samp_rate))
+       sb.add_param('Y per div', Int(20), variable=True)
+       sb.add_param('Reference Level', Int(20), variable=True)
+       sb.add_param('FFT Size', Int(512))      
+       sb.add_param('FFT Rate', Int(15))       
+       sb.add_param('Options', Enum([('Off', None), ('Average Values', 1), 
('Peak Hold', 2)]))
+       sb.set_docs('''The fft sink has a throttle automatically attatched to 
it at runtime to save the CPU.''')        
+       def make(fg, type, title, samp_rate, y_per_div, ref_lvl, fft_size, 
fft_rate, options):
+               options = options.parse()
+               peak_hold = (options == 2)
+               average = (options == 1)
+               block = type.parse()[0](fg.get_panel(), title=title.parse(), 
y_per_div=y_per_div.parse(), 
+                       ref_level=ref_lvl.parse(), fft_size=fft_size.parse(), 
sample_rate=samp_rate.parse(),
+                       fft_rate=fft_rate.parse())
+               block.set_peak_hold(peak_hold)  #set the peak hold option 
outside the contructor 
+               block.set_average(average)                      #set the 
average option outside the contructor
+               fg.add_window(block.win, fft_display_priority, title.parse())
+               fg.add_callback(block.set_ref_level, ref_lvl)
+               fg.add_callback(block.set_y_per_div, y_per_div)
+               throttle = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
+               fg.connect(throttle, block)
+               return throttle
+       return sb, make
+       
+def WaterfallSink(sb):
+       from gnuradio.wxgui import waterfallsink2
+       type = Enum([
+               ('Complex', (waterfallsink2.waterfall_sink_c, Complex())),
+               ('Float', (waterfallsink2.waterfall_sink_f, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Title', String('Waterfall'))
+       sb.add_param('Sampling Rate', Int(default_samp_rate))
+       sb.add_param('Baseband Freq', Int(0), variable=True)
+       sb.add_param('Y per div', Int(20))
+       sb.add_param('Reference Level', Int(20))
+       sb.add_param('FFT Size', Int(512))      
+       sb.add_param('FFT Rate', Int(15))       
+       sb.add_param('Options', Enum([('Off', None), ('Average Values', 1)]))
+       sb.set_docs('''The waterfall sink has a throttle automatically 
attatched to it at runtime to save the CPU.''')  
+       def make(fg, type, title, samp_rate, baseband_freq, y_per_div, ref_lvl, 
fft_size, fft_rate, options):
+               options = options.parse()
+               average = (options == 1)
+               block = type.parse()[0](fg.get_panel(), title=title.parse(), 
y_per_div=y_per_div.parse(), 
+                       ref_level=ref_lvl.parse(), fft_size=fft_size.parse(), 
sample_rate=samp_rate.parse(),
+                       baseband_freq=baseband_freq.parse(), 
fft_rate=fft_rate.parse())         
+               block.set_average(average)                      #set the 
average option outside the contructor
+               fg.add_window(block.win, waterfall_display_priority, 
title.parse())
+               fg.add_callback(block.set_baseband_freq, baseband_freq)
+               throttle = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
+               fg.connect(throttle, block)
+               return throttle
+       return sb, make
+       
+def ScopeSink(sb):
+       from gnuradio.wxgui import scopesink2
+       type = Enum([
+               ('Complex', (scopesink2.scope_sink_c, Complex())),
+               ('Float', (scopesink2.scope_sink_f, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Title', String('Scope'))
+       sb.add_param('Sampling Rate', Int(default_samp_rate))   
+       sb.add_param('Frame Decimation', Int(1))
+       sb.add_param('Vertical Scale', Float(0))        
+       sb.add_param('Time Scale', Float(.001))
+       sb.set_docs('''\
+The scope sink has a throttle automatically attatched to it at runtime to save 
the CPU. \
+Complex inputs to the scope show up as 2 channels (real and imaginary). \
+A Vertical Scale of 0, sets the scope to auto-scale.''')       
+       def make(fg, type, title, samp_rate, frame_decim, v_scale, t_scale):
+               v_scale = v_scale.parse()
+               if v_scale == 0: v_scale = None # v_scale = None means 
auto-scale
+               block = type.parse()[0](fg.get_panel(), title=title.parse(), 
+                       sample_rate=samp_rate.parse(), 
frame_decim=frame_decim.parse(), 
+                       v_scale=v_scale, t_scale=t_scale.parse())
+               fg.add_window(block.win, scope_display_priority, title.parse()) 
+               throttle = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
+               fg.connect(throttle, block)
+               return throttle
+       return sb, make
+       
+def ConstellationSink(sb):
+       from gnuradio.wxgui import scopesink2
+       fcn = scopesink2.scope_sink_c   #dont tell anyone that its really a 
scope sink
+       sb.add_input_socket('in', Complex())
+       sb.add_param('Title', String('Constellation'))
+       sb.add_param('Sampling Rate', Int(default_samp_rate))   
+       sb.add_param('Frame Decimation', Int(1))
+       sb.add_param('Marker', Enum([('Plus', 0), ('Dot', 1), ('Line', 2)]))
+       sb.set_docs('''\
+The constellation sink has a throttle automatically attatched to it at runtime 
to save the CPU. ''')   
+       def make(fg, title, samp_rate, frame_decim, marker):
+               block = fcn(fg.get_panel(), title=title.parse(), 
+                       sample_rate=samp_rate.parse(), 
frame_decim=frame_decim.parse())
+               block.win.info.xy = True        #true for X:Y
+               marker = marker.parse()
+               if marker == 0: block.win.set_format_plus()
+               elif marker == 1: block.win.set_format_dot()
+               elif marker == 2: block.win.set_format_line()
+               fg.add_window(block.win, constellation_display_pritority, 
title.parse())        
+               throttle = gr.throttle(Complex().get_num_bytes(), 
samp_rate.parse())
+               fg.connect(throttle, block)
+               return throttle
+       return sb, make
+
+def NumericalSink(sb):
+       from gnuradio.wxgui import numbersink2
+       type = Enum([
+               ('Complex', (numbersink2.number_sink_c, Complex())),
+               ('Float', (numbersink2.number_sink_f, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Title', String('Number'))
+       sb.add_param('Unit', String('Units'))
+       sb.add_param('Sampling Rate', Int(default_samp_rate))
+       sb.add_param('Base Value', Float(0.0), variable=True)
+       sb.add_param('Min Value', Float(-100))
+       sb.add_param('Max Value', Float(100))
+       sb.add_param('Factor', Float(1.0))
+       sb.add_param('Decimal Places', Int(6), variable=True)
+       sb.add_param('Reference Level', Int(50), variable=True)
+       sb.add_param('Number Rate', Int(15))    
+       sb.add_param('Options', Enum([('Off', None), ('Average Values', 1), 
('Peak Hold', 2)]))
+       sb.add_param('Gauge', Bool(true='Show', false='Hide', default=True))
+       sb.set_docs('''\
+The number sink has a throttle automatically attatched to it at runtime to 
save the CPU. ''')  
+       def make(fg, type, label, unit, samp_rate, base, min, max, factor, 
decimals, ref_lvl, num_rate, options, gauge):                
+               options = options.parse()
+               peak_hold = (options == 2)
+               average = (options == 1)
+               block = type.parse()[0](fg.get_panel(), unit=unit.parse(), 
+                       base_value=base.parse(), minval=min.parse(), 
maxval=max.parse(), factor=factor.parse(),
+                       decimal_places=decimals.parse(), 
ref_level=ref_lvl.parse(), sample_rate=samp_rate.parse(), #number_size=512,
+                       number_rate=num_rate.parse(),   label=label.parse())
+               block.set_show_gauge(gauge.parse())
+               block.set_peak_hold(peak_hold)  #set the peak hold option 
outside the contructor 
+               block.set_average(average)                      #set the 
average option outside the contructor
+               fg.add_window(block.win, number_display_pritority, 
label.parse()+unit.parse())  
+               fg.add_callback(block.set_base_value, base)
+               fg.add_callback(block.set_ref_level, ref_lvl)
+               fg.add_callback(block.set_decimal_places, decimals)
+               throttle = gr.throttle(type.parse()[1].get_num_bytes(), 
samp_rate.parse())
+               fg.connect(throttle, block)
+               return throttle
+       return sb, make
+               
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py (from rev 6449, 
grc/trunk/src/SignalBlockDefs/Misc.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py                               
(rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/Misc.py       2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,223 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.Misc
+#These blocks were not categorized. Try to keep the number of misc blocks 
small.
address@hidden Josh Blum
+
+import gnuradio.gr.gr_threading as threading
+from DataTypes import *
+from gnuradio import gr,blks
+from SignalBlockConstants import default_samp_rate,all_choices,MAX_NUM_SOCKETS
+
+def Throttle(sb):
+       fcn = gr.throttle
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Sampling Rate', Float(default_samp_rate)) 
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''Connect a throttle to control the actual rate of the 
data.''')   
+       return sb, lambda fg, type, samp_rate, vlen: 
fcn(type.parse().get_num_bytes()*vlen.parse(), samp_rate.parse())
+       
+def Head(sb):
+       fcn = gr.head
+       type = Enum(all_choices, 1)     
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Num Items', Int(1000, min=0))     
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''Copies the first num items to the output then stops.''') 
+       return sb, lambda fg, type, num_items, vlen: 
fcn(type.parse().get_num_bytes()*vlen.parse(), num_items.parse())
+       
+def SkipHead(sb):
+       fcn = gr.skiphead
+       type = Enum(all_choices, 1)     
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Num Items', Int(1000, min=0))     
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''Skips the first num items, and then copies input to 
output.''')  
+       return sb, lambda fg, type, num_items, vlen: 
fcn(type.parse().get_num_bytes()*vlen.parse(), num_items.parse())
+       
+def RMS(sb):
+       type = Enum([
+               ('Complex', (gr.rms_cf, Complex())),
+               ('Float', (gr.rms_ff, Float())),
+       ], 1)
+       sb.add_input_socket('in', Variable(type, index=1))
+       sb.add_output_socket('out', Float())
+       sb.add_param('Input Type', type, False, type=True)
+       sb.add_param('Alpha', Float(0.0001), variable=True)
+       def make(fg, type, alpha):
+               block = type.parse()[0](alpha.parse())
+               fg.add_callback(block.set_alpha, alpha)
+               return block    
+       return sb, make
+       
+def About(sb):
+       sb.add_param('Title', String(''))
+       sb.add_param('Author', String(''))
+       return sb, lambda *args: None
+       
+def Note(sb):
+       sb.add_param('Note', String(''))
+       return sb, lambda *args: None   
+
+#######################################################################################
+##     Selector Def, and Helper Block
+#######################################################################################
+
+class SelectorHelper(gr.hier_block2):
+       """A hier2 block with N inputs and M outputs, where data is only 
forwarded through input n to output m."""
+       def __init__(self, item_size, num_inputs, num_outputs, input_index, 
output_index):      
+               """!
+               SelectorHelper constructor.
+               @param item_size the size of the gr data stream in bytes
+               @param num_inputs the number of inputs (integer)
+               @param num_outputs the number of outputs (integer)
+               @param input_index the index for the source data
+               @param output_index the index for the destination data
+               """     
+               gr.hier_block2.__init__(
+                       self, 'selector', 
+                       gr.io_signature(num_inputs, num_inputs, item_size), 
+                       gr.io_signature(num_outputs, num_outputs, item_size),
+               )
+               #terminator blocks for unused inputs and outputs        
+               self.input_terminators = [gr.null_sink(item_size) for i in 
range(num_inputs)]
+               self.output_terminators = [gr.head(item_size, 0) for i in 
range(num_outputs)]           
+               self.copy = None
+               #connections            
+               for i in range(num_inputs): self.connect((self, i), 
self.input_terminators[i])
+               for i in range(num_outputs): 
self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))  
   
+               self.item_size = item_size              
+               self.input_index = input_index
+               self.output_index = output_index        
+               self.num_inputs = num_inputs
+               self.num_outputs = num_outputs
+               self._connect_current()
+               
+       def _indexes_valid(self):
+               """!
+               Are the input and output indexes within range of the number of 
inputs and outputs?
+               @return true if input index and output index are in range
+               """
+               return self.input_index in range(self.num_inputs) and 
self.output_index in range(self.num_outputs)
+               
+       def _connect_current(self):
+               """If the input and output indexes are valid: 
+               disconnect the blocks at the input and output index from their 
terminators, 
+               and connect them to one another. Then connect the terminators 
to one another."""
+               if self._indexes_valid():
+                       self.disconnect((self, self.input_index), 
self.input_terminators[self.input_index])                             
+                       
self.disconnect(self.output_terminators[self.output_index], (self, 
self.output_index))
+                       self.copy = gr.skiphead(self.item_size, 0)
+                       self.connect((self, self.input_index), self.copy)
+                       self.connect(self.copy, (self, self.output_index))      
        
+                       
self.connect(self.output_terminators[self.output_index], 
self.input_terminators[self.input_index])      
+               
+       def _disconnect_current(self):
+               """If the input and output indexes are valid: 
+               disconnect the blocks at the input and output index from one 
another, 
+               and the terminators at the input and output index from one 
another.
+               Reconnect the blocks to the terminators."""
+               if self._indexes_valid():
+                       self.disconnect((self, self.input_index), self.copy)
+                       self.disconnect(self.copy, (self, self.output_index))
+                       
self.disconnect(self.output_terminators[self.output_index], 
self.input_terminators[self.input_index])
+                       del self.copy                   
+                       self.copy = None                        
+                       self.connect((self, self.input_index), 
self.input_terminators[self.input_index])
+                       
self.connect(self.output_terminators[self.output_index], (self, 
self.output_index))
+               
+       def set_input_index(self, input_index):
+               """!
+               Change the block to the new input index if the index changed.
+               @param input_index the new input index
+               """
+               if self.input_index != input_index:
+                       self.lock()
+                       self._disconnect_current()
+                       self.input_index = input_index
+                       self._connect_current()
+                       self.unlock()           
+               
+       def set_output_index(self, output_index):
+               """!
+               Change the block to the new output index if the index changed.
+               @param output_index the new output index
+               """             
+               if self.output_index != output_index:   
+                       self.lock()
+                       self._disconnect_current()
+                       self.output_index = output_index
+                       self._connect_current()                 
+                       self.unlock()           
+                       
+def Selector(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Input Index', Int(0), variable=True)
+       sb.add_param('Output Index', Int(0), variable=True)     
+       sb.add_param('Num Inputs', Int(1, min=1, max=MAX_NUM_SOCKETS), 
+               show_label=False, input_sockets_controller=True)
+       sb.add_param('Num Outputs', Int(1, min=1, max=MAX_NUM_SOCKETS), 
+               show_label=False, output_sockets_controller=True)
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''Forward data from the input index to the output 
index.''')       
+       def make(fg, type, input_index, output_index, num_inputs, num_outputs, 
vlen):
+               item_size = type.parse().get_num_bytes()*vlen.parse()
+               block = SelectorHelper(
+                       item_size, 
+                       num_inputs.parse(), 
+                       num_outputs.parse(), 
+                       input_index.parse(), 
+                       output_index.parse(),
+               )
+               fg.add_callback_locked(block.set_input_index, input_index)
+               fg.add_callback_locked(block.set_output_index, output_index)
+               return block
+       return sb, make
+
+def Valve(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_output_socket('out', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Open', Int(0), variable=True)     
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''When open is 0, the valve will forward data.''') 
+       def make(fg, type, open, vlen):
+               item_size = type.parse().get_num_bytes()*vlen.parse()
+               block = SelectorHelper(item_size, 1, 1, 0, open.parse())
+               fg.add_callback_locked(block.set_output_index, open)
+               return block
+       return sb, make
+       
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py (from rev 6449, 
grc/trunk/src/SignalBlockDefs/Modulators.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py                         
(rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/Modulators.py 2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,289 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.Modulations
+#Various modulation schemes.
address@hidden Josh Blum
+
+from DataTypes import *
+from gnuradio import gr,blks2
+
+def FrequencyMod(sb):
+       fcn = gr.frequency_modulator_fc
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Sensitivity', Float(.01)) 
+       return sb, lambda fg, sensitivity: fcn(sensitivity.parse())
+       
+def PhaseMod(sb):
+       fcn = gr.phase_modulator_fc
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Sensitivity', Float(.01)) 
+       return sb, lambda fg, sensitivity: fcn(sensitivity.parse())
+       
+def QuadratureDemod(sb):
+       fcn = gr.quadrature_demod_cf
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Float())    
+       sb.add_param('Gain', Float(1))  
+       return sb, lambda fg, gain: fcn(gain.parse())
+       
+###########################################################################
+#      Narrow band and Wide band FM
+###########################################################################    
        
+       
+def WFMReceive(sb):
+       fcn = blks2.wfm_rcv
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Float())    
+       sb.add_param('Quad Rate', Float(100e3))
+       sb.add_param('Audio Decimation', Int(1, min=1))         
+       sb.set_docs('''\
+Wide Band FM Receiver.
+The audio rate is the quad rate/audio decimation.''')
+       return sb, lambda fg, quad_rate, audio_dec: fcn(quad_rate.parse(), 
audio_dec.parse())
+       
+def WFMTransmit(sb):
+       fcn = blks2.wfm_tx
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Quad Rate', Int(100e3))
+       sb.add_param('Audio Decimation', Int(1, min=1)) 
+       sb.add_param('Tau', Float(75e-6))
+       sb.add_param('Max Deviation', Float(75e3))              
+       sb.set_docs('''\
+Wide Band FM Transmitter.
+The audio rate is the quad rate/audio decimation.''')
+       def make(fg, quad_rate, audio_decimation, tau, max_dev):
+               quad_rate = quad_rate.parse()
+               audio_decimation = audio_decimation.parse()
+               #       make sure that the quad rate is an integer multiple of 
the audio rate   #
+               audio_rate = quad_rate/audio_decimation
+               quad_rate = audio_decimation * (quad_rate/audio_decimation)
+               return fcn(audio_rate, quad_rate, tau.parse(), max_dev.parse())
+       return sb, make
+       
+def NBFMReceive(sb):
+       fcn = blks2.nbfm_rx
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Float())    
+       sb.add_param('Quad Rate', Int(100e3))
+       sb.add_param('Audio Decimation', Int(1, min=1)) 
+       sb.add_param('Tau', Float(75e-6))
+       sb.add_param('Max Deviation', Float(5e3))               
+       sb.set_docs('''\
+Narrow Band FM Receiver.
+The audio rate is the quad rate/audio decimation.''')
+       def make(fg, quad_rate, audio_decimation, tau, max_dev):
+               quad_rate = quad_rate.parse()
+               audio_decimation = audio_decimation.parse()
+               #       make sure that the quad rate is an integer multiple of 
the audio rate   #
+               audio_rate = quad_rate/audio_decimation
+               quad_rate = audio_decimation * (quad_rate/audio_decimation)
+               return fcn(audio_rate, quad_rate, tau.parse(), max_dev.parse())
+       return sb, make 
+       
+def NBFMTransmit(sb):
+       fcn = blks2.nbfm_tx
+       sb.add_input_socket('in', Float())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Quad Rate', Int(100e3))
+       sb.add_param('Audio Decimation', Int(1, min=1)) 
+       sb.add_param('Tau', Float(75e-6))
+       sb.add_param('Max Deviation', Float(5e3))               
+       sb.set_docs('''\
+Narrow Band FM Transmitter.
+The audio rate is the quad rate/audio decimation.''')
+       def make(fg, quad_rate, audio_decimation, tau, max_dev):
+               quad_rate = quad_rate.parse()
+               audio_decimation = audio_decimation.parse()
+               #       make sure that the quad rate is an integer multiple of 
the audio rate   #
+               audio_rate = quad_rate/audio_decimation
+               quad_rate = audio_decimation * (quad_rate/audio_decimation)
+               return fcn(audio_rate, quad_rate, tau.parse(), max_dev.parse())
+       return sb, make 
+               
+###########################################################################
+#      AM and FM demodulation
+###########################################################################    
                
+               
+def AMDemod(sb):
+       fcn = blks2.am_demod_cf
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Float())    
+       sb.add_param('Channel Rate', Int(100e3))
+       sb.add_param('Audio Decimation', Int(1, min=1)) 
+       sb.add_param('Audio Passband (Hz)', Float(5e3))
+       sb.add_param('Audio Stopband (Hz)', Float(5.5e3))
+       return sb, lambda fg, *args: fcn(*map(lambda a: a.parse(), args))
+               
+def FMDemod(sb):
+       fcn = blks2.fm_demod_cf
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Float())    
+       sb.add_param('Channel Rate', Int(100e3))
+       sb.add_param('FM Deviation (Hz)', Int(5e3))
+       sb.add_param('Audio Decimation', Int(1, min=1)) 
+       sb.add_param('Audio Passband (Hz)', Float(3e3))
+       sb.add_param('Audio Stopband (Hz)', Float(4e3))
+       sb.add_param('Gain', Float(1))
+       sb.add_param('Tau', Float(75e-6))
+       return sb, lambda fg, *args: fcn(*map(lambda a: a.parse(), args))
+       
+###########################################################################
+#      Phase shift keying
+###########################################################################    
+       
+def PSKMod(sb):
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Type', Enum([
+               ('DBPSK', blks2.dbpsk_mod), 
+               ('DQPSK', blks2.dqpsk_mod),
+               ('D8PSK', blks2.d8psk_mod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: type.parse()(*map(lambda a: 
a.parse(), args))
+       
+def PSKDemod(sb):
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Byte())     
+       sb.add_param('Type', Enum([
+               ('DBPSK', blks2.dbpsk_demod), 
+               ('DQPSK', blks2.dqpsk_demod),
+               ('D8PSK', blks2.d8psk_demod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Costas Alpha', Float(0.03))
+       sb.add_param('Gain Mu', Float(0.05))
+       sb.add_param('Mu', Float(0.005))
+       sb.add_param('Omega Relative Limit', Float(0.05))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: type.parse()(*map(lambda a: 
a.parse(), args))
+
+###########################################################################
+#      Gaussian minimum shift keying
+###########################################################################    
+       
+def GMSKMod(sb):
+       fcn = blks2.gmsk_mod
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Filter BW', Float(0.35))
+       return sb, lambda fg, *args: fcn(*map(lambda a: a.parse(), args))
+       
+def GMSKDemod(sb):
+       fcn = blks2.gmsk_demod
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Byte())     
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Gain Mu', Float(0.05))
+       sb.add_param('Mu', Float(0.5, min=0, max=1))
+       sb.add_param('Omega Relative Limit', Float(0.005))
+       sb.add_param('Frequency Error', Float(0))
+       sb.set_docs('''Mu is the fractional delay between 0 and 1''')
+       return sb, lambda fg, *args: fcn(*map(lambda a: a.parse(), args))
+       
+###########################################################################
+#      Quadrature amplitude modulation
+###########################################################################
+       
+def QAMMod(sb):
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Complex())  
+       sb.add_param('Type', Enum([
+               ('QAM 8', blks2.qam8_mod), 
+               ('QAM 16', blks2.qam16_mod), 
+               ('QAM 64', blks2.qam64_mod),
+               ('QAM 256', blks2.qam256_mod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: type.parse()(*map(lambda a: 
a.parse(), args))
+       
+def QAMDemod(sb):
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Byte())     
+       sb.add_param('Type', Enum([
+               ('QAM 8', blks2.qam8_demod), 
+               ('QAM 16', blks2.qam16_demod),
+               ('QAM 64', blks2.qam64_demod),
+               ('QAM 256', blks2.qam256_demod),
+       ]), type=True)
+       sb.add_param('Samples/Symbol', Int(2, min=2))
+       sb.add_param('Excess BW', Float(0.35))
+       sb.add_param('Costas Alpha', Float(0.03))
+       sb.add_param('Gain Mu', Float(0.05))
+       sb.add_param('Mu', Float(0.005))
+       sb.add_param('Omega Relative Limit', Float(0.05))
+       sb.add_param('Use Gray Code', Bool(true='Yes', false='No', 
default=True))
+       return sb, lambda fg, type, *args: type.parse()(*map(lambda a: 
a.parse(), args))
+               
+###########################################################################
+#      Phase Locked Loops
+###########################################################################    
+       
+def CostasLoop(sb):
+       fcn = gr.costas_loop_cc
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('bout', Complex())
+       sb.add_output_socket('nout', Complex(), optional=True)
+       sb.add_param('Alpha', Float())
+       sb.add_param('Beta', Float())
+       sb.add_param('Max Freq', Float())
+       sb.add_param('Min Freq', Float())
+       sb.add_param('Order', Enum([('2', 2), ('4', 4)]))
+       sb.set_docs('''\
+Carrier tracking PLL for QPSK input. \
+The Costas loop has two output streams: \
+"bout" is the baseband I stream, "nout" is the normalized frequency of the 
loop. \
+The "nout" may be left open. ''')
+       return sb, lambda fg, *args: fcn(*map(lambda a: a.parse(), args))
+       
+def PLL(sb):
+       type = Enum([                                           #fcn, output 
type
+               ('Carrier Tracking', (gr.pll_carriertracking_cc, Complex())),
+               ('Freq Det', (gr.pll_freqdet_cf, Float())),
+               ('Ref Out', (gr.pll_refout_cc, Complex())),
+       ])
+       sb.add_input_socket('in', Complex())
+       sb.add_output_socket('out', Variable(type, index=1))
+       sb.add_param('Type', type, type=True)   
+       sb.add_param('Alpha', Float())
+       sb.add_param('Beta', Float())
+       sb.add_param('Max Freq', Float())
+       sb.add_param('Min Freq', Float())
+       sb.set_docs('''\
+All settings max_freq and min_freq are in terms of radians per sample, NOT 
HERTZ. \
+Alpha is the phase gain (first order, units of radians per radian), and \
+beta is the frequency gain (second order, units of radians per sample per 
radian).
+
+Carrier Tracking - This PLL locks onto a [possibly noisy] reference carrier on 
the input and outputs that signal, downconverted to DC.
+
+Freq Det - This PLL locks onto a [possibly noisy] reference carrier on the 
input and outputs an estimate of that frequency in radians per sample.
+
+Ref Out - This PLL locks onto a [possibly noisy] reference carrier on the 
input and outputs a clean version which is phase and frequency aligned to it.
+''')
+       return sb, lambda fg, type, *args: type.parse()[0](*map(lambda a: 
a.parse(), args))             
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py (from rev 6460, 
grc/trunk/src/SignalBlockDefs/Packet.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py                             
(rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/Packet.py     2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,359 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.Packet
+#Support for the gr packet framework.
address@hidden Josh Blum
+
+import struct
+import os
+from DataTypes import *
+from gnuradio import gr, packet_utils
+import gnuradio.gr.gr_threading as threading
+from SignalBlockConstants import all_choices
+
+##payload length in bytes
+DEFAULT_PAYLOAD_LEN = 512
+
+##how many messages in a queue
+DEFAULT_MSGQ_LIMIT = 2
+
+##threshold for unmaking packets
+DEFAULT_THRESHOLD = 12
+
+#######################################################################################
+##     Packet Mod
+#######################################################################################
+
+class PacketModThread(threading.Thread):
+       """
+       Sample the input message queue and call send payload.           
+       """
+       
+       def __init__(self, msgq, payload_length, send_payload):
+               """!
+               Create the packet_mod_thread.
+               @param msgq the message queue to sample
+               @param payload_length number of bytes in a data-stream slice
+               @param send_payload a function that takes a payload
+               """             
+               self._msgq = msgq
+               self._payload_length = payload_length
+               self._send_payload = send_payload
+               threading.Thread.__init__(self)
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               
+       def run(self):
+               """
+               Run this thread by sampling the message queue in and cutting 
out chunks of size payload.
+               """
+               sample = '' #residual sample
+               while self.keep_running:
+                       msg = self._msgq.delete_head() #blocking read of 
message queue
+                       sample = sample + msg.to_string() #get the body of the 
msg as a string  
+                       while len(sample) >= self._payload_length:              
+                               payload = sample[0:self._payload_length]
+                               sample = sample[self._payload_length:]          
        
+                               self._send_payload(payload)     
+
+class PacketModHelper(gr.hier_block2):
+       """
+       Hierarchical block for sending packet based data.               
+       """
+       
+       def __init__(self, item_size, samples_per_symbol, bits_per_symbol, 
payload_length=None, access_code=None, pad_for_usrp=True):
+               """!
+               PacketModHelper constructor.
+               @param item_size the size of the input data stream in bytes
+               @param samples_per_symbol number of samples per symbol
+               @param bits_per_symbol number of bits per symbol
+               @param payload_length number of bytes in a data-stream slice
+               @param access_code AKA sync vector
+               @param pad_for_usrp If true, packets are padded such that they 
end up a multiple of 128 samples
+               """
+               #setup parameters
+               self._item_size = item_size
+               self._samples_per_symbol = samples_per_symbol
+               self._bits_per_symbol = bits_per_symbol
+               self._pad_for_usrp = pad_for_usrp
+               if access_code is None: #get access code
+                       access_code = packet_utils.default_access_code
+               if not packet_utils.is_1_0_string(access_code):
+                       raise ValueError, "Invalid access_code %r. Must be 
string of 1's and 0's" % (access_code,)
+               self._access_code = access_code         
+               if payload_length is None: #get packet length
+                       payload_length = DEFAULT_PAYLOAD_LEN
+               if payload_length%self._item_size != 0: #verify that packet 
length is a multiple of the stream size
+                       raise ValueError, 'The packet length: "%d" is not a 
mutiple of the stream size: "%d".'%(payload_length, item_size)
+               self._payload_length = payload_length
+               self._pad_for_usrp = pad_for_usrp               
+               #create message queues and message blocks
+               self._msgq_in = gr.msg_queue(DEFAULT_MSGQ_LIMIT)
+               msg_sink        = gr.message_sink(self._item_size, 
self._msgq_in, False) #False -> blocking
+               msg_source = gr.message_source(gr.sizeof_char, 
DEFAULT_MSGQ_LIMIT)
+               self._msgq_out = msg_source.msgq()              
+               #initialize hier2
+               gr.hier_block2.__init__(
+                       self, 
+                       "packet_mod",
+                       gr.io_signature(1, 1, self._item_size), # Input 
signature
+                       gr.io_signature(1, 1, gr.sizeof_char) # Output signature
+               )
+               #connect
+               self.connect(self, msg_sink)
+               self.connect(msg_source, self)
+               #start thread
+               PacketModThread(self._msgq_in, self._payload_length, 
self._send_payload)
+               
+       def _send_payload(self, payload):
+               """!
+               Wrap the payload in a packet and push onto the message queue.
+               @param payload data to send
+               """
+               packet = packet_utils.make_packet(
+                       payload,
+                       self._samples_per_symbol,
+                       self._bits_per_symbol,
+                       self._access_code,
+                       self._pad_for_usrp
+               )
+               msg = gr.message_from_string(packet)
+               self._msgq_out.insert_tail(msg)
+
+def PacketMod(sb):
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))
+       sb.add_output_socket('out', Byte())             
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Samples/Symbol', Int(1))
+       sb.add_param('Bits/Symbol', Int(1))
+       sb.add_param('Payload Length', Int(DEFAULT_PAYLOAD_LEN))
+       sb.add_param('Access Code', String())
+       sb.add_param('Pad for USRP', Bool(true='Yes', false='No', default=True))
+       sb.set_docs("""\
+Packet modulator block, for use with the gnuradio modulator blocks: gmsk, psk, 
qam.
+
+Access Code: string of 1's and 0's, leave blank for default.
+
+Bits/Symbol should be set accordingly: 
+       gmsk -> 1
+       dbpsk -> 1
+       dqpsk -> 2
+       d8psk -> 3
+       qam8 -> 3
+       qam16 -> 4
+       qam64 -> 6
+       qam256 -> 8
+""")
+       def make(fg, type, samples_per_symbol, bits_per_symbol, payload_length, 
access_code, pad_for_usrp):
+               access_code = access_code.parse()
+               if not access_code: access_code = None
+               return PacketModHelper(
+                       item_size = type.parse().get_num_bytes(),
+                       samples_per_symbol=samples_per_symbol.parse(), 
+                       bits_per_symbol=bits_per_symbol.parse(), 
+                       payload_length=payload_length.parse(), 
+                       access_code=access_code, 
+                       pad_for_usrp=pad_for_usrp.parse(),
+               )
+       return sb, make
+       
+#######################################################################################
+##     Packet Demod
+#######################################################################################
+
+class PacketDemodThread(threading.Thread):
+       """
+       Sample the input message queue and call send packet.            
+       """
+       
+       def __init__(self, msgq, recv_packet):
+               """!
+               Create the packet_mod_thread.
+               @param msgq the message queue to sample
+               @param recv_packet a function that takes a packet
+               """             
+               self._msgq = msgq
+               self._recv_packet = recv_packet
+               threading.Thread.__init__(self)
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               
+       def run(self):
+               """
+               Run this thread by sampling the message queue and calling send 
payload          
+               """
+               while self.keep_running:
+                       msg = self._msgq.delete_head() #blocking read of 
message queue
+                       packet = msg.to_string()        
+                       self._recv_packet(packet)       
+
+class PacketDemodHelper(gr.hier_block2):
+       """
+       Hierarchical block for demodulating and deframing packets.
+       """
+
+       def __init__(self, item_size, access_code=None, threshold=-1):
+               """!
+               PacketDemodHelper contructor.   
+               @param item_size the size of the input data stream in bytes     
+               @param access_code AKA sync vector
+               @param threshold detect access_code with up to threshold bits 
wrong (-1 -> use default)
+               """
+               #setup parameters
+               self._item_size = item_size                     
+               #access code
+               if access_code is None: #get access code
+                       access_code = packet_utils.default_access_code
+               if not packet_utils.is_1_0_string(access_code):
+                       raise ValueError, "Invalid access_code %r. Must be 
string of 1's and 0's" % (access_code,)
+               self._access_code = access_code         
+      #threshold
+               if threshold == -1: threshold = DEFAULT_THRESHOLD 
+               self._threshold = threshold  
+               #initialize hier2
+               gr.hier_block2.__init__(
+                       self,
+                       "packet_demod",
+                       gr.io_signature(1, 1, gr.sizeof_char), # Input signature
+                       gr.io_signature(1, 1, self._item_size), # Output 
signature
+               ) 
+               #blocks
+               self._msgq_in = gr.msg_queue(DEFAULT_MSGQ_LIMIT)          # 
holds packets from the PHY
+               correlator = gr.correlate_access_code_bb(self._access_code, 
self._threshold)
+               framer_sink = gr.framer_sink_1(self._msgq_in)           
+               msg_source = gr.message_source(self._item_size, 
DEFAULT_MSGQ_LIMIT)
+               self._msgq_out = msg_source.msgq()      
+               #connect
+               self.connect(self, correlator, framer_sink)
+               self.connect(msg_source, self)
+               #start thread
+               PacketDemodThread(self._msgq_in, self._recv_packet)
+                       
+       def _recv_packet(self, packet):
+               """!
+               Extract the payload from the packet and push onto message queue.
+               @param packet data received
+               """
+               ok, payload = packet_utils.unmake_packet(packet)
+               msg = gr.message_from_string(payload, 0, self._item_size, 
len(payload)/self._item_size)
+               if ok: self._msgq_out.insert_tail(msg)
+       
+def PacketDemod(sb):
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Byte())
+       sb.add_output_socket('out', Variable(type))             
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Access Code', String())
+       sb.add_param('Threshold', Int(-1))
+       sb.set_docs("""\
+Packet demodulator block, for use with the gnuradio demodulator blocks: gmsk, 
psk, qam.
+
+Access Code: string of 1's and 0's, leave blank for default.
+""")
+       def make(fg, type, access_code, threshold):
+               access_code = access_code.parse()
+               if not access_code: access_code = None
+               return PacketDemodHelper(
+                       item_size = type.parse().get_num_bytes(),
+                       access_code=access_code, 
+                       threshold=threshold.parse(),
+               )
+       return sb, make
+               
+#######################################################################################
+##     TUN/TAP 
+#######################################################################################
+
+IFF_TUN                = 0x0001   # tunnel IP packets
+IFF_TAP                = 0x0002   # tunnel ethernet frames
+IFF_NO_PI      = 0x1000   # don't pass extra packet info
+IFF_ONE_QUEUE  = 0x2000   # beats me ;)
+DEFAULT_TUN_DEVICE = '/dev/net/tun'
+DEFAULT_VIRTUAL_DEVICE = 'tun%d'
+DEFAULT_IP_ADDR = '10.0.0.1'
+
+def open_tun_interface(tun_device_filename=DEFAULT_TUN_DEVICE, 
virtual_device_filename=DEFAULT_VIRTUAL_DEVICE):
+       """!
+       Open a virtual ethernet interface via the Tun/Tap framework.
+       An alternative function can be found: "from eunuchs.tuntap import 
opentuntap"
+       @param tun_device_filename the path to the tun device
+       @param virtual_device_filename the name of the virtual device (to be 
created)
+       @return a file descriptor to rw the device, name of the virtual device 
(created)
+       """
+       from fcntl import ioctl    
+       mode = IFF_TAP | IFF_NO_PI
+       TUNSETIFF = 0x400454ca
+       tun_fd = os.open(tun_device_filename, os.O_RDWR)
+       ifs = ioctl(tun_fd, TUNSETIFF, struct.pack("16sH", 
virtual_device_filename, mode))
+       ifname = ifs[:16].strip("\x00")
+       return tun_fd, ifname
+
+class TunTapHelper(gr.hier_block2):
+       """Make the tun tap hier2 block."""
+       def __init__(self, item_size, tun_fd):
+               """!
+               TunTapHelper constructor.
+               @param item_size the size in bytes of the IO data stream
+               @param tun_fd the file descriptor for the virtual device
+               """
+               #create hier block
+               gr.hier_block2.__init__(
+                       self, 'tun_tap', 
+                       gr.io_signature(1, 1, item_size), 
+                       gr.io_signature(1, 1, item_size)
+               )
+               #I/O blocks
+               sink = gr.file_descriptor_sink(item_size, tun_fd)
+               source = gr.file_descriptor_source(item_size, tun_fd)
+               #connect 
+               self.connect(self, sink)
+               self.connect(source, self)              
+    
+def TunTap(sb):
+       gr.file_descriptor_sink, gr.file_descriptor_source      #uses
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))
+       sb.add_output_socket('out', Variable(type))             
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Tun Device', String(DEFAULT_TUN_DEVICE))
+       sb.add_param('Virtual Device', String(DEFAULT_VIRTUAL_DEVICE))
+       sb.add_param('IP Address', String(DEFAULT_IP_ADDR))
+       sb.set_docs('''\
+Foward data between gnuradio and a virtual ethernet interface.
+---
+Tun Device: File path to the tun device.
+
+Virtual Device: Desired name for the virtual ethernet device. \
+"%d" will give the device a number starting at zero.
+
+IP Address: IP address for the virtual device, leave blank and device will not 
be configured.
+''')
+       def make(fg, type, tun, virt, ip_addr):
+               item_size = type.parse().get_num_bytes()
+               tun_fd, ifname = open_tun_interface(tun.parse(), virt.parse())
+               #try to set the ip address
+               ip_addr = ip_addr.parse()
+               if ip_addr: os.system('ifconfig %s %s'%(ifname, ip_addr))
+               return TunTapHelper(item_size, tun_fd)
+       return sb, make
+       
+       
\ No newline at end of file

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py (from rev 
6449, grc/trunk/src/SignalBlockDefs/SignalBlockTree.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py                    
        (rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/SignalBlockTree.py    2007-09-20 
01:49:24 UTC (rev 6483)
@@ -0,0 +1,247 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.SignalBlockTree
+#The data structure to categorize the signal blocks, and to map id tags to 
block building functions.
address@hidden Josh Blum
+
+from Elements import SignalBlock
+import Sources
+import Sinks
+import Audio
+import GraphicalSinks
+import Conversions
+import Operators
+import Filters
+import Modulators
+import Misc
+import USRP
+import Coders
+import Trellis
+import Packet
+import Custom
+
+##A categorized list of all signal blocks
+SB_TREE = [
+                       ('Sources', [           
+                               ('Signal Source', Sources.SignalSource),
+                               ('Noise Source', Sources.NoiseSource),          
                                                
+                               ('Vector Source', Sources.VectorSource),
+                               ('Random Source', Sources.RandomVector),        
        
+                               ('Null Source', Sources.NullSource),    
+                               ('File Source', Sources.FileSource),
+                               ('UDP Source', Sources.UDPSource),              
                
+                               ('Audio Source', Audio.AudioSource),
+                               ('USRP Source', USRP.USRPSource),
+                               ('USRP Dual Source', USRP.USRPDualSource),
+                       ]),
+                       ('Sinks', [             
+                               ('Variable Sink', Sinks.VariableSink),          
                        
+                               ('Null Sink', Sinks.NullSink),
+                               ('File Sink', Sinks.FileSink),  
+                               ('UDP Sink', Sinks.UDPSink),                    
        
+                               ('Audio Sink', Audio.AudioSink),
+                               ('USRP Sink', USRP.USRPSink),
+                               ('USRP Dual Sink', USRP.USRPDualSink),
+                       ]),
+                       ('Graphical Sinks', [                   
+                               ('Numerical Sink', 
GraphicalSinks.NumericalSink),       
+                               ('Scope Sink', GraphicalSinks.ScopeSink),
+                               ('FFT Sink', GraphicalSinks.FFTSink),   
+                               ('Waterfall Sink', 
GraphicalSinks.WaterfallSink),
+                               ('Constellation Sink', 
GraphicalSinks.ConstellationSink),
+                       ]),
+                       ('Operators', [                                         
        
+                               ('Add', Operators.Add),
+                               ('Subtract', Operators.Subtract),
+                               ('Multiply', Operators.Multiply),               
                
+                               ('Divide', Operators.Divide),                   
                                        
+                               ('nLog10', Operators.nLog10),
+                               ('Add Vector', Operators.AddVector),
+                               ('Multiply Vector', Operators.MultiplyVector),
+                               ('Add Constant', Operators.AddConstant),
+                               ('Multiply Constant', 
Operators.MultiplyConstant),      
+                               ('Add Constant Vector', 
Operators.AddConstantVector),                                   
+                               ('Multiply Constant Vector', 
Operators.MultiplyConstantVector),
+                       ]),
+                       ('Conversions', [                       
+                               ('Complex Components', 
Conversions.ComplexComponents),
+                               ('Complex Conjugate', 
Conversions.ComplexConjugate),
+                               ('Float to Complex', 
Conversions.FloatToComplex),
+                               ('Complex to Float', 
Conversions.ComplexToFloat),
+                               ('Float to Short', Conversions.FloatToShort),
+                               ('Short to Float', Conversions.ShortToFloat),
+                               ('Float to Char', Conversions.FloatToChar),
+                               ('Char to Float', Conversions.CharToFloat),
+                               ('Float to UChar', Conversions.FloatToUChar),
+                               ('UChar to Float', Conversions.UCharToFloat),
+                               ('Complex to IShort', 
Conversions.ComplexToIShort),
+                               ('IShort to Complex', 
Conversions.IShortToComplex),     
+                               ('Unpacked to Packed', 
Conversions.UnpackedToPacked),
+                               ('Packed to Unpacked', 
Conversions.PackedToUnpacked),
+                               ('Unpack k Bits', Conversions.UnpackKBits),
+                               ('Binary Slicer', Conversions.BinarySlicer),
+                               ('Chunks to Symbols', 
Conversions.ChunksToSymbols),
+                               ('Map', Conversions.Map),
+                               ('VCO', Conversions.VCO),
+                               ('Interleave', Conversions.Interleave),
+                               ('Deinterleave', Conversions.Deinterleave),
+                               ('Streams to Stream', 
Conversions.StreamsToStream),
+                               ('Stream to Streams', 
Conversions.StreamToStreams),
+                               ('Streams to Vector', 
Conversions.StreamsToVector),
+                               ('Vector to Streams', 
Conversions.VectorToStreams),
+                               ('Stream to Vector', 
Conversions.StreamToVector),       
+                               ('Vector to Stream', 
Conversions.VectorToStream),                                                    
   
+                       ]),     
+                       ('Generic Filters', [                   
+                               ('FIR Filter', Filters.FIRFilter),
+                               ('FFT Filter', Filters.FFTFilter),
+                               ('Freq Xlating FIR Filter', 
Filters.FreqXlatingFIRFilter),              
+                               ('Rational Resampler', 
Filters.RationalResampler),      
+                               ('IIR Filer', Filters.IIRFiler),        
+                               ('Filter Delay', Filters.FilterDelay),
+                               ('Channel Model', Filters.ChannelModel),
+                       ]),             
+                       ('Filters', [                   
+                               ('Low Pass Filter', Filters.LowPassFilter),
+                               ('High Pass Filter', Filters.HighPassFilter),
+                               ('Band Pass Filter', Filters.BandPassFilter),
+                               ('Band Reject Filter', 
Filters.BandRejectFilter),
+                               ('Window', Filters.Window),
+                               ('Root Raised Cosine', 
Filters.RootRaisedCosine),                                                      
         
+                               ('Single Pole IIR Filter', 
Filters.SinglePoleIIRFilter),
+                               ('Hilbert', Filters.Hilbert),
+                               ('Goertzel', Filters.Goertzel), 
+                               ('Power Squelch', Filters.PowerSquelch),
+                               ('Downsample', Filters.Downsample),
+                               ('Upsample', Filters.Upsample),                 
        
+                               ('Fractional Resampler', 
Filters.FractionalResampler),
+                               ('Fractional Interpolator', 
Filters.FractionalInterpolator),
+                               ('Automatic Gain Control', 
Filters.AutomaticGainControl),
+                               ('Automatic Gain Control2', 
Filters.AutomaticGainControl2),
+                               ('Feed Forward AGC', Filters.FeedForwardAGC),
+                               ('CMA Filter', Filters.CMAFilter),
+                               ('Clock Recovery', Filters.ClockRecovery),
+                               ('FFT', Filters.FFT),
+                               ('IFFT', Filters.IFFT),
+                       ]),
+                       ('Modulators', [                        
+                               ('Frequency Modulator', 
Modulators.FrequencyMod),
+                               ('Phase Modulator', Modulators.PhaseMod),
+                               ('Quadrature Demodulator', 
Modulators.QuadratureDemod),
+                               ('Costas Loop', Modulators.CostasLoop),
+                               ('Phase Locked Loop', Modulators.PLL),
+                               ('WFM Receive', Modulators.WFMReceive),         
        
+                               ('WFM Transmit', Modulators.WFMTransmit),       
+                               ('NBFM Receive', Modulators.NBFMReceive),       
                
+                               ('NBFM Transmit', Modulators.NBFMTransmit),     
+                               ('AM Demodulator', Modulators.AMDemod),
+                               ('FM Demodulator', Modulators.FMDemod),
+                               ('PSK Modulator', Modulators.PSKMod),
+                               ('PSK Demodulator', Modulators.PSKDemod),
+                               ('GMSK Modulator', Modulators.GMSKMod),
+                               ('GMSK Demodulator', Modulators.GMSKDemod),
+                               ('QAM Modulator', Modulators.QAMMod),
+                               ('QAM Demodulator', Modulators.QAMDemod),
+                               ('Packet Modulator', Packet.PacketMod),
+                               ('Packet Demodulator', Packet.PacketDemod),
+                       ]),
+                       ('Coders', [
+                               ('Constellation Decoder', 
Coders.ConstellationDecoder),                         
+                               ('Differential Encoder', 
Coders.DifferentialEncoder),
+                               ('Differential Decoder', 
Coders.DifferentialDecoder),   
+                               ('Differential Phasor', 
Coders.DifferentialPhasor),     
+                               ('Correlate Access Code', 
Coders.CorrelateAccessCode),                                          
+                       ]),
+                       ('Trellis', [
+                               ('Trellis Encoder', Trellis.Encoder),
+                               ('Metrics', Trellis.Metrics),
+                               ('Viterbi Decoder', Trellis.Viterbi),
+                               ('Viterbi Decoder Combined with Metric', 
Trellis.Viterbi_Combined),
+                               ('BCJR Algorithm', Trellis.Soft_In_Soft_Out),
+                               ('BCJR Algorithm Combined with Metric', 
Trellis.Soft_In_Soft_Out_Combined),
+                               ('Interleaver', Trellis.Interleaver),
+                               ('Deinterleaver', Trellis.Deinterleaver),
+                       ]),
+                       ('Misc', [      
+                               ('Throttle', Misc.Throttle),
+                               ('Valve', Misc.Valve),
+                               ('Selector', Misc.Selector),
+                               ('Head', Misc.Head),    
+                               ('Skip Head', Misc.SkipHead),                   
                
+                               ('Tun Tap', Packet.TunTap),     
+                               ('RMS', Misc.RMS),      
+                               ('About', Misc.About),
+                               ('Note', Misc.Note),    
+                       ]),
+                       ('Custom', Custom.CUSTOM_BLOCKS),
+               ] 
+               
+def get_signal_block(parent=None, coor=(0,0), rot=0, lookup_tag='', id='', 
signal_block_constructor=SignalBlock):
+       """!
+       Create a new signal block.
+       @param parent the flow graph
+       @param coor the (x,y) corrdinate
+       @param rot the rotation in degrees
+       @param lookup_tag the tag of the desired signal block
+       @param id the unique id for the new signal block
+       @param signal_block_constructor the contructor for a new signal block
+       @throw TagNotFoundException tag not found
+       @return (the signal block, a gnuradio signal block builder function) 
tuple
+       """
+       sb = signal_block_constructor(parent, coor, rot, lookup_tag, id)
+       for category, signal_blocks in SB_TREE:
+               for tag, builder in signal_blocks:
+                       if lookup_tag == tag: return builder(sb)
+       raise TagNotFoundException(lookup_tag)  
+       
+#      remove the bad tags     #
+tags_set = set()
+for category,tags in SB_TREE:
+       tags_to_remove = list()
+       for tag in tags:
+               try: 
+                       get_signal_block(lookup_tag=tag[0])
+                       if tag[0] in tags_set:  #       remove redundant tags   
#
+                               print 'Removing redundant tag "%s" in category 
"%s"...'%(tag[0], category)
+                               tags_to_remove.append(tag)      
+                       else: tags_set.add(tag[0])
+               except (ImportError, AttributeError), e: 
+                       print e, " in %s! -> continuing..."%tag[0]      
+                       tags_to_remove.append(tag)              
+       for tag in tags_to_remove: tags.remove(tag)
+       
+#      remove empty categories #
+cats_to_remove = list()
+for category,tags in SB_TREE:
+       if len(tags) == 0: 
+               print 'Removing empty category "%s"...'%category
+               cats_to_remove.append((category,tags))
+for cat in cats_to_remove: SB_TREE.remove(cat)
+        
+
+class TagNotFoundException(Exception):
+       def __init__(self, value):      self.value = value
+       def __str__(self): return 'Exception! The tag: %s could not be 
found'%repr(self.value)
+               
+def print_sb_tree():
+       """Print the signal block tree."""
+       for category,tags in TAGS:
+               print category
+               for tag in tags: print '\t%s'%tag[0]
+                                       

Deleted: grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py

Copied: grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py (from rev 6476, 
grc/trunk/src/SignalBlockDefs/Sinks.py)
===================================================================
--- grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py                              
(rev 0)
+++ grc/tags/grc_0.69/src/SignalBlockDefs/Sinks.py      2007-09-20 01:49:24 UTC 
(rev 6483)
@@ -0,0 +1,144 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion 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 this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
address@hidden SignalBlockDefs.Sinks
+#Various data sinks.
address@hidden Josh Blum
+
+from DataTypes import *
+from gnuradio import gr
+from SignalBlockConstants import *
+from Constants import DEFAULT_FILE_PATH,MUTEX
+
+def NullSink(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''\
+If the data stream is not throttled, the null sink will use 100% CPU. \
+Manually connect a throttle to the null sink to save the CPU.''')
+       return sb, lambda fg, type, vlen: 
gr.null_sink(type.parse().get_num_bytes()*vlen.parse())
+
+def FileSink(sb):
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('File Path', FileSave(DEFAULT_FILE_PATH))
+       sb.add_param('Vector Length', vlen)
+       sb.set_docs('''\
+If the data stream is not throttled, the file sink will use 100% CPU. \
+Manually connect a throttle to the file sink to save the CPU.''')
+       return sb, lambda fg, type, file_path, vlen: 
gr.file_sink(type.parse().get_num_bytes()*vlen.parse(), file_path.parse()) 
+       
+def UDPSink(sb):
+       fcn = gr.udp_sink       
+       type = Enum(all_choices, 1)
+       vlen = Int(1, min=1)
+       sb.add_input_socket('in', Variable(type), vlen=vlen)
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Source Addr', String(''))
+       sb.add_param('Source Port', Short(default_udp_port, min=1))
+       sb.add_param('Destination Addr', String(''))
+       sb.add_param('Destination Port', Short(default_udp_port, min=1))
+       sb.add_param('Payload Size', Int(512, min=1))
+       sb.add_param('Vector Length', vlen)
+       return sb, lambda fg, type, s_addr, s_port, d_addr, d_port, size, vlen: 
fcn(
+               type.parse().get_num_bytes()*vlen.parse(), 
+               s_addr.parse(), s_port.parse(),
+               d_addr.parse(), d_port.parse(), 
+               size.parse())
+                       
+#######################################################################################
+##     Variable Sink definition and thread class
+#######################################################################################
+       
+import threading
+import Variables
+import numpy
+       
+class VariableSinkThread(threading.Thread):
+       """
+       This thread will read the vector sink,
+       write the numeric value back to the variable,
+       and re-parse the flow graph's callbacks.
+       """
+       def __init__(self, fg, var_key, msgq):
+               """!
+               VariableSinkThread constructor.
+               @param fg the gr flow graph
+               @param var_key the variable key
+               @param msgq the message queue
+               """
+               self.fg = fg
+               self.var_key = var_key
+               self.msgq = msgq
+               threading.Thread.__init__(self)
+               self.setDaemon(1)
+               self.keep_running = True
+               self.start()
+               print 'Created variable sink thread for variable "%s".'%var_key
+                               
+       def run(self):
+               """
+               In an endless while loop: read the vector sink,
+               write to the variable, and parse the callbacks.
+               """
+               while self.keep_running:
+                       msg = self.msgq.delete_head()  # blocking read of 
message queue
+                       itemsize = int(msg.arg1())
+                       nitems = int(msg.arg2())                                
+                       s = msg.to_string()            # get the body of the 
msg as a string                            
+                       # There may be more than one number in the message.
+                       # If so, we take only the last one
+                       if nitems > 1:
+                               start = itemsize * (nitems - 1)
+                               s = s[start:start+itemsize]                     
        
+                       #       parse the data to a complex or float/int string 
#
+                       complex_data = numpy.fromstring (s, numpy.float32)
+                       if len(complex_data) == 2: new_value = "%f + 
%fj"%(complex_data[0], complex_data[1])
+                       else: new_value = "%f"%(complex_data[0],)
+                       # write the new value #         
+                       Variables.reregister(self.var_key, new_value)           
                
+                       #       parse the call backs    #                       
        
+                       self.fg.parse_callbacks()       
+               
+def VariableSink(sb):
+       type = Enum(all_choices, 1)
+       sb.add_input_socket('in', Variable(type))
+       sb.add_param('Type', type, False, type=True)
+       sb.add_param('Variable', VariableKeySelector()) 
+       sb.add_param('Samp Rate', Float(default_samp_rate))
+       sb.set_docs('''\
+A thread reads a message sink and writes to the variable. \
+The variable cannot have a range. \
+The variable must be specified using its name without the "$" symbol. \
+The variable sink has a throttle automatically attatched to it at runtime to 
save the CPU.''') 
+       def make(fg, type, var_key, samp_rate):
+               msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
+               item_size = type.parse().get_num_bytes()
+               block = gr.message_sink(item_size, msgq, True)
+               var_sink_thread = VariableSinkThread(fg, var_key.parse(), msgq)
+               throttle = gr.throttle(item_size, samp_rate.parse())
+               fg.connect(throttle, block)             
+               return throttle
+       return sb, make 
+       
+       
\ No newline at end of file





reply via email to

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