diff options
Diffstat (limited to 'grc')
280 files changed, 23909 insertions, 0 deletions
diff --git a/grc/Makefile.am b/grc/Makefile.am new file mode 100644 index 000000000..93b0a5032 --- /dev/null +++ b/grc/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = \ + data \ + examples \ + scripts \ + src diff --git a/grc/Makefile.common b/grc/Makefile.common new file mode 100644 index 000000000..3bad4ce04 --- /dev/null +++ b/grc/Makefile.common @@ -0,0 +1,41 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +grc_data_prefix = @datadir@/${PACKAGE}/grc +grc_examples_prefix = @datadir@/${PACKAGE}/examples/grc + +grc_data_dir = $(grc_data_prefix)/grc +grc_gnuradio_data_dir = $(grc_data_prefix)/grc_gnuradio +grc_gnuradio_blocks_dir = $(grc_data_prefix)/grc_gnuradio/blocks + +install-data-local: + $(mkinstalldirs) $(datadir) + $(foreach file, $(EXTRA_DIST), \ + $(INSTALL_DATA) $(srcdir)/$(file) $(datadir)/$(file); \ + ) + +uninstall-local: + $(foreach file, $(EXTRA_DIST), \ + $(RM) $(datadir)/$(file); \ + ) + $(RM) -fr $(datadir) diff --git a/grc/data/Makefile.am b/grc/data/Makefile.am new file mode 100644 index 000000000..2b0c18e8c --- /dev/null +++ b/grc/data/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = grc grc_gnuradio diff --git a/grc/data/grc/Makefile.am b/grc/data/grc/Makefile.am new file mode 100644 index 000000000..54ffda91b --- /dev/null +++ b/grc/data/grc/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_data_dir) + +EXTRA_DIST = \ + block_tree.dtd \ + flow_graph.dtd \ + grc-icon-256.png \ + grc-icon-256.svg \ + grc-icon-32.png diff --git a/grc/data/grc/block_tree.dtd b/grc/data/grc/block_tree.dtd new file mode 100644 index 000000000..be1524a38 --- /dev/null +++ b/grc/data/grc/block_tree.dtd @@ -0,0 +1,26 @@ +<!-- +Copyright 2008 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 +--> +<!-- + block_tree.dtd + Josh Blum + The document type definition for a block tree category listing. + --> +<!ELEMENT cat (name, cat*, block*)> +<!ELEMENT name (#PCDATA)> +<!ELEMENT block (#PCDATA)> diff --git a/grc/data/grc/flow_graph.dtd b/grc/data/grc/flow_graph.dtd new file mode 100644 index 000000000..904147b37 --- /dev/null +++ b/grc/data/grc/flow_graph.dtd @@ -0,0 +1,36 @@ +<!-- +Copyright 2008 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 +--> +<!-- + flow_graph.dtd + Josh Blum + The document type definition for flow graph xml files. + --> +<!ELEMENT flow_graph (timestamp?, block*, connection*)> <!-- optional timestamp --> +<!ELEMENT timestamp (#PCDATA)> +<!-- Block --> +<!ELEMENT block (key, param*)> +<!ELEMENT param (key, value)> +<!ELEMENT key (#PCDATA)> +<!ELEMENT value (#PCDATA)> +<!-- Connection --> +<!ELEMENT connection (source_block_id, sink_block_id, source_key, sink_key)> +<!ELEMENT source_block_id (#PCDATA)> +<!ELEMENT sink_block_id (#PCDATA)> +<!ELEMENT source_key (#PCDATA)> +<!ELEMENT sink_key (#PCDATA)> diff --git a/grc/data/grc/grc-icon-256.png b/grc/data/grc/grc-icon-256.png Binary files differnew file mode 100644 index 000000000..e4e8e54ae --- /dev/null +++ b/grc/data/grc/grc-icon-256.png diff --git a/grc/data/grc/grc-icon-256.svg b/grc/data/grc/grc-icon-256.svg new file mode 100644 index 000000000..87526d46c --- /dev/null +++ b/grc/data/grc/grc-icon-256.svg @@ -0,0 +1,216 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="256" + height="256" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + version="1.0" + sodipodi:docbase="/home/past/src" + sodipodi:docname="grc-icon-v3.svg" + inkscape:export-filename="/home/past/src/grc-icon-v3.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <defs + id="defs4"> + <linearGradient + id="linearGradient3661"> + <stop + style="stop-color:#0012dc;stop-opacity:1;" + offset="0" + id="stop3663" /> + <stop + style="stop-color:#8b92ff;stop-opacity:0.55371898;" + offset="1" + id="stop3665" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3661" + id="linearGradient2801" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-162.6648,798.0997)" + x1="17.664845" + y1="132.0565" + x2="157.82524" + y2="132.0565" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.7382812" + inkscape:cx="126.48791" + inkscape:cy="128.00013" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + gridoriginx="1px" + gridoriginy="1px" + gridspacingx="2px" + gridspacingy="2px" + guidecolor="#00ff0a" + guideopacity="0.49803922" + inkscape:grid-points="true" + inkscape:window-width="1098" + inkscape:window-height="904" + inkscape:window-x="149" + inkscape:window-y="42" + showguides="true" + inkscape:guide-bbox="true" + inkscape:object-points="true" + inkscape:object-nodes="true" + inkscape:object-bbox="true"> + <sodipodi:guide + orientation="vertical" + position="224" + id="guide10639" /> + <sodipodi:guide + orientation="vertical" + position="227.64729" + id="guide10641" /> + <sodipodi:guide + orientation="vertical" + position="220" + id="guide10643" /> + <sodipodi:guide + orientation="horizontal" + position="268.4015" + id="guide10645" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> + <dc:creator> + <cc:Agent> + <dc:title>Patrick Strasser <patrick.strasser@tugraz.at></dc:title> + </cc:Agent> + </dc:creator> + <dc:description>Icon/Symbol for the GNURadio Companion</dc:description> + <dc:title>grc-icon.svg</dc:title> + <dc:date>2007-02-23</dc:date> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/by-sa/2.5/"> + <cc:permits + rdf:resource="http://web.resource.org/cc/Reproduction" /> + <cc:permits + rdf:resource="http://web.resource.org/cc/Distribution" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/Notice" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/Attribution" /> + <cc:permits + rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/ShareAlike" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-796.3622)"> + <g + id="g7451" + transform="matrix(1.025628,0,0,1.030546,-0.101723,-32.00742)"> + <path + id="rect2760" + d="M 4.1981031,916.37787 L 160.00074,916.37787 L 160.00074,1048.3467 L 4.1981031,1048.3467 L 4.1981031,916.37787 z " + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.78145933;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <g + transform="matrix(0.995753,0,0,1.003897,164.8198,-8.972397)" + id="g2789" + style="stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none"> + <rect + style="fill:url(#linearGradient2801);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.78288651;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect9020" + width="140.1604" + height="16.796082" + x="-145" + y="921.75818" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.78288651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -161.50649,938.55428 L -4.8395996,938.55428" + id="path9005" /> + </g> + </g> + <g + id="g5503" + transform="matrix(1.028571,0,0,1.172413,-5.14284,-137.9928)"> + <rect + y="800.36212" + x="40" + height="116.00005" + width="140" + id="rect4562" + style="fill:#f3c690;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.28504848;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <g + transform="matrix(0.921053,0,0,1,26.93956,1.859948)" + id="g3694"> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.59084845;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 44,820.3622 L 136.35974,820.3622" + id="path4564" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.59084749;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 80,811.74976 L 80,828.3622" + id="path5451" /> + </g> + <g + id="g5499"> + <rect + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.28504944;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect7223" + width="140" + height="68.000015" + x="40" + y="848.36218" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.28505039;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 57.001362,905.90132 C 88.923615,905.8552 86.182775,867.89142 95.399136,867.52563 C 104.60967,867.16008 113.73233,867.60291 124.38688,868.00066 C 137.23411,868.48027 130.39915,906.48027 162.99863,906.48027" + id="path7225" + sodipodi:nodetypes="czss" /> + </g> + </g> + <rect + style="fill:#b890f3;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999952;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect14319" + width="79.999992" + height="64.000023" + x="27.999992" + y="960.36249" /> + <rect + style="fill:#f3c690;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999905;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect15206" + width="24.000004" + height="24.000004" + x="108" + y="980.36218" /> + <path + id="path13320" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999666;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M 220.97574,800.36203 L 220.97574,865.80513 C 236.42474,865.93437 248.49884,861.19996 248.96304,854.45866 C 249.42721,847.71737 237.26568,843.20829 221.81667,846.27676 C 206.36767,849.34522 193.45938,858.02071 192.98843,867.61976 C 192.53101,876.94268 204.68583,884.63729 220.13479,885.43882 C 235.58379,885.69443 248.49884,880.72833 248.96304,873.98703 C 249.42721,867.24575 237.26567,862.73666 221.81666,865.80513 C 206.36766,868.8736 193.45939,877.54909 192.98843,887.14813 C 192.53101,896.47106 204.68582,904.16566 220.13479,904.86701 C 235.5838,905.02246 248.49885,900.05636 248.96305,893.31506 C 249.42722,886.57378 237.26568,882.06469 221.81667,885.13316 C 206.36767,888.20162 193.45939,896.87711 192.98844,906.47616 C 192.53102,915.79909 204.68583,923.49369 220.13479,923.98015 C 235.58379,923.92069 248.49884,918.95459 248.96304,912.21329 C 249.42721,905.47201 237.26567,900.96293 221.81666,904.0314 C 206.36766,907.09986 193.45939,915.77535 192.98843,925.37439 C 192.53101,934.69732 207.20989,943.06708 221.81667,943.00644 L 221.81667,967.97713 C 221.63716,982.45754 209.62079,992.36197 195.88792,992.36199 L 132.42659,992.36199" + sodipodi:nodetypes="cccssscssscssscssccc" /> + </g> +</svg> diff --git a/grc/data/grc/grc-icon-32.png b/grc/data/grc/grc-icon-32.png Binary files differnew file mode 100644 index 000000000..1e4f4f6c5 --- /dev/null +++ b/grc/data/grc/grc-icon-32.png diff --git a/grc/data/grc_gnuradio/Makefile.am b/grc/data/grc_gnuradio/Makefile.am new file mode 100644 index 000000000..1f64722f5 --- /dev/null +++ b/grc/data/grc_gnuradio/Makefile.am @@ -0,0 +1,32 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = blocks + +datadir = $(grc_gnuradio_data_dir) + +EXTRA_DIST = \ + block.dtd \ + block_tree.xml \ + default_flow_graph.grc.xml \ + flow_graph.tmpl diff --git a/grc/data/grc_gnuradio/block.dtd b/grc/data/grc_gnuradio/block.dtd new file mode 100644 index 000000000..d892b1287 --- /dev/null +++ b/grc/data/grc_gnuradio/block.dtd @@ -0,0 +1,54 @@ +<!-- +Copyright 2008 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 +--> +<!-- + gnuradio_python.blocks.dtd + Josh Blum + The document type definition for blocks. + --> +<!-- + Top level element. + A block contains a name, ...parameters list, and list of IO ports. + --> +<!ELEMENT block (name, key, category?, import*, make, callback*, param*, check*, sink*, source*, doc?)> +<!-- + Sub level elements. + --> +<!ELEMENT param (name, key, value?, type, hide?, option*)> +<!ELEMENT option (name, key, opt*)> +<!ELEMENT sink (name, type, vlen?, nports?, optional?)> +<!ELEMENT source (name, type, vlen?, nports?, optional?)> +<!-- + Bottom level elements. + Character data only. + --> +<!ELEMENT category (#PCDATA)> +<!ELEMENT import (#PCDATA)> +<!ELEMENT doc (#PCDATA)> +<!ELEMENT name (#PCDATA)> +<!ELEMENT key (#PCDATA)> +<!ELEMENT check (#PCDATA)> +<!ELEMENT opt (#PCDATA)> +<!ELEMENT type (#PCDATA)> +<!ELEMENT hide (#PCDATA)> +<!ELEMENT vlen (#PCDATA)> +<!ELEMENT nports (#PCDATA)> +<!ELEMENT make (#PCDATA)> +<!ELEMENT value (#PCDATA)> +<!ELEMENT callback (#PCDATA)> +<!ELEMENT optional (#PCDATA)> diff --git a/grc/data/grc_gnuradio/block_tree.xml b/grc/data/grc_gnuradio/block_tree.xml new file mode 100644 index 000000000..4e5070d36 --- /dev/null +++ b/grc/data/grc_gnuradio/block_tree.xml @@ -0,0 +1,271 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Block Tree for platform gnuradio python. +################################################### + --> +<cat> + <name></name> <!-- Blank for Root Name --> + <cat> + <name>Sources</name> + <block>gr_sig_source_x</block> + <block>gr_noise_source_x</block> + <block>gr_vector_source_x</block> + <block>random_source_x</block> + <block>gr_glfsr_source_x</block> + <block>gr_null_source</block> + <block>gr_file_source</block> + <block>gr_udp_source</block> + <block>audio_source</block> + <block>gr_wavfile_source</block> + <block>pad_source</block> + </cat> + <cat> + <name>Sinks</name> + <block>gr_vector_sink_x</block> + <block>gr_null_sink</block> + <block>gr_file_sink</block> + <block>gr_udp_sink</block> + <block>audio_sink</block> + <block>gr_wavfile_sink</block> + <block>pad_sink</block> + </cat> + <cat> + <name>Graphical Sinks</name> + <block>wxgui_numbersink2</block> + <block>wxgui_scopesink2</block> + <block>wxgui_fftsink2</block> + <block>wxgui_constellationsink2</block> + <block>wxgui_waterfallsink2</block> + </cat> + <cat> + <name>Operators</name> + <block>gr_add_vxx</block> + <block>gr_sub_xx</block> + <block>gr_multiply_vxx</block> + <block>gr_divide_xx</block> + <block>gr_nlog10_ff</block> + + <block>gr_add_const_vxx</block> + <block>gr_multiply_const_vxx</block> + + <block>gr_not_xx</block> + <block>gr_and_xx</block> + <block>gr_or_xx</block> + <block>gr_xor_xx</block> + + <block>gr_max_xx</block> + <block>gr_argmax_xx</block> + <block>gr_rms_xx</block> + <block>gr_integrate_xx</block> + + <block>gr_conjugate_cc</block> + + <block>gr_fft_vxx</block> + <block>blks2_logpwrfft_x</block> + </cat> + <cat> + <name>Type Conversions</name> + <block>gr_complex_to_arg</block> + <block>gr_complex_to_mag</block> + <block>gr_complex_to_mag_squared</block> + <block>gr_complex_to_real</block> + <block>gr_complex_to_imag</block> + + <block>gr_complex_to_float</block> + <block>gr_float_to_complex</block> + + <block>gr_float_to_short</block> + <block>gr_short_to_float</block> + + <block>gr_float_to_char</block> + <block>gr_char_to_float</block> + + <block>gr_float_to_uchar</block> + <block>gr_uchar_to_float</block> + + <block>gr_complex_to_interleaved_short</block> + <block>gr_interleaved_short_to_complex</block> + </cat> + <cat> + <name>Stream Conversions</name> + <block>gr_interleave</block> + <block>gr_deinterleave</block> + + <block>gr_streams_to_stream</block> + <block>gr_stream_to_streams</block> + + <block>gr_streams_to_vector</block> + <block>gr_vector_to_streams</block> + + <block>gr_stream_to_vector</block> + <block>gr_vector_to_stream</block> + + <block>blks2_stream_to_vector_decimator</block> + </cat> + <cat> + <name>Misc Conversions</name> + <block>gr_unpacked_to_packed_xx</block> + <block>gr_packed_to_unpacked_xx</block> + <block>gr_unpack_k_bits_bb</block> + <block>gr_binary_slicer_fb</block> + <block>gr_chunks_to_symbols_xx</block> + <block>gr_map_bb</block> + </cat> + <cat> + <name>Synchronizers</name> + <block>gr_clock_recovery_mm_xx</block> + + <block>gr_costas_loop_cc</block> + <block>gr_dd_mpsk_sync_cc</block> + <block>gr_mpsk_sync_cc</block> + <block>gr_mpsk_receiver_cc</block> + + <block>gr_pll_carriertracking_cc</block> + <block>gr_pll_freqdet_cf</block> + <block>gr_pll_refout_cc</block> + + <block>gr_correlate_access_code_bb</block> + <block>gr_pn_correlator_cc</block> + <block>gr_simple_correlator</block> + <block>gr_simple_framer</block> + </cat> + <cat> + <name>Level Controls</name> + <block>gr_dpll_bb</block> + <block>gr_peak_detector_xb</block> + <block>gr_peak_detector2_fb</block> + <block>gr_sample_and_hold_xx</block> + + <block>gr_agc_xx</block> + <block>gr_agc2_xx</block> + <block>gr_feedforward_agc_cc</block> + + <block>gr_mute_xx</block> + <block>gr_simple_squelch_cc</block> + <block>blks2_standard_squelch</block> + <block>gr_pwr_squelch_xx</block> + <block>gr_threshold_ff</block> + </cat> + <cat> + <name>Filters</name> + <!-- FIR convenience filters --> + <block>low_pass_filter</block> + <block>high_pass_filter</block> + <block>band_pass_filter</block> + <block>band_reject_filter</block> + <!-- Filters that take taps as aruments --> + <block>gr_fir_filter_xxx</block> + <block>gr_interp_fir_filter_xxx</block> + <block>gr_fft_filter_xxx</block> + <block>gr_freq_xlating_fir_filter_xxx</block> + <block>gr_iir_filter_ffd</block> + <block>gr_filter_delay_fc</block> + <block>blks2_channel_model</block> + <!-- Other filters --> + <block>gr_single_pole_iir_filter_xx</block> + <block>gr_hilbert_fc</block> + <block>gr_goertzel_fc</block> + <block>gr_cma_equalizer_cc</block> + <block>gr_rational_resampler_base_xxx</block> + <block>blks2_rational_resampler_xxx</block> + <block>gr_fractional_interpolator_xx</block> + <block>gr_keep_one_in_n</block> + <block>gr_moving_average_xx</block> + <block>gr_iqcomp_cc</block> + </cat> + <cat> + <name>Modulators</name> + <block>gr_vco_f</block> + <block>gr_frequency_modulator_fc</block> + <block>gr_phase_modulator_fc</block> + <block>gr_quadrature_demod_cf</block> + + <block>gr_diff_phasor_cc</block> + <block>gr_constellation_decoder_cb</block> + + <block>gr_diff_encoder_bb</block> + <block>gr_diff_decoder_bb</block> + + <block>blks2_wfm_tx</block> + <block>blks2_wfm_rcv</block> + <block>blks2_wfm_rcv_pll</block> + + <block>blks2_nbfm_tx</block> + <block>blks2_nbfm_rx</block> + + <block>blks2_am_demod_cf</block> + <block>blks2_fm_demod_cf</block> + <block>blks2_fm_deemph</block> + <block>blks2_fm_preemph</block> + + <block>blks2_dxpsk_mod</block> + <block>blks2_dxpsk_demod</block> + + <block>blks2_gmsk_mod</block> + <block>blks2_gmsk_demod</block> + + <block>blks2_qamx_mod</block> + <block>blks2_qamx_demod</block> + + <block>blks2_synthesis_filterbank</block> + <block>blks2_analysis_filterbank</block> + </cat> + <cat> + <name>Error Correction</name> + + <block>blks2_packet_decoder</block> + <block>blks2_packet_encoder</block> + + <block>gr_encode_ccsds_27_bb</block> + <block>gr_decode_ccsds_27_fb</block> + </cat> + <cat> + <name>Trellis</name> + <block>trellis_encoder_xx</block> + <block>trellis_metrics_x</block> + <block>trellis_permutation</block> + <block>trellis_siso_combined_f</block> + <block>trellis_siso_f</block> + <block>trellis_viterbi_combined_xx</block> + <block>trellis_viterbi_x</block> + </cat> + <cat> + <name>USRP</name> + <block>usrp_simple_source_x</block> + <block>usrp_simple_sink_x</block> + <block>usrp_dual_source_x</block> + <block>usrp_dual_sink_x</block> + </cat> + <cat> + <name>Variables</name> + <block>variable</block> + <block>variable_slider</block> + <block>variable_chooser</block> + <block>variable_text_box</block> + <block>variable_sink</block> + <block>parameter</block> + </cat> + <cat> + <name>Misc</name> + <block>note</block> + <block>import</block> + + <block>gr_throttle</block> + <block>gr_delay</block> + <block>gr_repeat</block> + + <block>blks2_selector</block> + <block>blks2_valve</block> + <block>blks2_error_rate</block> + + <block>gr_head</block> + <block>gr_skiphead</block> + + <block>gr_kludge_copy</block> + <block>gr_nop</block> + + <block>xmlrpc_server</block> + <block>xmlrpc_client</block> + </cat> +</cat> diff --git a/grc/data/grc_gnuradio/blocks/Makefile.am b/grc/data/grc_gnuradio/blocks/Makefile.am new file mode 100644 index 000000000..4e6aae828 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/Makefile.am @@ -0,0 +1,205 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_gnuradio_blocks_dir) + +EXTRA_DIST = \ + audio_sink.xml \ + audio_source.xml \ + band_pass_filter.xml \ + band_reject_filter.xml \ + blks2_am_demod_cf.xml \ + blks2_analysis_filterbank.xml \ + blks2_channel_model.xml \ + blks2_dxpsk_demod.xml \ + blks2_dxpsk_mod.xml \ + blks2_error_rate.xml \ + blks2_fm_deemph.xml \ + blks2_fm_demod_cf.xml \ + blks2_fm_preemph.xml \ + blks2_gmsk_demod.xml \ + blks2_gmsk_mod.xml \ + blks2_logpwrfft_x.xml \ + blks2_nbfm_rx.xml \ + blks2_nbfm_tx.xml \ + blks2_packet_decoder.xml \ + blks2_packet_encoder.xml \ + blks2_qamx_demod.xml \ + blks2_qamx_mod.xml \ + blks2_rational_resampler_xxx.xml \ + blks2_selector.xml \ + blks2_standard_squelch.xml \ + blks2_stream_to_vector_decimator.xml \ + blks2_synthesis_filterbank.xml \ + blks2_valve.xml \ + blks2_wfm_rcv.xml \ + blks2_wfm_rcv_pll.xml \ + blks2_wfm_tx.xml \ + gr_add_const_vxx.xml \ + gr_add_vxx.xml \ + gr_agc2_xx.xml \ + gr_agc_xx.xml \ + gr_and_xx.xml \ + gr_argmax_xx.xml \ + gr_binary_slicer_fb.xml \ + gr_char_to_float.xml \ + gr_chunks_to_symbols.xml \ + gr_clock_recovery_mm_xx.xml \ + gr_cma_equalizer_cc.xml \ + gr_complex_to_arg.xml \ + gr_complex_to_float.xml \ + gr_complex_to_imag.xml \ + gr_complex_to_interleaved_short.xml \ + gr_complex_to_mag.xml \ + gr_complex_to_mag_squared.xml \ + gr_complex_to_real.xml \ + gr_conjugate_cc.xml \ + gr_constellation_decoder_cb.xml \ + gr_correlate_access_code_bb.xml \ + gr_costas_loop_cc.xml \ + gr_dd_mpsk_sync_cc.xml \ + gr_decode_ccsds_27_fb.xml \ + gr_deinterleave.xml \ + gr_delay.xml \ + gr_diff_decoder_bb.xml \ + gr_diff_encoder_bb.xml \ + gr_diff_phasor_cc.xml \ + gr_divide_xx.xml \ + gr_dpll_bb.xml \ + gr_encode_ccsds_27_bb.xml \ + gr_feedforward_agc_cc.xml \ + gr_fft_filter_xxx.xml \ + gr_fft_vxx.xml \ + gr_file_sink.xml \ + gr_file_source.xml \ + gr_filter_delay_fc.xml \ + gr_fir_filter_xxx.xml \ + gr_float_to_char.xml \ + gr_float_to_complex.xml \ + gr_float_to_short.xml \ + gr_float_to_uchar.xml \ + gr_fractional_interpolator_xx.xml \ + gr_freq_xlating_fir_filter_xxx.xml \ + gr_frequency_modulator_fc.xml \ + gr_glfsr_source_x.xml \ + gr_goertzel_fc.xml \ + gr_head.xml \ + gr_hilbert_fc.xml \ + gr_iir_filter_ffd.xml \ + gr_integrate_xx.xml \ + gr_interleave.xml \ + gr_interleaved_short_to_complex.xml \ + gr_interp_fir_filter_xxx.xml \ + gr_iqcomp_cc.xml \ + gr_keep_one_in_n.xml \ + gr_kludge_copy.xml \ + gr_map_bb.xml \ + gr_max_xx.xml \ + gr_moving_average_xx.xml \ + gr_mpsk_receiver_cc.xml \ + gr_mpsk_sync_cc.xml \ + gr_multiply_const_vxx.xml \ + gr_multiply_vxx.xml \ + gr_mute_xx.xml \ + gr_nlog10_ff.xml \ + gr_noise_source_x.xml \ + gr_nop.xml \ + gr_not_xx.xml \ + gr_null_sink.xml \ + gr_null_source.xml \ + gr_or_xx.xml \ + gr_packed_to_unpacked_xx.xml \ + gr_peak_detector2_fb.xml \ + gr_peak_detector_xb.xml \ + gr_phase_modulator_fc.xml \ + gr_pll_carriertracking_cc.xml \ + gr_pll_freqdet_cf.xml \ + gr_pll_refout_cc.xml \ + gr_pn_correlator_cc.xml \ + gr_pwr_squelch_xx.xml \ + gr_quadrature_demod_cf.xml \ + gr_rational_resampler_base_xxx.xml \ + gr_repeat.xml \ + gr_rms_xx.xml \ + gr_sample_and_hold_xx.xml \ + gr_short_to_float.xml \ + gr_sig_source_x.xml \ + gr_simple_correlator.xml \ + gr_simple_framer.xml \ + gr_simple_squelch_cc.xml \ + gr_single_pole_iir_filter_xx.xml \ + gr_skiphead.xml \ + gr_stream_to_streams.xml \ + gr_stream_to_vector.xml \ + gr_streams_to_stream.xml \ + gr_streams_to_vector.xml \ + gr_sub_xx.xml \ + gr_threshold_ff.xml \ + gr_throttle.xml \ + gr_uchar_to_float.xml \ + gr_udp_sink.xml \ + gr_udp_source.xml \ + gr_unpack_k_bits_bb.xml \ + gr_unpacked_to_packed_xx.xml \ + gr_vco_f.xml \ + gr_vector_sink_x.xml \ + gr_vector_source_x.xml \ + gr_vector_to_stream.xml \ + gr_vector_to_streams.xml \ + gr_wavfile_sink.xml \ + gr_wavfile_source.xml \ + gr_xor_xx.xml \ + high_pass_filter.xml \ + import.xml \ + low_pass_filter.xml \ + note.xml \ + options.xml \ + pad_sink.xml \ + pad_source.xml \ + parameter.xml \ + preferences.xml \ + random_source_x.xml \ + trellis_encoder_xx.xml \ + trellis_metrics_x.xml \ + trellis_permutation.xml \ + trellis_siso_combined_f.xml \ + trellis_siso_f.xml \ + trellis_viterbi_combined_xx.xml \ + trellis_viterbi_x.xml \ + usrp_diagnostics.xml \ + usrp_dual_sink_x.xml \ + usrp_dual_source_x.xml \ + usrp_simple_sink_x.xml \ + usrp_simple_source_x.xml \ + variable.xml \ + variable_chooser.xml \ + variable_sink.xml \ + variable_slider.xml \ + variable_text_box.xml \ + wxgui_constellationsink2.xml \ + wxgui_fftsink2.xml \ + wxgui_numbersink2.xml \ + wxgui_scopesink2.xml \ + wxgui_waterfallsink2.xml \ + xmlrpc_client.xml \ + xmlrpc_server.xml diff --git a/grc/data/grc_gnuradio/blocks/audio_sink.xml b/grc/data/grc_gnuradio/blocks/audio_sink.xml new file mode 100644 index 000000000..56c5980fc --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/audio_sink.xml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Audio Sink +################################################### + --> +<block> + <name>Audio Sink</name> + <key>audio_sink</key> + <import>from gnuradio import audio</import> + <make>audio.sink($samp_rate, $device_name, $ok_to_block)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>32000</value> + <type>enum</type> + <option> + <name>16KHz</name> + <key>16000</key> + </option> + <option> + <name>22.05KHz</name> + <key>22050</key> + </option> + <option> + <name>24KHz</name> + <key>24000</key> + </option> + <option> + <name>32KHz</name> + <key>32000</key> + </option> + <option> + <name>44.1KHz</name> + <key>44100</key> + </option> + <option> + <name>48KHz</name> + <key>48000</key> + </option> + </param> + <param> + <name>Device Name</name> + <key>device_name</key> + <value></value> + <type>string</type> + </param> + <param> + <name>OK to Block</name> + <key>ok_to_block</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>1</value> + <type>int</type> + </param> + <check>0 < $num_inputs</check> + <sink> + <name>in</name> + <type>float</type> + <nports>$num_inputs</nports> + </sink> + <doc> +Not all sampling rates will be supported by your hardware. + +Leave the device name blank to choose deafult audio device. \ +Audio device names may look like hw:0,0 + +The audio sink can have multiple inputs depending upon your hardware. \ +For example, set the inputs to 2 for stereo audio. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/audio_source.xml b/grc/data/grc_gnuradio/blocks/audio_source.xml new file mode 100644 index 000000000..2ae74e491 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/audio_source.xml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Audio Source +################################################### + --> +<block> + <name>Audio Source</name> + <key>audio_source</key> + <import>from gnuradio import audio</import> + <make>audio.source($samp_rate, $device_name, $ok_to_block)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>32000</value> + <type>enum</type> + <option> + <name>16KHz</name> + <key>16000</key> + </option> + <option> + <name>22.05KHz</name> + <key>22050</key> + </option> + <option> + <name>24KHz</name> + <key>24000</key> + </option> + <option> + <name>32KHz</name> + <key>32000</key> + </option> + <option> + <name>44.1KHz</name> + <key>44100</key> + </option> + <option> + <name>48KHz</name> + <key>48000</key> + </option> + </param> + <param> + <name>Device Name</name> + <key>device_name</key> + <value></value> + <type>string</type> + </param> + <param> + <name>OK to Block</name> + <key>ok_to_block</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Num Outputs</name> + <key>num_outputs</key> + <value>1</value> + <type>int</type> + </param> + <check>0 < $num_outputs</check> + <source> + <name>out</name> + <type>float</type> + <nports>$num_outputs</nports> + </source> + <doc> +Not all sampling rates will be supported by your hardware. + +Leave the device name blank to choose deafult audio device. \ +Audio device names may look like hw:0,0 + +The audio source can have multiple outputs depending upon your hardware. \ +For example, set the outputs to 2 for stereo audio. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/band_pass_filter.xml b/grc/data/grc_gnuradio/blocks/band_pass_filter.xml new file mode 100644 index 000000000..2dac2960e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/band_pass_filter.xml @@ -0,0 +1,125 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Band Pass Filter: Custom wrapper +################################################### + --> +<block> + <name>Band Pass Filter</name> + <key>band_pass_filter</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.$(type)($decim, firdes.band_pass( + $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</make> + <callback>set_taps(firdes.band_pass($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</callback> + <param> + <name>FIR Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Decimating)</name> + <key>fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Complex->Complex (Interpolating)</name> + <key>interp_fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Float->Float (Decimating)</name> + <key>fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + <option> + <name>Float->Float (Interpolating)</name> + <key>interp_fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Low Cutoff Freq</name> + <key>low_cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>High Cutoff Freq</name> + <key>high_cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>Transition Width</name> + <key>width</key> + <type>real</type> + </param> + <param> + <name>Window</name> + <key>window</key> + <type>enum</type> + <option> + <name>Hamming</name> + <key>WIN_HAMMING</key> + </option> + <option> + <name>Hann</name> + <key>WIN_HANN</key> + </option> + <option> + <name>Blackman</name> + <key>WIN_BLACKMAN</key> + </option> + <option> + <name>Rectangular</name> + <key>WIN_RECTANGULAR</key> + </option> + <option> + <name>Kaiser</name> + <key>WIN_KAISER</key> + </option> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <value>6.76</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +This filter is a convenience wrapper for an fir filter and a firdes taps generating function. + +The decimation paramater becomes interpolation when the filter type is set to interpolating. + +Sample rate, cutoff frequency, and transition width are in Hertz. + +The beta paramater only applies to the Kaiser window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/band_reject_filter.xml b/grc/data/grc_gnuradio/blocks/band_reject_filter.xml new file mode 100644 index 000000000..ed6a5fa88 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/band_reject_filter.xml @@ -0,0 +1,125 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Band Reject Filter: Custom wrapper +################################################### + --> +<block> + <name>Band Reject Filter</name> + <key>band_reject_filter</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.$(type)($decim, firdes.band_reject( + $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</make> + <callback>set_taps(firdes.band_reject($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</callback> + <param> + <name>FIR Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Decimating)</name> + <key>fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Complex->Complex (Interpolating)</name> + <key>interp_fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Float->Float (Decimating)</name> + <key>fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + <option> + <name>Float->Float (Interpolating)</name> + <key>interp_fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Low Cutoff Freq</name> + <key>low_cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>High Cutoff Freq</name> + <key>high_cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>Transition Width</name> + <key>width</key> + <type>real</type> + </param> + <param> + <name>Window</name> + <key>window</key> + <type>enum</type> + <option> + <name>Hamming</name> + <key>WIN_HAMMING</key> + </option> + <option> + <name>Hann</name> + <key>WIN_HANN</key> + </option> + <option> + <name>Blackman</name> + <key>WIN_BLACKMAN</key> + </option> + <option> + <name>Rectangular</name> + <key>WIN_RECTANGULAR</key> + </option> + <option> + <name>Kaiser</name> + <key>WIN_KAISER</key> + </option> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <value>6.76</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +This filter is a convenience wrapper for an fir filter and a firdes taps generating function. + +The decimation paramater becomes interpolation when the filter type is set to interpolating. + +Sample rate, cutoff frequency, and transition width are in Hertz. + +The beta paramater only applies to the Kaiser window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_am_demod_cf.xml b/grc/data/grc_gnuradio/blocks/blks2_am_demod_cf.xml new file mode 100644 index 000000000..898c613be --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_am_demod_cf.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AM Demod +################################################### + --> +<block> + <name>AM Demod</name> + <key>blks2_am_demod_cf</key> + <import>from gnuradio import blks2</import> + <make>blks2.am_demod_cf( + channel_rate=$chan_rate, + audio_decim=$audio_decim, + audio_pass=$audio_pass, + audio_stop=$audio_stop, +)</make> + <param> + <name>Channel Rate</name> + <key>chan_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decim</key> + <type>int</type> + </param> + <param> + <name>Audio Pass</name> + <key>audio_pass</key> + <value>5000</value> + <type>real</type> + </param> + <param> + <name>Audio Stop</name> + <key>audio_stop</key> + <value>5500</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_analysis_filterbank.xml b/grc/data/grc_gnuradio/blocks/blks2_analysis_filterbank.xml new file mode 100644 index 000000000..93cfa30af --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_analysis_filterbank.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Analysis Filterbank +################################################### + --> +<block> + <name>Analysis Filterbank</name> + <key>blks2_analysis_filterbank</key> + <import>from gnuradio import blks2</import> + <make>blks2.analysis_filterbank(mpoints=$mpoints, taps=$taps)</make> + <param> + <name>MPoints</name> + <key>mpoints</key> + <value>3</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>complex_vector</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + <nports>$mpoints</nports> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_channel_model.xml b/grc/data/grc_gnuradio/blocks/blks2_channel_model.xml new file mode 100644 index 000000000..88805636c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_channel_model.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Channel Model +################################################### + --> +<block> + <name>Channel Model</name> + <key>blks2_channel_model</key> + <import>from gnuradio import blks2</import> + <import>from gnuradio.gr import firdes</import> + <make>blks2.channel_model( + noise_voltage=$noise_voltage, + frequency_offset=$freq_offset, + epsilon=$epsilon, + taps=$taps, + noise_seed=$seed, +)</make> + <callback>set_noise_voltage($noise_voltage)</callback> + <callback>set_frequency_offset($freq_offset)</callback> + <callback>set_taps($taps)</callback> + <param> + <name>Noise Voltage</name> + <key>noise_voltage</key> + <value>0.0</value> + <type>real</type> + </param> + <param> + <name>Frequency Offset</name> + <key>freq_offset</key> + <value>0.0</value> + <type>real</type> + </param> + <param> + <name>Epsilon</name> + <key>epsilon</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <value>1.0, 0.0</value> + <type>complex_vector</type> + </param> + <param> + <name>Seed</name> + <key>seed</key> + <value>42</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_dxpsk_demod.xml b/grc/data/grc_gnuradio/blocks/blks2_dxpsk_demod.xml new file mode 100644 index 000000000..6a8cb9c3b --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_dxpsk_demod.xml @@ -0,0 +1,95 @@ +<?xml version="1.0"?> +<!-- +################################################### +##DPSK Demod - 2, 4, 8 +################################################### + --> +<block> + <name>DPSK Demod</name> + <key>blks2_dxpsk_demod</key> + <import>from gnuradio import blks2</import> + <make>blks2.$(type)_demod( + samples_per_symbol=$samples_per_symbol, + excess_bw=$excess_bw, + costas_alpha=$costas_alpha, + gain_mu=$gain_mu, + mu=$mu, + omega_relative_limit=$omega_relative_limit, + gray_code=$gray_code, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>DBPSK</name> + <key>dbpsk</key> + </option> + <option> + <name>DQPSK</name> + <key>dqpsk</key> + </option> + <option> + <name>D8PSK</name> + <key>d8psk</key> + </option> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Excess BW</name> + <key>excess_bw</key> + <value>0.35</value> + <type>real</type> + </param> + <param> + <name>Costas Alpha</name> + <key>costas_alpha</key> + <value>0.175</value> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <value>0.175</value> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <value>0.5</value> + <type>real</type> + </param> + <param> + <name>Omega Relative Limit</name> + <key>omega_relative_limit</key> + <value>0.005</value> + <type>real</type> + </param> + <param> + <name>Gray Code</name> + <key>gray_code</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_dxpsk_mod.xml b/grc/data/grc_gnuradio/blocks/blks2_dxpsk_mod.xml new file mode 100644 index 000000000..ebbee404d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_dxpsk_mod.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##DPSK Mod - 2, 4, 8 +################################################### + --> +<block> + <name>DPSK Mod</name> + <key>blks2_dxpsk_mod</key> + <import>from gnuradio import blks2</import> + <make>blks2.$(type)_mod( + samples_per_symbol=$samples_per_symbol, + excess_bw=$excess_bw, + gray_code=$gray_code, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>DBPSK</name> + <key>dbpsk</key> + </option> + <option> + <name>DQPSK</name> + <key>dqpsk</key> + </option> + <option> + <name>D8PSK</name> + <key>d8psk</key> + </option> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Excess BW</name> + <key>excess_bw</key> + <value>0.35</value> + <type>real</type> + </param> + <param> + <name>Gray Code</name> + <key>gray_code</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_error_rate.xml b/grc/data/grc_gnuradio/blocks/blks2_error_rate.xml new file mode 100644 index 000000000..79703f6e9 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_error_rate.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Error Rate: +## Custom blks2 block +################################################### + --> +<block> + <name>Error Rate</name> + <key>blks2_error_rate</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.error_rate( + type=$type, + win_size=$win_size, + bits_per_symbol=$bits_per_symbol, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Bit Error Rate</name> + <key>"BER"</key> + </option> + <option> + <name>Symbol Error Rate</name> + <key>"SER"</key> + </option> + </param> + <param> + <name>Window Size</name> + <key>win_size</key> + <value>1000</value> + <type>int</type> + </param> + <param> + <name>Bits per Symbol</name> + <key>bits_per_symbol</key> + <value>2</value> + <type>int</type> + </param> + <sink> + <name>ref</name> + <type>byte</type> + </sink> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> + <doc> +Calculate the bit error rate (BER) or the symbol error rate (SER) over a number of samples given by the window size. \ +The actual window size will start at size one and grow to the full window size as new samples arrive. \ +Once the window has reached full size, old samples are shifted out of the window and new samples shfited in. + +The error block compares the input byte stream to the reference byte stream. \ +For example, the reference byte stream could be the input to a modulator, \ +and the input byte stream could be the output of a modulator. + +Each byte in the incoming stream represents one symbol. \ +The bits per symbol parameter is only useful for calculating the BER. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_fm_deemph.xml b/grc/data/grc_gnuradio/blocks/blks2_fm_deemph.xml new file mode 100644 index 000000000..6f38dab6d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_fm_deemph.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Deemphasis +################################################### + --> +<block> + <name>FM Deemphasis</name> + <key>blks2_fm_deemph</key> + <import>from gnuradio import blks2</import> + <make>blks2.fm_deemph(fs=$samp_rate, tau=$tau)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_fm_demod_cf.xml b/grc/data/grc_gnuradio/blocks/blks2_fm_demod_cf.xml new file mode 100644 index 000000000..2ce1fb973 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_fm_demod_cf.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Demod +################################################### + --> +<block> + <name>FM Demod</name> + <key>blks2_fm_demod_cf</key> + <import>from gnuradio import blks2</import> + <make>blks2.fm_demod_cf( + channel_rate=$chan_rate, + audio_decim=$audio_decim, + deviation=$deviation, + audio_pass=$audio_pass, + audio_stop=$audio_stop, + gain=$gain, + tau=$tau, +)</make> + <param> + <name>Channel Rate</name> + <key>chan_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decim</key> + <type>int</type> + </param> + <param> + <name>Deviation</name> + <key>deviation</key> + <value>75000</value> + <type>real</type> + </param> + <param> + <name>Audio Pass</name> + <key>audio_pass</key> + <value>15000</value> + <type>real</type> + </param> + <param> + <name>Audio Stop</name> + <key>audio_stop</key> + <value>16000</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_fm_preemph.xml b/grc/data/grc_gnuradio/blocks/blks2_fm_preemph.xml new file mode 100644 index 000000000..672a7a7b2 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_fm_preemph.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Preemphasis +################################################### + --> +<block> + <name>FM Preemphasis</name> + <key>blks2_fm_preemph</key> + <import>from gnuradio import blks2</import> + <make>blks2.fm_preemph(fs=$samp_rate, tau=$tau)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_gmsk_demod.xml b/grc/data/grc_gnuradio/blocks/blks2_gmsk_demod.xml new file mode 100644 index 000000000..318c4b4b2 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_gmsk_demod.xml @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<!-- +################################################### +##GMSK Demod +################################################### + --> +<block> + <name>GMSK Demod</name> + <key>blks2_gmsk_demod</key> + <import>from gnuradio import blks2</import> + <make>blks2.gmsk_demod( + samples_per_symbol=$samples_per_symbol, + gain_mu=$gain_mu, + mu=$mu, + omega_relative_limit=$omega_relative_limit, + freq_error=$freq_error, +)</make> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <value>0.175</value> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <value>0.5</value> + <type>real</type> + </param> + <param> + <name>Omega Relative Limit</name> + <key>omega_relative_limit</key> + <value>0.005</value> + <type>real</type> + </param> + <param> + <name>Freq Error</name> + <key>freq_error</key> + <value>0.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_gmsk_mod.xml b/grc/data/grc_gnuradio/blocks/blks2_gmsk_mod.xml new file mode 100644 index 000000000..1633dc8ef --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_gmsk_mod.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##GMSK Mod +################################################### + --> +<block> + <name>GMSK Mod</name> + <key>blks2_gmsk_mod</key> + <import>from gnuradio import blks2</import> + <make>blks2.gmsk_mod( + samples_per_symbol=$samples_per_symbol, + bt=$bt, +)</make> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>BT</name> + <key>bt</key> + <value>0.35</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_logpwrfft_x.xml b/grc/data/grc_gnuradio/blocks/blks2_logpwrfft_x.xml new file mode 100644 index 000000000..ef49c443e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_logpwrfft_x.xml @@ -0,0 +1,89 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Log Power FFT +################################################### + --> +<block> + <name>Log Power FFT</name> + <key>blks2_logpwrfft_x</key> + <import>from gnuradio import blks2</import> + <make>blks2.logpwrfft_$(type.fcn)( + sample_rate=$sample_rate, + fft_size=$fft_size, + ref_scale=$ref_scale, + frame_rate=$frame_rate, + avg_alpha=$avg_alpha, + average=$average, +)</make> + <callback>set_sample_rate($sample_rate)</callback> + <callback>set_avg_alpha($avg_alpha)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>sample_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>FFT Size</name> + <key>fft_size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Reference Scale</name> + <key>ref_scale</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Frame Rate</name> + <key>frame_rate</key> + <value>30</value> + <type>real</type> + </param> + <param> + <name>Average Alpha</name> + <key>avg_alpha</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Average</name> + <key>average</key> + <value>False</value> + <type>enum</type> + <option> + <name>On</name> + <key>True</key> + </option> + <option> + <name>Off</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$fft_size</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_nbfm_rx.xml b/grc/data/grc_gnuradio/blocks/blks2_nbfm_rx.xml new file mode 100644 index 000000000..d332b9a6b --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_nbfm_rx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##NBFM Receive +################################################### + --> +<block> + <name>NBFM Receive</name> + <key>blks2_nbfm_rx</key> + <import>from gnuradio import blks2</import> + <make>blks2.nbfm_rx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>5e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_nbfm_tx.xml b/grc/data/grc_gnuradio/blocks/blks2_nbfm_tx.xml new file mode 100644 index 000000000..3aa7ede0e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_nbfm_tx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##NBFM Transmit +################################################### + --> +<block> + <name>NBFM Transmit</name> + <key>blks2_nbfm_tx</key> + <import>from gnuradio import blks2</import> + <make>blks2.nbfm_tx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>5e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_packet_decoder.xml b/grc/data/grc_gnuradio/blocks/blks2_packet_decoder.xml new file mode 100644 index 000000000..d360bc177 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_packet_decoder.xml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Packet Decoder +################################################### + --> +<block> + <name>Packet Decoder</name> + <key>blks2_packet_decoder</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <import>from gnuradio import gr</import> + <make>grc_blks2.packet_decoder( + item_size_out=$type.size*$vlen, + access_code=$access_code, + threshold=$threshold, +)</make> + <param> + <name>Output Type</name> + <key>type</key> + <value>float</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Access Code</name> + <key>access_code</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Threshold</name> + <key>threshold</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> + <doc> +Packet decoder block, for use with the gnuradio demodulator blocks: gmsk, psk, qam. + +Access Code: string of 1's and 0's, leave blank for default. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_packet_encoder.xml b/grc/data/grc_gnuradio/blocks/blks2_packet_encoder.xml new file mode 100644 index 000000000..ea9927225 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_packet_encoder.xml @@ -0,0 +1,117 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Packet Encoder +################################################### + --> +<block> + <name>Packet Encoder</name> + <key>blks2_packet_encoder</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <import>from gnuradio import gr</import> + <make>grc_blks2.packet_encoder( + item_size_in=$type.size*$vlen, + samples_per_symbol=$samples_per_symbol, + bits_per_symbol=$bits_per_symbol, + access_code=$access_code, + pad_for_usrp=$pad_for_usrp, + payload_length=$payload_length, +)</make> + <param> + <name>Input Type</name> + <key>type</key> + <value>float</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <type>int</type> + </param> + <param> + <name>Bits/Symbol</name> + <key>bits_per_symbol</key> + <type>int</type> + </param> + <param> + <name>Access Code</name> + <key>access_code</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Pad for USRP</name> + <key>pad_for_usrp</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Payload Length</name> + <key>payload_length</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> + <doc> +Packet encoder 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 + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_qamx_demod.xml b/grc/data/grc_gnuradio/blocks/blks2_qamx_demod.xml new file mode 100644 index 000000000..0d311bbe1 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_qamx_demod.xml @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QAM Demod - 8, 16, 64, 256 +################################################### + --> +<block> + <name>QAM Demod</name> + <key>blks2_qamx_demod</key> + <import>from gnuradio import blks2</import> + <make>blks2.$(type)_demod( + samples_per_symbol=$samples_per_symbol, + excess_bw=$excess_bw, + costas_alpha=$costas_alpha, + gain_mu=$gain_mu, + mu=$mu, + omega_relative_limit=$omega_relative_limit, + gray_code=$gray_code, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>QAM8</name> + <key>qam8</key> + </option> + <option> + <name>QAM16</name> + <key>qam16</key> + </option> + <option> + <name>QAM64</name> + <key>qam64</key> + </option> + <option> + <name>QAM256</name> + <key>qam256</key> + </option> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Excess BW</name> + <key>excess_bw</key> + <value>0.35</value> + <type>real</type> + </param> + <param> + <name>Costas Alpha</name> + <key>costas_alpha</key> + <value>0.175</value> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <value>0.03</value> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <value>0.05</value> + <type>real</type> + </param> + <param> + <name>Omega Relative Limit</name> + <key>omega_relative_limit</key> + <value>0.005</value> + <type>real</type> + </param> + <param> + <name>Gray Code</name> + <key>gray_code</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_qamx_mod.xml b/grc/data/grc_gnuradio/blocks/blks2_qamx_mod.xml new file mode 100644 index 000000000..5ab0e2180 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_qamx_mod.xml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QAM Mod - 8, 16, 64, 256 +################################################### + --> +<block> + <name>QAM Mod</name> + <key>blks2_qamx_mod</key> + <import>from gnuradio import blks2</import> + <make>blks2.$(type)_mod( + samples_per_symbol=$samples_per_symbol, + excess_bw=$excess_bw, + gray_code=$gray_code, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>QAM8</name> + <key>qam8</key> + </option> + <option> + <name>QAM16</name> + <key>qam16</key> + </option> + <option> + <name>QAM64</name> + <key>qam64</key> + </option> + <option> + <name>QAM256</name> + <key>qam256</key> + </option> + </param> + <param> + <name>Samples/Symbol</name> + <key>samples_per_symbol</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Excess BW</name> + <key>excess_bw</key> + <value>0.35</value> + <type>real</type> + </param> + <param> + <name>Gray Code</name> + <key>gray_code</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_rational_resampler_xxx.xml b/grc/data/grc_gnuradio/blocks/blks2_rational_resampler_xxx.xml new file mode 100644 index 000000000..2f81a50e5 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_rational_resampler_xxx.xml @@ -0,0 +1,88 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Rational Resampler +################################################### + --> +<block> + <name>Rational Resampler</name> + <key>blks2_rational_resampler_xxx</key> + <import>from gnuradio import blks2</import> + <import>from gnuradio.gr import firdes</import> + <make>blks2.rational_resampler_$(type)( + interpolation=$interp, + decimation=$decim, +#if $taps.eval + taps=$taps, +#else + taps=None, +#end if +#if $fractional_bw.eval != 0 + fractional_bw=$fractional_bw, +#else + fractional_bw=None, +#end if +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Real Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Float (Real Taps)</name> + <key>fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Interpolation</name> + <key>interp</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <value>[]</value> + <type>$type.taps</type> + </param> + <param> + <name>Fractional BW</name> + <key>fractional_bw</key> + <value>0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +Leave taps empty for automatic value. +Leave fractional bandwidth 0 for automatic value. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_selector.xml b/grc/data/grc_gnuradio/blocks/blks2_selector.xml new file mode 100644 index 000000000..457f8695e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_selector.xml @@ -0,0 +1,97 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Selector: +## Custom blks2 block +################################################### + --> +<block> + <name>Selector</name> + <key>blks2_selector</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.selector( + item_size=$type.size*$vlen, + num_inputs=$num_inputs, + num_outputs=$num_outputs, + input_index=$input_index, + output_index=$output_index, +)</make> + <callback>set_input_index($input_index)</callback> + <callback>set_output_index($output_index)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Num Outputs</name> + <key>num_outputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Input Index</name> + <key>input_index</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Output Index</name> + <key>output_index</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_outputs</nports> + </source> + <doc> +Connect the sink at input index to the source at output index. Leave all other ports disconnected. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_standard_squelch.xml b/grc/data/grc_gnuradio/blocks/blks2_standard_squelch.xml new file mode 100644 index 000000000..fa32c6c31 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_standard_squelch.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Standard Squelch +################################################### + --> +<block> + <name>Standard Squelch</name> + <key>blks2_standard_squelch</key> + <import>from gnuradio import blks2</import> + <make>blks2.standard_squelch(audio_rate=$audio_rate) +$id.set_threshold($threshold)</make> + <callback>set_threshold($threshold)</callback> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>real</type> + </param> + <param> + <name>Threshold</name> + <key>threshold</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_stream_to_vector_decimator.xml b/grc/data/grc_gnuradio/blocks/blks2_stream_to_vector_decimator.xml new file mode 100644 index 000000000..25f8f7a62 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_stream_to_vector_decimator.xml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream to Vector Decimator +################################################### + --> +<block> + <name>Stream to Vec Decim</name> + <key>blks2_stream_to_vector_decimator</key> + <import>from gnuradio import blks2</import> + <make>blks2.stream_to_vector_decimator( + item_size=$type.size, + sample_rate=$sample_rate, + vec_rate=$vec_rate, + vec_len=$vlen, +)</make> + <callback>set_sample_rate($sample_rate)</callback> + <callback>set_vec_rate($vec_rate)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>sample_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Vec Rate</name> + <key>vec_rate</key> + <value>30</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1024</value> + <type>int</type> + </param> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_synthesis_filterbank.xml b/grc/data/grc_gnuradio/blocks/blks2_synthesis_filterbank.xml new file mode 100644 index 000000000..5979ed3f7 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_synthesis_filterbank.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Synthesis Filterbank +################################################### + --> +<block> + <name>Synthesis Filterbank</name> + <key>blks2_synthesis_filterbank</key> + <import>from gnuradio import blks2</import> + <make>blks2.synthesis_filterbank(mpoints=$mpoints, taps=$taps)</make> + <param> + <name>MPoints</name> + <key>mpoints</key> + <value>3</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>complex_vector</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + <nports>$mpoints</nports> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_valve.xml b/grc/data/grc_gnuradio/blocks/blks2_valve.xml new file mode 100644 index 000000000..47c553523 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_valve.xml @@ -0,0 +1,72 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Valve: +## Custom blks2 block +################################################### + --> +<block> + <name>Valve</name> + <key>blks2_valve</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.valve(item_size=$type.size*$vlen, open=bool($open))</make> + <callback>set_open(bool($open))</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Open</name> + <key>open</key> + <value>0</value> + <type>raw</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_outputs</nports> + </source> + <doc> +Connect output to input when valve is closed (not open). + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv.xml b/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv.xml new file mode 100644 index 000000000..37fb3ba8c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Receive +################################################### + --> +<block> + <name>WBFM Receive</name> + <key>blks2_wfm_rcv</key> + <import>from gnuradio import blks2</import> + <make>blks2.wfm_rcv( + quad_rate=$quad_rate, + audio_decimation=$audio_decimation, +)</make> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decimation</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv_pll.xml b/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv_pll.xml new file mode 100644 index 000000000..3563a1f2a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_wfm_rcv_pll.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Receive PLL +################################################### + --> +<block> + <name>WBFM Receive PLL</name> + <key>blks2_wfm_rcv_pll</key> + <import>from gnuradio import blks2</import> + <make>blks2.wfm_rcv_pll( + demod_rate=$quad_rate, + audio_decimation=$audio_decimation, +)</make> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decimation</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/blks2_wfm_tx.xml b/grc/data/grc_gnuradio/blocks/blks2_wfm_tx.xml new file mode 100644 index 000000000..cff92d819 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/blks2_wfm_tx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Transmit +################################################### + --> +<block> + <name>WBFM Transmit</name> + <key>blks2_wfm_tx</key> + <import>from gnuradio import blks2</import> + <make>blks2.wfm_tx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>75e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_add_const_vxx.xml b/grc/data/grc_gnuradio/blocks/gr_add_const_vxx.xml new file mode 100644 index 000000000..9f1c545ab --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_add_const_vxx.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Add Const Block: +## all types, 1 output, 1 input & const +################################################### + --> +<block> + <name>Add Const</name> + <key>gr_add_const_vxx</key> + <import>from gnuradio import gr</import> + <make>gr.add_const_v$(type.fcn)($const)</make> + <callback>set_k($const)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>const_type:complex_vector</opt> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>const_type:real_vector</opt> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>$type.const_type</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>len($const) == $vlen</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_add_vxx.xml b/grc/data/grc_gnuradio/blocks/gr_add_vxx.xml new file mode 100644 index 000000000..479cdaae4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_add_vxx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Add Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Add</name> + <key>gr_add_vxx</key> + <import>from gnuradio import gr</import> + <make>gr.add_v$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs > 1</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_agc2_xx.xml b/grc/data/grc_gnuradio/blocks/gr_agc2_xx.xml new file mode 100644 index 000000000..fb3ae5704 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_agc2_xx.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AGC2 +################################################### + --> +<block> + <name>AGC2</name> + <key>gr_agc2_xx</key> + <import>from gnuradio import gr</import> + <make>gr.agc2_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain, $max_gain)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Attack Rate</name> + <key>attack_rate</key> + <value>1e-1</value> + <type>real</type> + </param> + <param> + <name>Decay Rate</name> + <key>decay_rate</key> + <value>1e-2</value> + <type>real</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Max Gain</name> + <key>max_gain</key> + <value>0.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_agc_xx.xml b/grc/data/grc_gnuradio/blocks/gr_agc_xx.xml new file mode 100644 index 000000000..c87d239ed --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_agc_xx.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AGC +################################################### + --> +<block> + <name>AGC</name> + <key>gr_agc_xx</key> + <import>from gnuradio import gr</import> + <make>gr.agc_$(type.fcn)($rate, $reference, $gain, $max_gain)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Rate</name> + <key>rate</key> + <value>1e-4</value> + <type>real</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Max Gain</name> + <key>max_gain</key> + <value>0.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_and_xx.xml b/grc/data/grc_gnuradio/blocks/gr_and_xx.xml new file mode 100644 index 000000000..9ed006090 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_and_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical And Block +################################################### + --> +<block> + <name>And</name> + <key>gr_and_xx</key> + <import>from gnuradio import gr</import> + <make>gr.and_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_argmax_xx.xml b/grc/data/grc_gnuradio/blocks/gr_argmax_xx.xml new file mode 100644 index 000000000..e3e4e3ead --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_argmax_xx.xml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- +################################################### +##ArgMax: +## 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Argmax</name> + <key>gr_argmax_xx</key> + <import>from gnuradio import gr</import> + <make>gr.argmax_$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:fs</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:is</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:dd</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>short</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_binary_slicer_fb.xml b/grc/data/grc_gnuradio/blocks/gr_binary_slicer_fb.xml new file mode 100644 index 000000000..85d71e709 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_binary_slicer_fb.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Binary Slicer +################################################### + --> +<block> + <name>Binary Slicer</name> + <key>gr_binary_slicer_fb</key> + <import>from gnuradio import gr</import> + <make>gr.binary_slicer_fb()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_char_to_float.xml b/grc/data/grc_gnuradio/blocks/gr_char_to_float.xml new file mode 100644 index 000000000..9ab778051 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_char_to_float.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Char to Float: +################################################### + --> +<block> + <name>Char To Float</name> + <key>gr_char_to_float</key> + <import>from gnuradio import gr</import> + <make>gr.char_to_float()</make> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_chunks_to_symbols.xml b/grc/data/grc_gnuradio/blocks/gr_chunks_to_symbols.xml new file mode 100644 index 000000000..b54e710ef --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_chunks_to_symbols.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Chunks to Symbols +################################################### + --> +<block> + <name>Chunks to Symbols</name> + <key>gr_chunks_to_symbols_xx</key> + <import>from gnuradio import gr</import> + <make>gr.chunks_to_symbols_$(in_type.fcn)$(out_type.fcn)($symbol_table, $dimension)</make> + <param> + <name>Input Type</name> + <key>in_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>table:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>table:real_vector</opt> + </option> + </param> + <param> + <name>Symbol Table</name> + <key>symbol_table</key> + <type>$out_type.table</type> + </param> + <param> + <name>Dimension</name> + <key>dimension</key> + <value>2</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$in_type</type> + </sink> + <source> + <name>out</name> + <type>$out_type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_clock_recovery_mm_xx.xml b/grc/data/grc_gnuradio/blocks/gr_clock_recovery_mm_xx.xml new file mode 100644 index 000000000..613cc23bf --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_clock_recovery_mm_xx.xml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Clock Recovery MM +################################################### + --> +<block> + <name>Clock Recovery MM</name> + <key>gr_clock_recovery_mm_xx</key> + <import>from gnuradio import gr</import> + <make>gr.clock_recovery_mm_$(type.fcn)($omega, $gain_omega, $mu, $gain_mu, $omega_relative_limit)</make> + <callback>set_omega($omega)</callback> + <callback>set_gain_omega($gain_omega)</callback> + <callback>set_mu($mu)</callback> + <callback>set_gain_mu($gain_mu)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Omega</name> + <key>omega</key> + <type>real</type> + </param> + <param> + <name>Gain Omega</name> + <key>gain_omega</key> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <type>real</type> + </param> + <param> + <name>Omega Relative Limit</name> + <key>omega_relative_limit</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_cma_equalizer_cc.xml b/grc/data/grc_gnuradio/blocks/gr_cma_equalizer_cc.xml new file mode 100644 index 000000000..142fb6d81 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_cma_equalizer_cc.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +################################################### +##CMA Equalizer +################################################### + --> +<block> + <name>CMA Equalizer</name> + <key>gr_cma_equalizer_cc</key> + <import>from gnuradio import gr</import> + <make>gr.cma_equalizer_cc($num_taps, $modulus, $mu)</make> + <param> + <name>Num Taps</name> + <key>num_taps</key> + <value>64</value> + <type>int</type> + </param> + <param> + <name>Modulus</name> + <key>modulus</key> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_arg.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_arg.xml new file mode 100644 index 000000000..a7bbacd74 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_arg.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Arg +################################################### + --> +<block> + <name>Complex to Arg</name> + <key>gr_complex_to_arg</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_arg($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_float.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_float.xml new file mode 100644 index 000000000..5b02c3d34 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_float.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Float: +## one or two output streams +################################################### + --> +<block> + <name>Complex To Float</name> + <key>gr_complex_to_float</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_float($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + <optional>1</optional> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_imag.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_imag.xml new file mode 100644 index 000000000..7c120eedd --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_imag.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Imaginary +################################################### + --> +<block> + <name>Complex to Imag</name> + <key>gr_complex_to_imag</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_imag($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_interleaved_short.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_interleaved_short.xml new file mode 100644 index 000000000..5e999599a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_interleaved_short.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Interleaved Short: +################################################### + --> +<block> + <name>Complex To IShort</name> + <key>gr_complex_to_interleaved_short</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_interleaved_short()</make> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>short</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_mag.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_mag.xml new file mode 100644 index 000000000..adc95f207 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_mag.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Magnitude +################################################### + --> +<block> + <name>Complex to Mag</name> + <key>gr_complex_to_mag</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_mag($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_mag_squared.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_mag_squared.xml new file mode 100644 index 000000000..cd23bfb5c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_mag_squared.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Magnitude Squared +################################################### + --> +<block> + <name>Complex to Mag^2</name> + <key>gr_complex_to_mag_squared</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_mag_squared($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_complex_to_real.xml b/grc/data/grc_gnuradio/blocks/gr_complex_to_real.xml new file mode 100644 index 000000000..ae9ec7b14 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_complex_to_real.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex to Real +################################################### + --> +<block> + <name>Complex to Real</name> + <key>gr_complex_to_real</key> + <import>from gnuradio import gr</import> + <make>gr.complex_to_real($vlen)</make> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>complex</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_conjugate_cc.xml b/grc/data/grc_gnuradio/blocks/gr_conjugate_cc.xml new file mode 100644 index 000000000..0b4deb347 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_conjugate_cc.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Complex Conjugate +################################################### + --> +<block> + <name>Complex Conjugate</name> + <key>gr_conjugate_cc</key> + <import>from gnuradio import gr</import> + <make>gr.conjugate_cc()</make> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_constellation_decoder_cb.xml b/grc/data/grc_gnuradio/blocks/gr_constellation_decoder_cb.xml new file mode 100644 index 000000000..99d897a3a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_constellation_decoder_cb.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Constellation Decoder +################################################### + --> +<block> + <name>Constellation Decoder</name> + <key>gr_constellation_decoder_cb</key> + <import>from gnuradio import gr</import> + <make>gr.constellation_decoder_cb($sym_position, $sym_value_out)</make> + <param> + <name>Symbol Position</name> + <key>sym_position</key> + <type>complex_vector</type> + </param> + <param> + <name>Symbol Value Out</name> + <key>sym_value_out</key> + <type>int_vector</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_correlate_access_code_bb.xml b/grc/data/grc_gnuradio/blocks/gr_correlate_access_code_bb.xml new file mode 100644 index 000000000..e13d2d070 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_correlate_access_code_bb.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Correlate Access Code +################################################### + --> +<block> + <name>Correlate Access Code</name> + <key>gr_correlate_access_code_bb</key> + <import>from gnuradio import gr</import> + <make>gr.correlate_access_code_bb($access_code, $threshold)</make> + <param> + <name>Access Code</name> + <key>access_code</key> + <value>101010</value> + <type>string</type> + </param> + <param> + <name>Threshold</name> + <key>threshold</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_costas_loop_cc.xml b/grc/data/grc_gnuradio/blocks/gr_costas_loop_cc.xml new file mode 100644 index 000000000..e0db8bc5d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_costas_loop_cc.xml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Costas Loop +################################################### + --> +<block> + <name>Costas Loop</name> + <key>gr_costas_loop_cc</key> + <import>from gnuradio import gr</import> + <make>gr.costas_loop_cc($alpha, $beta, $max_freq, $min_freq, $order)</make> + <callback>set_alpha($alpha)</callback> + <callback>set_beta($beta)</callback> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <param> + <name>Order</name> + <key>order</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> + <source> + <name>out</name> + <type>complex</type> + <optional>1</optional> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_dd_mpsk_sync_cc.xml b/grc/data/grc_gnuradio/blocks/gr_dd_mpsk_sync_cc.xml new file mode 100644 index 000000000..aed0e8d31 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_dd_mpsk_sync_cc.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##DD MPSK Sync +################################################### + --> +<block> + <name>DD MPSK Sync</name> + <key>gr_dd_mpsk_sync_cc</key> + <import>from gnuradio import gr</import> + <make>gr.dd_mpsk_sync_cc($alpha, $beta, $max_freq, $min_freq, $ref_phase, $omega, $gain_omega, $mu, $gain_mu)</make> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <param> + <name>Reference Phase</name> + <key>ref_phase</key> + <type>real</type> + </param> + <param> + <name>Omega</name> + <key>omega</key> + <type>real</type> + </param> + <param> + <name>Gain Omega</name> + <key>gain_omega</key> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_decode_ccsds_27_fb.xml b/grc/data/grc_gnuradio/blocks/gr_decode_ccsds_27_fb.xml new file mode 100644 index 000000000..03b31db83 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_decode_ccsds_27_fb.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Decode CCSDS 27 +################################################### + --> +<block> + <name>Decode CCSDS 27</name> + <key>gr_decode_ccsds_27_fb</key> + <import>from gnuradio import gr</import> + <make>gr.decode_ccsds_27_fb()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_deinterleave.xml b/grc/data/grc_gnuradio/blocks/gr_deinterleave.xml new file mode 100644 index 000000000..a7482978c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_deinterleave.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Deinterleave +################################################### + --> +<block> + <name>Deinterleave</name> + <key>gr_deinterleave</key> + <import>from gnuradio import gr</import> + <make>gr.deinterleave($type.size*$vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_delay.xml b/grc/data/grc_gnuradio/blocks/gr_delay.xml new file mode 100644 index 000000000..b9d429798 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_delay.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Delay +################################################### + --> +<block> + <name>Delay</name> + <key>gr_delay</key> + <import>from gnuradio import gr</import> + <make>gr.head($type.size*$vlen, $delay)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Delay</name> + <key>delay</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_diff_decoder_bb.xml b/grc/data/grc_gnuradio/blocks/gr_diff_decoder_bb.xml new file mode 100644 index 000000000..ea7cf1734 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_diff_decoder_bb.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Differential Decoder +################################################### + --> +<block> + <name>Differential Decoder</name> + <key>gr_diff_decoder_bb</key> + <import>from gnuradio import gr</import> + <make>gr.diff_decoder_bb($modulus)</make> + <param> + <name>Modulus</name> + <key>modulus</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_diff_encoder_bb.xml b/grc/data/grc_gnuradio/blocks/gr_diff_encoder_bb.xml new file mode 100644 index 000000000..21241eac2 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_diff_encoder_bb.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Differential Encoder +################################################### + --> +<block> + <name>Differential Encoder</name> + <key>gr_diff_encoder_bb</key> + <import>from gnuradio import gr</import> + <make>gr.diff_encoder_bb($modulus)</make> + <param> + <name>Modulus</name> + <key>modulus</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_diff_phasor_cc.xml b/grc/data/grc_gnuradio/blocks/gr_diff_phasor_cc.xml new file mode 100644 index 000000000..2b2d7e372 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_diff_phasor_cc.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Differential Phasor +################################################### + --> +<block> + <name>Differential Phasor</name> + <key>gr_diff_phasor_cc</key> + <import>from gnuradio import gr</import> + <make>gr.diff_phasor_cc()</make> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_divide_xx.xml b/grc/data/grc_gnuradio/blocks/gr_divide_xx.xml new file mode 100644 index 000000000..7f8752919 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_divide_xx.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Divide Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Divide</name> + <key>gr_divide_xx</key> + <import>from gnuradio import gr</import> + <make>gr.divide_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_dpll_bb.xml b/grc/data/grc_gnuradio/blocks/gr_dpll_bb.xml new file mode 100644 index 000000000..044d398ff --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_dpll_bb.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Detect Peak +################################################### + --> +<block> + <name>Detect Peak</name> + <key>gr_dpll_bb</key> + <import>from gnuradio import gr</import> + <make>gr.dpll_bb($period, $gain)</make> + <param> + <name>Period</name> + <key>period</key> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_encode_ccsds_27_bb.xml b/grc/data/grc_gnuradio/blocks/gr_encode_ccsds_27_bb.xml new file mode 100644 index 000000000..f31e6b6c8 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_encode_ccsds_27_bb.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Encode CCSDS 27 +################################################### + --> +<block> + <name>Encode CCSDS 27</name> + <key>gr_encode_ccsds_27_bb</key> + <import>from gnuradio import gr</import> + <make>gr.encode_ccsds_27_bb()</make> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_feedforward_agc_cc.xml b/grc/data/grc_gnuradio/blocks/gr_feedforward_agc_cc.xml new file mode 100644 index 000000000..24e80953f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_feedforward_agc_cc.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Feed Forward AGC +################################################### + --> +<block> + <name>Feed Forward AGC</name> + <key>gr_feedforward_agc_cc</key> + <import>from gnuradio import gr</import> + <make>gr.feedforward_agc_cc($num_samples, $reference)</make> + <param> + <name>Num Samples</name> + <key>num_samples</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Reference</name> + <key>reference</key> + <value>1.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_fft_filter_xxx.xml b/grc/data/grc_gnuradio/blocks/gr_fft_filter_xxx.xml new file mode 100644 index 000000000..c1633094b --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_fft_filter_xxx.xml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FFT Filter +################################################### + --> +<block> + <name>FFT Filter</name> + <key>gr_fft_filter_xxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.fft_filter_$(type)($decim, $taps)</make> + <callback>set_taps($taps)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Float->Float (Real Taps)</name> + <key>fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>$type.taps</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_fft_vxx.xml b/grc/data/grc_gnuradio/blocks/gr_fft_vxx.xml new file mode 100644 index 000000000..c2c13d0ae --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_fft_vxx.xml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FFT +################################################### + --> +<block> + <name>FFT</name> + <key>gr_fft_vxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio import window</import> + <make>#if $type.eval == "complex" +gr.fft_vcc($fft_size, $forward, $window, $shift) +#else +gr.fft_vfc($fft_size, $forward, $window) +#end if</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>hide_shift:</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>hide_shift:all</opt> + </option> + </param> + <param> + <name>FFT Size</name> + <key>fft_size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Forward/Reverse</name> + <key>forward</key> + <type>enum</type> + <option> + <name>Forward</name> + <key>True</key> + </option> + <option> + <name>Reverse</name> + <key>False</key> + </option> + </param> + <param> + <name>Window</name> + <key>window</key> + <value>window.blackmanharris(1024)</value> + <type>real_vector</type> + </param> + <param> + <name>Shift</name> + <key>shift</key> + <type>enum</type> + <hide>$type.hide_shift</hide> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$fft_size</vlen> + </sink> + <source> + <name>out</name> + <type>complex</type> + <vlen>$fft_size</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_file_sink.xml b/grc/data/grc_gnuradio/blocks/gr_file_sink.xml new file mode 100644 index 000000000..880dc2759 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_file_sink.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- +################################################### +##File Sink +################################################### + --> +<block> + <name>File Sink</name> + <key>gr_file_sink</key> + <import>from gnuradio import gr</import> + <make>gr.file_sink($type.size*$vlen, $file)</make> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_save</type> + </param> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_file_source.xml b/grc/data/grc_gnuradio/blocks/gr_file_source.xml new file mode 100644 index 000000000..fcc7a7040 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_file_source.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +################################################### +##File Source +################################################### + --> +<block> + <name>File Source</name> + <key>gr_file_source</key> + <import>from gnuradio import gr</import> + <make>gr.file_source($type.size*$vlen, $file, $repeat)</make> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_open</type> + </param> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_filter_delay_fc.xml b/grc/data/grc_gnuradio/blocks/gr_filter_delay_fc.xml new file mode 100644 index 000000000..30d65bf82 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_filter_delay_fc.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Filter Delay +################################################### + --> +<block> + <name>Filter Delay</name> + <key>gr_filter_delay_fc</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.filter_delay_fc($taps)</make> + <param> + <name>Taps</name> + <key>taps</key> + <type>real_vector</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <sink> + <name>in</name> + <type>float</type> + <optional>1</optional> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_fir_filter_xxx.xml b/grc/data/grc_gnuradio/blocks/gr_fir_filter_xxx.xml new file mode 100644 index 000000000..c4de8f539 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_fir_filter_xxx.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Decimating FIR Filter +################################################### + --> +<block> + <name>Decimating FIR Filter</name> + <key>gr_fir_filter_xxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.fir_filter_$(type)($decim, $taps)</make> + <callback>set_taps($taps)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Real Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Complex (Complex Taps)</name> + <key>fcc</key> + <opt>input:float</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Float->Float (Real Taps)</name> + <key>fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Short (Real Taps)</name> + <key>fsf</key> + <opt>input:float</opt> + <opt>output:short</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Short->Complex (Complex Taps)</name> + <key>scc</key> + <opt>input:short</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>$type.taps</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_float_to_char.xml b/grc/data/grc_gnuradio/blocks/gr_float_to_char.xml new file mode 100644 index 000000000..5714130ac --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_float_to_char.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Char: +################################################### + --> +<block> + <name>Float To Char</name> + <key>gr_float_to_char</key> + <import>from gnuradio import gr</import> + <make>gr.gr_float_to_char()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_float_to_complex.xml b/grc/data/grc_gnuradio/blocks/gr_float_to_complex.xml new file mode 100644 index 000000000..e8734fc6a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_float_to_complex.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Complex: +## one or two input streams +################################################### + --> +<block> + <name>Float To Complex</name> + <key>gr_float_to_complex</key> + <import>from gnuradio import gr</import> + <make>gr.float_to_complex()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <sink> + <name>in</name> + <type>float</type> + <optional>1</optional> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_float_to_short.xml b/grc/data/grc_gnuradio/blocks/gr_float_to_short.xml new file mode 100644 index 000000000..cb2bcd4be --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_float_to_short.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Short: +################################################### + --> +<block> + <name>Float To Short</name> + <key>gr_float_to_short</key> + <import>from gnuradio import gr</import> + <make>gr.float_to_short()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>short</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_float_to_uchar.xml b/grc/data/grc_gnuradio/blocks/gr_float_to_uchar.xml new file mode 100644 index 000000000..aa804d7d9 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_float_to_uchar.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Float to Unsigned Char: +################################################### + --> +<block> + <name>Float To UChar</name> + <key>gr_float_to_uchar</key> + <import>from gnuradio import gr</import> + <make>gr.float_to_uchar()</make> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_fractional_interpolator_xx.xml b/grc/data/grc_gnuradio/blocks/gr_fractional_interpolator_xx.xml new file mode 100644 index 000000000..8d65ff8bf --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_fractional_interpolator_xx.xml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Fractional Interpolator +################################################### + --> +<block> + <name>Fractional Interpolator</name> + <key>gr_fractional_interpolator_xx</key> + <import>from gnuradio import gr</import> + <make>gr.fractional_interpolator_$(type.fcn)($phase_shift, $interp_ratio)</make> + <callback>set_interp_ratio($interp_ratio)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Phase Shift</name> + <key>phase_shift</key> + <type>real</type> + </param> + <param> + <name>Interpolation Ratio</name> + <key>interp_ratio</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_freq_xlating_fir_filter_xxx.xml b/grc/data/grc_gnuradio/blocks/gr_freq_xlating_fir_filter_xxx.xml new file mode 100644 index 000000000..e3ee66977 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_freq_xlating_fir_filter_xxx.xml @@ -0,0 +1,93 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Frequency Xlating Filter +################################################### + --> +<block> + <name>Frequency Xlating FIR Filter</name> + <key>gr_freq_xlating_fir_filter_xxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.freq_xlating_fir_filter_$(type)($decim, $taps, $center_freq, $samp_rate)</make> + <callback>set_taps($taps)</callback> + <callback>set_center_freq($center_freq)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Real Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Complex (Complex Taps)</name> + <key>fcc</key> + <opt>input:float</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Float->Complex (Real Taps)</name> + <key>fcf</key> + <opt>input:float</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Short->Complex (Complex Taps)</name> + <key>scc</key> + <opt>input:short</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Short->Complex (Real Taps)</name> + <key>scf</key> + <opt>input:short</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>$type.taps</type> + </param> + <param> + <name>Center Frequency</name> + <key>center_freq</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_frequency_modulator_fc.xml b/grc/data/grc_gnuradio/blocks/gr_frequency_modulator_fc.xml new file mode 100644 index 000000000..f18d9f1e1 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_frequency_modulator_fc.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Frequency Modulator +################################################### + --> +<block> + <name>Frequency Mod</name> + <key>gr_frequency_modulator_fc</key> + <import>from gnuradio import gr</import> + <make>gr.frequency_modulator_fc($sensitivity)</make> + <param> + <name>Sensitivity</name> + <key>sensitivity</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_glfsr_source_x.xml b/grc/data/grc_gnuradio/blocks/gr_glfsr_source_x.xml new file mode 100644 index 000000000..88fb66797 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_glfsr_source_x.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##GLFSR Source +################################################### + --> +<block> + <name>GLFSR Source</name> + <key>gr_glfsr_source_x</key> + <import>from gnuradio import gr</import> + <make>gr.glfsr_source_$(type.fcn)($degree, $repeat, $mask, $seed)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <param> + <name>Degree</name> + <key>degree</key> + <type>int</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Mask</name> + <key>mask</key> + <type>int</type> + </param> + <param> + <name>Seed</name> + <key>seed</key> + <type>int</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_goertzel_fc.xml b/grc/data/grc_gnuradio/blocks/gr_goertzel_fc.xml new file mode 100644 index 000000000..2105445d1 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_goertzel_fc.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Goertzel +################################################### + --> +<block> + <name>Goertzel</name> + <key>gr_goertzel_fc</key> + <import>from gnuradio import gr</import> + <make>gr.goertzel_fc($rate, $len, $freq)</make> + <param> + <name>Rate</name> + <key>rate</key> + <type>int</type> + </param> + <param> + <name>Length</name> + <key>len</key> + <type>int</type> + </param> + <param> + <name>Frequency</name> + <key>freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_head.xml b/grc/data/grc_gnuradio/blocks/gr_head.xml new file mode 100644 index 000000000..e5ff7f6aa --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_head.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Head +################################################### + --> +<block> + <name>Head</name> + <key>gr_head</key> + <import>from gnuradio import gr</import> + <make>gr.head($type.size*$vlen, $num_items)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_hilbert_fc.xml b/grc/data/grc_gnuradio/blocks/gr_hilbert_fc.xml new file mode 100644 index 000000000..165e8da23 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_hilbert_fc.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Hilbert +################################################### + --> +<block> + <name>Hilbert</name> + <key>gr_hilbert_fc</key> + <import>from gnuradio import gr</import> + <make>gr.hilbert_fc($num_taps)</make> + <param> + <name>Num Taps</name> + <key>num_taps</key> + <value>64</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_iir_filter_ffd.xml b/grc/data/grc_gnuradio/blocks/gr_iir_filter_ffd.xml new file mode 100644 index 000000000..9799150e8 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_iir_filter_ffd.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##IIR Filter +################################################### + --> +<block> + <name>IIR Filter</name> + <key>gr_iir_filter_ffd</key> + <import>from gnuradio import gr</import> + <make>gr.iir_filter_ffd($fftaps, $fbtaps)</make> + <callback>set_taps($fftaps, $fbtaps)</callback> + <param> + <name>Feed-forward Taps</name> + <key>fftaps</key> + <type>real_vector</type> + </param> + <param> + <name>Feedback Taps</name> + <key>fbtaps</key> + <type>real_vector</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_integrate_xx.xml b/grc/data/grc_gnuradio/blocks/gr_integrate_xx.xml new file mode 100644 index 000000000..d0ebd42e2 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_integrate_xx.xml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Integrate +################################################### + --> +<block> + <name>Integrate</name> + <key>gr_integrate_xx</key> + <import>from gnuradio import gr</import> + <make>gr.integrate_$(type.fcn)($decim)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_interleave.xml b/grc/data/grc_gnuradio/blocks/gr_interleave.xml new file mode 100644 index 000000000..3db16ab55 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_interleave.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Interleave +################################################### + --> +<block> + <name>Interleave</name> + <key>gr_interleave</key> + <import>from gnuradio import gr</import> + <make>gr.interleave($type.size*$vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_interleaved_short_to_complex.xml b/grc/data/grc_gnuradio/blocks/gr_interleaved_short_to_complex.xml new file mode 100644 index 000000000..e3023e499 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_interleaved_short_to_complex.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Interleaved Short to Complex: +################################################### + --> +<block> + <name>IShort To Complex</name> + <key>gr_interleaved_short_to_complex</key> + <import>from gnuradio import gr</import> + <make>gr.interleaved_short_to_complex()</make> + <sink> + <name>in</name> + <type>short</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_interp_fir_filter_xxx.xml b/grc/data/grc_gnuradio/blocks/gr_interp_fir_filter_xxx.xml new file mode 100644 index 000000000..55375ae02 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_interp_fir_filter_xxx.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Interpolating FIR Filter +################################################### + --> +<block> + <name>Interpolating FIR Filter</name> + <key>gr_interp_fir_filter_xxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.interp_fir_filter_$(type)($interp, $taps)</make> + <callback>set_taps($taps)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Real Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Complex (Complex Taps)</name> + <key>fcc</key> + <opt>input:float</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Float->Float (Real Taps)</name> + <key>fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Short (Real Taps)</name> + <key>fsf</key> + <opt>input:float</opt> + <opt>output:short</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Short->Complex (Complex Taps)</name> + <key>scc</key> + <opt>input:short</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + </param> + <param> + <name>Interpolation</name> + <key>interp</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>$type.taps</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_iqcomp_cc.xml b/grc/data/grc_gnuradio/blocks/gr_iqcomp_cc.xml new file mode 100644 index 000000000..1603bdc42 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_iqcomp_cc.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##IQ Comp +################################################### + --> +<block> + <name>IQ Comp</name> + <key>gr_iqcomp_cc</key> + <import>from gnuradio import gr</import> + <make>gr.iqcomp_cc($mu)</make> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_keep_one_in_n.xml b/grc/data/grc_gnuradio/blocks/gr_keep_one_in_n.xml new file mode 100644 index 000000000..21595b755 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_keep_one_in_n.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Keep 1 in N +################################################### + --> +<block> + <name>Keep 1 in N</name> + <key>gr_keep_one_in_n</key> + <import>from gnuradio import gr</import> + <make>gr.keep_one_in_n($type.size*$vlen, $n)</make> + <callback>set_n($n)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>N</name> + <key>n</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$n > 0</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_kludge_copy.xml b/grc/data/grc_gnuradio/blocks/gr_kludge_copy.xml new file mode 100644 index 000000000..3c817c572 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_kludge_copy.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Kludge Copy +################################################### + --> +<block> + <name>Copy</name> + <key>gr_kludge_copy</key> + <import>from gnuradio import gr</import> + <make>gr.kludge_copy($type.size*$vlen)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_map_bb.xml b/grc/data/grc_gnuradio/blocks/gr_map_bb.xml new file mode 100644 index 000000000..20d6bd2b4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_map_bb.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Map +################################################### + --> +<block> + <name>Map</name> + <key>gr_map_bb</key> + <import>from gnuradio import gr</import> + <make>gr.map_bb($map)</make> + <param> + <name>Map</name> + <key>map</key> + <type>int_vector</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_max_xx.xml b/grc/data/grc_gnuradio/blocks/gr_max_xx.xml new file mode 100644 index 000000000..9dbbe60e5 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_max_xx.xml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Max: +## 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Max</name> + <key>gr_max_xx</key> + <import>from gnuradio import gr</import> + <make>gr.max_$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:dd</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_moving_average_xx.xml b/grc/data/grc_gnuradio/blocks/gr_moving_average_xx.xml new file mode 100644 index 000000000..2c3be4033 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_moving_average_xx.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Moving Average +################################################### + --> +<block> + <name>Moving Average</name> + <key>gr_moving_average_xx</key> + <import>from gnuradio import gr</import> + <make>gr.moving_average_$(type.fcn)($length, $scale, $max_iter)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + <opt>scale:complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + <opt>scale:real</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + <opt>scale:int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + <opt>scale:int</opt> + </option> + </param> + <param> + <name>Length</name> + <key>length</key> + <value>1000</value> + <type>int</type> + </param> + <param> + <name>Scale</name> + <key>scale</key> + <value>1</value> + <type>$type.scale</type> + </param> + <param> + <name>Max Iter</name> + <key>max_iter</key> + <value>4000</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_mpsk_receiver_cc.xml b/grc/data/grc_gnuradio/blocks/gr_mpsk_receiver_cc.xml new file mode 100644 index 000000000..843c3a4c1 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_mpsk_receiver_cc.xml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<!-- +################################################### +##MPSK Receiver +################################################### + --> +<block> + <name>MPSK Receiver</name> + <key>gr_mpsk_receiver_cc</key> + <import>from gnuradio import gr</import> + <make>gr.mpsk_receiver_cc($M, $theta, $alpha, $beta, $fmin, $fmax, $mu, $gain_mu, $omega, $gain_omega, $omega_relative_limit)</make> + <callback>set_alpha($alpha)</callback> + <callback>set_beta($beta)</callback> + <callback>set_mu($mu)</callback> + <callback>set_gain_mu($gain_mu)</callback> + <callback>set_omega($omega)</callback> + <callback>set_gain_omega($gain_omega)</callback> + <param> + <name>M</name> + <key>M</key> + <type>int</type> + </param> + <param> + <name>Theta</name> + <key>theta</key> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>fmin</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>fmax</key> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <type>real</type> + </param> + <param> + <name>Omega</name> + <key>omega</key> + <type>real</type> + </param> + <param> + <name>Gain Omega</name> + <key>gain_omega</key> + <type>real</type> + </param> + <param> + <name>Omega Relative Limit</name> + <key>omega_relative_limit</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_mpsk_sync_cc.xml b/grc/data/grc_gnuradio/blocks/gr_mpsk_sync_cc.xml new file mode 100644 index 000000000..fd08f8340 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_mpsk_sync_cc.xml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- +################################################### +##MPSK Sync +################################################### + --> +<block> + <name>MPSK Sync</name> + <key>gr_mpsk_sync_cc</key> + <import>from gnuradio import gr</import> + <make>gr.mpsk_sync_cc($alpha, $beta, $max_freq, $min_freq, $ref_phase, $omega, $gain_omega, $mu, $gain_mu)</make> + <callback>set_mu($mu)</callback> + <callback>set_gain_mu($gain_mu)</callback> + <callback>set_omega($omega)</callback> + <callback>set_gain_omega($gain_omega)</callback> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <param> + <name>Reference Phase</name> + <key>ref_phase</key> + <type>real</type> + </param> + <param> + <name>Omega</name> + <key>omega</key> + <type>real</type> + </param> + <param> + <name>Gain Omega</name> + <key>gain_omega</key> + <type>real</type> + </param> + <param> + <name>Mu</name> + <key>mu</key> + <type>real</type> + </param> + <param> + <name>Gain Mu</name> + <key>gain_mu</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_multiply_const_vxx.xml b/grc/data/grc_gnuradio/blocks/gr_multiply_const_vxx.xml new file mode 100644 index 000000000..1309d75cd --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_multiply_const_vxx.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Multiply Const Block: +## all types, 1 output, 1 input & const +################################################### + --> +<block> + <name>Multiply Const</name> + <key>gr_multiply_const_vxx</key> + <import>from gnuradio import gr</import> + <make>gr.multiply_const_v$(type.fcn)($const)</make> + <callback>set_k($const)</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>const_type:complex_vector</opt> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>const_type:real_vector</opt> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>const_type:int_vector</opt> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>$type.const_type</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>len($const) == $vlen</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_multiply_vxx.xml b/grc/data/grc_gnuradio/blocks/gr_multiply_vxx.xml new file mode 100644 index 000000000..ea0d555b6 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_multiply_vxx.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Multiply Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Multiply</name> + <key>gr_multiply_vxx</key> + <import>from gnuradio import gr</import> + <make>gr.multiply_v$(type.fcn)($vlen)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_inputs > 1</check> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_mute_xx.xml b/grc/data/grc_gnuradio/blocks/gr_mute_xx.xml new file mode 100644 index 000000000..668d7c599 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_mute_xx.xml @@ -0,0 +1,53 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Mute Block: +## Cast input to bool. +################################################### + --> +<block> + <name>Mute</name> + <key>gr_mute_xx</key> + <import>from gnuradio import gr</import> + <make>gr.mute_$(type.fcn)(bool($mute))</make> + <callback>set_mute(bool($mute))</callback> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Mute</name> + <key>mute</key> + <value>False</value> + <type>raw</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_nlog10_ff.xml b/grc/data/grc_gnuradio/blocks/gr_nlog10_ff.xml new file mode 100644 index 000000000..935078236 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_nlog10_ff.xml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Log10 Block: +## float in/ float out +################################################### + --> +<block> + <name>Log10</name> + <key>gr_nlog10_ff</key> + <import>from gnuradio import gr</import> + <make>gr.nlog10_ff($n, $vlen, $k)</make> + <param> + <name>n</name> + <key>n</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>k</name> + <key>k</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>float</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_noise_source_x.xml b/grc/data/grc_gnuradio/blocks/gr_noise_source_x.xml new file mode 100644 index 000000000..664a108d3 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_noise_source_x.xml @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Noise Source +################################################### + --> +<block> + <name>Noise Source</name> + <key>gr_noise_source_x</key> + <import>from gnuradio import gr</import> + <make>gr.noise_source_$(type.fcn)($noise_type, $amp, $seed)</make> + <callback>set_amplitude($amp)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Noise Type</name> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + <type>enum</type> + <option> + <name>Uniform</name> + <key>gr.GR_UNIFORM</key> + </option> + <option> + <name>Gaussian</name> + <key>gr.GR_GAUSSIAN</key> + </option> + <option> + <name>Laplacian</name> + <key>gr.GR_LAPLACIAN</key> + </option> + <option> + <name>Impulse</name> + <key>gr.GR_IMPULSE</key> + </option> + </param> + <param> + <name>Amplitude</name> + <key>amp</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Seed</name> + <key>seed</key> + <value>42</value> + <type>int</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_nop.xml b/grc/data/grc_gnuradio/blocks/gr_nop.xml new file mode 100644 index 000000000..127a78a55 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_nop.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Nop +################################################### + --> +<block> + <name>Nop</name> + <key>gr_nop</key> + <import>from gnuradio import gr</import> + <make>gr.nop($type.size*$vlen)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_not_xx.xml b/grc/data/grc_gnuradio/blocks/gr_not_xx.xml new file mode 100644 index 000000000..7af7e4b6b --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_not_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Not Block +################################################### + --> +<block> + <name>Not</name> + <key>gr_not_xx</key> + <import>from gnuradio import gr</import> + <make>gr.not_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_null_sink.xml b/grc/data/grc_gnuradio/blocks/gr_null_sink.xml new file mode 100644 index 000000000..ed106b495 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_null_sink.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Null Sink +################################################### + --> +<block> + <name>Null Sink</name> + <key>gr_null_sink</key> + <import>from gnuradio import gr</import> + <make>gr.null_sink($type.size*$vlen)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_null_source.xml b/grc/data/grc_gnuradio/blocks/gr_null_source.xml new file mode 100644 index 000000000..6132eae3c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_null_source.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Null Source +################################################### + --> +<block> + <name>Null Source</name> + <key>gr_null_source</key> + <import>from gnuradio import gr</import> + <make>gr.null_source($type.size*$vlen)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_or_xx.xml b/grc/data/grc_gnuradio/blocks/gr_or_xx.xml new file mode 100644 index 000000000..b374aa22a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_or_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Or Block +################################################### + --> +<block> + <name>Or</name> + <key>gr_or_xx</key> + <import>from gnuradio import gr</import> + <make>gr.or_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_packed_to_unpacked_xx.xml b/grc/data/grc_gnuradio/blocks/gr_packed_to_unpacked_xx.xml new file mode 100644 index 000000000..5fd9729a4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_packed_to_unpacked_xx.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Packed to Unpacked +################################################### + --> +<block> + <name>Packed to Unpacked</name> + <key>gr_packed_to_unpacked_xx</key> + <import>from gnuradio import gr</import> + <make>gr.packed_to_unpacked_$(type.fcn)($bits_per_chunk, $endianness)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Bits per Chunk</name> + <key>bits_per_chunk</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Endianness</name> + <key>endianness</key> + <type>enum</type> + <option> + <name>MSB</name> + <key>gr.GR_MSB_FIRST</key> + </option> + <option> + <name>LSB</name> + <key>gr.GR_LSB_FIRST</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_peak_detector2_fb.xml b/grc/data/grc_gnuradio/blocks/gr_peak_detector2_fb.xml new file mode 100644 index 000000000..6c496da77 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_peak_detector2_fb.xml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Peak Detector2 +################################################### + --> +<block> + <name>Peak Detector2</name> + <key>gr_peak_detector2_fb</key> + <import>from gnuradio import gr</import> + <make>gr.peak_detector2_fb($threshold_factor_rise, $look_ahead, $alpha)</make> + <callback>set_threshold_factor_rise($threshold_factor_rise)</callback> + <callback>set_look_ahead($look_ahead)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>TH Factor Rise</name> + <key>threshold_factor_rise</key> + <type>real</type> + </param> + <param> + <name>Look Ahead</name> + <key>look_ahead</key> + <type>int</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_peak_detector_xb.xml b/grc/data/grc_gnuradio/blocks/gr_peak_detector_xb.xml new file mode 100644 index 000000000..394b0697f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_peak_detector_xb.xml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Peak Detector +################################################### + --> +<block> + <name>Peak Detector</name> + <key>gr_peak_detector_xb</key> + <import>from gnuradio import gr</import> + <make>gr.peak_detector_$(type.fcn)b($threshold_factor_rise, $threshold_factor_fall, $look_ahead, $alpha)</make> + <callback>set_threshold_factor_rise($threshold_factor_rise)</callback> + <callback>set_threshold_factor_fall($threshold_factor_fall)</callback> + <callback>set_look_ahead($look_ahead)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>TH Factor Rise</name> + <key>threshold_factor_rise</key> + <type>real</type> + </param> + <param> + <name>TH Factor Fall</name> + <key>threshold_factor_fall</key> + <type>real</type> + </param> + <param> + <name>Look Ahead</name> + <key>look_ahead</key> + <type>int</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_phase_modulator_fc.xml b/grc/data/grc_gnuradio/blocks/gr_phase_modulator_fc.xml new file mode 100644 index 000000000..758c50863 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_phase_modulator_fc.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Phase Modulator +################################################### + --> +<block> + <name>Phase Mod</name> + <key>gr_phase_modulator_fc</key> + <import>from gnuradio import gr</import> + <make>gr.phase_modulator_fc($sensitivity)</make> + <param> + <name>Sensitivity</name> + <key>sensitivity</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_pll_carriertracking_cc.xml b/grc/data/grc_gnuradio/blocks/gr_pll_carriertracking_cc.xml new file mode 100644 index 000000000..5b876b259 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_pll_carriertracking_cc.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Carrier Tracking +################################################### + --> +<block> + <name>PLL Carrier Tracking</name> + <key>gr_pll_carriertracking_cc</key> + <import>from gnuradio import gr</import> + <make>gr.pll_carriertracking_cc($alpha, $beta, $max_freq, $min_freq)</make> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_pll_freqdet_cf.xml b/grc/data/grc_gnuradio/blocks/gr_pll_freqdet_cf.xml new file mode 100644 index 000000000..8ec1fb3bb --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_pll_freqdet_cf.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Frequency Det +################################################### + --> +<block> + <name>PLL Freq Det</name> + <key>gr_pll_freqdet_cf</key> + <import>from gnuradio import gr</import> + <make>gr.pll_freqdet_cf($alpha, $beta, $max_freq, $min_freq)</make> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_pll_refout_cc.xml b/grc/data/grc_gnuradio/blocks/gr_pll_refout_cc.xml new file mode 100644 index 000000000..64cf2bfb6 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_pll_refout_cc.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PLL Reference Out +################################################### + --> +<block> + <name>PLL Ref Out</name> + <key>gr_pll_refout_cc</key> + <import>from gnuradio import gr</import> + <make>gr.pll_refout_cc($alpha, $beta, $max_freq, $min_freq)</make> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <type>real</type> + </param> + <param> + <name>Max Freq</name> + <key>max_freq</key> + <type>real</type> + </param> + <param> + <name>Min Freq</name> + <key>min_freq</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_pn_correlator_cc.xml b/grc/data/grc_gnuradio/blocks/gr_pn_correlator_cc.xml new file mode 100644 index 000000000..094f46cdf --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_pn_correlator_cc.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##PN Correlator +################################################### + --> +<block> + <name>PN Correlator</name> + <key>gr_pn_correlator_cc</key> + <import>from gnuradio import gr</import> + <make>gr.pn_correlator_cc($degree, $mask, $seed)</make> + <param> + <name>Degree</name> + <key>degree</key> + <type>int</type> + </param> + <param> + <name>Mask</name> + <key>mask</key> + <type>int</type> + </param> + <param> + <name>Seed</name> + <key>seed</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_pwr_squelch_xx.xml b/grc/data/grc_gnuradio/blocks/gr_pwr_squelch_xx.xml new file mode 100644 index 000000000..08d621177 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_pwr_squelch_xx.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Power Squelch +################################################### + --> +<block> + <name>Power Squelch</name> + <key>gr_pwr_squelch_xx</key> + <import>from gnuradio import gr</import> + <make>gr.pwr_squelch_$(type.fcn)($threshold, $alpha, $ramp, $gate)</make> + <callback>set_threshold($threshold)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Threshold (dB)</name> + <key>threshold</key> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <param> + <name>Ramp</name> + <key>ramp</key> + <type>int</type> + </param> + <param> + <name>Gate</name> + <key>gate</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_quadrature_demod_cf.xml b/grc/data/grc_gnuradio/blocks/gr_quadrature_demod_cf.xml new file mode 100644 index 000000000..a0e630c7e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_quadrature_demod_cf.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Quadrature Demodulator +################################################### + --> +<block> + <name>Quadrature Demod</name> + <key>gr_quadrature_demod_cf</key> + <import>from gnuradio import gr</import> + <make>gr.quadrature_demod_cf($gain)</make> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_rational_resampler_base_xxx.xml b/grc/data/grc_gnuradio/blocks/gr_rational_resampler_base_xxx.xml new file mode 100644 index 000000000..4b7720173 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_rational_resampler_base_xxx.xml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Rational Resampler Base +################################################### + --> +<block> + <name>Rational Resampler Base</name> + <key>gr_rational_resampler_base_xxx</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.rational_resampler_base_$(type)($interp, $decim, $taps)</make> + <callback>set_taps($taps)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Real Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Complex (Complex Taps)</name> + <key>fcc</key> + <opt>input:float</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Float->Float (Real Taps)</name> + <key>fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Float->Short (Real Taps)</name> + <key>fsf</key> + <opt>input:float</opt> + <opt>output:short</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Short->Complex (Complex Taps)</name> + <key>scc</key> + <opt>input:short</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + </param> + <param> + <name>Interpolation</name> + <key>interp</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <type>$type.taps</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_repeat.xml b/grc/data/grc_gnuradio/blocks/gr_repeat.xml new file mode 100644 index 000000000..ba652a4d7 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_repeat.xml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Repeat +################################################### + --> +<block> + <name>Repeat</name> + <key>gr_repeat</key> + <import>from gnuradio import gr</import> + <make>gr.repeat($type.size*$vlen, $interp)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Interpolation</name> + <key>interp</key> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_rms_xx.xml b/grc/data/grc_gnuradio/blocks/gr_rms_xx.xml new file mode 100644 index 000000000..1e0947192 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_rms_xx.xml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- +################################################### +##RMS +################################################### + --> +<block> + <name>RMS</name> + <key>gr_rms_xx</key> + <import>from gnuradio import gr</import> + <make>gr.rms_$(type.fcn)f($alpha)</make> + <callback>set_alpha($alpha)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_sample_and_hold_xx.xml b/grc/data/grc_gnuradio/blocks/gr_sample_and_hold_xx.xml new file mode 100644 index 000000000..bfe66bb00 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_sample_and_hold_xx.xml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Sample and Hold +################################################### + --> +<block> + <name>Sample and Hold</name> + <key>gr_sample_and_hold_xx</key> + <import>from gnuradio import gr</import> + <make>gr.sample_and_hold_$(type.fcn)()</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <sink> + <name>ctrl</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_short_to_float.xml b/grc/data/grc_gnuradio/blocks/gr_short_to_float.xml new file mode 100644 index 000000000..8dac97c09 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_short_to_float.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Short to Float: +################################################### + --> +<block> + <name>Short To Float</name> + <key>gr_short_to_float</key> + <import>from gnuradio import gr</import> + <make>gr.short_to_float()</make> + <sink> + <name>in</name> + <type>short</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_sig_source_x.xml b/grc/data/grc_gnuradio/blocks/gr_sig_source_x.xml new file mode 100644 index 000000000..7ad0c20a4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_sig_source_x.xml @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Signal Source +################################################### + --> +<block> + <name>Signal Source</name> + <key>gr_sig_source_x</key> + <import>from gnuradio import gr</import> + <make>gr.sig_source_$(type.fcn)($samp_rate, $waveform, $freq, $amp, $offset)</make> + <callback>set_sampling_freq($samp_rate)</callback> + <callback>set_frequency($freq)</callback> + <callback>set_amplitude($amp)</callback> + <callback>set_offset($offset)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Waveform</name> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + <type>enum</type> + <option> + <name>Constant</name> + <key>gr.GR_CONST_WAVE</key> + </option> + <option> + <name>Sine</name> + <key>gr.GR_SIN_WAVE</key> + </option> + <option> + <name>Cosine</name> + <key>gr.GR_COS_WAVE</key> + </option> + <option> + <name>Square</name> + <key>gr.GR_SQR_WAVE</key> + </option> + <option> + <name>Triangle</name> + <key>gr.GR_TRI_WAVE</key> + </option> + <option> + <name>Saw Tooth</name> + <key>gr.GR_SAW_WAVE</key> + </option> + </param> + <param> + <name>Frequency</name> + <key>freq</key> + <value>1000</value> + <type>real</type> + </param> + <param> + <name>Amplitude</name> + <key>amp</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Offset</name> + <key>offset</key> + <value>0</value> + <type>complex</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_simple_correlator.xml b/grc/data/grc_gnuradio/blocks/gr_simple_correlator.xml new file mode 100644 index 000000000..820523a64 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_simple_correlator.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple Correlator +################################################### + --> +<block> + <name>Simple Correlator</name> + <key>gr_simple_correlator</key> + <import>from gnuradio import gr</import> + <make>gr.simple_correlator($payload_bytesize)</make> + <param> + <name>Payload Byte Size</name> + <key>payload_bytesize</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_simple_framer.xml b/grc/data/grc_gnuradio/blocks/gr_simple_framer.xml new file mode 100644 index 000000000..2a0295c41 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_simple_framer.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple Framer +################################################### + --> +<block> + <name>Simple Framer</name> + <key>gr_simple_framer</key> + <import>from gnuradio import gr</import> + <make>gr.simple_framer($payload_bytesize)</make> + <param> + <name>Payload Byte Size</name> + <key>payload_bytesize</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_simple_squelch_cc.xml b/grc/data/grc_gnuradio/blocks/gr_simple_squelch_cc.xml new file mode 100644 index 000000000..5c0727f5f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_simple_squelch_cc.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple Squelch +################################################### + --> +<block> + <name>Simple Squelch</name> + <key>gr_simple_squelch_cc</key> + <import>from gnuradio import gr</import> + <make>gr.simple_squelch_cc($threshold, $alpha)</make> + <callback>set_threshold($threshold)</callback> + <callback>set_alpha($alpha)</callback> + <param> + <name>Threshold (dB)</name> + <key>threshold</key> + <type>real</type> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_single_pole_iir_filter_xx.xml b/grc/data/grc_gnuradio/blocks/gr_single_pole_iir_filter_xx.xml new file mode 100644 index 000000000..50cf4a82d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_single_pole_iir_filter_xx.xml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Single Pole IIR Filter +################################################### + --> +<block> + <name>Single Pole IIR Filter</name> + <key>gr_single_pole_iir_filter_xx</key> + <import>from gnuradio import gr</import> + <make>gr.single_pole_iir_filter_$(type.fcn)($alpha, $vlen)</make> + <callback>set_taps($alpha)</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + </param> + <param> + <name>Alpha</name> + <key>alpha</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_skiphead.xml b/grc/data/grc_gnuradio/blocks/gr_skiphead.xml new file mode 100644 index 000000000..0849ad298 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_skiphead.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Skip Head +################################################### + --> +<block> + <name>Skip Head</name> + <key>gr_skiphead</key> + <import>from gnuradio import gr</import> + <make>gr.skiphead($type.size*$vlen, $num_items)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_stream_to_streams.xml b/grc/data/grc_gnuradio/blocks/gr_stream_to_streams.xml new file mode 100644 index 000000000..82542b8d4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_stream_to_streams.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream to Streams +################################################### + --> +<block> + <name>Stream to Streams</name> + <key>gr_stream_to_streams</key> + <import>from gnuradio import gr</import> + <make>gr.stream_to_streams($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_stream_to_vector.xml b/grc/data/grc_gnuradio/blocks/gr_stream_to_vector.xml new file mode 100644 index 000000000..296d786f8 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_stream_to_vector.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Stream to Vector +################################################### + --> +<block> + <name>Stream to Vector</name> + <key>gr_stream_to_vector</key> + <import>from gnuradio import gr</import> + <make>gr.stream_to_vector($type.size*$vlen, $num_items)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_items > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen*$num_items</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_streams_to_stream.xml b/grc/data/grc_gnuradio/blocks/gr_streams_to_stream.xml new file mode 100644 index 000000000..7aadd7eef --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_streams_to_stream.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Streams to Stream +################################################### + --> +<block> + <name>Streams to Stream</name> + <key>gr_streams_to_stream</key> + <import>from gnuradio import gr</import> + <make>gr.streams_to_stream($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_streams_to_vector.xml b/grc/data/grc_gnuradio/blocks/gr_streams_to_vector.xml new file mode 100644 index 000000000..4ecdcb2d4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_streams_to_vector.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Streams to Vector +################################################### + --> +<block> + <name>Streams to Vector</name> + <key>gr_streams_to_vector</key> + <import>from gnuradio import gr</import> + <make>gr.streams_to_vector($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen*$num_streams</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_sub_xx.xml b/grc/data/grc_gnuradio/blocks/gr_sub_xx.xml new file mode 100644 index 000000000..488e6c364 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_sub_xx.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Subtract Block: +## all types, 1 output, 2 to inf inputs +################################################### + --> +<block> + <name>Subtract</name> + <key>gr_sub_xx</key> + <import>from gnuradio import gr</import> + <make>gr.sub_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:cc</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:ff</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_threshold_ff.xml b/grc/data/grc_gnuradio/blocks/gr_threshold_ff.xml new file mode 100644 index 000000000..97764d733 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_threshold_ff.xml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Threshold +################################################### + --> +<block> + <name>Threshold</name> + <key>gr_threshold_ff</key> + <import>from gnuradio import gr</import> + <make>gr.threshold_ff($low, $high, $init)</make> + <param> + <name>Low</name> + <key>low</key> + <value>-100</value> + <type>real</type> + </param> + <param> + <name>High</name> + <key>high</key> + <value>100</value> + <type>real</type> + </param> + <param> + <name>Initial State</name> + <key>init</key> + <value>0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_throttle.xml b/grc/data/grc_gnuradio/blocks/gr_throttle.xml new file mode 100644 index 000000000..ab8506f55 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_throttle.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Throttle +################################################### + --> +<block> + <name>Throttle</name> + <key>gr_throttle</key> + <import>from gnuradio import gr</import> + <make>gr.throttle($type.size*$vlen, $samples_per_second)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>samples_per_second</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_uchar_to_float.xml b/grc/data/grc_gnuradio/blocks/gr_uchar_to_float.xml new file mode 100644 index 000000000..0a5f7f96a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_uchar_to_float.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Unsigned Char to Float: +################################################### + --> +<block> + <name>UChar To Float</name> + <key>gr_uchar_to_float</key> + <import>from gnuradio import gr</import> + <make>gr.uchar_to_float()</make> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_udp_sink.xml b/grc/data/grc_gnuradio/blocks/gr_udp_sink.xml new file mode 100644 index 000000000..e9f6c2be8 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_udp_sink.xml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<!-- +################################################### +##UDP Sink +################################################### + --> +<block> + <name>UDP Sink</name> + <key>gr_udp_sink</key> + <import>from gnuradio import gr</import> + <make>gr.udp_sink($type.size*$vlen, $ipaddr_local, $port_local, $ipaddr_remote, $port_remote, $mtu)</make> + <callback>set_mtu($mtu)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Local IP Address</name> + <key>ipaddr_local</key> + <value>127.0.0.1</value> + <type>string</type> + </param> + <param> + <name>Local Port</name> + <key>port_local</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Remote IP Address</name> + <key>ipaddr_remote</key> + <value>127.0.0.1</value> + <type>string</type> + </param> + <param> + <name>Remote Port</name> + <key>port_remote</key> + <value>1234</value> + <type>int</type> + </param> + <param> + <name>MTU</name> + <key>mtu</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_udp_source.xml b/grc/data/grc_gnuradio/blocks/gr_udp_source.xml new file mode 100644 index 000000000..f03adf802 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_udp_source.xml @@ -0,0 +1,73 @@ +<?xml version="1.0"?> +<!-- +################################################### +##UDP Source +################################################### + --> +<block> + <name>UDP Source</name> + <key>gr_udp_source</key> + <import>from gnuradio import gr</import> + <make>gr.udp_source($type.size*$vlen, $ipaddr, $port, $mtu)</make> + <callback>set_mtu($mtu)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>IP Address</name> + <key>ipaddr</key> + <value>127.0.0.1</value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>1234</value> + <type>int</type> + </param> + <param> + <name>MTU</name> + <key>mtu</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_unpack_k_bits_bb.xml b/grc/data/grc_gnuradio/blocks/gr_unpack_k_bits_bb.xml new file mode 100644 index 000000000..9917644ab --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_unpack_k_bits_bb.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Unpack K Bits +################################################### + --> +<block> + <name>Unpack K Bits</name> + <key>gr_unpack_k_bits_bb</key> + <import>from gnuradio import gr</import> + <make>gr.unpack_k_bits_bb($k)</make> + <param> + <name>K</name> + <key>k</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_unpacked_to_packed_xx.xml b/grc/data/grc_gnuradio/blocks/gr_unpacked_to_packed_xx.xml new file mode 100644 index 000000000..f7457eb5c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_unpacked_to_packed_xx.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Unpacked to Packed +################################################### + --> +<block> + <name>Unpacked to Packed</name> + <key>gr_unpacked_to_packed_xx</key> + <import>from gnuradio import gr</import> + <make>gr.unpacked_to_packed_$(type.fcn)($bits_per_chunk, $endianness)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Bits per Chunk</name> + <key>bits_per_chunk</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Endianness</name> + <key>endianness</key> + <type>enum</type> + <option> + <name>MSB</name> + <key>gr.GR_MSB_FIRST</key> + </option> + <option> + <name>LSB</name> + <key>gr.GR_LSB_FIRST</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_vco_f.xml b/grc/data/grc_gnuradio/blocks/gr_vco_f.xml new file mode 100644 index 000000000..e49c53965 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_vco_f.xml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- +################################################### +##VCO +################################################### + --> +<block> + <name>VCO</name> + <key>gr_vco_f</key> + <import>from gnuradio import gr</import> + <make>gr.vco_f($samp_rate, $sensitivity, $amplitude)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <type>real</type> + </param> + <param> + <name>Sensitivity</name> + <key>sensitivity</key> + <type>real</type> + </param> + <param> + <name>Amplitude</name> + <key>amplitude</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_vector_sink_x.xml b/grc/data/grc_gnuradio/blocks/gr_vector_sink_x.xml new file mode 100644 index 000000000..d901b1d78 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_vector_sink_x.xml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector sink +################################################### + --> +<block> + <name>Vector Sink</name> + <key>gr_vector_sink_x</key> + <import>from gnuradio import gr</import> + <make>gr.vector_sink_$(type.fcn)()</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_vector_source_x.xml b/grc/data/grc_gnuradio/blocks/gr_vector_source_x.xml new file mode 100644 index 000000000..240273e42 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_vector_source_x.xml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector Source +################################################### + --> +<block> + <name>Vector Source</name> + <key>gr_vector_source_x</key> + <import>from gnuradio import gr</import> + <make>gr.vector_source_$(type.fcn)($vector, $repeat)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>vec_type:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>vec_type:real_vector</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + <opt>vec_type:int_vector</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + <opt>vec_type:int_vector</opt> + </option> + </param> + <param> + <name>Vector</name> + <key>vector</key> + <value>0, 0, 0</value> + <type>$type.vec_type</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_vector_to_stream.xml b/grc/data/grc_gnuradio/blocks/gr_vector_to_stream.xml new file mode 100644 index 000000000..d56d34067 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_vector_to_stream.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector to Stream +################################################### + --> +<block> + <name>Vector to Stream</name> + <key>gr_vector_to_stream</key> + <import>from gnuradio import gr</import> + <make>gr.vector_to_stream($type.size*$vlen, $num_items)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Items</name> + <key>num_items</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_items > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen*$num_items</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_vector_to_streams.xml b/grc/data/grc_gnuradio/blocks/gr_vector_to_streams.xml new file mode 100644 index 000000000..86cb56813 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_vector_to_streams.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Vector to Streams +################################################### + --> +<block> + <name>Vector to Streams</name> + <key>gr_vector_to_streams</key> + <import>from gnuradio import gr</import> + <make>gr.vector_to_streams($type.size*$vlen, $num_streams)</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams > 0</check> + <check>$vlen >= 1</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen*$num_streams</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_streams</nports> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_wavfile_sink.xml b/grc/data/grc_gnuradio/blocks/gr_wavfile_sink.xml new file mode 100644 index 000000000..f2c8a009f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_wavfile_sink.xml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Wav File Sink +################################################### + --> +<block> + <name>Wav File Sink</name> + <key>gr_wavfile_sink</key> + <import>from gnuradio import gr</import> + <make>gr.wavfile_sink($file, $nchan, $samp_rate, $bits_per_sample)</make> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_save</type> + </param> + <param> + <name>N Channels</name> + <key>nchan</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>int</type> + </param> + <param> + <name>Bits per Sample</name> + <key>bits_per_sample</key> + <value>8</value> + <type>int</type> + </param> + <check>1 <= $nchan</check> + <sink> + <name>in</name> + <type>float</type> + <nports>$nchan</nports> + </sink> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_wavfile_source.xml b/grc/data/grc_gnuradio/blocks/gr_wavfile_source.xml new file mode 100644 index 000000000..433bb0af2 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_wavfile_source.xml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Wav File Source +################################################### + --> +<block> + <name>Wav File Source</name> + <key>gr_wavfile_source</key> + <import>from gnuradio import gr</import> + <make>gr.wavfile_source($file, $repeat)</make> + <param> + <name>File</name> + <key>file</key> + <value></value> + <type>file_open</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>N Channels</name> + <key>nchan</key> + <value>1</value> + <type>int</type> + </param> + <check>1 <= $nchan</check> + <source> + <name>out</name> + <type>float</type> + <nports>$nchan</nports> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/gr_xor_xx.xml b/grc/data/grc_gnuradio/blocks/gr_xor_xx.xml new file mode 100644 index 000000000..97d97b01a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/gr_xor_xx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Logical Xor Block +################################################### + --> +<block> + <name>Xor</name> + <key>gr_xor_xx</key> + <import>from gnuradio impxort gr</import> + <make>gr.xor_$(type.fcn)()</make> + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:ii</opt> + </option> + <option> + <name>Shxort</name> + <key>short</key> + <opt>fcn:ss</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:bb</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <check>$num_inputs >= 2</check> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/high_pass_filter.xml b/grc/data/grc_gnuradio/blocks/high_pass_filter.xml new file mode 100644 index 000000000..0673fd124 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/high_pass_filter.xml @@ -0,0 +1,120 @@ +<?xml version="1.0"?> +<!-- +################################################### +##High Pass Filter: Custom wrapper +################################################### + --> +<block> + <name>High Pass Filter</name> + <key>high_pass_filter</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.$(type)($decim, firdes.high_pass( + $gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</make> + <callback>set_taps(firdes.high_pass($gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</callback> + <param> + <name>FIR Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Decimating)</name> + <key>fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Complex->Complex (Interpolating)</name> + <key>interp_fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Float->Float (Decimating)</name> + <key>fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + <option> + <name>Float->Float (Interpolating)</name> + <key>interp_fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Cutoff Freq</name> + <key>cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>Transition Width</name> + <key>width</key> + <type>real</type> + </param> + <param> + <name>Window</name> + <key>window</key> + <type>enum</type> + <option> + <name>Hamming</name> + <key>WIN_HAMMING</key> + </option> + <option> + <name>Hann</name> + <key>WIN_HANN</key> + </option> + <option> + <name>Blackman</name> + <key>WIN_BLACKMAN</key> + </option> + <option> + <name>Rectangular</name> + <key>WIN_RECTANGULAR</key> + </option> + <option> + <name>Kaiser</name> + <key>WIN_KAISER</key> + </option> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <value>6.76</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +This filter is a convenience wrapper for an fir filter and a firdes taps generating function. + +The decimation paramater becomes interpolation when the filter type is set to interpolating. + +Sample rate, cutoff frequency, and transition width are in Hertz. + +The beta paramater only applies to the Kaiser window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/import.xml b/grc/data/grc_gnuradio/blocks/import.xml new file mode 100644 index 000000000..feea052d3 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/import.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Import python modules into the namespace +################################################### + --> +<block> + <name>Import</name> + <key>import</key> + <import>$import</import> + <make></make> + <param> + <name>Import</name> + <key>import</key> + <value></value> + <type>import</type> + </param> + <doc> +Import additional python modules into the namespace. + +Examples: +from gnuradio.gr import firdes +import math,cmath +from math import pi + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/low_pass_filter.xml b/grc/data/grc_gnuradio/blocks/low_pass_filter.xml new file mode 100644 index 000000000..1e8802c80 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/low_pass_filter.xml @@ -0,0 +1,120 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Low Pass Filter: Custom wrapper +################################################### + --> +<block> + <name>Low Pass Filter</name> + <key>low_pass_filter</key> + <import>from gnuradio import gr</import> + <import>from gnuradio.gr import firdes</import> + <make>gr.$(type)($decim, firdes.low_pass( + $gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</make> + <callback>set_taps(firdes.low_pass($gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</callback> + <param> + <name>FIR Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex->Complex (Decimating)</name> + <key>fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Complex->Complex (Interpolating)</name> + <key>interp_fir_filter_ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + </option> + <option> + <name>Float->Float (Decimating)</name> + <key>fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + <option> + <name>Float->Float (Interpolating)</name> + <key>interp_fir_filter_fff</key> + <opt>input:float</opt> + <opt>output:float</opt> + </option> + </param> + <param> + <name>Decimation</name> + <key>decim</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1</value> + <type>real</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Cutoff Freq</name> + <key>cutoff_freq</key> + <type>real</type> + </param> + <param> + <name>Transition Width</name> + <key>width</key> + <type>real</type> + </param> + <param> + <name>Window</name> + <key>window</key> + <type>enum</type> + <option> + <name>Hamming</name> + <key>WIN_HAMMING</key> + </option> + <option> + <name>Hann</name> + <key>WIN_HANN</key> + </option> + <option> + <name>Blackman</name> + <key>WIN_BLACKMAN</key> + </option> + <option> + <name>Rectangular</name> + <key>WIN_RECTANGULAR</key> + </option> + <option> + <name>Kaiser</name> + <key>WIN_KAISER</key> + </option> + </param> + <param> + <name>Beta</name> + <key>beta</key> + <value>6.76</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +This filter is a convenience wrapper for an fir filter and a firdes taps generating function. + +The decimation paramater becomes interpolation when the filter type is set to interpolating. + +Sample rate, cutoff frequency, and transition width are in Hertz. + +The beta paramater only applies to the Kaiser window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/note.xml b/grc/data/grc_gnuradio/blocks/note.xml new file mode 100644 index 000000000..db6687c03 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/note.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Note Block (dummy) +################################################### + --> +<block> + <name>Note</name> + <key>note</key> + <make></make> + <param> + <name>Note</name> + <key>note</key> + <value></value> + <type>string</type> + </param> +</block> diff --git a/grc/data/grc_gnuradio/blocks/options.xml b/grc/data/grc_gnuradio/blocks/options.xml new file mode 100644 index 000000000..541028d5c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/options.xml @@ -0,0 +1,89 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Options Block: +## options for window size, +## and flow graph building. +################################################### + --> +<block> + <name>Options</name> + <key>options</key> + <import>from gnuradio import gr +#if $generate_options.eval == 'wx_gui' +from grc_gnuradio import wxgui as grc_wxgui +import wx +#end if +</import> + <make></make> + <param> + <name>Title</name> + <key>title</key> + <value>untitled</value> + <type>string</type> + </param> + <param> + <name>Author</name> + <key>author</key> + <value>unknown</value> + <type>string</type> + </param> + <param> + <name>Description</name> + <key>description</key> + <value>gnuradio flow graph</value> + <type>string</type> + </param> + <param> + <name>Window Size</name> + <key>window_size</key> + <value>1280, 1024</value> + <type>int_vector</type> + </param> + <param> + <name>Generate Options</name> + <key>generate_options</key> + <value>wx_gui</value> + <type>enum</type> + <option> + <name>WX GUI</name> + <key>wx_gui</key> + </option> + <option> + <name>No GUI</name> + <key>no_gui</key> + </option> + <option> + <name>Hier Block</name> + <key>hb</key> + </option> + </param> + <param> + <name>Category</name> + <key>category</key> + <value>Custom</value> + <type>string</type> + </param> + <check>len($window_size) == 2</check> + <check>300 <= $(window_size)[0] <= 2048</check> + <check>300 <= $(window_size)[1] <= 2048</check> + <doc> +The options block sets special parameters for the flow graph. \ +Only one option block is allowed per flow graph. + +Title, author, and description parameters are for identification purposes. + +The window size controls the dimensions of the flow graph editor. \ +The window size (width, height) must be between (300, 300) and (2048, 2048). + +The generate options controls the type of code generated. \ +Non-graphical flow graphs should avoid using graphical sinks or graphical variable controls. + +The id of this block determines the name of the generated file and the name of the class. \ +For example, an id of my_block will generate the file my_block.py and class my_block(gr.... + +The category parameter determines the placement of the block in the block selection window. \ +The category only applies when creating hier blocks. \ +To put hier blocks into the root category, enter / for the category. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/pad_sink.xml b/grc/data/grc_gnuradio/blocks/pad_sink.xml new file mode 100644 index 000000000..477f2ad13 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/pad_sink.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Pad Sink: IO Pads +################################################### + --> +<block> + <name>Pad Sink</name> + <key>pad_sink</key> + <make></make> + <param> + <name>Num Inputs</name> + <key>nports</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <check>0 < $nports</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$nports</nports> + </sink> + <doc> +This is a sink pad block for creating hierarchical flow graphs. \ +The inputs of this block will become the outputs to this flow graph when it is instantiated as a hierarchical block. \ +Limit one sink pad block per flow graph. + +Remember to set the generate options to hier block. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/pad_source.xml b/grc/data/grc_gnuradio/blocks/pad_source.xml new file mode 100644 index 000000000..b6ef2c55d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/pad_source.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Pad Source: IO Pads +################################################### + --> +<block> + <name>Pad Source</name> + <key>pad_source</key> + <make></make> + <param> + <name>Num Outputs</name> + <key>nports</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <check>0 < $nports</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$nports</nports> + </source> + <doc> +This is a source pad block for creating hierarchical flow graphs. \ +The outputs of this block will become the inputs to this flow graph when it is instantiated as a hierarchical block. \ +Limit one source pad block per flow graph. + +Remember to set the generate options to hier block. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/parameter.xml b/grc/data/grc_gnuradio/blocks/parameter.xml new file mode 100644 index 000000000..b9dcce424 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/parameter.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Parameter block: a grc variable with key, value +################################################### + --> +<block> + <name>Parameter</name> + <key>parameter</key> + <make>$value</make> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Value</name> + <key>value</key> + <value>0</value> + <type>raw</type> + </param> + <doc> +This block represents a parameter to the flow graph, \ +used when the flow graph is instantiated as a hier block. + +The paramater value cannot depend on any variables. + +Leave the label blank to use the parameter id as the label. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/preferences.xml b/grc/data/grc_gnuradio/blocks/preferences.xml new file mode 100644 index 000000000..51138c123 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/preferences.xml @@ -0,0 +1,146 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Global Preferences: +## This block should not appear in the tree. +################################################### + --> +<block> + <name>Preferences</name> + <key>preferences</key> + <make></make> + <!-- Hidden Prefs --> + <param> + <name>Prefs File</name> + <key>prefs_file</key> + <value>.grc</value> + <type>string</type> + </param> + <param> + <name>File Open</name> + <key>file_open</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Files Open</name> + <key>files_open</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Window Size</name> + <key>window_size</key> + <value>800, 600</value> + <type>int_vector</type> + </param> + <!-- Snap to Grid --> + <param> + <name>Snap to Grid</name> + <key>snap_to_grid</key> + <value>off</value> + <type>enum</type> + <option> + <name>Off</name> + <key>off</key> + </option> + <option> + <name>On</name> + <key>on</key> + </option> + </param> + <param> + <name>Grid Size</name> + <key>grid_size</key> + <value>20</value> + <type>enum</type> + <option> + <name>10 pixels</name> + <key>10</key> + </option> + <option> + <name>20 pixels</name> + <key>20</key> + </option> + <option> + <name>50 pixels</name> + <key>50</key> + </option> + <option> + <name>100 pixels</name> + <key>100</key> + </option> + </param> + <param> + <name>Show Grid</name> + <key>show_grid</key> + <value>hide</value> + <type>enum</type> + <option> + <name>Show</name> + <key>show</key> + </option> + <option> + <name>Hide</name> + <key>hide</key> + </option> + </param> + <!-- Appearance Prefs --> + <param> + <name>Show Reports Window</name> + <key>show_reports</key> + <value>show</value> + <type>enum</type> + <option> + <name>Show</name> + <key>show</key> + </option> + <option> + <name>Hide</name> + <key>hide</key> + </option> + </param> + <param> + <name>Show Params Labels</name> + <key>show_params</key> + <value>show</value> + <type>enum</type> + <option> + <name>Show</name> + <key>show</key> + </option> + <option> + <name>Hide</name> + <key>hide</key> + </option> + </param> + <param> + <name>Show ID Label</name> + <key>show_id</key> + <value>show</value> + <type>enum</type> + <option> + <name>Show</name> + <key>show</key> + </option> + <option> + <name>Hide</name> + <key>hide</key> + </option> + </param> + <!-- Misc Prefs --> + <param> + <name>Restore Open Files</name> + <key>restore_files</key> + <value>yes</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>yes</key> + </option> + <option> + <name>No</name> + <key>no</key> + </option> + </param> +</block> diff --git a/grc/data/grc_gnuradio/blocks/random_source_x.xml b/grc/data/grc_gnuradio/blocks/random_source_x.xml new file mode 100644 index 000000000..f04dcd8da --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/random_source_x.xml @@ -0,0 +1,73 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Random Source: +## Custom block +################################################### + --> +<block> + <name>Random Source</name> + <key>random_source_x</key> + <import>from gnuradio import gr</import> + <import>import numpy</import> + <make>gr.vector_source_$(type.fcn)(numpy.random.randint($min, $max, $num_samps), $repeat)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <param> + <name>Minimum</name> + <key>min</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Maximum</name> + <key>max</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Num Samples</name> + <key>num_samps</key> + <value>1000</value> + <type>int</type> + </param> + <param> + <name>Repeat</name> + <key>repeat</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> + <doc> +Generate num samples of random numbers of [min, max). Repeat samples if specified. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_encoder_xx.xml b/grc/data/grc_gnuradio/blocks/trellis_encoder_xx.xml new file mode 100644 index 000000000..74a8cc346 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_encoder_xx.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis Encoder +################################################### + --> +<block> + <name>Trellis Encoder</name> + <key>trellis_encoder_xx</key> + <import>from gnuradio import trellis</import> + <make>trellis.encoder_$(type)(trellis.fsm($fsm_args), $init_state)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte->Byte</name> + <key>bb</key> + <opt>input:byte</opt> + <opt>output:byte</opt> + </option> + <option> + <name>Byte->Short</name> + <key>bs</key> + <opt>input:byte</opt> + <opt>output:short</opt> + </option> + <option> + <name>Byte->Int</name> + <key>bi</key> + <opt>input:byte</opt> + <opt>output:int</opt> + </option> + <option> + <name>Short->Short</name> + <key>ss</key> + <opt>input:short</opt> + <opt>output:short</opt> + </option> + <option> + <name>Short->Int</name> + <key>si</key> + <opt>input:short</opt> + <opt>output:int</opt> + </option> + <option> + <name>Int->Int</name> + <key>ii</key> + <opt>input:int</opt> + <opt>output:int</opt> + </option> + </param> + <param> + <name>FSM Args</name> + <key>fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State</name> + <key>init_state</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_metrics_x.xml b/grc/data/grc_gnuradio/blocks/trellis_metrics_x.xml new file mode 100644 index 000000000..f09d54f09 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_metrics_x.xml @@ -0,0 +1,84 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis Metrics +################################################### + --> +<block> + <name>Trellis Metrics</name> + <key>trellis_metrics_x</key> + <import>from gnuradio import trellis</import> + <make>trellis.metrics_$(type)($card, $dim, $table, $metric_type)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>c</key> + <opt>io:complex</opt> + <opt>table:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>f</key> + <opt>io:float</opt> + <opt>table:real_vector</opt> + </option> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + <opt>table:int_vector</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + <opt>table:int_vector</opt> + </option> + </param> + <param> + <name>Output Cardinality</name> + <key>card</key> + <type>int</type> + </param> + <param> + <name>Dimensionality</name> + <key>dim</key> + <type>int</type> + </param> + <param> + <name>Constellation</name> + <key>table</key> + <type>$type.table</type> + </param> + <param> + <name>Metric Type</name> + <key>metric_type</key> + <type>enum</type> + <option> + <name>Euclidean</name> + <key>trellis.TRELLIS_EUCLIDEAN</key> + </option> + <option> + <name>Hard Symbol</name> + <key>trellis.TRELLIS_HARD_SYMBOL</key> + </option> + <option> + <name>Hard Bit</name> + <key>trellis.TRELLIS_HARD_BIT</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type.io</type> + </sink> + <source> + <name>out</name> + <type>$type.io</type> + </source> + <doc> +Generate metrics required for Viterbi or SISO algorithms. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_permutation.xml b/grc/data/grc_gnuradio/blocks/trellis_permutation.xml new file mode 100644 index 000000000..7721cc71d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_permutation.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis Permutation +################################################### + --> +<block> + <name>Trellis Permutation</name> + <key>trellis_permutation</key> + <import>from gnuradio import trellis</import> + <make>trellis.permutation($block_size, $table, $syms_per_block, $type.size*$vlen)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Table</name> + <key>table</key> + <type>int_vector</type> + </param> + <param> + <name>Symbols per Block</name> + <key>syms_per_block</key> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_siso_combined_f.xml b/grc/data/grc_gnuradio/blocks/trellis_siso_combined_f.xml new file mode 100644 index 000000000..98874d7f4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_siso_combined_f.xml @@ -0,0 +1,112 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis SISO Combined +################################################### + --> +<block> + <name>Trellis SISO Combo</name> + <key>trellis_siso_combined_f</key> + <import>from gnuradio import trellis</import> + <make>trellis.siso_combined_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type, $dim, $table, $metric_type)</make> + <param> + <name>FSM Args</name> + <key>fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Initial State</name> + <key>init_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Final State</name> + <key>final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>A-posteriori In</name> + <key>a_post_in</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>A-posteriori Out</name> + <key>a_post_out</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <param> + <name>Dimensionality</name> + <key>dim</key> + <type>int</type> + </param> + <param> + <name>Constellation</name> + <key>table</key> + <type>real_vector</type> + </param> + <param> + <name>Metric Type</name> + <key>metric_type</key> + <type>enum</type> + <option> + <name>Euclidean</name> + <key>trellis.TRELLIS_EUCLIDEAN</key> + </option> + <option> + <name>Hard Symbol</name> + <key>trellis.TRELLIS_HARD_SYMBOL</key> + </option> + <option> + <name>Hard Bit</name> + <key>trellis.TRELLIS_HARD_BIT</key> + </option> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> + <doc> +BCJR Algorithm combined with metric calculation. \ +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_siso_f.xml b/grc/data/grc_gnuradio/blocks/trellis_siso_f.xml new file mode 100644 index 000000000..2b9cfe5f7 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_siso_f.xml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis SISO +################################################### + --> +<block> + <name>Trellis SISO</name> + <key>trellis_siso_f</key> + <import>from gnuradio import trellis</import> + <make>trellis.siso_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type)</make> + <param> + <name>FSM Args</name> + <key>fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Initial State</name> + <key>init_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Final State</name> + <key>final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>A-posteriori In</name> + <key>a_post_in</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>A-posteriori Out</name> + <key>a_post_out</key> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> + <doc> +BCJR Algorithm. \ +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_viterbi_combined_xx.xml b/grc/data/grc_gnuradio/blocks/trellis_viterbi_combined_xx.xml new file mode 100644 index 000000000..0a67d0bfc --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_viterbi_combined_xx.xml @@ -0,0 +1,122 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis Viterbi Combined +################################################### + --> +<block> + <name>Trellis Viterbi Combo</name> + <key>trellis_viterbi_combined_xx</key> + <import>from gnuradio import trellis</import> + <make>trellis.viterbi_combined_$(type)$(out_type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $dim, $table, $metric_type)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>c</key> + <opt>io:complex</opt> + <opt>table:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>f</key> + <opt>io:float</opt> + <opt>table:real_vector</opt> + </option> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + <opt>table:int_vector</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + <opt>table:int_vector</opt> + </option> + </param> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>FSM Args</name> + <key>fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Initial State</name> + <key>init_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Final State</name> + <key>final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Dimensionality</name> + <key>dim</key> + <type>int</type> + </param> + <param> + <name>Constellation</name> + <key>table</key> + <type>$type.table</type> + </param> + <param> + <name>Metric Type</name> + <key>metric_type</key> + <type>enum</type> + <option> + <name>Euclidean</name> + <key>trellis.TRELLIS_EUCLIDEAN</key> + </option> + <option> + <name>Hard Symbol</name> + <key>trellis.TRELLIS_HARD_SYMBOL</key> + </option> + <option> + <name>Hard Bit</name> + <key>trellis.TRELLIS_HARD_BIT</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type.io</type> + </sink> + <source> + <name>out</name> + <type>$out_type.io</type> + </source> + <doc> +Viterbi Decoder combined with metric calculation. \ +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/trellis_viterbi_x.xml b/grc/data/grc_gnuradio/blocks/trellis_viterbi_x.xml new file mode 100644 index 000000000..7465b11db --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/trellis_viterbi_x.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Trellis Viterbi +################################################### + --> +<block> + <name>Trellis Viterbi</name> + <key>trellis_viterbi_x</key> + <import>from gnuradio import trellis</import> + <make>trellis.viterbi_$(type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>FSM Args</name> + <key>fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Initial State</name> + <key>init_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Final State</name> + <key>final_state</key> + <value>-1</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type.io</type> + </sink> + <source> + <name>out</name> + <type>$type.io</type> + </source> + <doc> +Viterbi Decoder. \ +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/usrp_diagnostics.xml b/grc/data/grc_gnuradio/blocks/usrp_diagnostics.xml new file mode 100644 index 000000000..52dd885a4 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/usrp_diagnostics.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- +################################################### +##USRP Diagnostics: +## This block should not appear in the tree. +################################################### + --> +<block> + <name>USRP Diagnostics</name> + <key>usrp_diagnostics</key> + <make></make> + <param> + <name>USRP Number</name> + <key>usrp_number</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>USRP Type</name> + <key>usrp_type</key> + <value>rx</value> + <type>enum</type> + <option> + <name>Receive</name> + <key>rx</key> + </option> + <option> + <name>Transmit</name> + <key>tx</key> + </option> + </param> + <param> + <name>Side:Subdevice</name> + <key>side_subdev</key> + <value>(0, 0)</value> + <type>enum</type> + <option> + <name>Side A:0</name> + <key>(0, 0)</key> + </option> + <option> + <name>Side B:0</name> + <key>(1, 0)</key> + </option> + <option> + <name>Side A:1</name> + <key>(0, 1)</key> + </option> + <option> + <name>Side B:0</name> + <key>(1, 1)</key> + </option> + </param> +</block> diff --git a/grc/data/grc_gnuradio/blocks/usrp_dual_sink_x.xml b/grc/data/grc_gnuradio/blocks/usrp_dual_sink_x.xml new file mode 100644 index 000000000..acc14b1f6 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/usrp_dual_sink_x.xml @@ -0,0 +1,154 @@ +<?xml version="1.0"?> +<!-- +################################################### +##USRP Dual Sink +################################################### + --> +<block> + <name>USRP Dual Sink</name> + <key>usrp_dual_sink_x</key> + <import>from grc_gnuradio import usrp as grc_usrp</import> + <make>grc_usrp.dual_sink_$(type.fcn)( + number=$number, + frequency_a=$frequency_a, + frequency_b=$frequency_b, + interpolation=$interpolation, + gain_a=$gain_a, + gain_b=$gain_b, + mux=$mux, + auto_tr=$auto_tr, + tx_enb_a=$tx_enb_a, + tx_enb_b=$tx_enb_b, +)</make> + <callback>set_interp_rate($interpolation)</callback> + <callback>set_frequency_a($frequency_a)</callback> + <callback>set_gain_a($gain_a)</callback> + <callback>set_frequency_b($frequency_b)</callback> + <callback>set_gain_b($gain_b)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Unit Number</name> + <key>number</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Frequency A</name> + <key>frequency_a</key> + <type>real</type> + </param> + <param> + <name>Frequency B</name> + <key>frequency_b</key> + <type>real</type> + </param> + <param> + <name>Interpolation</name> + <key>interpolation</key> + <type>int</type> + </param> + <param> + <name>Gain A</name> + <key>gain_a</key> + <type>real</type> + </param> + <param> + <name>Gain B</name> + <key>gain_b</key> + <type>real</type> + </param> + <param> + <name>Mux</name> + <key>mux</key> + <value>0xba98</value> + <type>hex</type> + </param> + <param> + <name>Auto T/R</name> + <key>auto_tr</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <param> + <name>TX Enable A</name> + <key>tx_enb_a</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <param> + <name>TX Enable B</name> + <key>tx_enb_b</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <sink> + <name>Ain</name> + <type>$type</type> + </sink> + <sink> + <name>Bin</name> + <type>$type</type> + </sink> + <doc> +The USRP sink inputs 128 Megasamples per second / interpolation. + +--- Flex RF specific --- +The "Auto TR" and "TX Enable" settings are flex rf specific and should be left at "Ignore" unless this is a flex rf board. + +If enabled, "Auto Transmit/Receive Switching" handles the preference for transmit packets vs receive packets. \ +By default, "Auto TR" is disabled. + +The "Transmit Enable" configures the transmitter to be on or off. \ +Do not leave this unconfigured. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/usrp_dual_source_x.xml b/grc/data/grc_gnuradio/blocks/usrp_dual_source_x.xml new file mode 100644 index 000000000..68526b47e --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/usrp_dual_source_x.xml @@ -0,0 +1,154 @@ +<?xml version="1.0"?> +<!-- +################################################### +##USRP Dual Source +################################################### + --> +<block> + <name>USRP Dual Source</name> + <key>usrp_dual_source_x</key> + <import>from grc_gnuradio import usrp as grc_usrp</import> + <make>grc_usrp.dual_source_$(type.fcn)( + number=$number, + frequency_a=$frequency_a, + frequency_b=$frequency_b, + decimation=$decimation, + gain_a=$gain_a, + gain_b=$gain_b, + mux=$mux, + auto_tr=$auto_tr, + rx_ant_a=$rx_ant_a, + rx_ant_b=$rx_ant_b, +)</make> + <callback>set_decim_rate($decimation)</callback> + <callback>set_frequency_a($frequency_a)</callback> + <callback>set_gain_a($gain_a)</callback> + <callback>set_frequency_b($frequency_b)</callback> + <callback>set_gain_b($gain_b)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Unit Number</name> + <key>number</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Frequency A</name> + <key>frequency_a</key> + <type>real</type> + </param> + <param> + <name>Frequency B</name> + <key>frequency_b</key> + <type>real</type> + </param> + <param> + <name>Decimation</name> + <key>decimation</key> + <type>int</type> + </param> + <param> + <name>Gain A</name> + <key>gain_a</key> + <type>real</type> + </param> + <param> + <name>Gain B</name> + <key>gain_b</key> + <type>real</type> + </param> + <param> + <name>Mux</name> + <key>mux</key> + <value>0x3210</value> + <type>hex</type> + </param> + <param> + <name>Auto T/R</name> + <key>auto_tr</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <param> + <name>RX Antenna B</name> + <key>rx_ant_a</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>TX/RX</name> + <key>"TX/RX"</key> + </option> + <option> + <name>RX2</name> + <key>"RX2"</key> + </option> + </param> + <param> + <name>RX Antenna B</name> + <key>rx_ant_b</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>TX/RX</name> + <key>"TX/RX"</key> + </option> + <option> + <name>RX2</name> + <key>"RX2"</key> + </option> + </param> + <source> + <name>Aout</name> + <type>$type</type> + </source> + <source> + <name>Bout</name> + <type>$type</type> + </source> + <doc> +The USRP source outputs 64 Megasamples per second / decimation. + +--- Flex RF specific --- +The "Auto TR" and "RX Antenna" settings are flex rf specific and should be left at "Ignore" unless this is a flex rf board. + +If enabled, "Auto Transmit/Receive Switching" handles the preference for transmit packets vs receive packets. \ +By default, "Auto TR" is disabled. + +The "Receive Antenna Setting" selects one of the SMA connectors as the data source. \ +By default, 'TX/RX' is selected. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/usrp_simple_sink_x.xml b/grc/data/grc_gnuradio/blocks/usrp_simple_sink_x.xml new file mode 100644 index 000000000..b525d031f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/usrp_simple_sink_x.xml @@ -0,0 +1,140 @@ +<?xml version="1.0"?> +<!-- +################################################### +##USRP Simple Sink +################################################### + --> +<block> + <name>USRP Sink</name> + <key>usrp_simple_sink_x</key> + <import>from grc_gnuradio import usrp as grc_usrp</import> + <make>grc_usrp.simple_sink_$(type.fcn)( + number=$number, + subdev_spec=$subdev_spec, + frequency=$frequency, + interpolation=$interpolation, + gain=$gain, +#if $mux.eval == hex(0) + mux=None, +#else + mux=$mux, +#end if + auto_tr=$auto_tr, + tx_enb=$tx_enb, +)</make> + <callback>set_interp_rate($interpolation)</callback> + <callback>set_frequency($frequency)</callback> + <callback>set_gain($gain)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Unit Number</name> + <key>number</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Subdev Spec</name> + <key>subdev_spec</key> + <value>auto</value> + <type>enum</type> + <option> + <name>Auto</name> + <key>None</key> + </option> + <option> + <name>Side A</name> + <key>(0, 0)</key> + </option> + <option> + <name>Side B</name> + <key>(1, 0)</key> + </option> + </param> + <param> + <name>Frequency</name> + <key>frequency</key> + <type>real</type> + </param> + <param> + <name>Interpolation</name> + <key>interpolation</key> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <param> + <name>Mux</name> + <key>mux</key> + <value>0x0</value> + <type>hex</type> + </param> + <param> + <name>Auto T/R</name> + <key>auto_tr</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <param> + <name>TX Enable</name> + <key>tx_enb</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <doc> +The USRP sink inputs 128 Megasamples per second / interpolation. + +--- Flex RF specific --- +The "Auto TR" and "TX Enable" settings are flex rf specific and should be left at "Ignore" unless this is a flex rf board. + +If enabled, "Auto Transmit/Receive Switching" handles the preference for transmit packets vs receive packets. \ +By default, "Auto TR" is disabled. + +The "Transmit Enable" configures the transmitter to be on or off. \ +Do not leave this unconfigured. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/usrp_simple_source_x.xml b/grc/data/grc_gnuradio/blocks/usrp_simple_source_x.xml new file mode 100644 index 000000000..a1598583f --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/usrp_simple_source_x.xml @@ -0,0 +1,148 @@ +<?xml version="1.0"?> +<!-- +################################################### +##USRP Simple Source +################################################### + --> +<block> + <name>USRP Source</name> + <key>usrp_simple_source_x</key> + <import>from grc_gnuradio import usrp as grc_usrp</import> + <make>grc_usrp.simple_source_$(type.fcn)( + number=$number, + subdev_spec=$subdev_spec, + frequency=$frequency, + decimation=$decimation, + gain=$gain, +#if $mux.eval == hex(0) + mux=None, +#else + mux=$mux, +#end if + auto_tr=$auto_tr, + rx_ant=$rx_ant, +)</make> + <callback>set_decim_rate($decimation)</callback> + <callback>set_frequency($frequency)</callback> + <callback>set_gain($gain)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + </param> + <param> + <name>Unit Number</name> + <key>number</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Subdev Spec</name> + <key>subdev_spec</key> + <value>auto</value> + <type>enum</type> + <option> + <name>Auto</name> + <key>None</key> + </option> + <option> + <name>Side A:0</name> + <key>(0, 0)</key> + </option> + <option> + <name>Side B:0</name> + <key>(1, 0)</key> + </option> + <option> + <name>Side A:1</name> + <key>(0, 1)</key> + </option> + <option> + <name>Side B:1</name> + <key>(1, 1)</key> + </option> + </param> + <param> + <name>Frequency</name> + <key>frequency</key> + <type>real</type> + </param> + <param> + <name>Decimation</name> + <key>decimation</key> + <type>int</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <type>real</type> + </param> + <param> + <name>Mux</name> + <key>mux</key> + <value>0x0</value> + <type>hex</type> + </param> + <param> + <name>Auto T/R</name> + <key>auto_tr</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>Enable</name> + <key>True</key> + </option> + <option> + <name>Disable</name> + <key>False</key> + </option> + </param> + <param> + <name>RX Antenna</name> + <key>rx_ant</key> + <value>None</value> + <type>enum</type> + <option> + <name>Ignore</name> + <key>None</key> + </option> + <option> + <name>TX/RX</name> + <key>"TX/RX"</key> + </option> + <option> + <name>RX2</name> + <key>"RX2"</key> + </option> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> + <doc> +The USRP source outputs 64 Megasamples per second / decimation. + +--- Flex RF specific --- +The "Auto TR" and "RX Antenna" settings are flex rf specific and should be left at "Ignore" unless this is a flex rf board. + +If enabled, "Auto Transmit/Receive Switching" handles the preference for transmit packets vs receive packets. \ +By default, "Auto TR" is disabled. + +The "Receive Antenna Setting" selects one of the SMA connectors as the data source. \ +By default, 'TX/RX' is selected. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/variable.xml b/grc/data/grc_gnuradio/blocks/variable.xml new file mode 100644 index 000000000..d620e1607 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/variable.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable block: a grc variable with key, value +################################################### + --> +<block> + <name>Variable</name> + <key>variable</key> + <make>$value</make> + <param> + <name>Value</name> + <key>value</key> + <value>0</value> + <type>raw</type> + </param> + <doc> +This block maps a value to a unique variable. \ +This variable block has no graphical representation. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/variable_chooser.xml b/grc/data/grc_gnuradio/blocks/variable_chooser.xml new file mode 100644 index 000000000..4eba84d4c --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/variable_chooser.xml @@ -0,0 +1,93 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Chooser: a grc variable with multiple choices +################################################### + --> +<block> + <name>Variable Chooser</name> + <key>variable_chooser</key> + <make>$(choices)[$value_index] +_$(id)_control = grc_wxgui.$(chooser_type)_control( + window=self.GetWin(), + callback=self.set_$(id), + #if $label.eval + label=$label, + #else + label="$id", + #end if + index=$value_index, + choices=$choices, + labels=$labels, +) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(_$(id)_control) +#else +self.GridAdd(_$(id)_control, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Value Index</name> + <key>value_index</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Choices</name> + <key>choices</key> + <value>[1, 2, 3]</value> + <type>raw</type> + </param> + <param> + <name>Labels</name> + <key>labels</key> + <value>[]</value> + <type>raw</type> + </param> + <param> + <name>Chooser Type</name> + <key>chooser_type</key> + <value>drop_down</value> + <type>enum</type> + <option> + <name>Drop Down</name> + <key>drop_down</key> + </option> + <option> + <name>Radio Buttons Horizontal</name> + <key>radio_buttons_horizontal</key> + </option> + <option> + <name>Radio Buttons Vertical</name> + <key>radio_buttons_vertical</key> + </option> + <option> + <name>Button</name> + <key>button</key> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <check>$value_index in range(len($choices))</check> + <check>not $labels or len($labels) == len($choices)</check> + <doc> +This block creates a variable with a drop down, radio buttons, or a button. \ +Leave the label blank to use the variable id as the label. \ +The value index is the index of a particular choice, \ +which defines the default choice when the flow graph starts. \ +The choices must be a list of possible values. \ +Leave labels empty to use the choices as the labels. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/variable_sink.xml b/grc/data/grc_gnuradio/blocks/variable_sink.xml new file mode 100644 index 000000000..13737b2cf --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/variable_sink.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Sink: Custom blks2 block +################################################### + --> +<block> + <name>Variable Sink</name> + <key>variable_sink</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.queue_sink_$(type.fcn)($vlen) +grc_blks2.queue_sink_thread(self.$id, set_$(variable))</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>fcn:b</opt> + </option> + </param> + <param> + <name>Variable</name> + <key>variable</key> + <value></value> + <type>raw</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <doc> +Read samples from the input stream and write each sample to the variable. + +The variable must be the id of an existing variable block. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/variable_slider.xml b/grc/data/grc_gnuradio/blocks/variable_slider.xml new file mode 100644 index 000000000..2f6374b9a --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/variable_slider.xml @@ -0,0 +1,92 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Slider: a grc variable with key, value, min, max, step +################################################### + --> +<block> + <name>Variable Slider</name> + <key>variable_slider</key> + <make>$value +_$(id)_control = grc_wxgui.slider_$(slider_type)_control( + window=self.GetWin(), + callback=self.set_$(id), + #if $label.eval + label=$label, + #else + label="$id", + #end if + value=$id, + min=$min, + max=$max, + num_steps=$num_steps, +) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(_$(id)_control) +#else +self.GridAdd(_$(id)_control, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>50</value> + <type>real</type> + </param> + <param> + <name>Minimum</name> + <key>min</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Maximum</name> + <key>max</key> + <value>100</value> + <type>real</type> + </param> + <param> + <name>Num Steps</name> + <key>num_steps</key> + <value>100</value> + <type>int</type> + </param> + <param> + <name>Slider Type</name> + <key>slider_type</key> + <value>horizontal</value> + <type>enum</type> + <option> + <name>Horizontal</name> + <key>horizontal</key> + </option> + <option> + <name>Vertical</name> + <key>vertical</key> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <check>$min <= $value <= $max</check> + <check>$min < $max</check> + <check>0 < $num_steps <= 1000</check> + <doc> +This block creates a variable with a slider. \ +Leave the label blank to use the variable id as the label. \ +The value must be a real number. \ +The value must be between the minimum and the maximum. \ +The number of steps must be between 0 and 1000. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/variable_text_box.xml b/grc/data/grc_gnuradio/blocks/variable_text_box.xml new file mode 100644 index 000000000..0dad3d826 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/variable_text_box.xml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Variable Text Box: a grc variable with key, value +################################################### + --> +<block> + <name>Variable Text Box</name> + <key>variable_text_box</key> + <make>$value +_$(id)_control = grc_wxgui.text_box_control( + window=self.GetWin(), + callback=self.set_$(id), + #if $label.eval + label=$label, + #else + label="$id", + #end if + value=$id, +) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(_$(id)_control) +#else +self.GridAdd(_$(id)_control, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Label</name> + <key>label</key> + <value></value> + <type>string</type> + </param> + <param> + <name>Default Value</name> + <key>value</key> + <value>0</value> + <type>raw</type> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <doc> +This block creates a variable with a text box. \ +Leave the label blank to use the variable id as the label. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/wxgui_constellationsink2.xml b/grc/data/grc_gnuradio/blocks/wxgui_constellationsink2.xml new file mode 100644 index 000000000..cf3f29280 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/wxgui_constellationsink2.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Constellation Sink +################################################### + --> +<block> + <name>Constellation Sink</name> + <key>wxgui_constellationsink2</key> + <import>from gnuradio.wxgui import scopesink2</import> + <make>scopesink2.constellation_sink( + self.GetWin(), + title=$title, + sample_rate=$samp_rate, + frame_decim=$frame_decim, +) +self.$(id).win.$(marker)() +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(self.$(id).win) +#else +self.GridAdd(self.$(id).win, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <callback>set_sample_rate($samp_rate)</callback> + <param> + <name>Title</name> + <key>title</key> + <value>Constellation Plot</value> + <type>string</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Frame Decimation</name> + <key>frame_decim</key> + <value>15</value> + <type>int</type> + </param> + <param> + <name>Marker</name> + <key>marker</key> + <value>set_format_plus</value> + <type>enum</type> + <option> + <name>Line</name> + <key>set_format_line</key> + </option> + <option> + <name>Dot</name> + <key>set_format_dot</key> + </option> + <option> + <name>Plus</name> + <key>set_format_plus</key> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <doc> +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/wxgui_fftsink2.xml b/grc/data/grc_gnuradio/blocks/wxgui_fftsink2.xml new file mode 100644 index 000000000..68b07ba9d --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/wxgui_fftsink2.xml @@ -0,0 +1,148 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FFT Sink +################################################### + --> +<block> + <name>FFT Sink</name> + <key>wxgui_fftsink2</key> + <import>from gnuradio.wxgui import fftsink2</import> + <make>fftsink2.$(type.fcn)( + self.GetWin(), + baseband_freq=$baseband_freq, + y_per_div=$y_per_div, + y_divs=$y_divs, + ref_level=$ref_level, + sample_rate=$samp_rate, + fft_size=$fft_size, + fft_rate=$fft_rate, + average=$average, +#if $avg_alpha.eval == 0 + avg_alpha=None, +#else + avg_alpha=$avg_alpha, +#end if + title=$title, + peak_hold=$peak_hold, +) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(self.$(id).win) +#else +self.GridAdd(self.$(id).win, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:fft_sink_c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:fft_sink_f</opt> + </option> + </param> + <param> + <name>Title</name> + <key>title</key> + <value>FFT Plot</value> + <type>string</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Baseband Freq</name> + <key>baseband_freq</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Y per Div</name> + <key>y_per_div</key> + <value>10</value> + <type>real</type> + </param> + <param> + <name>Y Divs</name> + <key>y_divs</key> + <value>8</value> + <type>real</type> + </param> + <param> + <name>Reference Level</name> + <key>ref_level</key> + <value>50</value> + <type>real</type> + </param> + <param> + <name>FFT Size</name> + <key>fft_size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Refresh Rate</name> + <key>fft_rate</key> + <value>30</value> + <type>int</type> + </param> + <param> + <name>Average Alpha</name> + <key>avg_alpha</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Average</name> + <key>average</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Peak Hold</name> + <key>peak_hold</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <doc> +Set Average Alpha to 0 for automatic setting. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/wxgui_numbersink2.xml b/grc/data/grc_gnuradio/blocks/wxgui_numbersink2.xml new file mode 100644 index 000000000..e54da3e61 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/wxgui_numbersink2.xml @@ -0,0 +1,173 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Number Sink +################################################### + --> +<block> + <name>Number Sink</name> + <key>wxgui_numbersink2</key> + <import>from gnuradio.wxgui import numbersink2</import> + <make>numbersink2.$(type.fcn)( + self.GetWin(), + unit=$units, + base_value=$base_value, + minval=$min_value, + maxval=$max_value, + factor=$factor, + decimal_places=$decimal_places, + ref_level=$ref_level, + sample_rate=$samp_rate, + number_rate=$number_rate, + average=$options.average, +#if $avg_alpha.eval == 0 + avg_alpha=None, +#else + avg_alpha=$avg_alpha, +#end if + label=$title, + peak_hold=$options.peak_hold, +) +self.$(id).set_show_gauge($show_gauge) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(self.$(id).win) +#else +self.GridAdd(self.$(id).win, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:number_sink_c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:number_sink_f</opt> + </option> + </param> + <param> + <name>Title</name> + <key>title</key> + <value>Number Plot</value> + <type>string</type> + </param> + <param> + <name>Units</name> + <key>units</key> + <value>Units</value> + <type>string</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Base Value</name> + <key>base_value</key> + <value>0.0</value> + <type>real</type> + </param> + <param> + <name>Min Value</name> + <key>min_value</key> + <value>-100</value> + <type>real</type> + </param> + <param> + <name>Max Value</name> + <key>max_value</key> + <value>100</value> + <type>real</type> + </param> + <param> + <name>Factor</name> + <key>factor</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Decimal Places</name> + <key>decimal_places</key> + <value>10</value> + <type>int</type> + </param> + <param> + <name>Reference Level</name> + <key>ref_level</key> + <value>50</value> + <type>real</type> + </param> + <param> + <name>Number Rate</name> + <key>number_rate</key> + <value>15</value> + <type>int</type> + </param> + <param> + <name>Average Alpha</name> + <key>avg_alpha</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Options</name> + <key>options</key> + <value>none</value> + <type>enum</type> + <option> + <name>None</name> + <key>none</key> + <opt>peak_hold:False</opt> + <opt>average:False</opt> + </option> + <option> + <name>Average</name> + <key>average</key> + <opt>peak_hold:False</opt> + <opt>average:True</opt> + </option> + <option> + <name>Peak Hold</name> + <key>peak_hold</key> + <opt>peak_hold:True</opt> + <opt>average:False</opt> + </option> + </param> + <param> + <name>Show Gauge</name> + <key>show_gauge</key> + <value>True</value> + <type>enum</type> + <option> + <name>Show</name> + <key>True</key> + </option> + <option> + <name>Hide</name> + <key>False</key> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <doc> +Set Average Alpha to 0 for automatic setting. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/wxgui_scopesink2.xml b/grc/data/grc_gnuradio/blocks/wxgui_scopesink2.xml new file mode 100644 index 000000000..7cf49d5d6 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/wxgui_scopesink2.xml @@ -0,0 +1,146 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Scope Sink +################################################### + --> +<block> + <name>Scope Sink</name> + <key>wxgui_scopesink2</key> + <import>from gnuradio.wxgui import scopesink2</import> + <import>from gnuradio import gr</import> + <make>scopesink2.$(type.fcn)( + self.GetWin(), + title=$title, + sample_rate=$samp_rate, + frame_decim=$frame_decim, +#if $v_scale.eval == 0 + v_scale=None, +#else + v_scale=$v_scale, +#end if + t_scale=$t_scale, + num_inputs=$num_inputs, +) +self.$(id).win.$(marker)() +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(self.$(id).win) +#else +self.GridAdd(self.$(id).win, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> +<!-- +$(id).win.info.scopesink.set_trigger_channel($(trigger_channel)) +$(id).win.info.scopesink.set_trigger_mode(gr.$(trigger_mode)) --> + <callback>set_sample_rate($samp_rate)</callback> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:scope_sink_c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:scope_sink_f</opt> + </option> + </param> + <param> + <name>Title</name> + <key>title</key> + <value>Scope Plot</value> + <type>string</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Frame Decimation</name> + <key>frame_decim</key> + <value>15</value> + <type>int</type> + </param> + <param> + <name>V Scale</name> + <key>v_scale</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>T Scale</name> + <key>t_scale</key> + <value>.001</value> + <type>real</type> + </param> + <param> + <name>Marker</name> + <key>marker</key> + <value>set_format_line</value> + <type>enum</type> + <option> + <name>Line</name> + <key>set_format_line</key> + </option> + <option> + <name>Dot</name> + <key>set_format_dot</key> + </option> + <option> + <name>Plus</name> + <key>set_format_plus</key> + </option> + </param> + <!-- <param> + <name>Trigger Channel</name> + <key>trigger_channel</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Trigger Mode</name> + <key>trigger_mode</key> + <value>gr_TRIG_AUTO</value> + <type>enum</type> + <option> + <name>Auto</name> + <key>gr_TRIG_AUTO</key> + </option> + <option> + <name>Positive Slope</name> + <key>gr_TRIG_POS_SLOPE</key> + </option> + <option> + <name>Negative Slope</name> + <key>gr_TRIG_NEG_SLOPE</key> + </option> + </param> --> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + <nports>$num_inputs</nports> + </sink> + <doc> +Set the V Scale to 0 for the scope to auto-scale. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/wxgui_waterfallsink2.xml b/grc/data/grc_gnuradio/blocks/wxgui_waterfallsink2.xml new file mode 100644 index 000000000..b5172f094 --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/wxgui_waterfallsink2.xml @@ -0,0 +1,128 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Waterfall Sink +################################################### + --> +<block> + <name>Waterfall Sink</name> + <key>wxgui_waterfallsink2</key> + <import>from gnuradio.wxgui import waterfallsink2</import> + <make>waterfallsink2.$(type.fcn)( + self.GetWin(), + baseband_freq=$baseband_freq, + y_per_div=$y_per_div, + ref_level=$ref_level, + sample_rate=$samp_rate, + fft_size=$fft_size, + fft_rate=$fft_rate, + average=$options.average, +#if $avg_alpha.eval == 0 + avg_alpha=None, +#else + avg_alpha=$avg_alpha, +#end if + title=$title, +) +#set $grid_pos = $grid_pos.eval +#if not grid_pos +self.Add(self.$(id).win) +#else +self.GridAdd(self.$(id).win, $grid_pos[0], $grid_pos[1], $grid_pos[2], $grid_pos[3]) +#end if</make> + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:waterfall_sink_c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:waterfall_sink_f</opt> + </option> + </param> + <param> + <name>Title</name> + <key>title</key> + <value>Waterfall Plot</value> + <type>string</type> + </param> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Baseband Freq</name> + <key>baseband_freq</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Y per Div</name> + <key>y_per_div</key> + <value>10</value> + <type>real</type> + </param> + <param> + <name>Reference Level</name> + <key>ref_level</key> + <value>50</value> + <type>real</type> + </param> + <param> + <name>FFT Size</name> + <key>fft_size</key> + <value>512</value> + <type>int</type> + </param> + <param> + <name>FFT Rate</name> + <key>fft_rate</key> + <value>15</value> + <type>int</type> + </param> + <param> + <name>Average Alpha</name> + <key>avg_alpha</key> + <value>0</value> + <type>real</type> + </param> + <param> + <name>Options</name> + <key>options</key> + <value>none</value> + <type>enum</type> + <option> + <name>None</name> + <key>none</key> + <opt>average:False</opt> + </option> + <option> + <name>Average</name> + <key>average</key> + <opt>average:True</opt> + </option> + </param> + <param> + <name>Grid Position</name> + <key>grid_pos</key> + <value></value> + <type>grid_pos</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <doc> +Set Average Alpha to 0 for automatic setting. + +Use the Grid Position (row, column, row span, column span) to position the graphical element in the window. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/xmlrpc_client.xml b/grc/data/grc_gnuradio/blocks/xmlrpc_client.xml new file mode 100644 index 000000000..82ae8ceed --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/xmlrpc_client.xml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple XMLRPC Client +################################################### + --> +<block> + <name>XMLRPC Client</name> + <key>xmlrpc_client</key> + <import>import xmlrpclib</import> + <make>xmlrpclib.Server("http://$(addr.eval):$(port)")</make> + <callback>$(callback.eval)($variable)</callback> + <param> + <name>Address</name> + <key>addr</key> + <value>localhost</value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>8080</value> + <type>int</type> + </param> + <param> + <name>Callback</name> + <key>callback</key> + <value>set_</value> + <type>string</type> + </param> + <param> + <name>Variable</name> + <key>variable</key> + <type>raw</type> + </param> + <doc> +This block will create an XMLRPC client. \ +The client will execute the callback on the server when the variable is changed. \ +The callback should be a the name of a function registered on the server. \ +The variable should be an expression containing a the name of a variable in flow graph. + </doc> +</block> diff --git a/grc/data/grc_gnuradio/blocks/xmlrpc_server.xml b/grc/data/grc_gnuradio/blocks/xmlrpc_server.xml new file mode 100644 index 000000000..40e547efc --- /dev/null +++ b/grc/data/grc_gnuradio/blocks/xmlrpc_server.xml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Simple XMLRPC Server +################################################### + --> +<block> + <name>XMLRPC Server</name> + <key>xmlrpc_server</key> + <import>import SimpleXMLRPCServer</import> + <import>import threading</import> + <make>SimpleXMLRPCServer.SimpleXMLRPCServer(($addr, $port), allow_none=True) +self.$(id).register_instance(self) +threading.Thread(target=self.$(id).serve_forever).start()</make> + <param> + <name>Address</name> + <key>addr</key> + <value>localhost</value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>8080</value> + <type>int</type> + </param> + <doc> +This block will start an XMLRPC server. \ +The server provides access to the run, start, stop, wait functions of the flow graph. \ +The server also provides access to the variable callbacks in the flow graph. \ +Ex: If the variable is called freq, the function provided by the server will be called set_freq(new_freq). + +Example client in python: + +import xmlrpclib +s = xmlrpclib.Server("http://localhost:8080") +s.set_freq(5000) + </doc> +</block> diff --git a/grc/data/grc_gnuradio/default_flow_graph.grc.xml b/grc/data/grc_gnuradio/default_flow_graph.grc.xml new file mode 100644 index 000000000..dea26f3a5 --- /dev/null +++ b/grc/data/grc_gnuradio/default_flow_graph.grc.xml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Default Flow Graph: +## include an options block and a variable for sample rate +################################################### + --> +<flow_graph> + <block> + <key>options</key> + <param> + <key>id</key> + <value>top_block</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> +</flow_graph> diff --git a/grc/data/grc_gnuradio/flow_graph.tmpl b/grc/data/grc_gnuradio/flow_graph.tmpl new file mode 100644 index 000000000..932aa42ec --- /dev/null +++ b/grc/data/grc_gnuradio/flow_graph.tmpl @@ -0,0 +1,179 @@ +#!/usr/bin/env python +######################################################## +##Cheetah template - gnuradio_python +## +##@param imports the import statements +##@param flow_graph the flow_graph +##@param variables the variable blocks +##@param parameters the paramater blocks +##@param blocks the signal blocks +##@param connections the connections +##@param generate_options the type of flow graph +##@param var_id2expr variable id map to expression +##@param var_id2deps variable id map to direct dependencies +##@param var_id2cbs variable id map to callback strings +######################################################## +#import time +#set $DIVIDER = '#'*50 +$DIVIDER +# Gnuradio Python Flow Graph +$('# Title: %s'%$flow_graph.get_option('title')) +$('# Author: %s'%$flow_graph.get_option('author')) +$('# Description: %s'%$flow_graph.get_option('description')) +$('# Generated: %s'%time.ctime()) +$DIVIDER + +######################################################## +##Create Imports +######################################################## +#for $imp in $imports +$imp +#end for + +######################################################## +##Create Class +## Write the class declaration for a top or hier block. +## The parameter names are the arguments to __init__. +## Determine the absolute icon path (wx gui only). +## Setup the IO signature (hier block only). +######################################################## +#set $class_name = $flow_graph.get_option('id') +#set $param_str = ', '.join(['self'] + ['%s=%s'%(param.get_id(), param.get_make()) for param in $parameters]) +#if $generate_options == 'wx_gui' + #from grc.Constants import MAIN_WINDOW_PREFIX, DATA_DIR +class $(class_name)(grc_wxgui.top_block_gui): + + def __init__($param_str): + grc_wxgui.top_block_gui.__init__( + self, + title="$MAIN_WINDOW_PREFIX - Executing: $flow_graph.get_option('title')", + icon="$(os.path.join($DATA_DIR, 'grc-icon-32.png'))", + ) +#elif $generate_options == 'no_gui' +class $(class_name)(gr.top_block): + + def __init__($param_str): + gr.top_block.__init__(self, "$flow_graph.get_option('title')") +#elif $generate_options == 'hb' + #set $in_sig = $flow_graph.get_input_signature() + #set $out_sig = $flow_graph.get_output_signature() +class $(class_name)(gr.hier_block2): + + def __init__($param_str): + gr.hier_block2.__init__( + self, + "$flow_graph.get_option('title')", + gr.io_signature($in_sig.nports, $in_sig.nports, $in_sig.size*$in_sig.vlen), + gr.io_signature($out_sig.nports, $out_sig.nports, $out_sig.size*$out_sig.vlen), + ) +#end if +######################################################## +##Create Parameters +## Set the parameter to a property of self.. +######################################################## +#if $parameters + + $DIVIDER + # Parameters + $DIVIDER +#end if +#for $param in $parameters + self.$param.get_id() = $param.get_id() +#end for +######################################################## +##Create Variables +## Set the variable to a property of self. +## Write the variable make, and indent with 2 tabs. +######################################################## +#if $variables + + $DIVIDER + # Variables + $DIVIDER +#end if +#for $var in $variables + #set $code = '\n\t\t'.join($var.get_make().splitlines()) + $var.get_id() = $code + self.$var.get_id() = $var.get_id() +#end for +######################################################## +##Create Blocks +## Write the block make, and indent with 2 tabs. +######################################################## +#if $blocks + + $DIVIDER + # Blocks + $DIVIDER +#end if +#for $blk in filter(lambda b: b.get_make(), $blocks) + #set $code = '\n\t\t'.join($blk.get_make().splitlines()) + $("self.%s = %s"%($blk.get_id(), $code)) +#end for +######################################################## +##Create Connections +## The port name should be the id of the parent block. +## However, port names for IO pads should be self. +######################################################## +#if $connections + + $DIVIDER + # Connections + $DIVIDER +#end if +#for $con in $connections + #set $source = $con.get_source() + #set $sink = $con.get_sink() + #if $source.get_parent().get_key() == 'pad_source' + #set $source_name = 'self' + #else + #set $source_name = 'self.' + $source.get_parent().get_id() + #end if + #if $sink.get_parent().get_key() == 'pad_sink' + #set $sink_name = 'self' + #else + #set $sink_name = 'self.' + $sink.get_parent().get_id() + #end if + $("self.connect((%s, %s), (%s, %s))"%( + $source_name, + $source.get_key(), + $sink_name, + $sink.get_key(), + ) + ) +#end for + +######################################################## +##Create Callbacks +## Write a set method for this variable that calls the callbacks +## and sets the direct variable dependencies. +######################################################## +#for $var in $parameters + $variables + #set $id = $var.get_id() + def set_$(id)(self, $id): + self.$id = $id + #for $dep in $var_id2deps[$id] + self.set_$(dep)($var_id2expr[$dep]) + #end for + #for $callback in $var_id2cbs[$id] + self.$callback + #end for + +#end for +######################################################## +##Create Main +## For top block code, generate a main routine. +## Instantiate the top block and run as gui or cli. +######################################################## +#if $generate_options != 'hb' +if __name__ == '__main__': + tb = $(class_name)() + #if $generate_options == 'wx_gui' + tb.Run() + #elif $generate_options == 'no_gui' + tb.start() + raw_input('Press Enter to quit: ') + tb.stop() + #end if +#end if + diff --git a/grc/examples/Makefile.am b/grc/examples/Makefile.am new file mode 100644 index 000000000..9bba14bc9 --- /dev/null +++ b/grc/examples/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = \ + audio \ + simple \ + usrp \ + xmlrpc diff --git a/grc/examples/audio/Makefile.am b/grc/examples/audio/Makefile.am new file mode 100644 index 000000000..78800edcc --- /dev/null +++ b/grc/examples/audio/Makefile.am @@ -0,0 +1,26 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_examples_prefix)/audio + +EXTRA_DIST = dial_tone.grc diff --git a/grc/examples/audio/dial_tone.grc b/grc/examples/audio/dial_tone.grc new file mode 100644 index 000000000..6f96d9748 --- /dev/null +++ b/grc/examples/audio/dial_tone.grc @@ -0,0 +1,375 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:27:48 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>dial_tone</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>Dial Tone</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>example flow graph</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_vxx</key> + <param> + <key>id</key> + <value>gr_add_vxx</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>num_inputs</key> + <value>3</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(513, 277)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>audio_sink</key> + <param> + <key>id</key> + <value>audio_sink</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>samp_rate</key> + <value>32000</value> + </param> + <param> + <key>device_name</key> + <value/> + </param> + <param> + <key>ok_to_block</key> + <value>True</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(699, 112)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noise</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(238, 380)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>440</value> + </param> + <param> + <key>amp</key> + <value>ampl</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(240, 208)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>350</value> + </param> + <param> + <key>amp</key> + <value>ampl</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(240, 38)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>ampl</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Volume</value> + </param> + <param> + <key>value</key> + <value>.4</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>.5</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(634, 413)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>noise</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Noise</value> + </param> + <param> + <key>value</key> + <value>.005</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>.2</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(443, 412)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(11, 171)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_sig_source_x0</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sig_source_x</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>2</sink_key> + </connection> + <connection> + <source_block_id>gr_add_vxx</source_block_id> + <sink_block_id>audio_sink</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph>
\ No newline at end of file diff --git a/grc/examples/simple/Makefile.am b/grc/examples/simple/Makefile.am new file mode 100644 index 000000000..a2fcd614e --- /dev/null +++ b/grc/examples/simple/Makefile.am @@ -0,0 +1,26 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_examples_prefix)/simple + +EXTRA_DIST = ber_simulation.grc diff --git a/grc/examples/simple/ber_simulation.grc b/grc/examples/simple/ber_simulation.grc new file mode 100644 index 000000000..0e4ce64ed --- /dev/null +++ b/grc/examples/simple/ber_simulation.grc @@ -0,0 +1,540 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:28:06 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>ber_sim</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>BER Simulation</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>Adjust the noise and constellation... see what happens!</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(16, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_vxx</key> + <param> + <key>id</key> + <value>gr_add_vxx</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(652, 395)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_constellationsink2</key> + <param> + <key>id</key> + <value>wxgui_constellationsink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>"Constellation: "+str(const)</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>frame_decim</key> + <value>15</value> + </param> + <param> + <key>marker</key> + <value>set_format_plus</value> + </param> + <param> + <key>grid_pos</key> + <value>2, 0, 1, 1</value> + </param> + <param> + <key>_coordinate</key> + <value>(907, 334)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noise</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(235, 379)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_chunks_to_symbols_xx</key> + <param> + <key>id</key> + <value>gr_chunks_to_symbols_xx</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>in_type</key> + <value>byte</value> + </param> + <param> + <key>out_type</key> + <value>complex</value> + </param> + <param> + <key>symbol_table</key> + <value>const</value> + </param> + <param> + <key>dimension</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(360, 237)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_numbersink2</key> + <param> + <key>id</key> + <value>wxgui_numbersink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>BER</value> + </param> + <param> + <key>units</key> + <value>%</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>base_value</key> + <value>0.0</value> + </param> + <param> + <key>min_value</key> + <value>0.0</value> + </param> + <param> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>100</value> + </param> + <param> + <key>decimal_places</key> + <value>4</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>options</key> + <value>none</value> + </param> + <param> + <key>show_gauge</key> + <value>False</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 0, 1, 1</value> + </param> + <param> + <key>_coordinate</key> + <value>(1062, 11)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>byte</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(397, 27)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blks2_error_rate</key> + <param> + <key>id</key> + <value>blks2_error_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>"BER"</value> + </param> + <param> + <key>win_size</key> + <value>1000000</value> + </param> + <param> + <key>bits_per_symbol</key> + <value>int(math.log(len(const))/math.log(2))</value> + </param> + <param> + <key>_coordinate</key> + <value>(670, 41)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_constellation_decoder_cb</key> + <param> + <key>id</key> + <value>gr_constellation_decoder_cb</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>sym_position</key> + <value>const</value> + </param> + <param> + <key>sym_value_out</key> + <value>range(len(const))</value> + </param> + <param> + <key>_coordinate</key> + <value>(708, 224)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>random_source_x</key> + <param> + <key>id</key> + <value>random_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>byte</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>len(const)</value> + </param> + <param> + <key>num_samps</key> + <value>1000000</value> + </param> + <param> + <key>repeat</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(15, 244)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>noise</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>.25</value> + </param> + <param> + <key>_coordinate</key> + <value>(18, 386)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>const</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1+1j, 1-1j, -1-1j, -1+1j</value> + </param> + <param> + <key>_coordinate</key> + <value>(16, 461)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>50e3</value> + </param> + <param> + <key>_coordinate</key> + <value>(20, 168)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>import</key> + <param> + <key>id</key> + <value>import</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>import</key> + <value>import math</value> + </param> + <param> + <key>_coordinate</key> + <value>(138, 168)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>blks2_error_rate</source_block_id> + <sink_block_id>wxgui_numbersink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle</source_block_id> + <sink_block_id>blks2_error_rate</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_constellation_decoder_cb</source_block_id> + <sink_block_id>blks2_error_rate</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_add_vxx</source_block_id> + <sink_block_id>gr_constellation_decoder_cb</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_chunks_to_symbols_xx</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_add_vxx</source_block_id> + <sink_block_id>wxgui_constellationsink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>random_source_x</source_block_id> + <sink_block_id>gr_throttle</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>random_source_x</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph>
\ No newline at end of file diff --git a/grc/examples/usrp/Makefile.am b/grc/examples/usrp/Makefile.am new file mode 100644 index 000000000..9ad96c915 --- /dev/null +++ b/grc/examples/usrp/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_examples_prefix)/usrp + +EXTRA_DIST = \ + usrp_two_tone_loopback.grc \ + usrp_wbfm_receive.grc diff --git a/grc/examples/usrp/usrp_two_tone_loopback.grc b/grc/examples/usrp/usrp_two_tone_loopback.grc new file mode 100644 index 000000000..ccbe190ec --- /dev/null +++ b/grc/examples/usrp/usrp_two_tone_loopback.grc @@ -0,0 +1,675 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:27:46 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>top_block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>USRP Loopback - 2 Tone</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>Loopback test with basic rx and basic tx</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>usrp_simple_source_x</key> + <param> + <key>id</key> + <value>usrp_simple_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>number</key> + <value>0</value> + </param> + <param> + <key>subdev_spec</key> + <value>None</value> + </param> + <param> + <key>frequency</key> + <value>tun_freq</value> + </param> + <param> + <key>decimation</key> + <value>200</value> + </param> + <param> + <key>gain</key> + <value>20</value> + </param> + <param> + <key>mux</key> + <value>0x0</value> + </param> + <param> + <key>auto_tr</key> + <value>None</value> + </param> + <param> + <key>rx_ant</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(578, 319)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_fftsink2</key> + <param> + <key>id</key> + <value>wxgui_fftsink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>FFT Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>baseband_freq</key> + <value>0</value> + </param> + <param> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>8</value> + </param> + <param> + <key>ref_level</key> + <value>100</value> + </param> + <param> + <key>fft_size</key> + <value>512*2</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 2, 2, 4</value> + </param> + <param> + <key>_coordinate</key> + <value>(845, 228)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>tone2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Tone 2</value> + </param> + <param> + <key>value</key> + <value>75e3</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>150000</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 4, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(397, 478)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>tone1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Tone 1</value> + </param> + <param> + <key>value</key> + <value>50e3</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>150000</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 2, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(220, 475)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>noise_ampl</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Noise Ampl</value> + </param> + <param> + <key>value</key> + <value>2000</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>5000</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>vertical</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 1, 2, 1</value> + </param> + <param> + <key>_coordinate</key> + <value>(20, 243)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>tone_ampl</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Tone Ampl</value> + </param> + <param> + <key>value</key> + <value>5000</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>5000</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>vertical</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 0, 2, 1</value> + </param> + <param> + <key>_coordinate</key> + <value>(21, 422)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>usrp_simple_sink_x</key> + <param> + <key>id</key> + <value>usrp_simple_sink_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>number</key> + <value>0</value> + </param> + <param> + <key>subdev_spec</key> + <value>None</value> + </param> + <param> + <key>frequency</key> + <value>tun_freq</value> + </param> + <param> + <key>interpolation</key> + <value>400</value> + </param> + <param> + <key>gain</key> + <value>0</value> + </param> + <param> + <key>mux</key> + <value>0x0</value> + </param> + <param> + <key>auto_tr</key> + <value>None</value> + </param> + <param> + <key>tx_enb</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(835, 5)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_float_to_complex</key> + <param> + <key>id</key> + <value>gr_float_to_complex</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(634, 226)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_vxx</key> + <param> + <key>id</key> + <value>gr_add_vxx</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>num_inputs</key> + <value>3</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(528, 78)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>tone1</value> + </param> + <param> + <key>amp</key> + <value>tone_ampl</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(258, 20)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>tone2</value> + </param> + <param> + <key>amp</key> + <value>tone_ampl</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(255, 179)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noise_ampl</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(257, 337)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>64e6/200</value> + </param> + <param> + <key>_coordinate</key> + <value>(9, 166)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>tun_freq</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>int(100e6)</value> + </param> + <param> + <key>_coordinate</key> + <value>(116, 166)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_sig_source_x</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sig_source_x0</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x</source_block_id> + <sink_block_id>gr_add_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>2</sink_key> + </connection> + <connection> + <source_block_id>usrp_simple_source_x</source_block_id> + <sink_block_id>wxgui_fftsink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_float_to_complex</source_block_id> + <sink_block_id>usrp_simple_sink_x</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_vxx</source_block_id> + <sink_block_id>gr_float_to_complex</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_vxx</source_block_id> + <sink_block_id>gr_float_to_complex</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> +</flow_graph>
\ No newline at end of file diff --git a/grc/examples/usrp/usrp_wbfm_receive.grc b/grc/examples/usrp/usrp_wbfm_receive.grc new file mode 100644 index 000000000..7fb621241 --- /dev/null +++ b/grc/examples/usrp/usrp_wbfm_receive.grc @@ -0,0 +1,454 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:27:45 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>top_block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>USRP WBFM Receive</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>WBFM Receive with Basic RX or TV RX</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>usrp_simple_source_x</key> + <param> + <key>id</key> + <value>usrp_simple_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>number</key> + <value>0</value> + </param> + <param> + <key>subdev_spec</key> + <value>None</value> + </param> + <param> + <key>frequency</key> + <value>(freq+fine)*1e6</value> + </param> + <param> + <key>decimation</key> + <value>decim</value> + </param> + <param> + <key>gain</key> + <value>20</value> + </param> + <param> + <key>mux</key> + <value>0x0</value> + </param> + <param> + <key>auto_tr</key> + <value>None</value> + </param> + <param> + <key>rx_ant</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(277, 29)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>fine</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Fine Freq</value> + </param> + <param> + <key>value</key> + <value>0</value> + </param> + <param> + <key>min</key> + <value>-.1</value> + </param> + <param> + <key>max</key> + <value>.1</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 2, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(275, 246)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blks2_wfm_rcv</key> + <param> + <key>id</key> + <value>blks2_wfm_rcv</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>quad_rate</key> + <value>64e6/decim</value> + </param> + <param> + <key>audio_decimation</key> + <value>10</value> + </param> + <param> + <key>_coordinate</key> + <value>(510, 37)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>audio_sink</key> + <param> + <key>id</key> + <value>audio_sink</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>samp_rate</key> + <value>32000</value> + </param> + <param> + <key>device_name</key> + <value/> + </param> + <param> + <key>ok_to_block</key> + <value>True</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(703, 241)</value> + </param> + <param> + <key>_rotation</key> + <value>180</value> + </param> + </block> + <block> + <key>gr_multiply_const_vxx</key> + <param> + <key>id</key> + <value>gr_multiply_const_vxx</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>const</key> + <value>volume</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(764, 55)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_fftsink2</key> + <param> + <key>id</key> + <value>wxgui_fftsink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>FFT Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>64e6/decim</value> + </param> + <param> + <key>baseband_freq</key> + <value>0</value> + </param> + <param> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>8</value> + </param> + <param> + <key>ref_level</key> + <value>50</value> + </param> + <param> + <key>fft_size</key> + <value>512</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>grid_pos</key> + <value>2, 0, 2, 4</value> + </param> + <param> + <key>_coordinate</key> + <value>(512, 191)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>volume</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Volume</value> + </param> + <param> + <key>value</key> + <value>1</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>10</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 1, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(991, 40)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>freq</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Frequency</value> + </param> + <param> + <key>value</key> + <value>100</value> + </param> + <param> + <key>min</key> + <value>87.5</value> + </param> + <param> + <key>max</key> + <value>108.0</value> + </param> + <param> + <key>num_steps</key> + <value>1000</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(104, 243)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>decim</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>200</value> + </param> + <param> + <key>_coordinate</key> + <value>(14, 173)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>usrp_simple_source_x</source_block_id> + <sink_block_id>blks2_wfm_rcv</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>usrp_simple_source_x</source_block_id> + <sink_block_id>wxgui_fftsink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blks2_wfm_rcv</source_block_id> + <sink_block_id>gr_multiply_const_vxx</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_const_vxx</source_block_id> + <sink_block_id>audio_sink</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph>
\ No newline at end of file diff --git a/grc/examples/xmlrpc/Makefile.am b/grc/examples/xmlrpc/Makefile.am new file mode 100644 index 000000000..68ecbdd9b --- /dev/null +++ b/grc/examples/xmlrpc/Makefile.am @@ -0,0 +1,30 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +datadir = $(grc_examples_prefix)/xmlrpc + +EXTRA_DIST = \ + readme.txt \ + xmlrpc_client.grc \ + xmlrpc_client_script.py\ + xmlrpc_server.grc diff --git a/grc/examples/xmlrpc/readme.txt b/grc/examples/xmlrpc/readme.txt new file mode 100644 index 000000000..c1f87c1cb --- /dev/null +++ b/grc/examples/xmlrpc/readme.txt @@ -0,0 +1,18 @@ +################################################## +# XMLRPC example +################################################## + +XMLRPC allows software to make remote function calls over http. +In the case of GRC, one can use XMLRPC to modify variables in a running flow graph. +See http://www.xmlrpc.com/ + +--- Server Example --- +Place an "XMLRPC Server" block inside of any flow graph. +The server will provide set functions for every variable in the flow graph. +If a variable is called "freq", the server will provide a function set_freq(new_freq). +Run the server example and experiment with the example client script. + +-- Client Example -- +The "XMLRPC Client" block will give a variable control over one remove function. +In the example client, there is one client block and gui control per variable. +This technique can be used to remotely control a flow graph, perhaps running on a non-gui machine. diff --git a/grc/examples/xmlrpc/xmlrpc_client.grc b/grc/examples/xmlrpc/xmlrpc_client.grc new file mode 100644 index 000000000..3bb4e7ed3 --- /dev/null +++ b/grc/examples/xmlrpc/xmlrpc_client.grc @@ -0,0 +1,312 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:27:44 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>client_block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>XMLRPC Client</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>example flow graph</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>xmlrpc_client</key> + <param> + <key>id</key> + <value>xmlrpc_client0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>addr</key> + <value>localhost</value> + </param> + <param> + <key>port</key> + <value>1234</value> + </param> + <param> + <key>callback</key> + <value>set_ampl</value> + </param> + <param> + <key>variable</key> + <value>ampl</value> + </param> + <param> + <key>_coordinate</key> + <value>(409, 35)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>xmlrpc_client</key> + <param> + <key>id</key> + <value>xmlrpc_client</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>addr</key> + <value>localhost</value> + </param> + <param> + <key>port</key> + <value>1234</value> + </param> + <param> + <key>callback</key> + <value>set_freq</value> + </param> + <param> + <key>variable</key> + <value>freq</value> + </param> + <param> + <key>_coordinate</key> + <value>(222, 34)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>freq</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Frequency (Hz)</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>5000</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(207, 162)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>ampl</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Amplitude</value> + </param> + <param> + <key>value</key> + <value>1</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>2</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>slider_type</key> + <value>horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>1, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(397, 167)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_chooser</key> + <param> + <key>id</key> + <value>offset</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>Offset</value> + </param> + <param> + <key>value_index</key> + <value>1</value> + </param> + <param> + <key>choices</key> + <value>[-1, 0, 1]</value> + </param> + <param> + <key>labels</key> + <value>["neg", "zero", "pos"]</value> + </param> + <param> + <key>chooser_type</key> + <value>radio_buttons_horizontal</value> + </param> + <param> + <key>grid_pos</key> + <value>2, 0, 1, 2</value> + </param> + <param> + <key>_coordinate</key> + <value>(596, 177)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>xmlrpc_client</key> + <param> + <key>id</key> + <value>xmlrpc_client1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>addr</key> + <value>localhost</value> + </param> + <param> + <key>port</key> + <value>1234</value> + </param> + <param> + <key>callback</key> + <value>set_offset</value> + </param> + <param> + <key>variable</key> + <value>offset*ampl</value> + </param> + <param> + <key>_coordinate</key> + <value>(608, 39)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(13, 172)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> +</flow_graph>
\ No newline at end of file diff --git a/grc/examples/xmlrpc/xmlrpc_client_script.py b/grc/examples/xmlrpc/xmlrpc_client_script.py new file mode 100644 index 000000000..956fa07fb --- /dev/null +++ b/grc/examples/xmlrpc/xmlrpc_client_script.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +import time +import random +import xmlrpclib + +#create server object +s = xmlrpclib.Server("http://localhost:1234") + +#randomly change parameters of the sinusoid +for i in range(10): + #generate random values + new_freq = random.uniform(0, 5000) + new_ampl = random.uniform(0, 2) + new_offset = random.uniform(-1, 1) + #set new values + time.sleep(1) + s.set_freq(new_freq) + time.sleep(1) + s.set_ampl(new_ampl) + time.sleep(1) + s.set_offset(new_offset) + diff --git a/grc/examples/xmlrpc/xmlrpc_server.grc b/grc/examples/xmlrpc/xmlrpc_server.grc new file mode 100644 index 000000000..dc539ef1b --- /dev/null +++ b/grc/examples/xmlrpc/xmlrpc_server.grc @@ -0,0 +1,384 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Jul 24 14:27:42 2008</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>server_block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>XMLRPC Server</value> + </param> + <param> + <key>author</key> + <value>Example</value> + </param> + <param> + <key>description</key> + <value>example flow graph</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sig_source_x</key> + <param> + <key>id</key> + <value>gr_sig_source_x</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>gr.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>freq</value> + </param> + <param> + <key>amp</key> + <value>ampl</value> + </param> + <param> + <key>offset</key> + <value>offset</value> + </param> + <param> + <key>_coordinate</key> + <value>(162, 200)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>offset</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(12, 390)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>xmlrpc_server</key> + <param> + <key>id</key> + <value>xmlrpc_server</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>addr</key> + <value>localhost</value> + </param> + <param> + <key>port</key> + <value>1234</value> + </param> + <param> + <key>_coordinate</key> + <value>(395, 240)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(386, 93)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>frame_decim</key> + <value>15</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>.001</value> + </param> + <param> + <key>marker</key> + <value>set_format_line</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>grid_pos</key> + <value>0, 0, 2, 4</value> + </param> + <param> + <key>_coordinate</key> + <value>(623, 28)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_fftsink2</key> + <param> + <key>id</key> + <value>wxgui_fftsink2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>FFT Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>baseband_freq</key> + <value>0</value> + </param> + <param> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>8</value> + </param> + <param> + <key>ref_level</key> + <value>50</value> + </param> + <param> + <key>fft_size</key> + <value>512</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>grid_pos</key> + <value>2, 0, 2, 4</value> + </param> + <param> + <key>_coordinate</key> + <value>(630, 233)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(11, 160)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>freq</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(11, 237)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>ampl</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(13, 315)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>gr_sig_source_x</source_block_id> + <sink_block_id>gr_throttle</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle</source_block_id> + <sink_block_id>wxgui_scopesink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle</source_block_id> + <sink_block_id>wxgui_fftsink2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph>
\ No newline at end of file diff --git a/grc/scripts/Makefile.am b/grc/scripts/Makefile.am new file mode 100644 index 000000000..be4ae1b8d --- /dev/null +++ b/grc/scripts/Makefile.am @@ -0,0 +1,26 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = $(bin_SCRIPTS) + +bin_SCRIPTS = grc usrp_diagnostics diff --git a/grc/scripts/grc b/grc/scripts/grc new file mode 100755 index 000000000..44d07a7ee --- /dev/null +++ b/grc/scripts/grc @@ -0,0 +1,43 @@ +#!/usr/bin/env python +""" +Copyright 2008 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 +""" +##@package Editor +#Execute the flow graph editor GUI. This file must be called by the python interpreter. +#@author Josh Blum + +import grc +from grc.Constants import VERSION,FLOW_GRAPH_FILE_EXTENSION +from optparse import OptionParser + +if __name__ == "__main__": + usage = 'usage: %%prog [options] [optional_flow_graphs%s]'%FLOW_GRAPH_FILE_EXTENSION + version = """ +GNU Radio Companion %s + +This program is part of GNU Radio +GRC comes with ABSOLUTELY NO WARRANTY. +This is free software, +and you are welcome to redistribute it. +"""%VERSION + parser = OptionParser(usage=usage, version=version) + (options, args) = parser.parse_args() + from grc_gnuradio.Platform import Platform + from grc.ActionHandler import ActionHandler + ActionHandler(args, Platform()) + diff --git a/grc/scripts/usrp_diagnostics b/grc/scripts/usrp_diagnostics new file mode 100755 index 000000000..a7d9d6f5d --- /dev/null +++ b/grc/scripts/usrp_diagnostics @@ -0,0 +1,121 @@ +#!/usr/bin/env python +""" +Copyright 2008 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 +""" +##@package Graphics.USRPDiagnostics +#A dialog for querying USRP subdevices. USRP interfacing methods encapsulated here. +#@author Josh Blum + +from gnuradio import usrp +import os + +import pygtk +pygtk.require('2.0') +import gtk + +from grc.gui.Dialogs import TextDisplay + +from grc_gnuradio.Platform import Platform +platform = Platform(block_paths_internal_only=['usrp_diagnostics.xml']) + +from grc.gui.elements.Platform import Platform +platform = Platform(platform) + +flow_graph = platform.get_new_flow_graph() +block = flow_graph.get_new_block('usrp_diagnostics') + +##all params +usrp_number_param = block.get_param('usrp_number') +usrp_type_param = block.get_param('usrp_type') +side_subdev_param = block.get_param('side_subdev') + +class USRPDiagnosticsWindow(gtk.Window): + """ + The main window for USRP Dignostics. + """ + + def delete_event(self, widget, event, data=None): return False + + def destroy(self, widget, data=None): gtk.main_quit() + + def __init__(self): + """ + USRPDiagnosticsWindow contructor. + Create a new gtk Dialog with a close button, USRP input paramaters, and output labels. + """ + gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) + #quit signals + self.connect("delete_event", self.delete_event) + self.connect("destroy", self.destroy) + #set the title + self.set_title('USRP Diagnostics') + #create decorative frame + frame = gtk.Frame() + self.add(frame) + #create vbox for storage + vbox = gtk.VBox() + frame.add(vbox) + vbox.pack_start(usrp_number_param.get_input_object(), False) + vbox.pack_start(usrp_type_param.get_input_object(), False) + vbox.pack_start(side_subdev_param.get_input_object(), False) + self.diagnose_button = gtk.Button('Query') + self.diagnose_button.connect('clicked', self._diagnose_usrp) + 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...') + vbox.pack_start(self.query_buffer) + self.show_all() + + def _diagnose_usrp(self, widget=None): + """Query the USRP device and copy the results into the query text box.""" + type = usrp_type_param.evaluate() + 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(usrp_number_param.evaluate()) + subdev_spec = eval(side_subdev_param.evaluate()) + 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)) + +#enter the mainloop +gtk.gdk.threads_init() +gtk.gdk.threads_enter() +USRPDiagnosticsWindow() +gtk.main() +gtk.gdk.threads_leave() diff --git a/grc/src/Makefile.am b/grc/src/Makefile.am new file mode 100644 index 000000000..01c35d58b --- /dev/null +++ b/grc/src/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = grc grc_gnuradio diff --git a/grc/src/grc/ActionHandler.py b/grc/src/grc/ActionHandler.py new file mode 100644 index 000000000..491a0de6c --- /dev/null +++ b/grc/src/grc/ActionHandler.py @@ -0,0 +1,442 @@ +""" +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 +""" +##@package ActionHandler +#ActionHandler builds the interface and handles most of the user inputs. +#@author Josh Blum + +import os +import signal +from Constants import * +from Actions import * +import pygtk +pygtk.require('2.0') +import gtk +import gui +import Preferences +from threading import Thread +import Messages +import ParseXML +import random +from grc.gui.elements.Platform import Platform + +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, platform): + """! + 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 + @param platform platform module + """ + self.clipboard = None + platform = Platform(platform) + 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) + #setup the main window + self.main_window = gui.MainWindow(self.handle_states, platform) + self.main_window.connect('delete_event', self._quit) + self.main_window.connect('key_press_event', self._handle_key_press) + self.get_page = self.main_window.get_page + self.get_flow_graph = self.main_window.get_flow_graph + self.get_focus_flag = self.main_window.drawing_area.get_focus_flag + #setup the messages + Messages.register_messenger(self.main_window.add_report_line) + Messages.send_init() + #initialize + self.init_file_paths = file_paths + self.handle_states(APPLICATION_INITIALIZE) + #enter the mainloop + gtk.gdk.threads_init() + gtk.main() + + 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) + ctrl = event.state & gtk.gdk.CONTROL_MASK + alt = event.state & gtk.gdk.MOD1_MASK + shift = event.state & gtk.gdk.SHIFT_MASK + #################### save/open/new/close ############################### + if ctrl and keyname == 's': + self.handle_states(FLOW_GRAPH_SAVE) + elif ctrl and keyname == 'o': + self.handle_states(FLOW_GRAPH_OPEN) + elif ctrl and keyname == 'n': + self.handle_states(FLOW_GRAPH_NEW) + elif ctrl and keyname == 'q': + self.handle_states(FLOW_GRAPH_CLOSE) + #################### Cut/Copy/Paste ############################### + elif self.get_focus_flag() and ctrl and keyname == 'x': #mouse focus + self.handle_states(BLOCK_CUT) + elif self.get_focus_flag() and ctrl and keyname == 'c': #mouse focus + self.handle_states(BLOCK_COPY) + elif self.get_focus_flag() and ctrl and keyname == 'v': #mouse focus + self.handle_states(BLOCK_PASTE) + #################### Undo/Redo ############################### + elif ctrl and keyname == 'z': + self.handle_states(FLOW_GRAPH_UNDO) + elif ctrl and keyname == 'y': + self.handle_states(FLOW_GRAPH_REDO) + #################### Delete ############################### + elif self.get_focus_flag() and keyname == 'Delete': #mouse focus + self.handle_states(ELEMENT_DELETE) + #################### Params ############################### + elif self.get_focus_flag() and keyname == 'Return': #mouse focus + self.handle_states(BLOCK_PARAM_MODIFY) + #################### Rotate ############################### + elif self.get_focus_flag() and keyname == 'Right': #mouse focus + self.handle_states(BLOCK_ROTATE_RIGHT) + elif self.get_focus_flag() and keyname == 'Left': #mouse focus + self.handle_states(BLOCK_ROTATE_LEFT) + #################### Enable/Disable ############################### + elif self.get_focus_flag() and keyname == 'e': #mouse focus + self.handle_states(BLOCK_ENABLE) + elif self.get_focus_flag() and keyname == 'd': #mouse focus + self.handle_states(BLOCK_DISABLE) + #################### Data Type ############################### + elif self.get_focus_flag() and keyname == 'Down': #mouse focus + self.handle_states(BLOCK_INC_TYPE) + elif self.get_focus_flag() and keyname == 'Up': #mouse focus + self.handle_states(BLOCK_DEC_TYPE) + #################### Port Controllers ############################### + elif self.get_focus_flag() and keyname in ('equal','plus', 'KP_Add'): #mouse focus + self.handle_states(PORT_CONTROLLER_INC) + elif self.get_focus_flag() and keyname in ('minus', 'KP_Subtract'): #mouse focus + self.handle_states(PORT_CONTROLLER_DEC) + #################### Gen/Exec/Stop/Print ############################### + elif keyname == 'F5': + self.handle_states(FLOW_GRAPH_GEN) + elif keyname == 'F6': + self.handle_states(FLOW_GRAPH_EXEC) + elif keyname == 'F7': + self.handle_states(FLOW_GRAPH_KILL) + 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_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 gui 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 + """ + #print state + ############################################################################################## + # Initalize/Quit + ############################################################################################## + if state == APPLICATION_INITIALIZE: + for action in ACTIONS_LIST: action.set_sensitive(False) #set all actions disabled + # enable a select few actions + for action in ( + APPLICATION_QUIT, FLOW_GRAPH_NEW, FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS, FLOW_GRAPH_CLOSE, + ABOUT_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY, + 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: + if file_path: self.main_window.new_page(file_path) #load pages from file paths + if Preferences.file_open() in self.init_file_paths: self.main_window.new_page(Preferences.file_open(), show=True) + 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(): + gtk.main_quit() + exit(0) + ############################################################################################## + # Selections + ############################################################################################## + elif state == ELEMENT_SELECT: + self.get_flow_graph().update() + elif state == NOTHING_SELECT: + self.get_flow_graph().unselect() + self.get_flow_graph().update() + ############################################################################################## + # Enable/Disable + ############################################################################################## + elif state == BLOCK_ENABLE: + if self.get_flow_graph().enable_selected(True): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == BLOCK_DISABLE: + if self.get_flow_graph().enable_selected(False): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + ############################################################################################## + # Cut/Copy/Paste + ############################################################################################## + elif state == BLOCK_CUT: + self.handle_states(BLOCK_COPY) + self.handle_states(ELEMENT_DELETE) + elif state == BLOCK_COPY: + self.clipboard = self.get_flow_graph().copy_to_clipboard() + elif state == BLOCK_PASTE: + if self.clipboard: + self.get_flow_graph().paste_from_clipboard(self.clipboard) + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + ############################################################################################## + # Move/Rotate/Delete/Create + ############################################################################################## + elif state == BLOCK_MOVE: + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == BLOCK_ROTATE_LEFT: + if self.get_flow_graph().rotate_selected(DIR_LEFT): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == BLOCK_ROTATE_RIGHT: + if self.get_flow_graph().rotate_selected(DIR_RIGHT): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == ELEMENT_DELETE: + if self.get_flow_graph().remove_selected(): + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.handle_states(NOTHING_SELECT) + self.get_page().set_saved(False) + elif state == ELEMENT_CREATE: + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.handle_states(NOTHING_SELECT) + self.get_page().set_saved(False) + elif state == BLOCK_INC_TYPE: + if self.get_flow_graph().type_controller_modify_selected(1): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == BLOCK_DEC_TYPE: + if self.get_flow_graph().type_controller_modify_selected(-1): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == PORT_CONTROLLER_INC: + if self.get_flow_graph().port_controller_modify_selected(1): + self.get_flow_graph().update() + self.get_flow_graph().update() #2 times + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif state == PORT_CONTROLLER_DEC: + if self.get_flow_graph().port_controller_modify_selected(-1): + self.get_flow_graph().update() + self.get_flow_graph().update() #2 times + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + ############################################################################################## + # Window stuff + ############################################################################################## + elif state == PREFS_WINDOW_DISPLAY: + gui.PreferencesDialog() + self.get_flow_graph().update() + elif state == ABOUT_WINDOW_DISPLAY: + gui.AboutDialog() + elif state == HOTKEYS_WINDOW_DISPLAY: + gui.HotKeysDialog() + ############################################################################################## + # Param Modifications + ############################################################################################## + elif state == BLOCK_PARAM_MODIFY: + if self.get_flow_graph().param_modify_selected(): + self.get_flow_graph().update() + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + ############################################################################################## + # Undo/Redo + ############################################################################################## + elif state == FLOW_GRAPH_UNDO: + n = self.get_page().get_state_cache().get_prev_state() + if n: + self.get_flow_graph().unselect() + self.get_flow_graph().import_data(n) + self.get_flow_graph().update() + self.get_page().set_saved(False) + elif state == FLOW_GRAPH_REDO: + n = self.get_page().get_state_cache().get_next_state() + if n: + self.get_flow_graph().unselect() + self.get_flow_graph().import_data(n) + self.get_flow_graph().update() + 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_paths = gui.OpenFlowGraphFileDialog(self.get_page().get_file_path()).run() + if file_paths: #open a new page for each file, show only the first + for i,file_path in enumerate(file_paths): + self.main_window.new_page(file_path, show=(i==0)) + 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(self.get_flow_graph().export_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 = gui.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 = gui.SaveImageFileDialog(self.get_page().get_file_path()).run() + if file_path != None: + pixmap = self.get_flow_graph().get_drawing_area().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:]) + ############################################################################################## + # Gen/Exec/Stop + ############################################################################################## + elif state == FLOW_GRAPH_GEN: + if not self.get_page().get_pid(): + 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(): + generator = self.get_page().get_generator() + try: + Messages.send_start_gen(generator.get_file_path()) + generator.write() + except Exception,e: Messages.send_fail_gen(e) + else: self.generator = None + elif state == FLOW_GRAPH_EXEC: + if not self.get_page().get_pid(): + self.handle_states(FLOW_GRAPH_GEN) + if self.get_page().get_saved() and self.get_page().get_file_path(): + ExecFlowGraphThread(self) + elif state == FLOW_GRAPH_KILL: + if self.get_page().get_pid(): + try: os.kill(self.get_page().get_pid(), signal.SIGKILL) + except: print "could not kill pid: %s"%self.get_page().get_pid() + elif state == '': #pass and run the global actions + pass + else: print '!!! State "%s" not handled !!!'%state + ############################################################################################## + # Global Actions for all States + ############################################################################################## + #update general buttons + get_action_from_name(ELEMENT_DELETE).set_sensitive(bool(self.get_flow_graph().get_selected_elements())) + get_action_from_name(BLOCK_PARAM_MODIFY).set_sensitive(bool(self.get_flow_graph().get_selected_block())) + get_action_from_name(BLOCK_ROTATE_RIGHT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + get_action_from_name(BLOCK_ROTATE_LEFT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + #update cut/copy/paste + get_action_from_name(BLOCK_CUT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + get_action_from_name(BLOCK_COPY).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + get_action_from_name(BLOCK_PASTE).set_sensitive(bool(self.clipboard)) + #update enable/disable + get_action_from_name(BLOCK_ENABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + get_action_from_name(BLOCK_DISABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks())) + #set the exec and stop buttons + self.update_exec_stop() + #saved status + get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(not self.get_page().get_saved()) + self.main_window.update() + #draw the flow graph + self.get_flow_graph().draw() + + def update_exec_stop(self): + """ + Update the exec and stop buttons. + Lock and unlock the mutex for race conditions with exec flow graph threads. + """ + sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_pid() + get_action_from_name(FLOW_GRAPH_GEN).set_sensitive(sensitive) + get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(sensitive) + get_action_from_name(FLOW_GRAPH_KILL).set_sensitive(self.get_page().get_pid() != None) + +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.update_exec_stop = action_handler.update_exec_stop + self.flow_graph = action_handler.get_flow_graph() + #store page and dont use main window calls in run + self.page = action_handler.get_page() + Messages.send_start_exec(self.page.get_generator().get_file_path()) + #get the popen + try: + self.p = self.page.get_generator().get_popen() + self.page.set_pid(self.p.pid) + #update + self.update_exec_stop() + self.start() + except Exception, e: + Messages.send_verbose_exec(str(e)) + Messages.send_end_exec() + + def run(self): + """Wait on the flow graph.""" + #handle completion + r = "\n" + while(r): + gtk.gdk.threads_enter() + Messages.send_verbose_exec(r) + gtk.gdk.threads_leave() + r = os.read(self.p.stdout.fileno(), 1024) + gtk.gdk.threads_enter() + Messages.send_end_exec() + self.page.set_pid(None) + self.update_exec_stop() + gtk.gdk.threads_leave() + diff --git a/grc/src/grc/Actions.py b/grc/src/grc/Actions.py new file mode 100644 index 000000000..bd8d950ab --- /dev/null +++ b/grc/src/grc/Actions.py @@ -0,0 +1,108 @@ +""" +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 +""" +##@package Actions +#Global actions for gui elements to communicate state changes to the action handler. +#Use gtk.stock_list_ids() to get a list of possible stock ids (for toolbar/menu icons) +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk + +###################################################################################################### +# States +###################################################################################################### +APPLICATION_INITIALIZE = 'app init' +APPLICATION_QUIT = 'app quit' +PARAM_MODIFY = 'param modify' +BLOCK_MOVE = 'block move' +BLOCK_ROTATE_LEFT = 'block rotate left' +BLOCK_ROTATE_RIGHT = 'block rotate right' +BLOCK_PARAM_MODIFY = 'block param modify' +BLOCK_INC_TYPE = 'block increment type' +BLOCK_DEC_TYPE = 'block decrement type' +BLOCK_ENABLE = 'block enable' +BLOCK_DISABLE = 'block disable' +BLOCK_CUT = 'block cut' +BLOCK_COPY = 'block copy' +BLOCK_PASTE = 'block paste' +PORT_CONTROLLER_INC = 'port controller increment' +PORT_CONTROLLER_DEC = 'port controller decrement' +ELEMENT_CREATE = 'element create' +ELEMENT_DELETE = 'element delete' +ELEMENT_SELECT = 'element select' +NOTHING_SELECT = 'nothing select' +FLOW_GRAPH_OPEN = 'flow graph open' +FLOW_GRAPH_UNDO = 'flow graph undo' +FLOW_GRAPH_REDO = 'flow graph redo' +FLOW_GRAPH_SAVE = 'flow graph save' +FLOW_GRAPH_SAVE_AS = 'flow graph save as' +FLOW_GRAPH_CLOSE = 'flow graph close' +FLOW_GRAPH_NEW = 'flow graph new' +FLOW_GRAPH_GEN = 'flow graph gen' +FLOW_GRAPH_EXEC = 'flow graph exec' +FLOW_GRAPH_KILL = 'flow graph kill' +FLOW_GRAPH_SCREEN_CAPTURE = 'flow graph screen capture' +ABOUT_WINDOW_DISPLAY = 'about window display' +HOTKEYS_WINDOW_DISPLAY = 'hotkeys window display' +PREFS_WINDOW_DISPLAY = 'prefs window display' + +###################################################################################################### +# Actions +###################################################################################################### +ACTIONS_LIST = ( + gtk.Action(FLOW_GRAPH_NEW, '_New', 'Create a new flow graph', 'gtk-new'), + gtk.Action(FLOW_GRAPH_OPEN, '_Open', 'Open an existing flow graph', 'gtk-open'), + gtk.Action(FLOW_GRAPH_SAVE, '_Save', 'Save the current flow graph', 'gtk-save'), + gtk.Action(FLOW_GRAPH_SAVE_AS, 'Save _As', 'Save the current flow graph as...', 'gtk-save-as'), + gtk.Action(FLOW_GRAPH_CLOSE, '_Close', 'Close the current flow graph', 'gtk-close'), + gtk.Action(APPLICATION_QUIT, '_Quit', 'Quit program', 'gtk-quit'), + gtk.Action(FLOW_GRAPH_UNDO, '_Undo', 'Undo a change to the flow graph', 'gtk-undo'), + gtk.Action(FLOW_GRAPH_REDO, '_Redo', 'Redo a change to the flow graph', 'gtk-redo'), + gtk.Action(ELEMENT_DELETE, '_Delete', 'Delete the selected blocks', 'gtk-delete'), + gtk.Action(BLOCK_ROTATE_LEFT, 'Rotate _Left', 'Rotate the selected blocks 90 degrees', 'gtk-go-back'), + gtk.Action(BLOCK_ROTATE_RIGHT, 'Rotate _Right', 'Rotate the selected blocks -90 degrees', 'gtk-go-forward'), + gtk.Action(BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for the selected block', 'gtk-properties'), + gtk.Action(BLOCK_ENABLE, 'E_nable', 'Enable the selected blocks', 'gtk-connect'), + gtk.Action(BLOCK_DISABLE, 'D_isable', 'Disable the selected blocks', 'gtk-disconnect'), + gtk.Action(BLOCK_CUT, 'Cu_t', 'Cut', 'gtk-cut'), + gtk.Action(BLOCK_COPY, '_Copy', 'Copy', 'gtk-copy'), + gtk.Action(BLOCK_PASTE, '_Paste', 'Paste', 'gtk-paste'), + gtk.Action(PREFS_WINDOW_DISPLAY, '_Preferences', 'Configure Preferences', 'gtk-preferences'), + gtk.Action(ABOUT_WINDOW_DISPLAY, '_About', 'About this program', 'gtk-about'), + gtk.Action(HOTKEYS_WINDOW_DISPLAY, '_HotKeys', 'Hot Keys', 'gtk-info'), + gtk.Action(FLOW_GRAPH_GEN, '_Generate', 'Generate the flow graph', 'gtk-convert'), + gtk.Action(FLOW_GRAPH_EXEC, '_Execute', 'Execute the flow graph', 'gtk-execute'), + gtk.Action(FLOW_GRAPH_KILL, '_Kill', 'Kill the flow graph', 'gtk-stop'), + gtk.Action(FLOW_GRAPH_SCREEN_CAPTURE, 'S_creen Capture', 'Create a screen capture of the flow graph', 'gtk-print'), +) + +ACTIONS_DICT = dict((action.get_name(), action) for action in ACTIONS_LIST) + +def get_action_from_name(action_name): + """! + Retrieve the action from the action list. + Search the list and find an action with said name. + @param action_name the action name(string) + @throw KeyError bad action name + @return a gtk action object + """ + if ACTIONS_DICT.has_key(action_name): return ACTIONS_DICT[action_name] + raise KeyError('Action Name: "%s" does not exist'%action_name) + diff --git a/grc/src/grc/Constants.py.in b/grc/src/grc/Constants.py.in new file mode 100644 index 000000000..a16715080 --- /dev/null +++ b/grc/src/grc/Constants.py.in @@ -0,0 +1,154 @@ +""" +Copyright 2008 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 +""" +##@package grc.Constants +#Global constants +#@author Josh Blum + +import os + +###################################################################################################### +## Global Titles +###################################################################################################### + +##The current version of this code +VERSION = '@VERSION@' + +##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" + +###################################################################################################### +## Signal block connector lengths +###################################################################################################### + +##The length that a connection must extend from the port until the length depends on the index of the port. +CONNECTOR_EXTENSION_INITIAL_LENGTH = 11 + +##The length that a connection must extend from the initial length times the index of the port, after this length, the connection may have a bend. +CONNECTOR_EXTENSION_LENGTH = 11 + +##The length of the connector arrow base in pixels +CONNECTOR_ARROW_BASE = 13 + +##The length of the connector arrow height in pixels +CONNECTOR_ARROW_HEIGHT = 17 + +###################################################################################################### +## Signal block rotations +###################################################################################################### + +##List of possible angles (in degrees) that a block 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 +MIN_WINDOW_WIDTH = 600 +MIN_WINDOW_HEIGHT = 400 + +##dialog constraints +MIN_DIALOG_WIDTH = 500 +MIN_DIALOG_HEIGHT = 500 + +##static height of reports window +REPORTS_WINDOW_HEIGHT = 100 + +##static width of block selection window +BLOCK_SELECTION_WINDOW_WIDTH = 200 + +###################################################################################################### +## Constraints on displayable labels and ports +###################################################################################################### + +LABEL_SEPARATION = 3 +LABEL_PADDING_WIDTH = 9 +LABEL_PADDING_HEIGHT = 9 + +PORT_SEPARATION = 17 +PORT_HEIGHT = 15 +PORT_WIDTH = 25 +PORT_BORDER_SEPARATION = 9 +MAX_NUM_PORTS = 7 + +PARAM_LABEL_FONT = 'Sans 9.5' +PARAM_FONT = 'Sans 7.5' +BLOCK_FONT = 'Sans 8' +PORT_FONT = 'Sans 7.5' + +###################################################################################################### +## 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 = 50 + +##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 seconds must pass between motion events before a redraw? +MOTION_DETECT_REDRAWING_SENSITIVITY = .02 + +##How close the mouse click can be to a connection and register a connection select. +CONNECTION_SELECT_SENSITIVITY = 5 + +###################################################################################################### +# 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 external data files. +DATA_DIR = '@datadir@' + +##DTD validator for saved flow graphs. +FLOW_GRAPH_DTD = os.path.join(DATA_DIR, 'flow_graph.dtd') + +##The default file extension for flow graphs. +FLOW_GRAPH_FILE_EXTENSION = '.grc' + +##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.getcwd() + +##The default icon for the gtk windows. +PY_GTK_ICON = os.path.join(DATA_DIR, 'grc-icon-256.png') + +##The users home directory. +HOME_DIR = os.path.expanduser('~') + diff --git a/grc/src/grc/Makefile.am b/grc/src/grc/Makefile.am new file mode 100644 index 000000000..8872c7479 --- /dev/null +++ b/grc/src/grc/Makefile.am @@ -0,0 +1,50 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = elements gui + +ourpythondir = $(pythondir)/grc + +ourpython_PYTHON = \ + __init__.py \ + Constants.py \ + converter.py \ + ActionHandler.py \ + Actions.py \ + Messages.py \ + ParseXML.py \ + Preferences.py \ + StateCache.py \ + Utils.py + +BUILT_SOURCES = Constants.py + +Constants.py: Makefile $(srcdir)/Constants.py.in + sed \ + -e 's|@VERSION[@]|@VERSION@|g' \ + -e 's|@datadir[@]|$(grc_data_dir)|g' \ + $(srcdir)/Constants.py.in > $@ + +EXTRA_DIST = Constants.py.in + +MOSTLYCLEANFILES = $(BUILT_SOURCES) diff --git a/grc/src/grc/Messages.py b/grc/src/grc/Messages.py new file mode 100644 index 000000000..5d1218c68 --- /dev/null +++ b/grc/src/grc/Messages.py @@ -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 +""" +##@package Messages +#Handle all of the system messages and error reports. +#@author Josh Blum + +from Constants import VERSION +import traceback +import sys + +## A list of functions that can receive a message. +MESSENGERS_LIST = list() + +def register_messenger(messenger): + """! + Append the given messenger to the list of messengers. + @param messenger a method thats takes a string + """ + MESSENGERS_LIST.append(messenger) + +def send(message): + """! + Give the message to each of the messengers. + @param message a message string + """ + for messenger in MESSENGERS_LIST: messenger(message) + +#register stdout by default +register_messenger(sys.stdout.write) + +########################################################################### +# Special functions for specific program functionalities +########################################################################### +def send_init(): + send("""<<< Welcome to GRC %s >>>\n"""%VERSION) + +def send_page_switch(file_path): + send('\nShowing: "%s"\n'%file_path) + +################# functions for loading flow graphs ######################################## +def send_start_load(file_path): + send('\nLoading: "%s"'%file_path + '\n') + +def send_error_load(error): + send('>>> Error: %s\n'%error) + traceback.print_exc() + +def send_end_load(): + send(">>> Done\n") + +def send_fail_load(error): + send('Parser Error: %s\n'%error) + send(">>> Failue\n") + traceback.print_exc() + +################# functions for generating flow graphs ######################################## +def send_start_gen(file_path): + send('\nGenerating: "%s"'%file_path + '\n') + +def send_fail_gen(error): + send('Generate Error: %s\n'%error) + send(">>> Failue\n") + traceback.print_exc() + +################# functions for executing flow graphs ######################################## +def send_start_exec(file_path): + send('\nExecuting: "%s"'%file_path + '\n') + +def send_verbose_exec(verbose): + send(verbose) + +def send_end_exec(): + send("\n>>> Done\n") + +################# functions for saving flow graphs ######################################## +def send_fail_save(file_path): + send('>>> Error: Cannot save: %s\n'%file_path) + +################# functions for connections ######################################## +def send_fail_connection(): + send('>>> Warning: A connection can only be created between a source and an unconnected sink.\n') + +################# functions for preferences ######################################## +def send_fail_load_preferences(prefs_file_path): + send('>>> Error: Cannot load preferences file: "%s"\n'%prefs_file_path) + +def send_fail_save_preferences(prefs_file_path): + send('>>> Error: Cannot save preferences file: "%s"\n'%prefs_file_path) + diff --git a/grc/src/grc/ParseXML.py b/grc/src/grc/ParseXML.py new file mode 100644 index 000000000..3b43b8666 --- /dev/null +++ b/grc/src/grc/ParseXML.py @@ -0,0 +1,103 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.ParseXML +#Parse xml files to nested data and vice-versa. +#@author Josh Blum + +from lxml import etree +from Utils import odict + +XMLSyntaxError = etree.XMLSyntaxError + +def validate_dtd(xml_file, dtd_file=None): + """! + Validate an xml file against its dtd. + @param xml_file the xml file + @param dtd_file the optional dtd file + @throws Exception validation fails + """ + if dtd_file: + dtd = etree.DTD(dtd_file) + xml = etree.parse(xml_file) + if not dtd.validate(xml.getroot()): + raise XMLSyntaxError, '\n'.join(map(str, dtd.error_log.filter_from_errors())) + else: + parser = etree.XMLParser(dtd_validation=True) + xml = etree.parse(xml_file, parser=parser) + if parser.error_log: + raise XMLSyntaxError, '\n'.join(map(str, parser.error_log.filter_from_errors())) + +def from_file(xml_file): + """! + Create nested data from an xml file using the from xml helper. + @param xml_file the xml file path + @return the nested data + """ + xml = etree.parse(xml_file).getroot() + return _from_file(xml) + +def _from_file(xml): + """! + Recursivly parse the xml tree into nested data format. + @param xml the xml tree + @return the nested data + """ + tag = xml.tag + if not len(xml): + return odict({tag: xml.text or ''}) #store empty tags (text is None) as empty string + nested_data = odict() + for elem in xml: + key, value = _from_file(elem).items()[0] + if nested_data.has_key(key): nested_data[key].append(value) + else: nested_data[key] = [value] + #delistify if the length of values is 1 + for key, values in nested_data.iteritems(): + if len(values) == 1: nested_data[key] = values[0] + return odict({tag: nested_data}) + +def to_file(nested_data, xml_file): + """! + Write an xml file and use the to xml helper method to load it. + @param nested_data the nested data + @param xml_file the xml file path + """ + xml = _to_file(nested_data)[0] + open(xml_file, 'w').write(etree.tostring(xml, xml_declaration=True, pretty_print=True)) + +def _to_file(nested_data): + """! + Recursivly parse the nested data into xml tree format. + @param nested_data the nested data + @return the xml tree filled with child nodes + """ + nodes = list() + for key, values in nested_data.iteritems(): + #listify the values if not a list + if not isinstance(values, (list, set, tuple)): + values = [values] + for value in values: + node = etree.Element(key) + if isinstance(value, (str, unicode)): node.text = value + else: node.extend(_to_file(value)) + nodes.append(node) + return nodes + +if __name__ == '__main__': + """Use the main method to test parse xml's functions.""" + pass diff --git a/grc/src/grc/Preferences.py b/grc/src/grc/Preferences.py new file mode 100644 index 000000000..7bfea9660 --- /dev/null +++ b/grc/src/grc/Preferences.py @@ -0,0 +1,134 @@ +""" +Copyright 2008 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 +""" +##@package grc.Preferences +#Holds global paramerences +#@author Josh Blum + +from Constants import HOME_DIR, FLOW_GRAPH_DTD +import ParseXML +import Messages +import os + +##Access the loaded preferences in this module +_prefs = list() +def _set_prefs(prefs): _prefs.append(prefs) +def _get_prefs(): return _prefs[0] +def load(platform): _Preferences(platform) +def save(): _get_prefs().save() +def get_preferences(): return _get_prefs().get_preferences() + +class _Preferences(object): + + def __init__(self, platform): + #make self available to module + _set_prefs(self) + #get prefs block + self._prefs_block = platform.get_prefs_block() + #prefs file path + self._prefs_file_path = os.path.join(HOME_DIR, self._prefs_block.get_param('prefs_file').get_value()) + #load + try: + ParseXML.validate_dtd(self._prefs_file_path, FLOW_GRAPH_DTD) + n = ParseXML.from_file(self._prefs_file_path) + self._prefs_block.import_data(n['block']) + except: Messages.send_fail_load_preferences(self._prefs_file_path) + ##all params + self.snap_to_grid_param = self._prefs_block.get_param('snap_to_grid') + self.grid_size_param = self._prefs_block.get_param('grid_size') + self.show_grid_param = self._prefs_block.get_param('show_grid') + self.show_reports_param = self._prefs_block.get_param('show_reports') + self.restore_files_param = self._prefs_block.get_param('restore_files') + self.window_size_param = self._prefs_block.get_param('window_size') + self.file_open_param = self._prefs_block.get_param('file_open') + self.files_open_param = self._prefs_block.get_param('files_open') + self.show_params_param = self._prefs_block.get_param('show_params') + self.show_id_param = self._prefs_block.get_param('show_id') + + def save(self): + try: ParseXML.to_file({'block': self._prefs_block.export_data()}, self._prefs_file_path) + except IOError: Messages.send_fail_save_preferences(self._prefs_file_path) + + def get_preferences(self): + ##Preferences: title, notes, params + return [ + ( + 'Grid', + ''' +Show grid will draw a square grid onto the flow graph with grid points separated by grid size pixels. \ +Snap to Grid forces the upper right corner of the signal block to align with a grid point. +''', + [self.snap_to_grid_param, self.grid_size_param, self.show_grid_param], + ), + ( + 'Appearance', + ''' +Show or hide the reports window at the bottom of the main window. +Show or hide all paramater labels in the signal blocks. +Show or hide the ID label in the signal blocks. +''', + [self.show_reports_param, self.show_params_param, self.show_id_param], + ), + ( + 'Misc', + ''' +Restore previously opened files on start-up. +''', + [self.restore_files_param], + ), + ] + +########################################################################### +# Special methods for specific program functionalities +########################################################################### + +def window_size(size=None): + if size: _get_prefs().window_size_param.set_value(size) + else: + try: return eval(_get_prefs().window_size_param.get_value()) + except: return (-1, -1) + +def restore_files(): + return _get_prefs().restore_files_param.get_value() == 'yes' + +def file_open(file=None): + if file is not None: _get_prefs().file_open_param.set_value(file) + else: return _get_prefs().file_open_param.get_value() + +def files_open(files=None): + if files is not None: _get_prefs().files_open_param.set_value('\n'.join(files)) + else: return _get_prefs().files_open_param.get_value().split('\n') + +def show_reports_window(): + return _get_prefs().show_reports_param.get_value() == 'show' + +def get_grid_size(): + return int(_get_prefs().grid_size_param.get_value()) + +def snap_to_grid(): + return _get_prefs().snap_to_grid_param.get_value() == 'on' + +def show_grid(): + return _get_prefs().show_grid_param.get_value() == 'show' + +def show_params(): + return _get_prefs().show_params_param.get_value() == 'show' + +def show_id(): + return _get_prefs().show_id_param.get_value() == 'show' + diff --git a/grc/src/grc/StateCache.py b/grc/src/grc/StateCache.py new file mode 100644 index 000000000..d07fab30e --- /dev/null +++ b/grc/src/grc/StateCache.py @@ -0,0 +1,98 @@ +""" +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 +""" +##@package StateCache +#Stores the flow graph states to drive the undo/redo and save interface. +#@author Josh Blum + +from Actions import FLOW_GRAPH_UNDO, FLOW_GRAPH_REDO, get_action_from_name + +from Constants import STATE_CACHE_SIZE + +class StateCache(object): + """ + The state cache is an interface to a list to record data/states and to revert to previous states. + States are recorded into the list in a circular fassion by using an index for the current state, + and counters for the range where states are stored. + """ + + def __init__(self, initial_state): + """! + StateCache constructor. + @param initial_state the intial state (nested data) + """ + self.states = [None] * STATE_CACHE_SIZE #fill states + self.current_state_index = 0 + self.num_prev_states = 0 + self.num_next_states = 0 + self.states[0] = initial_state + self.update_actions() + + def save_new_state(self, state): + """! + Save a new state. + Place the new state at the next index and add one to the number of previous states. + @param state the new state + """ + self.current_state_index = (self.current_state_index + 1)%STATE_CACHE_SIZE + self.states[self.current_state_index] = state + self.num_prev_states = self.num_prev_states + 1 + if self.num_prev_states == STATE_CACHE_SIZE: self.num_prev_states = STATE_CACHE_SIZE - 1 + self.num_next_states = 0 + self.update_actions() + + def get_current_state(self): + """! + Get the state at the current index. + @return the current state (nested data) + """ + self.update_actions() + return self.states[self.current_state_index] + + def get_prev_state(self): + """! + Get the previous state and decrement the current index. + @return the previous state or None + """ + if self.num_prev_states > 0: + self.current_state_index = (self.current_state_index + STATE_CACHE_SIZE -1)%STATE_CACHE_SIZE + self.num_next_states = self.num_next_states + 1 + self.num_prev_states = self.num_prev_states - 1 + return self.get_current_state() + return None + + def get_next_state(self): + """! + Get the nest state and increment the current index. + @return the next state or None + """ + if self.num_next_states > 0: + self.current_state_index = (self.current_state_index + 1)%STATE_CACHE_SIZE + self.num_next_states = self.num_next_states - 1 + self.num_prev_states = self.num_prev_states + 1 + return self.get_current_state() + return None + + def update_actions(self): + """ + Update the undo and redo actions based on the number of next and prev states. + """ + get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(self.num_next_states != 0) + get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(self.num_prev_states != 0) + + diff --git a/grc/src/grc/Utils.py b/grc/src/grc/Utils.py new file mode 100644 index 000000000..e9c988c5f --- /dev/null +++ b/grc/src/grc/Utils.py @@ -0,0 +1,60 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.Utils +#Utility methods and classes. +#@author Josh Blum + +from UserDict import DictMixin + +class odict(DictMixin): + + def __init__(self, d={}): + self._keys = list(d.keys()) + self._data = dict(d.copy()) + + def __setitem__(self, key, value): + if key not in self._data: + self._keys.append(key) + self._data[key] = value + + def __getitem__(self, key): + return self._data[key] + + def __delitem__(self, key): + del self._data[key] + self._keys.remove(key) + + def keys(self): + return list(self._keys) + + def copy(self): + copy_dict = odict() + copy_dict._data = self._data.copy() + copy_dict._keys = list(self._keys) + return copy_dict + +def exists_or_else(d, key, alt): + if d.has_key(key): return d[key] + else: return alt + +def listify(d, key): + obj = exists_or_else(d, key, []) + if isinstance(obj, list): return obj + return [obj] + diff --git a/grc/src/grc/__init__.py b/grc/src/grc/__init__.py new file mode 100644 index 000000000..e44d7ff56 --- /dev/null +++ b/grc/src/grc/__init__.py @@ -0,0 +1,22 @@ +""" +Copyright 2008 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 +""" +##@package grc +#grc package. +#@author Josh Blum + diff --git a/grc/src/grc/converter.py b/grc/src/grc/converter.py new file mode 100644 index 000000000..7f2553304 --- /dev/null +++ b/grc/src/grc/converter.py @@ -0,0 +1,251 @@ +""" +Copyright 2008 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 +""" +##@package grc.converter +#convert old flow graph file format to new format +#@author Josh Blum + +from grc.Constants import FLOW_GRAPH_DTD +from grc import ParseXML, Utils +from grc.Utils import odict +from lxml import etree +import difflib +import os + +def _make_param(key, value): + """! + Make a paramater dict from the key/value pair. + @param key the key + @param value the value + @return a dictionary object + """ + param = odict() + param['key'] = key + param['value'] = value + return param + +def _get_blocks(blocks, tag): + """! + Get a list of blocks with the tag. + @param blocks the old block list + @param tag the tag name + @retun a list of matching blocks + """ + return filter(lambda b: b['tag'] == tag, blocks) + +def _get_params(block): + """! + Get a list of params. + @param block the old block + @retun a list of params + """ + params = Utils.exists_or_else(block, 'params', {}) or {} + params = Utils.listify(params, 'param') + return params + +def _convert_id(id): + """! + Convert an old id to a new safe id. + Replace spaces with underscores. + Lower case the odl id. + @return the reformatted id + """ + return id.lower().replace(' ', '_') + +def convert(file_path, platform): + """! + Convert the flow graph to the new format. + Make a backup of the old file. + Save a reformated flow graph to the file path. + If this is a new format flow graph, do nothing. + @param file_path the path to the saved flow graph + @param platform the grc gnuradio platform + """ + try: #return if file passes validation + ParseXML.validate_dtd(file_path, FLOW_GRAPH_DTD) + try: + changed = False + #convert instances of gui_coordinate and gui_rotation + xml = etree.parse(file_path) + for find, replace in ( + ('gui_coordinate', '_coordinate'), + ('gui_rotation', '_rotation'), + ): + keys = xml.xpath('/flow_graph/block/param[key="%s"]/key'%find) + for key in keys: + key.text = replace + changed = True + if not changed: return + #backup after successful conversion + os.rename(file_path, file_path+'.bak') + #save new flow graph to file path + xml.write(file_path, xml_declaration=True, pretty_print=True) + except Exception, e: print e + return + except: pass #convert + ############################################################ + # extract window size, variables, blocks, and connections + ############################################################ + old_n = ParseXML.from_file(file_path)['flow_graph'] + try: window_width = min(3*int(old_n['window_width'])/2, 2048) + except: window_width = 2048 + try: window_height = min(3*int(old_n['window_height'])/2, 2048) + except: window_height = 2048 + window_size = '%d, %d'%(window_width, window_height) + variables = Utils.exists_or_else(old_n, 'vars', {}) or {} + variables = Utils.listify(variables, 'var') + blocks = Utils.exists_or_else(old_n, 'signal_blocks', {}) or {} + blocks = Utils.listify(blocks, 'signal_block') + connections = Utils.exists_or_else(old_n, 'connections', {}) or {} + connections = Utils.listify(connections, 'connection') + #initialize new nested data + new_n = odict() + new_n['block'] = list() + new_n['connection'] = list() + ############################################################ + # conversion - options block + ############################################################ + #get name + about_blocks = _get_blocks(blocks, 'About') + if about_blocks: title = _get_params(about_blocks[0])[0] + else: title = 'Untitled' + #get author + if about_blocks: author = _get_params(about_blocks[0])[1] + else: author = '' + #get desc + note_blocks = _get_blocks(blocks, 'Note') + if note_blocks: desc = _get_params(note_blocks[0])[0] + else: desc = '' + #create options block + options_block = odict() + options_block['key'] = 'options' + options_block['param'] = [ + _make_param('id', 'top_block'), + _make_param('title', title), + _make_param('author', author), + _make_param('description', desc), + _make_param('window_size', window_size), + _make_param('_coordinate', '(10, 10)'), + ] + #append options block + new_n['block'].append(options_block) + ############################################################ + # conversion - variables + ############################################################ + x = 100 + for variable in variables: + key = variable['key'] + value = variable['value'] + minimum = Utils.exists_or_else(variable, 'min', '') + maximum = Utils.exists_or_else(variable, 'max', '') + step = Utils.exists_or_else(variable, 'step', '') + x = x + 150 + coor = '(%d, %d)'%(x, 10) + var_block = odict() + if minimum and maximum: #slider varible + #determine num steps + try: num_steps = str(int((float(maximum) - float(minimum))/float(step))) + except: num_steps = '100' + var_block['key'] = 'variable_slider' + var_block['param'] = [ + _make_param('id', key), + _make_param('value', value), + _make_param('min', minimum), + _make_param('max', maximum), + _make_param('num_steps', num_steps), + _make_param('_coordinate', coor), + ] + else: #regular variable + var_block['key'] = 'variable' + var_block['param'] = [ + _make_param('id', key), + _make_param('value', value), + _make_param('_coordinate', coor), + ] + #append variable block + new_n['block'].append(var_block) + ############################################################ + # conversion - blocks + ############################################################ + #create name to key map for all blocks in platform + name_to_key = dict((b.get_name(), b.get_key()) for b in platform.get_blocks()) + for block in blocks: + #extract info + tag = block['tag'] + #ignore list + if tag in ('Note', 'About'): continue + id = _convert_id(block['id']) + coor = '(%s, %s + 100)'%( + Utils.exists_or_else(block, 'x_coordinate', '0'), + Utils.exists_or_else(block, 'y_coordinate', '0'), + ) + rot = Utils.exists_or_else(block, 'rotation', '0') + params = _get_params(block) + #new block + new_block = odict() + matches = difflib.get_close_matches(tag, name_to_key.keys(), 1) + if not matches: continue + #match found + key = name_to_key[matches[0]] + new_block['key'] = key + new_block['param'] = [ + _make_param('id', id), + _make_param('_coordinate', coor), + _make_param('_rotation', rot), + ] + #handle specific blocks + if key == 'wxgui_fftsink2': + params = params[0:3] + ['0'] + params[3:4] + ['8'] + params[4:] + #append params + for i, param in enumerate(params): + platform_block = platform.get_block(key) + try: platform_param = platform_block.get_params()[i+2] + except IndexError: break + if platform_param.is_enum(): + try: param_value = platform_param.get_option_keys()[int(param)] + except: param_value = platform_param.get_option_keys()[0] + else: + param_value = param.replace('$', '').replace('^', '**') + new_block['param'].append(_make_param(platform_param.get_key(), param_value)) + #append block + new_n['block'].append(new_block) + ############################################################ + # conversion - connections + ############################################################ + for connection in connections: + #extract info + input_signal_block_id = connection['input_signal_block_id'] + input_socket_index = connection['input_socket_index'] + output_signal_block_id = connection['output_signal_block_id'] + output_socket_index = connection['output_socket_index'] + #new connection + new_conn = odict() + new_conn['source_block_id'] = _convert_id(output_signal_block_id) + new_conn['sink_block_id'] = _convert_id(input_signal_block_id) + new_conn['source_key'] = output_socket_index + new_conn['sink_key'] = input_socket_index + #append connection + new_n['connection'].append(new_conn) + ############################################################ + # backup and replace + ############################################################ + #backup after successful conversion + os.rename(file_path, file_path+'.bak') + #save new flow graph to file path + ParseXML.to_file({'flow_graph': new_n}, file_path) + diff --git a/grc/src/grc/elements/Block.py b/grc/src/grc/elements/Block.py new file mode 100644 index 000000000..e241fb27e --- /dev/null +++ b/grc/src/grc/elements/Block.py @@ -0,0 +1,240 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Block +#Flow graph block. +#@author Josh Blum + +from grc import Utils +from grc.Utils import odict +from grc.elements.Element import Element +from grc.elements.Param import Param +from grc.elements.Port import Port + +from Cheetah.Template import Template +from UserDict import UserDict + +class TemplateArg(UserDict): + """ + A cheetah template argument created from a param. + The str of this class evaluates to the param's to code method. + The use of this class as a dictionary (enum only) will reveal the enum opts. + The eval method can return the param evaluated to a raw python data type. + """ + + def __init__(self, param): + UserDict.__init__(self) + self._param = param + if param.is_enum(): + for key in param.get_opt_keys(): + self[key] = str(param.get_opt(key)) + + def __str__(self): + return str(self._param.to_code()) + + def eval(self): + return self._param.evaluate() + +class Block(Element): + + def __init__(self, flow_graph, n): + """ + Make a new block from nested data. + @param flow graph the parent element + @param n the nested odict + @return block a new block + """ + #grab the data + name = n['name'] + key = n['key'] + category = Utils.exists_or_else(n, 'category', '') + params = Utils.listify(n, 'param') + sources = Utils.listify(n, 'source') + sinks = Utils.listify(n, 'sink') + #build the block + Element.__init__(self, flow_graph) + #store the data + self._name = name + self._key = key + self._category = category + #create the param objects + self._params = odict() + #add the id param + self._params['id'] = self.get_parent().get_parent().Param( + self, + { + 'name': 'ID', + 'key': 'id', + 'type': 'id', + } + ) + self._params['_enabled'] = self.get_parent().get_parent().Param( + self, + { + 'name': 'Enabled', + 'key': '_enabled', + 'type': 'raw', + 'value': 'True', + 'hide': 'all', + } + ) + for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params): + key = param.get_key() + #test against repeated keys + try: assert(key not in self.get_param_keys()) + except AssertionError: self._exit_with_error('Key "%s" already exists in params'%key) + #store the param + self._params[key] = param + #create the source objects + self._sources = odict() + for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources): + key = source.get_key() + #test against repeated keys + try: assert(key not in self.get_source_keys()) + except AssertionError: self._exit_with_error('Key "%s" already exists in sources'%key) + #store the port + self._sources[key] = source + #create the sink objects + self._sinks = odict() + for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks): + key = sink.get_key() + #test against repeated keys + try: assert(key not in self.get_sink_keys()) + except AssertionError: self._exit_with_error('Key "%s" already exists in sinks'%key) + #store the port + self._sinks[key] = sink + #begin the testing + self.test() + + def test(self): + """! + Call test on all children. + """ + map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources()) + + def get_enabled(self): + """! + Get the enabled state of the block. + @return true for enabled + """ + try: return eval(self.get_param('_enabled').get_value()) + except: return True + + def set_enabled(self, enabled): + """! + Set the enabled state of the block. + @param enabled true for enabled + """ + self.get_param('_enabled').set_value(str(enabled)) + + def validate(self): + """ + Validate the block. + All ports and params must be valid. + All checks must evaluate to true. + """ + if not self.get_enabled(): return + for c in self.get_params() + self.get_sinks() + self.get_sources(): + try: assert(c.is_valid()) + except AssertionError: + for msg in c.get_error_messages(): + self._add_error_message('%s: %s'%(c, msg)) + + def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key()) + + def get_id(self): return self.get_param('id').get_value() + + def is_block(self): return True + + def get_doc(self): return self._doc + + def get_name(self): return self._name + + def get_key(self): return self._key + + def get_category(self): return self._category + + def get_doc(self): return '' + + def get_ports(self): return self.get_sources() + self.get_sinks() + + ############################################## + # Access Params + ############################################## + def get_param_keys(self): return self._params.keys() + def get_param(self, key): return self._params[key] + def get_params(self): return self._params.values() + + ############################################## + # Access Sinks + ############################################## + def get_sink_keys(self): return self._sinks.keys() + def get_sink(self, key): return self._sinks[key] + def get_sinks(self): return self._sinks.values() + + ############################################## + # Access Sources + ############################################## + def get_source_keys(self): return self._sources.keys() + def get_source(self, key): return self._sources[key] + def get_sources(self): return self._sources.values() + + def get_connections(self): + return sum([port.get_connections() for port in self.get_ports()], []) + + def resolve_dependencies(self, tmpl): + """ + Resolve a paramater dependency with cheetah templates. + @param tmpl the string with dependencies + @return the resolved value + """ + tmpl = str(tmpl) + if '$' not in tmpl: return tmpl + n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params()) + try: return str(Template(tmpl, n)) + except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl) + + ############################################## + ## Import/Export Methods + ############################################## + def export_data(self): + """ + Export this block's params to nested data. + @return a nested data odict + """ + n = odict() + n['key'] = self.get_key() + n['param'] = map(lambda p: p.export_data(), self.get_params()) + return n + + def import_data(self, n): + """ + Import this block's params from nested data. + Any param keys that do not exist will be ignored. + @param n the nested data odict + """ + params_n = Utils.listify(n, 'param') + for param_n in params_n: + #key and value must exist in the n data + if 'key' in param_n.keys() and 'value' in param_n.keys(): + key = param_n['key'] + value = param_n['value'] + #the key must exist in this block's params + if key in self.get_param_keys(): + self.get_param(key).set_value(value) + self.validate() diff --git a/grc/src/grc/elements/Connection.py b/grc/src/grc/elements/Connection.py new file mode 100644 index 000000000..57871c75d --- /dev/null +++ b/grc/src/grc/elements/Connection.py @@ -0,0 +1,94 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Connection +#Flow graph connection. +#A connection exists between 2 ports. +#One port must be input, one output. +#The port decided whether it can have the connection. +#@author Josh Blum + +from grc.elements.Element import Element +from grc.Utils import odict + +class Connection(Element): + + def __init__(self, flow_graph, porta, portb): + """! + Make a new connection given the parent and 2 ports. + @param flow_graph the parent of this element + @param porta a port (any direction) + @param portb a port (any direction) + @throws Error cannot make connection + @return a new connection + """ + Element.__init__(self, flow_graph) + source = sink = None + #separate the source and sink + for port in (porta, portb): + if port.is_source(): source = port + if port.is_sink(): sink = port + #verify the source and sink + assert(source and sink) + assert(not source.is_full()) + assert(not sink.is_full()) + self._source = source + self._sink = sink + + def __str__(self): return 'Connection (%s -> %s)'%(self.get_source(), self.get_sink()) + + def is_connection(self): return True + + def validate(self): + """ + Validate the connections. + The ports must match in type. + """ + source_type = self.get_source().get_type() + sink_type = self.get_sink().get_type() + try: assert source_type == sink_type + except AssertionError: self._add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type)) + + def get_enabled(self): + """! + Get the enabled state of this connection. + @return true if source and sink blocks are enabled + """ + return self.get_source().get_parent().get_enabled() and \ + self.get_sink().get_parent().get_enabled() + + ############################# + # Access Ports + ############################# + def get_sink(self): return self._sink + def get_source(self): return self._source + + ############################################## + ## Import/Export Methods + ############################################## + def export_data(self): + """ + Export this connection's info. + @return a nested data odict + """ + n = odict() + n['source_block_id'] = self.get_source().get_parent().get_id() + n['sink_block_id'] = self.get_sink().get_parent().get_id() + n['source_key'] = self.get_source().get_key() + n['sink_key'] = self.get_sink().get_key() + return n diff --git a/grc/src/grc/elements/Element.py b/grc/src/grc/elements/Element.py new file mode 100644 index 000000000..b90f775c5 --- /dev/null +++ b/grc/src/grc/elements/Element.py @@ -0,0 +1,97 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Element +#The base class for all elements. +#@author Josh Blum + +class Element(object): + + def __init__(self, parent=None): + self._parent = parent + self._error_messages = [] + self.flag() + + def test(self): + """ + Test the element against failures. + Overload this method in sub-classes. + """ + pass + + def validate(self): + """ + Validate the data in this element. + Set the error message non blank for errors. + Overload this method in sub-classes. + """ + pass + + def is_valid(self): + self._error_messages = []#reset err msgs + try: self.validate() + except: pass + return not self.get_error_messages() + + def _add_error_message(self, msg): + self._error_messages.append(msg) + + def get_error_messages(self): + return self._error_messages + + def get_parent(self): + return self._parent + + def _exit_with_error(self, error): + parent = self + #build hier list of elements + elements = list() + while(parent): + elements.insert(0, parent) + parent = parent.get_parent() + #build error string + err_str = ">>> Error:" + for i, element in enumerate(elements + [error]): + err_str = err_str + '\n' + ''.join(' '*(i+2)) + str(element) + err_str = err_str + '\n' + exit(err_str) + + ############################################## + ## Update flagging + ############################################## + def is_flagged(self): return self._flag + def flag(self): + self._flag = True + if self.get_parent(): self.get_parent().flag() + def deflag(self): + self._flag = False + if self.get_parent(): self.get_parent().deflag() + + ############################################## + ## Type testing methods + ############################################## + def is_element(self): return True + def is_platform(self): return False + def is_flow_graph(self): return False + def is_connection(self): return False + def is_block(self): return False + def is_source(self): return False + def is_sink(self): return False + def is_port(self): return False + def is_param(self): return False + diff --git a/grc/src/grc/elements/FlowGraph.py b/grc/src/grc/elements/FlowGraph.py new file mode 100644 index 000000000..65d47f4d8 --- /dev/null +++ b/grc/src/grc/elements/FlowGraph.py @@ -0,0 +1,236 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.FlowGraph +#Primative flow graph. +#@author Josh Blum + +from grc import Utils +from grc.Utils import odict +from grc.elements.Element import Element +from grc.elements.Block import Block +from grc.elements.Connection import Connection + +from grc import Messages + +class FlowGraph(Element): + + def __init__(self, platform): + """! + Make a flow graph from the arguments. + @param platform a platforms with blocks and contrcutors + @return the flow graph object + """ + #hold connections and blocks + self._elements = list() + #initialize + Element.__init__(self, platform) + #inital blank import + self.import_data({'flow_graph': {}}) + + def __str__(self): return 'FlowGraph - "%s"'%self.get_option('name') + + def get_option(self, key): + """! + Get the option for a given key. + The option comes from the special options block. + @param key the param key for the options block + @return the value held by that param + """ + return self._options_block.get_param(key).evaluate() + + def is_flow_graph(self): return True + + ############################################## + ## Access Elements + ############################################## + def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0] + def get_blocks(self): return filter(lambda e: e.is_block(), self.get_elements()) + def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements()) + def get_elements(self): + """! + Get a list of all the elements. + Always ensure that the options block is in the list. + @return the element list + """ + if self._options_block not in self._elements: self._elements.append(self._options_block) + #ensure uniqueness of the elements list + element_set = set() + element_list = list() + for element in self._elements: + if element not in element_set: element_list.append(element) + element_set.add(element) + #store cleaned up list + self._elements = element_list + return self._elements + + def get_enabled_blocks(self): + """! + Get a list of all blocks that are enabled. + @return a list of blocks + """ + return filter(lambda b: b.get_enabled(), self.get_blocks()) + + def get_enabled_connections(self): + """! + Get a list of all connections that are enabled. + @return a list of connections + """ + return filter(lambda c: c.get_enabled(), self.get_connections()) + + def get_new_block(self, key): + """! + Get a new block of the specified key. + Add the block to the list of elements. + @param key the block key + @return the new block or None if not found + """ + self.flag() + if key not in self.get_parent().get_block_keys(): return None + block = self.get_parent().get_new_block(self, key) + self.get_elements().append(block) + return block + + def connect(self, porta, portb): + """! + Create a connection between porta and portb. + @param porta a port + @param portb another port + @throw Exception bad connection + @return the new connection + """ + self.flag() + connection = self.get_parent().Connection(self, porta, portb) + self.get_elements().append(connection) + return connection + + def remove_element(self, element): + """! + Remove the element from the list of elements. + If the element is a port, remove the whole block. + If the element is a block, remove its connections. + If the element is a connection, just remove the connection. + """ + self.flag() + if element not in self.get_elements(): return + #found a port, set to parent signal block + if element.is_port(): + element = element.get_parent() + #remove block, remove all involved connections + if element.is_block(): + for port in element.get_ports(): + map(lambda c: self.remove_element(c), port.get_connections()) + #remove a connection + elif element.is_connection(): pass + self.get_elements().remove(element) + + def evaluate(self, expr): + """! + Evaluate the expression. + @param expr the string expression + @throw NotImplementedError + """ + raise NotImplementedError + + def validate(self): + """ + Validate the flow graph. + All connections and blocks must be valid. + """ + for c in self.get_elements(): + try: assert(c.is_valid()) + except AssertionError: self._add_error_message('Element "%s" is not valid.'%c) + + ############################################## + ## Import/Export Methods + ############################################## + def export_data(self): + """ + Export this flow graph to nested data. + Export all block and connection data. + @return a nested data odict + """ + import time + n = odict() + n['timestamp'] = time.ctime() + n['block'] = [block.export_data() for block in self.get_blocks()] + n['connection'] = [connection.export_data() for connection in self.get_connections()] + return {'flow_graph': n} + + def import_data(self, n): + """ + Import blocks and connections into this flow graph. + Clear this flowgraph of all previous blocks and connections. + Any blocks or connections in error will be ignored. + @param n the nested data odict + """ + #remove previous elements + self._elements = list() + #the flow graph tag must exists, or use blank data + if 'flow_graph' in n.keys(): fg_n = n['flow_graph'] + else: + Messages.send_error_load('Flow graph data not found, loading blank flow graph.') + fg_n = {} + blocks_n = Utils.listify(fg_n, 'block') + connections_n = Utils.listify(fg_n, 'connection') + #create option block + self._options_block = self.get_parent().get_new_block(self, 'options') + self._options_block.get_param('id').set_value('options') + #build the blocks + for block_n in blocks_n: + key = block_n['key'] + if key == 'options': block = self._options_block + else: block = self.get_new_block(key) + #only load the block when the block key was valid + if block: block.import_data(block_n) + else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent())) + #build the connections + for connection_n in connections_n: + #test that the data tags exist + try: + assert('source_block_id' in connection_n.keys()) + assert('sink_block_id' in connection_n.keys()) + assert('source_key' in connection_n.keys()) + assert('sink_key' in connection_n.keys()) + except AssertionError: continue + #try to make the connection + try: + #get the block ids + source_block_id = connection_n['source_block_id'] + sink_block_id = connection_n['sink_block_id'] + #get the port keys + source_key = connection_n['source_key'] + sink_key = connection_n['sink_key'] + #verify the blocks + block_ids = map(lambda b: b.get_id(), self.get_blocks()) + assert(source_block_id in block_ids) + assert(sink_block_id in block_ids) + #get the blocks + source_block = self.get_block(source_block_id) + sink_block = self.get_block(sink_block_id) + #verify the ports + assert(source_key in source_block.get_source_keys()) + assert(sink_key in sink_block.get_sink_keys()) + #get the ports + source = source_block.get_source(source_key) + sink = sink_block.get_sink(sink_key) + #build the connection + self.connect(source, sink) + except AssertionError: Messages.send_error_load('Connection between %s(%s) and %s(%s) could not be made.'%(source_block_id, source_key, sink_block_id, sink_key)) + self.validate() + diff --git a/grc/src/grc/elements/Makefile.am b/grc/src/grc/elements/Makefile.am new file mode 100644 index 000000000..2b97c9771 --- /dev/null +++ b/grc/src/grc/elements/Makefile.am @@ -0,0 +1,34 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc/elements + +ourpython_PYTHON = \ + __init__.py \ + Block.py \ + Connection.py \ + Element.py \ + FlowGraph.py \ + Param.py \ + Platform.py \ + Port.py diff --git a/grc/src/grc/elements/Param.py b/grc/src/grc/elements/Param.py new file mode 100644 index 000000000..321800502 --- /dev/null +++ b/grc/src/grc/elements/Param.py @@ -0,0 +1,222 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Param +#Flow graph block parameters. +#And options for enum type paramater. +#@author Josh Blum + +from grc import Utils +from grc.Utils import odict +from grc.elements.Element import Element + +class Option(Element): + + def __init__(self, param, name, key, opts): + Element.__init__(self, param) + self._name = name + self._key = key + self._opts = dict() + for opt in opts: + #separate the key:value + try: key, value = opt.split(':') + except: self._exit_with_error('Error separating "%s" into key:value'%opt) + #test against repeated keys + try: assert(not self._opts.has_key(key)) + except AssertionError: self._exit_with_error('Key "%s" already exists in option'%key) + #store the option + self._opts[key] = value + + def __str__(self): return 'Option %s(%s)'%(self.get_name(), self.get_key()) + + def get_name(self): return self._name + + def get_key(self): return self._key + + ############################################## + # Access Opts + ############################################## + def get_opt_keys(self): return self._opts.keys() + def get_opt(self, key): return self._opts[key] + def get_opts(self): return self._opts.values() + + ############################################## + ## Static Make Methods + ############################################## + def make_option_from_n(param, n): + """ + Make a new option from nested data. + @param param the parent element + @param n the nested odict + @return a new option + """ + #grab the data + name = n['name'] + key = n['key'] + opts = Utils.listify(n, 'opt') + #build the option + return Option( + param=param, + name=name, + key=key, + opts=opts, + ) + make_option_from_n = staticmethod(make_option_from_n) + +class Param(Element): + + ##possible param types + TYPES = ['enum', 'raw'] + + def __init__(self, block, n): + """ + Make a new param from nested data. + @param block the parent element + @param n the nested odict + @return a new param + """ + #grab the data + name = n['name'] + key = n['key'] + value = Utils.exists_or_else(n, 'value', '') + type = n['type'] + hide = Utils.exists_or_else(n, 'hide', '') + options = Utils.listify(n, 'option') + #build the param + Element.__init__(self, block) + self._name = name + self._key = key + self._type = type + self._hide = hide + #create the Option objects from the n data + self._options = odict() + for option in map(lambda o: Option.make_option_from_n(self, o), options): + key = option.get_key() + #test against repeated keys + try: assert(key not in self.get_option_keys()) + except AssertionError: self._exit_with_error('Key "%s" already exists in options'%key) + #store the option + self._options[key] = option + #test the enum options + if self._options or self.is_enum(): + #test against bad combos of type and enum + try: assert(self._options) + except AssertionError: self._exit_with_error('At least one option must exist when type "enum" is set.') + try: assert(self.is_enum()) + except AssertionError: self._exit_with_error('Type "enum" must be set when options are present.') + #test against options with identical keys + try: assert(len(set(self.get_option_keys())) == len(self._options)) + except AssertionError: self._exit_with_error('Options keys "%s" are not unique.'%self.get_option_keys()) + #test against inconsistent keys in options + opt_keys = self._options.values()[0].get_opt_keys() + for option in self._options.values(): + try: assert(set(opt_keys) == set(option.get_opt_keys())) + except AssertionError: self._exit_with_error('Opt keys "%s" are not identical across all options.'%opt_keys) + #if a value is specified, it must be in the options keys + self._value = value or self.get_option_keys()[0] + try: assert(self.get_value() in self.get_option_keys()) + except AssertionError: self._exit_with_error('The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())) + else: self._value = value or '' + + def test(self): + """ + call test on all children + """ + map(lambda c: c.test(), self.get_options()) + + def validate(self): + """ + Validate the param. + The value must be evaluated and type must a possible type. + """ + try: + assert(self.get_type() in self.TYPES) + try: self.evaluate() + except: + #if the evaluate failed but added no error messages, add the generic one below + if not self.get_error_messages(): + self._add_error_message('Value "%s" cannot be evaluated.'%self.get_value()) + except AssertionError: self._add_error_message('Type "%s" is not a possible type.'%self.get_type()) + + def evaluate(self): + """! + Evaluate the value of this param. + @throw NotImplementedError + """ + raise NotImplementedError + + def to_code(self): + """! + Convert the value to code. + @throw NotImplementedError + """ + raise NotImplementedError + + def __str__(self): return 'Param - %s(%s)'%(self.get_name(), self.get_key()) + + def is_param(self): return True + + def get_name(self): return self._name + + def get_key(self): return self._key + + def get_hide(self): return self.get_parent().resolve_dependencies(self._hide) + + def get_value(self): + value = self._value + if self.is_enum() and value not in self.get_option_keys(): + value = self.get_option_keys()[0] + self.set_value(value) + return value + + def set_value(self, value): + self.flag() + self._value = str(value) #must be a string + + def get_type(self): return self.get_parent().resolve_dependencies(self._type) + + def is_enum(self): return self._type == 'enum' + + def is_type_dependent(self): return '$' in self._type + + ############################################## + # Access Options + ############################################## + def get_option_keys(self): return self._options.keys() + def get_option(self, key): return self._options[key] + def get_options(self): return self._options.values() + + ############################################## + # Access Opts + ############################################## + def get_opt_keys(self): return self._options[self.get_value()].get_opt_keys() + def get_opt(self, key): return self._options[self.get_value()].get_opt(key) + def get_opts(self): return self._options[self.get_value()].get_opts() + + ############################################## + ## Import/Export Methods + ############################################## + def export_data(self): + """ + Export this param's key/value. + @return a nested data odict + """ + n = odict() + n['key'] = self.get_key() + n['value'] = self.get_value() + return n diff --git a/grc/src/grc/elements/Platform.py b/grc/src/grc/elements/Platform.py new file mode 100644 index 000000000..fb8cb783d --- /dev/null +++ b/grc/src/grc/elements/Platform.py @@ -0,0 +1,147 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Platform +#A Platform contains all blocks in platform. +#@author Josh Blum + +import os +from grc import ParseXML +from grc import Utils +from grc.elements.Element import Element as _Element +from grc.elements.FlowGraph import FlowGraph as _FlowGraph +from grc.elements.Connection import Connection as _Connection +from grc.elements.Block import Block as _Block +from grc.elements.Port import Port as _Port +from grc.elements.Param import Param as _Param +from grc.Constants import DATA_DIR + +class Platform(_Element): + + def __init__(self, name, key, block_paths, block_dtd, block_tree, default_flow_graph, generator): + """! + Make a platform from the arguments. + @param name the platform name + @param key the unique platform key + @param block_paths the file paths to blocks in this platform + @param block_dtd the dtd validator for xml block wrappers + @param block_tree the nested tree of block keys and categories + @param default_flow_graph the default flow graph file path + @param load_one a single file to load into this platform or None + @return a platform object + """ + _Element.__init__(self) + self._name = name + self._key = key + self._block_paths = block_paths + self._block_dtd = block_dtd + self._block_tree = block_tree + self._default_flow_graph = default_flow_graph + self._generator = generator + #create a dummy flow graph for the blocks + self._flow_graph = _Element(self) + #load the blocks + self._blocks = dict() + self._blocks_n = dict() + for block_path in self._block_paths: + if os.path.isfile(block_path): self._load_block(block_path) + elif os.path.isdir(block_path): + for dirpath,dirnames,filenames in os.walk(block_path): + for filename in filter(lambda f: f.endswith('.xml'), filenames): + self._load_block(os.path.join(dirpath, filename)) + + def get_prefs_block(self): return self.get_new_flow_graph().get_new_block('preferences') + + def _load_block(self, f): + """! + Load the block wrapper from the file path. + The block wrapper must pass validation, and have a unique block key. + If any of the checks fail, exit with error. + @param f the file path + """ + try: ParseXML.validate_dtd(f, self._block_dtd) + except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block definition "%s" failed: \n\t%s'%(f, e)) + n = ParseXML.from_file(f)['block'] + block = self.Block(self._flow_graph, n) + key = block.get_key() + #test against repeated keys + try: assert(key not in self.get_block_keys()) + except AssertionError: self._exit_with_error('Key "%s" already exists in blocks'%key) + #store the block + self._blocks[key] = block + self._blocks_n[key] = n + + def load_block_tree(self, block_tree): + """! + Load a block tree with categories and blocks. + Step 1: Load all blocks from the xml specification. + Step 2: Load blocks with builtin category specifications. + @param block_tree the block tree object + """ + #recursive function to load categories and blocks + def load_category(cat_n, parent=''): + #add this category + parent = '%s/%s'%(parent, cat_n['name']) + block_tree.add_block(parent) + #recursive call to load sub categories + map(lambda c: load_category(c, parent), Utils.listify(cat_n, 'cat')) + #add blocks in this category + for block_key in Utils.listify(cat_n, 'block'): + block_tree.add_block(parent, self.get_block(block_key)) + #load the block tree + f = self._block_tree + try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR, 'block_tree.dtd')) + except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block tree "%s" failed: \n\t%s'%(f, e)) + #add all blocks in the tree + load_category(ParseXML.from_file(f)['cat']) + #add all other blocks, use the catgory + for block in self.get_blocks(): + #blocks with empty categories are in the xml block tree or hidden + if block.get_category(): block_tree.add_block(block.get_category(), block) + + def __str__(self): return 'Platform - %s(%s)'%(self.get_key(), self.get_name()) + + def is_platform(self): return True + + def get_new_flow_graph(self): return self.FlowGraph(self) + + def get_default_flow_graph(self): return self._default_flow_graph + + def get_generator(self): return self._generator + + ############################################## + # Access Blocks + ############################################## + def get_block_keys(self): return self._blocks.keys() + def get_block(self, key): return self._blocks[key] + def get_blocks(self): return self._blocks.values() + def get_new_block(self, flow_graph, key): return self.Block(flow_graph, n=self._blocks_n[key]) + + def get_name(self): return self._name + + def get_key(self): return self._key + + ############################################## + # Constructors + ############################################## + FlowGraph = _FlowGraph + Connection = _Connection + Block = _Block + Source = _Port + Sink = _Port + Param = _Param diff --git a/grc/src/grc/elements/Port.py b/grc/src/grc/elements/Port.py new file mode 100644 index 000000000..3c5425fda --- /dev/null +++ b/grc/src/grc/elements/Port.py @@ -0,0 +1,109 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements.Port +#Flow graph block port (source or sink). +#@author Josh Blum + +from grc import Utils +from grc.elements.Element import Element + +class Port(Element): + + ##possible port types + TYPES = [] + + def __init__(self, block, n): + """ + Make a new port from nested data. + @param block the parent element + @param n the nested odict + @return a new port + """ + #grab the data + name = n['name'] + key = n['key'] + type = n['type'] + #build the port + Element.__init__(self, block) + self._name = name + self._key = key + self._type = type + + def validate(self): + """! + Validate the port. + The port must be non-empty and type must a possible type. + """ + try: assert(not self.is_empty()) + except AssertionError: self._add_error_message('is empty.') + try: assert(self.get_type() in self.TYPES) + except AssertionError: self._add_error_message('Type "%s" is not a possible type.'%self.get_type()) + + def __str__(self): + if self.is_source(): + return 'Source - %s(%s)'%(self.get_name(), self.get_key()) + if self.is_sink(): + return 'Sink - %s(%s)'%(self.get_name(), self.get_key()) + + def is_port(self): return True + + def get_color(self): return '#FFFFFF' + + def get_name(self): return self._name + + def get_key(self): return self._key + + def is_sink(self): return self in self.get_parent().get_sinks() + + def is_source(self): return self in self.get_parent().get_sources() + + def get_type(self): return self.get_parent().resolve_dependencies(self._type) + + def get_connections(self): + """! + Get all connections that use this port. + @return a list of connection objects + """ + connections = self.get_parent().get_parent().get_connections() + connections = filter(lambda c: c.get_source() is self or c.get_sink() is self, connections) + return connections + + def is_connected(self): + """! + Is this port connected? + @return true if at least one connection + """ + return bool(self.get_connections()) + + def is_full(self): + """! + Is this port full of connections? + Generally a sink can handle one connection and a source can handle many. + @return true if the port is full + """ + if self.is_source(): return False + if self.is_sink(): return bool(self.get_connections()) + + def is_empty(self): + """! + Is this port empty? + An empty port has no connections. + @return true if empty + """ + return not self.get_connections() diff --git a/grc/src/grc/elements/__init__.py b/grc/src/grc/elements/__init__.py new file mode 100644 index 000000000..3700c9761 --- /dev/null +++ b/grc/src/grc/elements/__init__.py @@ -0,0 +1,22 @@ +""" +Copyright 2008 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 +""" +##@package grc.elements +#Package for flow graph elements. +#@author Josh Blum + diff --git a/grc/src/grc/gui/Bars.py b/grc/src/grc/gui/Bars.py new file mode 100644 index 000000000..1b4f5dc52 --- /dev/null +++ b/grc/src/grc/gui/Bars.py @@ -0,0 +1,143 @@ +""" +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 +""" +##@package grc.gui.Bars +#Create the GUI's toolbar and menubar +#@author Josh Blum + +from grc.Actions import * +import pygtk +pygtk.require('2.0') +import gtk + +##The list of actions for the toolbar. +TOOLBAR_LIST = ( + FLOW_GRAPH_NEW, + FLOW_GRAPH_OPEN, + FLOW_GRAPH_SAVE, + FLOW_GRAPH_CLOSE, + None, + FLOW_GRAPH_SCREEN_CAPTURE, + None, + BLOCK_CUT, + BLOCK_COPY, + BLOCK_PASTE, + ELEMENT_DELETE, + None, + FLOW_GRAPH_UNDO, + FLOW_GRAPH_REDO, + None, + FLOW_GRAPH_GEN, + FLOW_GRAPH_EXEC, + FLOW_GRAPH_KILL, + None, + BLOCK_ROTATE_LEFT, + BLOCK_ROTATE_RIGHT, + None, + BLOCK_ENABLE, + BLOCK_DISABLE, +) + +##The list of actions and categories for the menu bar. +MENU_BAR_LIST = ( + (gtk.Action('File', '_File', None, None), [ + FLOW_GRAPH_NEW, + FLOW_GRAPH_OPEN, + None, + FLOW_GRAPH_SAVE, + FLOW_GRAPH_SAVE_AS, + None, + FLOW_GRAPH_SCREEN_CAPTURE, + None, + FLOW_GRAPH_CLOSE, + APPLICATION_QUIT, + ]), + (gtk.Action('Edit', '_Edit', None, None), [ + FLOW_GRAPH_UNDO, + FLOW_GRAPH_REDO, + None, + BLOCK_CUT, + BLOCK_COPY, + BLOCK_PASTE, + ELEMENT_DELETE, + None, + BLOCK_ROTATE_LEFT, + BLOCK_ROTATE_RIGHT, + None, + BLOCK_ENABLE, + BLOCK_DISABLE, + None, + BLOCK_PARAM_MODIFY, + ]), + (gtk.Action('Build', '_Build', None, None), [ + FLOW_GRAPH_GEN, + FLOW_GRAPH_EXEC, + FLOW_GRAPH_KILL, + ]), + (gtk.Action('Options', '_Options', None, None), [ + PREFS_WINDOW_DISPLAY, + ]), + (gtk.Action('Help', '_Help', None, None), [ + ABOUT_WINDOW_DISPLAY, + HOTKEYS_WINDOW_DISPLAY, + ]), +) + +class Toolbar(gtk.Toolbar): + """The gtk toolbar with actions added from the toolbar list.""" + + def __init__(self): + """ + Parse the list of action names in the toolbar list. + Look up the action for each name in the action list and add it to the toolbar. + """ + gtk.Toolbar.__init__(self) + self.set_style(gtk.TOOLBAR_ICONS) + for action_name in TOOLBAR_LIST: + if action_name: #add a tool item + action = get_action_from_name(action_name) + self.add(action.create_tool_item()) + #this reset of the tooltip property is required (after creating the tool item) for the tooltip to show + action.set_property('tooltip', action.get_property('tooltip')) + else: self.add(gtk.SeparatorToolItem()) + +class MenuBar(gtk.MenuBar): + """The gtk menu bar with actions added from the menu bar list.""" + + def __init__(self): + """ + Parse the list of submenus from the menubar list. + For each submenu, get a list of action names. + Look up the action for each name in the action list and add it to the submenu. + Add the submenu to the menu bar. + """ + gtk.MenuBar.__init__(self) + for main_action,action_names in MENU_BAR_LIST: + #create the main menu item + main_menu_item = main_action.create_menu_item() + self.append(main_menu_item) + #create the menu + main_menu = gtk.Menu() + main_menu_item.set_submenu(main_menu) + for action_name in action_names: + if action_name: #append a menu item + action = get_action_from_name(action_name) + main_menu.append(action.create_menu_item()) + else: main_menu.append(gtk.SeparatorMenuItem()) + main_menu.show_all() #this show all is required for the separators to show + diff --git a/grc/src/grc/gui/BlockTreeWindow.py b/grc/src/grc/gui/BlockTreeWindow.py new file mode 100644 index 000000000..859f88362 --- /dev/null +++ b/grc/src/grc/gui/BlockTreeWindow.py @@ -0,0 +1,154 @@ +""" +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 +""" +##@package grc.gui.BlockTreeWindow +#The block selection panel gives the user a tree selection to choose a block. +#@author Josh Blum + +from grc.Constants import * +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +NAME_INDEX = 0 +KEY_INDEX = 1 + +class BlockTreeWindow(gtk.VBox): + """The block selection panel.""" + + def __init__(self, platform, get_flow_graph): + """! + BlockTreeWindow constructor. + Create a tree view of the possible blocks in the platform. + The tree view nodes will be category names, the leaves will be block names. + A mouse double click or button press action will trigger the add block event. + @param platform the particular platform will all block prototypes + @param get_flow_graph get the selected flow graph + """ + gtk.VBox.__init__(self) + self.platform = platform + self.get_flow_graph = get_flow_graph + #make the tree model for holding blocks + self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) + self.treeview = gtk.TreeView(self.treestore) + self.treeview.set_enable_search(False) #disable pop up search box + self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK) + self.treeview.connect('button_press_event', self._handle_mouse_button_press) + selection = self.treeview.get_selection() + selection.set_mode('single') + selection.connect('changed', self._handle_selection_change) + renderer = gtk.CellRendererText() + column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX) + self.treeview.append_column(column) + #make the scrolled window to hold the tree view + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolled_window.add_with_viewport(self.treeview) + scrolled_window.set_size_request(BLOCK_SELECTION_WINDOW_WIDTH, -1) + self.pack_start(scrolled_window) + #add button + self.add_button = gtk.Button(None, 'gtk-add') + self.add_button.connect('clicked', self._handle_add_button) + self.pack_start(self.add_button, False) + #map categories to iters + self.categories = dict() + self.categories[tuple()] = None + #add blocks and categories + self.platform.load_block_tree(self) + #initialize + self._update_add_button() + + ############################################################ + ## Block Tree Methods + ############################################################ + def add_block(self, category, block=None): + """! + Add a block with category to this selection window. + Add only the category when block is None. + @param category the category string + @param block the block object or None + """ + #rectify category + category = filter(lambda x: x, category.split('/')) + #add category and all sub categories + for i in range(len(category)): + sub_category = tuple(category[:i+1]) + if sub_category not in self.categories.keys(): + iter = self.treestore.insert_before(self.categories[tuple(category[:i])], None) + self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%category[i]) + self.treestore.set_value(iter, KEY_INDEX, '') + self.categories[sub_category] = iter + #add block + if block is None: return + iter = self.treestore.insert_before(self.categories[tuple(category)], None) + self.treestore.set_value(iter, NAME_INDEX, block.get_name()) + self.treestore.set_value(iter, KEY_INDEX, block.get_key()) + + ############################################################ + ## Helper Methods + ############################################################ + def _get_selected_block_key(self): + """! + Get the currently selected block key. + @return the key of the selected block or a empty string + """ + selection = self.treeview.get_selection() + treestore, iter = selection.get_selected() + return iter and treestore.get_value(iter, KEY_INDEX) or '' + + def _update_add_button(self): + """! + Update the add button's sensitivity. + The button should be active only if a block is selected. + """ + key = self._get_selected_block_key() + self.add_button.set_sensitive(bool(key)) + + def _add_selected_block(self): + """! + Add the selected block with the given key to the flow graph. + """ + key = self._get_selected_block_key() + if key: self.get_flow_graph().add_new_block(key) + + ############################################################ + ## Event Handlers + ############################################################ + def _handle_mouse_button_press(self, widget, event): + """! + Handle the mouse button press. + If a left double click is detected, call add selected block. + """ + if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: + self._add_selected_block() + + def _handle_selection_change(self, selection): + """! + Handle a selection change in the tree view. + If a selection changes, set the add button sensitive. + """ + self._update_add_button() + + def _handle_add_button(self, widget): + """! + Handle the add button clicked signal. + Call add selected block. + """ + self._add_selected_block() + diff --git a/grc/src/grc/gui/Dialogs.py b/grc/src/grc/gui/Dialogs.py new file mode 100644 index 000000000..1271f6e68 --- /dev/null +++ b/grc/src/grc/gui/Dialogs.py @@ -0,0 +1,149 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.Dialogs +#Misc dialogs. +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk +from grc.Constants import * +from grc 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_CHAR) + +###################################################################################################### +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,desc,params in Preferences.get_preferences(): + vbox = gtk.VBox() + vbox.pack_start(gtk.Label(''), False) #blank label for spacing + for param in params: vbox.pack_start(param.get_input_object(), False) + desc = desc.strip('\n') + if desc: vbox.pack_start(TextDisplay(desc), False, padding=5) + notebook.append_page(vbox, gtk.Label(title)) + self.vbox.pack_start(notebook, True) + self.show_all() + self.run() + self.destroy() + +###################################################################################################### +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 2008 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 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'), + ('Close Flow Graph', 'Ctrl + q'), + ('Cut Block', 'Ctrl + x'), + ('Copy Block', 'Ctrl + c'), + ('Paste Block', 'Ctrl + v'), + ('Undo Change', 'Ctrl + z'), + ('Redo Change', 'Ctrl + y'), + ('Delete Block', 'Delete'), + ('Modify Parameters', 'Enter'), + ('Rotate Block', 'Right'), + ('Rotate Block', 'Left'), + ('Enable Block', 'e'), + ('Disable Block', 'd'), + ('Modify Data Type', 'Up'), + ('Modify Data Type', 'Down'), + ('Add a Port', '+'), + ('Remove a Port', '-'), + ('Flow Graph Generate', 'F5'), + ('Flow Graph Execute', 'F6'), + ('Flow Graph Kill', '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() diff --git a/grc/src/grc/gui/DrawingArea.py b/grc/src/grc/gui/DrawingArea.py new file mode 100644 index 000000000..ca5ca4a76 --- /dev/null +++ b/grc/src/grc/gui/DrawingArea.py @@ -0,0 +1,121 @@ +""" +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 +""" +##@package grc.gui.DrawingArea +#Drawing area for graphical elements. +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk +from grc.Constants import * + +class DrawingArea(gtk.DrawingArea): + """ + DrawingArea is the gtk pixel map that graphical elements may draw themselves on. + The drawing area also responds to mouse and key events. + """ + + def __init__(self, main_window): + """! + DrawingArea contructor. + Connect event handlers. + @param main_window the main_window containing all flow graphs + """ + self.ctrl_mask = False + self._main_window = main_window + #inject drawing area into main_window + self._main_window.drawing_area = self + gtk.DrawingArea.__init__(self) + self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT) + 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) + #pixmap for drawing + self.pixmap = None + self.gc = None + + def draw(self): + """! + Draw the pixmap onto this drawing area. + """ + self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 0, 0, -1, -1) + + ########################################################################## + ## Handlers + ########################################################################## + def _handle_focus_event(self, widget, event, focus_flag): + """Record the focus state of the flow graph window.""" + self._focus_flag = focus_flag + + def _handle_mouse_button_press(self, widget, event): + """! + Forward button click information to the flow graph. + """ + self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK + self._main_window.get_flow_graph().handle_mouse_button_press( + left_click=(event.button == 1), + double_click=(event.type == gtk.gdk._2BUTTON_PRESS), + coordinate=(event.x, event.y), + ) + return True + + def _handle_mouse_button_release(self, widget, event): + """! + Forward button release information to the flow graph. + """ + self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK + self._main_window.get_flow_graph().handle_mouse_button_release( + left_click=(event.button == 1), + coordinate=(event.x, event.y), + ) + return True + + def _handle_mouse_motion(self, widget, event): + """! + Forward mouse motion information to the flow graph. + """ + self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK + self._main_window.get_flow_graph().handle_mouse_motion( + coordinate=(event.x, event.y), + ) + return True + + 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 not self.pixmap or (width, height) != self.pixmap.get_size(): + self.pixmap = gtk.gdk.Pixmap(self.window, width, height, -1) + self._main_window.get_flow_graph().draw() + return True diff --git a/grc/src/grc/gui/FileDialogs.py b/grc/src/grc/gui/FileDialogs.py new file mode 100644 index 000000000..2adfcde7b --- /dev/null +++ b/grc/src/grc/gui/FileDialogs.py @@ -0,0 +1,155 @@ +""" +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 +""" +##@package grc.gui.FileDialogs +#The open/save dialog for flow graph fFileDialogiles and screen shots. +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk +from Dialogs import MessageDialogHelper +from grc.Constants import DEFAULT_FILE_PATH,FLOW_GRAPH_FILE_EXTENSION,IMAGE_FILE_EXTENSION,NEW_FLOGRAPH_TITLE +from os import path + +OPEN_FLOW_GRAPH = 'open flow graph' +SAVE_FLOW_GRAPH = 'save flow graph' +SAVE_IMAGE = 'save image' + +##the filter for flow graph files +FLOW_GRAPH_FILE_FILTER = gtk.FileFilter() +FLOW_GRAPH_FILE_FILTER.set_name('GRC Files') +FLOW_GRAPH_FILE_FILTER.add_pattern('*'+FLOW_GRAPH_FILE_EXTENSION) +FLOW_GRAPH_FILE_FILTER.add_pattern('*.xml') #TEMP + +##the filter for image files +IMAGE_FILE_FILTER = gtk.FileFilter() +IMAGE_FILE_FILTER.set_name('Image Files') +IMAGE_FILE_FILTER.add_pattern('*'+IMAGE_FILE_EXTENSION) + +##the filter for all files +ALL_FILE_FILTER = gtk.FileFilter() +ALL_FILE_FILTER.set_name('All Files') +ALL_FILE_FILTER.add_pattern('*') + +class FileDialogHelper(gtk.FileChooserDialog): + """ + A wrapper class for the gtk file chooser dialog. + Implement a file chooser dialog with only necessary parameters. + """ + + def __init__(self, action, title): + """! + FileDialogHelper contructor. + Create a save or open dialog with cancel and ok buttons. + Use standard settings: no multiple selection, local files only, and the * filter. + @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE + @param title the title of the dialog (string) + """ + ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action] + gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK)) + self.set_select_multiple(False) + self.set_local_only(True) + self.add_filter(ALL_FILE_FILTER) + +class FileDialog(FileDialogHelper): + """A dialog box to save or open flow graph files. This is a base class, do not use.""" + + def __init__(self, current_file_path=''): + """! + FileDialog constructor. + @param current_file_path the current directory or path to the open flow graph + """ + if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + FLOW_GRAPH_FILE_EXTENSION) + if self.type == OPEN_FLOW_GRAPH: + FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...') + self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER) + self.set_select_multiple(True) + elif self.type == SAVE_FLOW_GRAPH: + FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...') + self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER) + self.set_current_name(path.basename(current_file_path)) #show the current filename + elif self.type == SAVE_IMAGE: + FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...') + self.add_and_set_filter(IMAGE_FILE_FILTER) + current_file_path = current_file_path + IMAGE_FILE_EXTENSION + self.set_current_name(path.basename(current_file_path)) #show the current filename + self.set_current_folder(path.dirname(current_file_path)) #current directory + + def add_and_set_filter(self, filter): + """! + Add the gtk file filter to the list of filters and set it as the default file filter. + @param filter a gtk file filter. + """ + self.add_filter(filter) + self.set_filter(filter) + + def get_rectified_filename(self): + """! + Run the dialog and get the filename. + If this is a save dialog and the file name is missing the extension, append the file extension. + If the file name with the extension already exists, show a overwrite dialog. + If this is an open dialog, return a list of filenames. + @return the complete file path + """ + if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel + ############################################# + # Handle Save Dialogs + ############################################# + if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE): + filename = self.get_filename() + for extension, filter in ( + (FLOW_GRAPH_FILE_EXTENSION, FLOW_GRAPH_FILE_FILTER), + (IMAGE_FILE_EXTENSION, IMAGE_FILE_FILTER), + ): #append the missing file extension if the filter matches + if filename[len(filename)-len(extension):] != extension \ + and filter == self.get_filter(): filename += extension + self.set_current_name(path.basename(filename)) #show the filename with extension + if path.exists(filename): #ask the user to confirm overwrite + if MessageDialogHelper( + gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!', + 'File <b>"%s"</b> Exists!\nWould you like to overwrite the existing file?'%filename, + ) == gtk.RESPONSE_NO: return self.get_rectified_filename() + return filename + ############################################# + # Handle Open Dialogs + ############################################# + elif self.type in (OPEN_FLOW_GRAPH,): + filenames = self.get_filenames() + for filename in filenames: + if not path.exists(filename): #show a warning and re-run + MessageDialogHelper( + gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!', + 'File <b>"%s"</b> Does not Exist!'%filename, + ) + return self.get_rectified_filename() + return filenames + + def run(self): + """! + Get the filename and destroy the dialog. + @return the filename or None if a close/cancel occured. + """ + filename = self.get_rectified_filename() + self.destroy() + return filename + +class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH +class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH +class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE + diff --git a/grc/src/grc/gui/MainWindow.py b/grc/src/grc/gui/MainWindow.py new file mode 100644 index 000000000..837de863f --- /dev/null +++ b/grc/src/grc/gui/MainWindow.py @@ -0,0 +1,321 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.MainWindow +#The main window, containing all windows, tool bars, and menu bars. +#@author Josh Blum + +from grc.Constants import * +from grc.Actions import * +import pygtk +pygtk.require('2.0') +import gtk +import Bars +from BlockTreeWindow import BlockTreeWindow +from Dialogs import TextDisplay,MessageDialogHelper +from DrawingArea import DrawingArea +from grc import Preferences +from grc import Messages +from NotebookPage import Page +import os + +############################################################ +# Main window +############################################################ + +class MainWindow(gtk.Window): + """The topmost window with menus, the tool bar, and other major windows.""" + + def __init__(self, handle_states, platform): + """! + MainWindow contructor. + @param handle_states the callback function + """ + self._platform = platform + #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) + #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.drawing_area = DrawingArea(self) + self.scrolled_window.add_with_viewport(self.drawing_area) + #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(BlockTreeWindow(platform, self.get_flow_graph)) #allow 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.notebook.hide() + self._show_reports_window(False) + # load preferences and show the main window + Preferences.load(platform) + self.resize(*Preferences.window_size()) + 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) + Messages.send_page_switch(self.current_page.get_file_path()) + self.handle_states() + + ############################################################ + # Report Window + ############################################################ + + def add_report_line(self, line): + """! + Place line 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) + vadj.emit('changed') + + 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='', show=False): + """! + Create a new notebook page. + Set the tab to be selected. + @param file_path optional file to load into the flow graph + @param show true if the page should be shown after loading + """ + #if the file is already open, show the open page and return + 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) + flow_graph = self._platform.get_new_flow_graph() + #inject drawing area and handle states into flow graph + flow_graph.drawing_area = self.drawing_area + flow_graph.handle_states = self.handle_states + page = Page( + self, + flow_graph=flow_graph, + file_path=file_path, + ) + if file_path: Messages.send_end_load() + except Exception, e: #return on failure + Messages.send_fail_load(e) + return + #add this page to the notebook + self.notebook.append_page(page, page.get_tab()) + try: self.notebook.set_tab_reorderable(page, True) + except: pass #gtk too old + self.notebook.set_tab_label_packing(page, False, False, gtk.PACK_START) + #only show if blank or manual + if not file_path or show: self._set_page(page) + + def close_pages(self): + """ + Close all the pages in this notebook. + @return true if all closed + """ + open_files = filter(lambda file: file, self._get_files()) #filter blank files + open_file = self.get_page().get_file_path() + #close each page + for page in self._get_pages(): + self.page_to_be_closed = page + self.close_page(False) + if self.notebook.get_n_pages(): return False + #save state before closing + Preferences.files_open(open_files) + Preferences.file_open(open_file) + Preferences.window_size(self.get_size()) + Preferences.save() + return True + + def close_page(self, ensure=True): + """ + Close the current page. + If the notebook becomes empty, and ensure is true, + call new page upon exit to ensure that at least one page exists. + @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() 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(): self.handle_states(FLOW_GRAPH_KILL) + #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(): + title = os.path.basename(page.get_file_path()) + #strip file extension #TEMP + if title.endswith('.xml'): + title = title[0:-len('.xml')] + #strip file extension + if title.endswith(FLOW_GRAPH_FILE_EXTENSION): + title = title[0:-len(FLOW_GRAPH_FILE_EXTENSION)] + page.set_text(''.join(( + (title or NEW_FLOGRAPH_TITLE), + (page.get_saved() and ' ' or '*'), #blank must be non empty + ) + ) + ) + #reports window + self._show_reports_window(Preferences.show_reports_window()) + #show/hide notebook tabs + if len(self._get_pages()) > 1: self.notebook.show() + else: self.notebook.hide() + + def get_page(self): + """! + Get the selected page. + @return the selected page + """ + return self.current_page + + def get_flow_graph(self): + """! + Get the selected flow graph. + @return the selected flow graph + """ + return self.get_page().get_flow_graph() + + ############################################################ + # 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())] + diff --git a/grc/src/grc/gui/Makefile.am b/grc/src/grc/gui/Makefile.am new file mode 100644 index 000000000..c9069beac --- /dev/null +++ b/grc/src/grc/gui/Makefile.am @@ -0,0 +1,37 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = elements + +ourpythondir = $(pythondir)/grc/gui + +ourpython_PYTHON = \ + __init__.py \ + Bars.py \ + BlockTreeWindow.py \ + Dialogs.py \ + DrawingArea.py \ + FileDialogs.py \ + MainWindow.py \ + NotebookPage.py \ + ParamsDialog.py diff --git a/grc/src/grc/gui/NotebookPage.py b/grc/src/grc/gui/NotebookPage.py new file mode 100644 index 000000000..71b6cdcfb --- /dev/null +++ b/grc/src/grc/gui/NotebookPage.py @@ -0,0 +1,176 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.NotebookPage +#A page in the notebook, represents an individual flow graph. +#@author Josh Blum + +from grc.Actions import * +import pygtk +pygtk.require('2.0') +import gtk +from grc import ParseXML +from grc.StateCache import StateCache +from grc.Constants import FLOW_GRAPH_DTD +import os + +############################################################ +## Notebook Page +############################################################ + +class Page(gtk.HBox): + """A page in the notebook.""" + + def __init__(self, main_window, flow_graph, file_path=''): + """ + Page constructor. + @param main_window main window + @param file_path path to a flow graph file + """ + self._flow_graph = flow_graph + self.set_pid(None) + #import the file + self.main_window = main_window + self.set_file_path(file_path) + file_path = file_path or flow_graph.get_parent().get_default_flow_graph() + ############################################################ + from grc import converter + converter.convert(file_path, flow_graph.get_parent()) + ############################################################ + ParseXML.validate_dtd(file_path, FLOW_GRAPH_DTD) + initial_state = ParseXML.from_file(file_path) + self.state_cache = StateCache(initial_state) + self.set_saved(True) + #import the data to the flow graph + self.get_flow_graph().import_data(initial_state) + self.get_flow_graph().update() + #initialize page gui + 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, False) + #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, False) + self.tab.show_all() + + def get_generator(self): + """! + Get the generator object for this flow graph. + @return generator + """ + return self.get_flow_graph().get_parent().get_generator()( + self.get_flow_graph(), + self.get_file_path(), + ) + + 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(self): + """! + Get the pid for the flow graph. + @return the pid number + """ + return self.pid + + def set_pid(self, pid): + """! + Set the pid number. + @param pid the new pid number + """ + self.pid = pid + + def get_flow_graph(self): + """! + Get the flow graph. + @return the flow graph + """ + return self._flow_graph + + 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 + diff --git a/grc/src/grc/gui/ParamsDialog.py b/grc/src/grc/gui/ParamsDialog.py new file mode 100644 index 000000000..9e0677918 --- /dev/null +++ b/grc/src/grc/gui/ParamsDialog.py @@ -0,0 +1,135 @@ +""" +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 +""" +##@package grc.gui.ParamsDialog +#A dialog for editing a block's parameters. +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk + +from Dialogs import TextDisplay +from grc.Constants import MIN_DIALOG_WIDTH,MIN_DIALOG_HEIGHT + +def get_title_label(title): + """! + Get a title label for the params window. + The title will be bold, underlined, and left justified. + @param title the text of the title + @return a gtk object + """ + label = gtk.Label() + label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title) + hbox = gtk.HBox() + hbox.pack_start(label, False, False, padding=11) + return hbox + +class ParamsDialog(gtk.Dialog): + """A dialog box to set block parameters.""" + + def __init__(self, block): + """! + SignalBlockParamsDialog contructor. + @param block the signal block + """ + gtk.Dialog.__init__(self, buttons=('gtk-close', gtk.RESPONSE_CLOSE)) + self.block = block + self.set_title('Properties: %s'%block.get_name()) + self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT) + vbox = gtk.VBox() + #Add the title label + vbox.pack_start(get_title_label('Parameters'), False) + #Create the scrolled window to hold all the parameters + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolled_window.add_with_viewport(vbox) + self.vbox.pack_start(scrolled_window, True) + #Error Messages for the block + self._error_messages_box = err_box = gtk.VBox() + self._error_messages_text_display = TextDisplay('') + err_box.pack_start(gtk.Label(''), False, False, 7) #spacing + err_box.pack_start(get_title_label('Error Messages'), False) + err_box.pack_start(self._error_messages_text_display, False) + #Add all the parameters + for param in self.block.get_params(): + vbox.pack_start(param.get_input_object(self._handle_changed), False) + vbox.pack_start(err_box, False) + #Done adding parameters + if self.block.get_doc(): + vbox.pack_start(gtk.Label(''), False, False, 7) #spacing + vbox.pack_start(get_title_label('Documentation'), False) + #Create the text box to display notes about the block + vbox.pack_start(TextDisplay(self.block.get_doc()), False) + self.connect('key_press_event', self._handle_key_press) + self.show_all() + #initial update + for param in self.block.get_params(): param.update() + self._update_error_messages() + + def _update_error_messages(self): + """ + Update the error messages in the error messages box. + Hide the box if there are no errors. + """ + if self.block.is_valid(): self._error_messages_box.hide() + else: self._error_messages_box.show() + messages = '\n'.join(self.block.get_error_messages()) + self._error_messages_text_display.set_text(messages) + + def _handle_key_press(self, widget, event): + """! + Handle key presses from the keyboard. + Call the ok response when enter is pressed. + @return false to forward the keypress + """ + keyname = gtk.gdk.keyval_name(event.keyval) + if keyname == 'Return': self.response(gtk.RESPONSE_OK) + return False #forward the keypress + + def _handle_changed(self, param): + """! + A change occured, update any dependent parameters: + The enum inside the variable type may have changed and, + the variable param will need an external update. + @param param the graphical parameter that initiated the callback + """ + self._update_error_messages() + #update dependent params + if param.is_enum(): + for other_param in param.get_parent().get_params(): + if param.get_key() is not other_param.get_key() and ( + param.get_key() in other_param._type or \ + param.get_key() in other_param._hide): other_param.update() + return True + + def run(self): + """! + Call run(). + @return true if a change occured. + """ + original_data = list() + for param in self.block.get_params(): + original_data.append(param.get_value()) + gtk.Dialog.run(self) + self.destroy() + new_data = list() + for param in self.block.get_params(): + new_data.append(param.get_value()) + return original_data != new_data + diff --git a/grc/src/grc/gui/__init__.py b/grc/src/grc/gui/__init__.py new file mode 100644 index 000000000..732931139 --- /dev/null +++ b/grc/src/grc/gui/__init__.py @@ -0,0 +1,27 @@ +""" +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 +""" +##@package grc.gui +#GTK based classes go into this package. +#@author Josh Blum + +#only import the modules that need external access +from MainWindow import MainWindow +from FileDialogs import OpenFlowGraphFileDialog,SaveFlowGraphFileDialog,SaveImageFileDialog +from Dialogs import PreferencesDialog,MessageDialogHelper,AboutDialog,HotKeysDialog + diff --git a/grc/src/grc/gui/elements/Block.py b/grc/src/grc/gui/elements/Block.py new file mode 100644 index 000000000..e6f5a107c --- /dev/null +++ b/grc/src/grc/gui/elements/Block.py @@ -0,0 +1,195 @@ +""" +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 +""" +##@package grc.gui.elements.Block +#The graphical signal block. +#@author Josh Blum + +from grc import Preferences +from Element import Element +import Utils +import Colors +from grc.Constants import * +import pygtk +pygtk.require('2.0') +import gtk +import pango + +class Block(Element): + """The graphical signal block.""" + + def __init__(self, *args, **kwargs): + """! + Block contructor. + Add graphics related params to the block. + """ + #add the position param + self._params['_coordinate'] = self.get_parent().get_parent().Param( + self, + { + 'name': 'GUI Coordinate', + 'key': '_coordinate', + 'type': 'raw', + 'value': '(0, 0)', + 'hide': 'all', + } + ) + self._params['_rotation'] = self.get_parent().get_parent().Param( + self, + { + 'name': 'GUI Rotation', + 'key': '_rotation', + 'type': 'raw', + 'value': '0', + 'hide': 'all', + } + ) + Element.__init__(self) + + def get_coordinate(self): + """! + Get the coordinate from the position param. + @return the coordinate tuple (x, y) or (0, 0) if failure + """ + try: #should evaluate to tuple + coor = eval(self.get_param('_coordinate').get_value()) + x, y = map(int, coor) + fgW,fgH = self.get_parent().get_size() + if x <= 0: + x = 0 + elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY: + x = fgW - BORDER_PROXIMITY_SENSITIVITY + if y <= 0: + y = 0 + elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY: + y = fgH - BORDER_PROXIMITY_SENSITIVITY + return (x, y) + except: + self.set_coordinate((0, 0)) + return (0, 0) + + def set_coordinate(self, coor): + """! + Set the coordinate into the position param. + @param coor the coordinate tuple (x, y) + """ + self.get_param('_coordinate').set_value(str(coor)) + + def get_rotation(self): + """! + Get the rotation from the position param. + @return the rotation in degrees or 0 if failure + """ + try: #should evaluate to dict + rotation = eval(self.get_param('_rotation').get_value()) + return int(rotation) + except: + self.set_rotation(POSSIBLE_ROTATIONS[0]) + return POSSIBLE_ROTATIONS[0] + + def set_rotation(self, rot): + """! + Set the rotation into the position param. + @param rot the rotation in degrees + """ + self.get_param('_rotation').set_value(str(rot)) + + def update(self): + """Update the block, parameters, and ports when a change occurs.""" + self.bg_color = self.get_enabled() and Colors.BG_COLOR or Colors.DISABLED_BG_COLOR + self.clear() + self._create_labels() + self.W = self.label_width + 2*LABEL_PADDING_WIDTH + max_ports = max(len(self.get_sinks()), len(self.get_sources()), 1) + self.H = max(self.label_height+2*LABEL_PADDING_HEIGHT, 2*PORT_BORDER_SEPARATION + max_ports*PORT_HEIGHT + (max_ports-1)*PORT_SEPARATION) + if self.is_horizontal(): self.add_area((0,0),(self.W,self.H)) + elif self.is_vertical(): self.add_area((0,0),(self.H,self.W)) + map(lambda p: p.update(), self.get_sinks() + self.get_sources()) + + def _create_labels(self): + """Create the labels for the signal block.""" + layouts = list() + #create the main layout + layout = gtk.DrawingArea().create_pango_layout('') + layouts.append(layout) + if self.is_valid(): layout.set_markup('<b>'+Utils.xml_encode(self.get_name())+'</b>') + else: layout.set_markup('<span foreground="red"><b>'+Utils.xml_encode(self.get_name())+'</b></span>') + desc = pango.FontDescription(BLOCK_FONT) + layout.set_font_description(desc) + self.label_width, self.label_height = layout.get_pixel_size() + #display the params (except for the special params id and position) + if Preferences.show_params(): + for param in filter(lambda p: p.get_hide() not in ('all', 'part'), self.get_params()): + if not Preferences.show_id() and param.get_key() == 'id': continue + layout = param.get_layout() + layouts.append(layout) + w,h = layout.get_pixel_size() + self.label_width = max(w, self.label_width) + self.label_height = self.label_height + h + LABEL_SEPARATION + width = self.label_width + height = self.label_height + #setup the pixmap + pixmap = gtk.gdk.Pixmap(self.get_parent().get_window(), width, height, -1) + gc = pixmap.new_gc() + gc.foreground = self.bg_color + pixmap.draw_rectangle(gc, True, 0, 0, width, height) + gc.foreground = Colors.TXT_COLOR + #draw the layouts + h_off = 0 + for i,layout in enumerate(layouts): + w,h = layout.get_pixel_size() + if i == 0: w_off = (width-w)/2 + else: w_off = 0 + pixmap.draw_layout(gc, w_off, h_off, layout) + h_off = h + h_off + LABEL_SEPARATION + #create vertical and horizontal images + self.horizontal_label = image = pixmap.get_image(0, 0, width, height) + if self.is_vertical(): + self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width) + for i in range(width): + for j in range(height): vimage.put_pixel(j, width-i-1, image.get_pixel(i, j)) + + def draw(self, window): + """! + Draw the signal block with label and inputs/outputs. + @param window the gtk window to draw on + """ + x, y = self.get_coordinate() + #draw main block + Element.draw(self, window, BG_color=self.bg_color) + #draw label image + gc = self.get_gc() + if self.is_horizontal(): + window.draw_image(gc, self.horizontal_label, 0, 0, x+LABEL_PADDING_WIDTH, y+(self.H-self.label_height)/2, -1, -1) + elif self.is_vertical(): + window.draw_image(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+LABEL_PADDING_WIDTH, -1, -1) + #draw ports + map(lambda p: p.draw(window), self.get_ports()) + + def what_is_selected(self, coor, coor_m=None): + """! + Get the element that is selected. + @param coor the (x,y) tuple + @param coor_m the (x_m, y_m) tuple + @return this block, a port, or None + """ + for port in self.get_ports(): + port_selected = port.what_is_selected(coor, coor_m) + if port_selected: return port_selected + return Element.what_is_selected(self, coor, coor_m) + diff --git a/grc/src/grc/gui/elements/Colors.py b/grc/src/grc/gui/elements/Colors.py new file mode 100644 index 000000000..80be8eba0 --- /dev/null +++ b/grc/src/grc/gui/elements/Colors.py @@ -0,0 +1,37 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.elements.Colors +#Global Colors for the gui +#@author Josh Blum + +import pygtk +pygtk.require('2.0') +import gtk + +COLORMAP = gtk.gdk.colormap_get_system() #create all of the colors +def get_color(color_code): return COLORMAP.alloc_color(color_code, True, True) + +BACKGROUND_COLOR = get_color('#FFF9FF') #main window background +FG_COLOR = get_color('black') #normal border color +BG_COLOR = get_color('#F1ECFF') #default background +DISABLED_BG_COLOR = get_color('#CCCCCC') #disabled background +DISABLED_FG_COLOR = get_color('#999999') #disabled foreground +H_COLOR = get_color('#00FFFF') #Highlight border color +TXT_COLOR = get_color('black') #text color +ERROR_COLOR = get_color('red') #error color diff --git a/grc/src/grc/gui/elements/Connection.py b/grc/src/grc/gui/elements/Connection.py new file mode 100644 index 000000000..c2e5edcfd --- /dev/null +++ b/grc/src/grc/gui/elements/Connection.py @@ -0,0 +1,170 @@ +""" +Copyright 2007, 2008 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 +""" +##@package grc.gui.elements.Connection +#The graphical connection for input/output ports. +#@author Josh Blum + +import Utils +from Element import Element +import Colors +from grc.Constants import CONNECTOR_ARROW_BASE,CONNECTOR_ARROW_HEIGHT + +class Connection(Element): + """A graphical connection for ports.""" + + def get_coordinate(self): + """! + Get the 0,0 coordinate. + Coordinates are irrelevant in connection. + @return 0, 0 + """ + return (0, 0) + + def get_rotation(self): + """! + Get the 0 degree rotation. + Rotations are irrelevant in connection. + @return 0 + """ + return 0 + + def update(self): + """Precalculate relative coordinates.""" + self._sink_rot = None + self._source_rot = None + self._sink_coor = None + self._source_coor = None + + sink = self.get_sink() + source = self.get_source() + + #get the source coordinate + x1, y1 = 0, 0 + connector_length = source.get_connector_length() + if source.get_rotation() == 0: + x1 = 0 + connector_length + elif source.get_rotation() == 90: + y1 = 0 - connector_length + elif source.get_rotation() == 180: + x1 = 0 - connector_length + elif source.get_rotation() == 270: + y1 = 0 + connector_length + self.x1, self.y1 = x1, y1 + + #get the sink coordinate + x2, y2 = 0, 0 + connector_length = sink.get_connector_length() + CONNECTOR_ARROW_HEIGHT + if sink.get_rotation() == 0: + x2 = 0 - connector_length + elif sink.get_rotation() == 90: + y2 = 0 + connector_length + elif sink.get_rotation() == 180: + x2 = 0 + connector_length + elif sink.get_rotation() == 270: + y2 = 0 - connector_length + self.x2, self.y2 = x2, y2 + + #build the arrow + if sink.get_rotation() == 0: + self.arrow = [(0, 0), (0-CONNECTOR_ARROW_HEIGHT, 0-CONNECTOR_ARROW_BASE/2), (0-CONNECTOR_ARROW_HEIGHT, 0+CONNECTOR_ARROW_BASE/2)] + elif sink.get_rotation() == 90: + self.arrow = [(0, 0), (0-CONNECTOR_ARROW_BASE/2, 0+CONNECTOR_ARROW_HEIGHT), (0+CONNECTOR_ARROW_BASE/2, 0+CONNECTOR_ARROW_HEIGHT)] + elif sink.get_rotation() == 180: + self.arrow = [(0, 0), (0+CONNECTOR_ARROW_HEIGHT, 0-CONNECTOR_ARROW_BASE/2), (0+CONNECTOR_ARROW_HEIGHT, 0+CONNECTOR_ARROW_BASE/2)] + elif sink.get_rotation() == 270: + self.arrow = [(0, 0), (0-CONNECTOR_ARROW_BASE/2, 0-CONNECTOR_ARROW_HEIGHT), (0+CONNECTOR_ARROW_BASE/2, 0-CONNECTOR_ARROW_HEIGHT)] + + self._update_after_move() + + def _update_after_move(self): + """Calculate coordinates.""" + + self.clear() + + #source connector + source = self.get_source() + X, Y = source.get_connector_coordinate() + x1, y1 = self.x1 + X, self.y1 + Y + self.add_line((x1, y1), (X, Y)) + + #sink connector + sink = self.get_sink() + X, Y = sink.get_connector_coordinate() + x2, y2 = self.x2 + X, self.y2 + Y + self.add_line((x2, y2), (X, Y)) + + #adjust arrow + self._arrow = [(x+X, y+Y) for x,y in self.arrow] + + #add the horizontal and vertical lines in this connection + if abs(source.get_connector_direction() - sink.get_connector_direction()) == 180: + W = abs(x1 - x2) + H = abs(y1 - y2) + midX = (x1+x2)/2 + midY = (y1+y2)/2 + sW = x1 - x2 + if source.get_connector_direction() == 0: sW = sW * -1 + sH = y1 - y2 + if source.get_connector_direction() == 270: sH = sH * -1 + if ((W>H or sW<0) and self.is_horizontal(source.get_connector_direction())) or \ + (W>=H and sH>=0 and self.is_vertical(source.get_connector_direction())): + self.add_line((x1,y1),(x1,midY)) + self.add_line((x1,midY),(x2,midY)) + self.add_line((x2,y2),(x2,midY)) + elif (H>=W and sW>=0 and self.is_horizontal(source.get_connector_direction())) or \ + ((H>W or sH<0) and self.is_vertical(source.get_connector_direction())): + self.add_line((x1,y1),(midX,y1)) + self.add_line((midX,y1),(midX,y2)) + self.add_line((x2,y2),(midX,y2)) + else: + #2 possible points to create a right-angled bend between the connectors + points = [(x1, y2), (x2, y1)] + #source connector -> points[0] should be in the direction of source (if possible) + if Utils.get_angle_from_coordinates((x1, y1), points[0]) != source.get_connector_direction(): points.reverse() + #points[0] -> sink connector should not be in the direction of sink + if Utils.get_angle_from_coordinates(points[0], (x2, y2)) == sink.get_connector_direction(): points.reverse() + #points[0] -> source connector should not be in the direction of source + if Utils.get_angle_from_coordinates(points[0], (x1, y1)) == source.get_connector_direction(): points.reverse() + #create right-angled connector + self.add_line((x1, y1), points[0]) + self.add_line((x2, y2), points[0]) + + def draw(self, window): + """! + Draw the connection. + @param window the gtk window to draw on + """ + sink = self.get_sink() + source = self.get_source() + #check for changes + if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.update() + elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate(): self._update_after_move() + #cache values + self._sink_rot = sink.get_rotation() + self._source_rot = source.get_rotation() + self._sink_coor = sink.get_coordinate() + self._source_coor = source.get_coordinate() + #draw + fg_color = self.get_enabled() and Colors.FG_COLOR or Colors.DISABLED_FG_COLOR + Element.draw(self, window, FG_color=fg_color) + gc = self.get_gc() + if self.is_valid(): gc.foreground = Colors.FG_COLOR + else: gc.foreground = Colors.ERROR_COLOR + #draw arrow on sink port + window.draw_polygon(gc, True, self._arrow) diff --git a/grc/src/grc/gui/elements/Element.py b/grc/src/grc/gui/elements/Element.py new file mode 100644 index 000000000..c3492d052 --- /dev/null +++ b/grc/src/grc/gui/elements/Element.py @@ -0,0 +1,234 @@ +""" +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 +""" +##@package grc.gui.elements.Element +#Base class for graphical elements such as: +#signal blocks, input sockets, output sockets and connections. +#@author Josh Blum + +import Colors +import pygtk +pygtk.require('2.0') +import gtk +import pango +from grc.Constants import * + +class Element(object): + """ + GraphicalElement is the base class for all graphical elements. + It contains an X,Y coordinate, a list of rectangular areas that the element occupies, + and methods to detect selection of those areas. + """ + + def __init__(self, *args, **kwargs): + """! + Make a new list of rectangular areas and lines, and set the coordinate and the rotation. + """ + self.set_rotation(POSSIBLE_ROTATIONS[0]) + self.set_coordinate((0, 0)) + self.clear() + self.set_highlighted(False) + + def is_horizontal(self, rotation=None): + """! + Is this element horizontal? + If rotation is None, use this element's rotation. + @param rotation the optional rotation + @return true if rotation is horizontal + """ + rotation = rotation or self.get_rotation() + return rotation in (0, 180) + + def is_vertical(self, rotation=None): + """! + Is this element vertical? + If rotation is None, use this element's rotation. + @param rotation the optional rotation + @return true if rotation is vertical + """ + rotation = rotation or self.get_rotation() + return rotation in (90, 270) + + def get_gc(self): return self._gc + + def draw(self, window, BG_color=Colors.BG_COLOR, FG_color=Colors.FG_COLOR): + """! + Draw in the given window. + @param window the gtk window to draw on + @param BG_color the background color + @param FG_color the foreground color + """ + gc = self.get_parent().get_gc() + self._gc = gc + X,Y = self.get_coordinate() + for (rX,rY),(W,H) in self.areas_dict[self.get_rotation()]: + aX = X + rX + aY = Y + rY + gc.foreground = BG_color + window.draw_rectangle(gc, True, aX, aY, W, H) + gc.foreground = self.is_highlighted() and Colors.H_COLOR or FG_color + window.draw_rectangle(gc, False, aX, aY, W, H) + for (x1, y1),(x2, y2) in self.lines_dict[self.get_rotation()]: + gc.foreground = self.is_highlighted() and Colors.H_COLOR or FG_color + window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2) + + def rotate(self, direction): + """! + Rotate all of the areas by 90 degrees. + @param direction 90 or 270 degrees + """ + self.set_rotation((self.get_rotation() + direction)%360) + + def clear(self): + """Empty the lines and areas.""" + self.areas_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS) + self.lines_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS) + + def set_coordinate(self, coor): + """! + Set the reference coordinate. + @param coor the coordinate tuple (x,y) + """ + self.coor = coor + + def get_parent(self): + """! + Get the parent of this element. + @return the parent + """ + return self.parent + + def set_highlighted(self, highlighted): + """! + Set the highlight status. + @param highlighted true to enable highlighting + """ + self.highlighted = highlighted + + def is_highlighted(self): + """! + Get the highlight status. + @return true if highlighted + """ + return self.highlighted + + def get_coordinate(self): + """!Get the coordinate. + @return the coordinate tuple (x,y) + """ + return self.coor + + def move(self, delta_coor): + """! + Move the element by adding the delta_coor to the current coordinate. + @param delta_coor (delta_x,delta_y) tuple + """ + deltaX, deltaY = delta_coor + X, Y = self.get_coordinate() + self.set_coordinate((X+deltaX, Y+deltaY)) + + def add_area(self, rel_coor, area, rotation=None): + """! + Add an area to the area list. + An area is actually a coordinate relative to the main coordinate + with a width/height pair relative to the area coordinate. + A positive width is to the right of the coordinate. + A positive height is above the coordinate. + The area is associated with a rotation. + If rotation is not specified, the element's current rotation is used. + @param rel_coor (x,y) offset from this element's coordinate + @param area (width,height) tuple + @param rotation rotation in degrees + """ + self.areas_dict[rotation or self.get_rotation()].append((rel_coor, area)) + + def add_line(self, rel_coor1, rel_coor2, rotation=None): + """! + Add a line to the line list. + A line is defined by 2 relative coordinates. + Lines must be horizontal or vertical. + The line is associated with a rotation. + If rotation is not specified, the element's current rotation is used. + @param rel_coor1 relative (x1,y1) tuple + @param rel_coor2 relative (x2,y2) tuple + @param rotation rotation in degrees + """ + self.lines_dict[rotation or self.get_rotation()].append((rel_coor1, rel_coor2)) + + def what_is_selected(self, coor, coor_m=None): + """! + One coordinate specified: + Is this element selected at given coordinate? + ie: is the coordinate encompassed by one of the areas or lines? + Both coordinates specified: + Is this element within the rectangular region defined by both coordinates? + ie: do any area corners or line endpoints fall within the region? + @param coor the selection coordinate, tuple x, y + @param coor_m an additional selection coordinate. + @return self if one of the areas/lines encompasses coor, else None. + """ + #function to test if p is between a and b (inclusive) + in_between = lambda p, a, b: p >= min(a, b) and p <= max(a, b) + #relative coordinate + x, y = [a-b for a,b in zip(coor, self.get_coordinate())] + if coor_m: + x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())] + #handle rectangular areas + for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]: + if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \ + in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \ + in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \ + in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m): + return self + #handle horizontal or vertical lines + for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]: + if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \ + in_between(x2, x, x_m) and in_between(y2, y, y_m): + return self + return None + else: + #handle rectangular areas + for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]: + if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self + #handle horizontal or vertical lines + for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]: + if x1 == x2: x1, x2 = x1-CONNECTION_SELECT_SENSITIVITY, x2+CONNECTION_SELECT_SENSITIVITY + if y1 == y2: y1, y2 = y1-CONNECTION_SELECT_SENSITIVITY, y2+CONNECTION_SELECT_SENSITIVITY + if in_between(x, x1, x2) and in_between(y, y1, y2): return self + return None + + def get_rotation(self): + """! + Get the rotation in degrees. + @return the rotation + """ + return self.rotation + + def set_rotation(self, rotation): + """! + Set the rotation in degrees. + @param rotation the rotation""" + if rotation not in POSSIBLE_ROTATIONS: + raise Exception('"%s" is not one of the possible rotations: (%s)'%(rotation,POSSIBLE_ROTATIONS)) + self.rotation = rotation + + def update(self): + """Do nothing for the update. Dummy method.""" + pass + + diff --git a/grc/src/grc/gui/elements/FlowGraph.py b/grc/src/grc/gui/elements/FlowGraph.py new file mode 100644 index 000000000..e9397ad71 --- /dev/null +++ b/grc/src/grc/gui/elements/FlowGraph.py @@ -0,0 +1,566 @@ +""" +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 +""" +##@package grc.gui.elements.FlowGraph +#A flow graph structure for storing signal blocks and their connections. +#@author Josh Blum + +from grc import Preferences +from grc import Utils +from grc.Constants import * +from grc.Actions import * +import Colors +from grc.gui.ParamsDialog import ParamsDialog +from Element import Element +from grc.elements import FlowGraph as _FlowGraph + +import pygtk +pygtk.require('2.0') +import gtk + +import random +import time +from grc import Messages + +class FlowGraph(Element): + """ + FlowGraph is the data structure to store graphical signal blocks, + graphical inputs and outputs, + and the connections between inputs and outputs. + """ + + def __init__(self, *args, **kwargs): + """! + FlowGraph contructor. + Create a list for signal blocks and connections. Connect mouse handlers. + """ + Element.__init__(self) + #when is the flow graph selected? (used by keyboard event handler) + self.is_selected = lambda: bool(self.get_selected_elements()) + #important vars dealing with mouse event tracking + self.element_moved = False + self.mouse_pressed = False + self.unselect() + self.time = 0 + self.press_coor = (0, 0) + #selected ports + self._old_selected_port = None + self._new_selected_port = None + + def _get_unique_id(self, base_id=''): + """! + Get a unique id starting with the base id. + @param base_id the id starts with this and appends a count + @return a unique id + """ + index = -1 + while True: + id = (index < 0) and base_id or '%s%d'%(base_id, index) + index = index + 1 + #make sure that the id is not used by another block + if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id + +########################################################################### +# Access Drawing Area +########################################################################### + def get_drawing_area(self): return self.drawing_area + def get_gc(self): return self.get_drawing_area().gc + def get_pixmap(self): return self.get_drawing_area().pixmap + def get_size(self): return self.get_drawing_area().get_size_request() + def set_size(self, *args): self.get_drawing_area().set_size_request(*args) + def get_window(self): return self.get_drawing_area().window + def get_scroll_pane(self): return self.drawing_area.get_parent() + def get_ctrl_mask(self): return self.drawing_area.ctrl_mask + + def add_new_block(self, key): + """! + Add a block of the given key to this flow graph. + @param key the block key + """ + id = self._get_unique_id(key) + #calculate the position coordinate + h_adj = self.get_scroll_pane().get_hadjustment() + v_adj = self.get_scroll_pane().get_vadjustment() + x = int(random.uniform(.25, .75)*h_adj.page_size + h_adj.get_value()) + y = int(random.uniform(.25, .75)*v_adj.page_size + v_adj.get_value()) + #get the new block + block = self.get_new_block(key) + block.set_coordinate((x, y)) + block.set_rotation(0) + block.get_param('id').set_value(id) + self.handle_states(ELEMENT_CREATE) + + ########################################################################### + # Copy Paste + ########################################################################### + def copy_to_clipboard(self): + """! + Copy the selected blocks and connections into the clipboard. + @return the clipboard + """ + #get selected blocks + blocks = self.get_selected_blocks() + if not blocks: return None + #calc x and y min + x_min, y_min = blocks[0].get_coordinate() + for block in blocks: + x, y = block.get_coordinate() + x_min = min(x, x_min) + y_min = min(y, y_min) + #get connections between selected blocks + connections = filter( + lambda c: c.get_source().get_parent() in blocks and c.get_sink().get_parent() in blocks, + self.get_connections(), + ) + clipboard = ( + (x_min, y_min), + [block.export_data() for block in blocks], + [connection.export_data() for connection in connections], + ) + return clipboard + + def paste_from_clipboard(self, clipboard): + """! + Paste the blocks and connections from the clipboard. + @param clipboard the nested data of blocks, connections + """ + selected = set() + (x_min, y_min), blocks_n, connections_n = clipboard + old_id2block = dict() + #recalc the position + h_adj = self.get_scroll_pane().get_hadjustment() + v_adj = self.get_scroll_pane().get_vadjustment() + x_off = h_adj.get_value() - x_min + h_adj.page_size/4 + y_off = v_adj.get_value() - y_min + v_adj.page_size/4 + #create blocks + for block_n in blocks_n: + block_key = block_n['key'] + if block_key == 'options': continue + block_id = self._get_unique_id(block_key) + block = self.get_new_block(block_key) + selected.add(block) + #set params + params_n = Utils.listify(block_n, 'param') + for param_n in params_n: + param_key = param_n['key'] + param_value = param_n['value'] + #setup id parameter + if param_key == 'id': + old_id2block[param_value] = block + param_value = block_id + #set value to key + block.get_param(param_key).set_value(param_value) + #move block to offset coordinate + block.move((x_off, y_off)) + #create connections + for connection_n in connections_n: + source = old_id2block[connection_n['source_block_id']].get_source(connection_n['source_key']) + sink = old_id2block[connection_n['sink_block_id']].get_sink(connection_n['sink_key']) + self.connect(source, sink) + #set all pasted elements selected + for block in selected: selected = selected.union(set(block.get_connections())) + self._selected_elements = list(selected) + + ########################################################################### + # Modify Selected + ########################################################################### + def type_controller_modify_selected(self, direction): + """! + Change the registered type controller for the selected signal blocks. + @param direction +1 or -1 + @return true for change + """ + changed = False + for selected_block in self.get_selected_blocks(): + for child in selected_block.get_params() + selected_block.get_ports(): + #find a param that controls a type + type_param = None + for param in selected_block.get_params(): + if not type_param and param.is_enum(): type_param = param + if param.is_enum() and param.get_key() in child._type: type_param = param + if type_param: + #try to increment the enum by direction + try: + keys = type_param.get_option_keys() + old_index = keys.index(type_param.get_value()) + new_index = (old_index + direction + len(keys))%len(keys) + type_param.set_value(keys[new_index]) + changed = True + except: pass + return changed + + def port_controller_modify_selected(self, direction): + """! + Change port controller for the selected signal blocks. + @param direction +1 or -1 + @return true for changed + """ + changed = False + for selected_block in self.get_selected_blocks(): + for ports in (selected_block.get_sources(), selected_block.get_sinks()): + if ports and hasattr(ports[0], 'get_nports') and ports[0].get_nports(): + #find the param that controls port0 + for param in selected_block.get_params(): + if param.get_key() in ports[0]._nports: + #try to increment the port controller by direction + try: + value = param.evaluate() + value = value + direction + assert(0 < value <= MAX_NUM_PORTS) + param.set_value(value) + changed = True + except: pass + return changed + + def param_modify_selected(self): + """! + Create and show a param modification dialog for the selected block. + @return true if parameters were changed + """ + if self.get_selected_block(): + signal_block_params_dialog = ParamsDialog(self.get_selected_block()) + return signal_block_params_dialog.run() + return False + + def enable_selected(self, enable): + """! + Enable/disable the selected blocks. + @param enable true to enable + @return true if changed + """ + changed = False + for selected_block in self.get_selected_blocks(): + if selected_block.get_enabled() != enable: + selected_block.set_enabled(enable) + changed = True + return changed + + def move_selected(self, delta_coordinate): + """! + Move the element and by the change in coordinates. + @param delta_coordinate the change in coordinates + """ + for selected_block in self.get_selected_blocks(): + selected_block.move(delta_coordinate) + self.element_moved = True + + def rotate_selected(self, direction): + """! + Rotate the selected blocks by 90 degrees. + @param direction DIR_LEFT or DIR_RIGHT + @return true if changed, otherwise false. + """ + if not self.get_selected_blocks(): return False + #determine the number of degrees to rotate + direction = {DIR_LEFT: 90, DIR_RIGHT:270}[direction] + cos_r = {0: 1, 90: 0, 180: -1, 270: 0}[direction] + sin_r = {0: 0, 90: 1, 180: 0, 270: -1}[direction] + #initialize min and max coordinates + min_x, min_y = self.get_selected_block().get_coordinate() + max_x, max_y = self.get_selected_block().get_coordinate() + #rotate each selected block, and find min/max coordinate + for selected_block in self.get_selected_blocks(): + selected_block.rotate(direction) + #update the min/max coordinate + x, y = selected_block.get_coordinate() + min_x, min_y = min(min_x, x), min(min_y, y) + max_x, max_y = max(max_x, x), max(max_y, y) + #calculate center point of slected blocks + ctr_x, ctr_y = (max_x + min_x)/2, (max_y + min_y)/2 + #rotate the blocks around the center point + for selected_block in self.get_selected_blocks(): + x, y = selected_block.get_coordinate() + x, y = x - ctr_x, y - ctr_y + x, y = (x*cos_r + y*sin_r + ctr_x, -x*sin_r + y*cos_r + ctr_y) + selected_block.set_coordinate((x, y)) + return True + + def remove_selected(self): + """! + Remove selected elements + @return true if changed. + """ + changed = False + for selected_element in self.get_selected_elements(): + self.remove_element(selected_element) + changed = True + return changed + + def draw(self): + """! + Draw the background and grid if enabled. + Draw all of the elements in this flow graph onto the pixmap. + Draw the pixmap to the drawable window of this flow graph. + """ + if self.get_gc(): + W,H = self.get_size() + #draw the background + self.get_gc().foreground = Colors.BACKGROUND_COLOR + self.get_pixmap().draw_rectangle(self.get_gc(), True, 0, 0, W, H) + #draw grid (depends on prefs) + 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.get_gc().foreground = Colors.TXT_COLOR + self.get_pixmap().draw_points(self.get_gc(), points) + #draw multi select rectangle + if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()): + #coordinates + x1, y1 = self.press_coor + x2, y2 = self.get_coordinate() + #calculate top-left coordinate and width/height + x, y = int(min(x1, x2)), int(min(y1, y2)) + w, h = int(abs(x1 - x2)), int(abs(y1 - y2)) + #draw + self.get_gc().foreground = Colors.H_COLOR + self.get_pixmap().draw_rectangle(self.get_gc(), True, x, y, w, h) + self.get_gc().foreground = Colors.TXT_COLOR + self.get_pixmap().draw_rectangle(self.get_gc(), False, x, y, w, h) + #draw blocks on top of connections + for element in self.get_connections() + self.get_blocks(): + element.draw(self.get_pixmap()) + #draw selected blocks on top of selected connections + for selected_element in self.get_selected_connections() + self.get_selected_blocks(): + selected_element.draw(self.get_pixmap()) + self.get_drawing_area().draw() + + def update(self): + """! + Update highlighting so only the selected is highlighted. + Call update on all elements. + Resize the window if size changed. + """ + #update highlighting + map(lambda e: e.set_highlighted(False), self.get_elements()) + for selected_element in self.get_selected_elements(): + selected_element.set_highlighted(True) + #update all elements + map(lambda e: e.update(), self.get_elements()) + #set the size of the flow graph area + old_x, old_y = self.get_size() + try: new_x, new_y = self.get_option('window_size') + except: new_x, new_y = old_x, old_y + if new_x != old_x or new_y != old_y: self.set_size(new_x, new_y) + + ########################################################################## + ## Get Selected + ########################################################################## + def unselect(self): + """! + Set selected elements to an empty set. + """ + self._selected_elements = [] + + def what_is_selected(self, coor, coor_m=None): + """! + What is selected? + At the given coordinate, return the elements found to be selected. + If coor_m is unspecified, return a list of only the first element found to be selected: + Iterate though the elements backwardssince 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. Update the selected port information. + @param coor the coordinate of the mouse click + @param coor_m the coordinate for multi select + @return the selected blocks and connections or an empty list + """ + selected_port = None + selected = set() + #check the elements + for element in reversed(self.get_elements()): + selected_element = element.what_is_selected(coor, coor_m) + if not selected_element: continue + #update the selected port information + if selected_element.is_port(): + if not coor_m: selected_port = selected_element + selected_element = selected_element.get_parent() + selected.add(selected_element) + #single select mode, break + if not coor_m: + self.get_elements().remove(element) + self.get_elements().append(element) + break; + #update selected ports + self._old_selected_port = self._new_selected_port + self._new_selected_port = selected_port + return list(selected) + + def get_selected_connections(self): + """! + Get a group of selected connections. + @return sub set of connections in this flow graph + """ + selected = set() + for selected_element in self.get_selected_elements(): + if selected_element.is_connection(): selected.add(selected_element) + return list(selected) + + def get_selected_blocks(self): + """! + Get a group of selected blocks. + @return sub set of blocks in this flow graph + """ + selected = set() + for selected_element in self.get_selected_elements(): + if selected_element.is_block(): selected.add(selected_element) + return list(selected) + + def get_selected_block(self): + """! + Get the selected block when a block or port is selected. + @return a block or None + """ + return self.get_selected_blocks() and self.get_selected_blocks()[0] or None + + def get_selected_elements(self): + """! + Get the group of selected elements. + @return sub set of elements in this flow graph + """ + return self._selected_elements + + def get_selected_element(self): + """! + Get the selected element. + @return a block, port, or connection or None + """ + return self.get_selected_elements() and self.get_selected_elements()[0] or None + + def update_selected_elements(self): + """! + Update the selected elements. + The update behavior depends on the state of the mouse button. + When the mouse button pressed the selection will change when + the control mask is set or the new selection is not in the current group. + When the mouse button is released the selection will change when + the mouse has moved and the control mask is set or the current group is empty. + Attempt to make a new connection if the old and ports are filled. + If the control mask is set, merge with the current elements. + """ + selected_elements = None + if self.mouse_pressed: + new_selection = self.what_is_selected(self.get_coordinate()) + #update the selections if the new selection is not in the current selections + #allows us to move entire selected groups of elements + if self.get_ctrl_mask() or not ( + new_selection and new_selection[0] in self.get_selected_elements() + ): selected_elements = new_selection + else: #called from a mouse release + if not self.element_moved and (not self.get_selected_elements() or self.get_ctrl_mask()): + selected_elements = self.what_is_selected(self.get_coordinate(), self.press_coor) + #this selection and the last were ports, try to connect them + if self._old_selected_port and self._new_selected_port and \ + self._old_selected_port is not self._new_selected_port: + try: + self.connect(self._old_selected_port, self._new_selected_port) + self.handle_states(ELEMENT_CREATE) + except: Messages.send_fail_connection() + self._old_selected_port = None + self._new_selected_port = None + return + #update selected elements + if selected_elements is None: return + old_elements = set(self.get_selected_elements()) + self._selected_elements = list(set(selected_elements)) + new_elements = set(self.get_selected_elements()) + #if ctrl, set the selected elements to the union - intersection of old and new + if self.get_ctrl_mask(): + self._selected_elements = list( + set.union(old_elements, new_elements) - set.intersection(old_elements, new_elements) + ) + self.handle_states(ELEMENT_SELECT) + + ########################################################################## + ## Event Handlers + ########################################################################## + def handle_mouse_button_press(self, left_click, double_click, coordinate): + """! + A mouse button is pressed, only respond to left clicks. + Find the selected element. Attempt a new connection if possible. + Open the block params window on a double click. + Update the selection state of the flow graph. + """ + if not left_click: return + self.press_coor = coordinate + self.set_coordinate(coordinate) + self.time = 0 + self.mouse_pressed = True + self.update_selected_elements() + #double click detected, bring up params dialog if possible + if double_click and self.get_selected_block(): + self.mouse_pressed = False + self.handle_states(BLOCK_PARAM_MODIFY) + + def handle_mouse_button_release(self, left_click, coordinate): + """! + A mouse button is released, record the state. + """ + if not left_click: return + self.set_coordinate(coordinate) + self.time = 0 + self.mouse_pressed = False + if self.element_moved: + if Preferences.snap_to_grid(): + grid_size = Preferences.get_grid_size() + X,Y = self.get_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(BLOCK_MOVE) + self.element_moved = False + self.update_selected_elements() + self.draw() + + def handle_mouse_motion(self, coordinate): + """! + The mouse has moved, respond to mouse dragging. + Move a selected element to the new coordinate. + Auto-scroll the scroll bars at the boundaries. + """ + #to perform a movement, the mouse must be pressed, timediff large enough + if not self.mouse_pressed: return + if time.time() - self.time < MOTION_DETECT_REDRAWING_SENSITIVITY: return + #perform autoscrolling + width, height = self.get_size() + x, y = coordinate + h_adj = self.get_scroll_pane().get_hadjustment() + v_adj = self.get_scroll_pane().get_vadjustment() + for pos, length, adj, adj_val, adj_len in ( + (x, width, h_adj, h_adj.get_value(), h_adj.page_size), + (y, height, v_adj, v_adj.get_value(), v_adj.page_size), + ): + #scroll if we moved near the border + if pos-adj_val > adj_len-SCROLL_PROXIMITY_SENSITIVITY and adj_val+SCROLL_DISTANCE < length-adj_len: + adj.set_value(adj_val+SCROLL_DISTANCE) + adj.emit('changed') + elif pos-adj_val < SCROLL_PROXIMITY_SENSITIVITY: + adj.set_value(adj_val-SCROLL_DISTANCE) + adj.emit('changed') + #move the selected element and record the new coordinate + X, Y = self.get_coordinate() + if not self.get_ctrl_mask(): self.move_selected((int(x - X), int(y - Y))) + self.draw() + self.set_coordinate((x, y)) + #update time + self.time = time.time() diff --git a/grc/src/grc/gui/elements/Makefile.am b/grc/src/grc/gui/elements/Makefile.am new file mode 100644 index 000000000..f075d4209 --- /dev/null +++ b/grc/src/grc/gui/elements/Makefile.am @@ -0,0 +1,36 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc/gui/elements + +ourpython_PYTHON = \ + __init__.py \ + Block.py \ + Colors.py \ + Connection.py \ + Element.py \ + FlowGraph.py \ + Param.py \ + Platform.py \ + Port.py \ + Utils.py diff --git a/grc/src/grc/gui/elements/Param.py b/grc/src/grc/gui/elements/Param.py new file mode 100644 index 000000000..6e48e7b84 --- /dev/null +++ b/grc/src/grc/gui/elements/Param.py @@ -0,0 +1,224 @@ +""" +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 +""" +##@package grc.gui.elements.Param +#GTK objects for handling input and the signal block parameter class. +#@author Josh Blum + +import Utils +from Element import Element +import pygtk +pygtk.require('2.0') +import gtk +import pango +import gobject +from grc.Constants import * +from os import path + +###################################################################################################### +# gtk objects for handling input +###################################################################################################### + +class InputParam(gtk.HBox): + """The base class for an input parameter inside the input parameters dialog.""" + + def __init__(self, param, _handle_changed): + gtk.HBox.__init__(self) + self.param = param + self._handle_changed = _handle_changed + self.label = gtk.Label('') #no label, markup is added by set_markup + self.label.set_size_request(150, -1) + self.pack_start(self.label, False) + self.set_markup = lambda m: self.label.set_markup(m) + self.tp = None + +class EntryParam(InputParam): + """Provide an entry box for strings and numbers.""" + + def __init__(self, *args, **kwargs): + InputParam.__init__(self, *args, **kwargs) + self.entry = input = gtk.Entry() + input.set_text(self.param.get_value()) + input.connect('changed', self._handle_changed) + self.pack_start(input, True) + self.get_text = input.get_text + #tool tip + self.tp = gtk.Tooltips() + self.tp.set_tip(self.entry, '') + self.tp.enable() + +class FileParam(EntryParam): + """Provide an entry box for filename and a button to browse for a file.""" + + def __init__(self, *args, **kwargs): + EntryParam.__init__(self, *args, **kwargs) + input = gtk.Button('...') + input.connect('clicked', self._handle_clicked) + self.pack_start(input, False) + + def _handle_clicked(self, widget=None): + """ + If the button was clicked, open a file dialog in open/save format. + Replace the text in the entry with the new filename from the file dialog. + """ + file_path = self.param.is_valid() and self.param.evaluate() or '' + #bad file paths will be redirected to default + if not path.exists(path.dirname(file_path)): file_path = DEFAULT_FILE_PATH + if self.param.get_type() == 'file_open': + file_dialog = gtk.FileChooserDialog('Open a Data File...', None, + gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK)) + elif self.param.get_type() == 'file_save': + file_dialog = gtk.FileChooserDialog('Save a Data File...', None, + gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK)) + file_dialog.set_do_overwrite_confirmation(True) + file_dialog.set_current_name(path.basename(file_path)) #show the current filename + file_dialog.set_current_folder(path.dirname(file_path)) #current directory + file_dialog.set_select_multiple(False) + file_dialog.set_local_only(True) + if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog + file_path = file_dialog.get_filename() #get the file path + self.entry.set_text(file_path) + self._handle_changed() + file_dialog.destroy() #destroy the dialog + +class EnumParam(InputParam): + """Provide an entry box for Enum types with a drop down menu.""" + + def __init__(self, *args, **kwargs): + InputParam.__init__(self, *args, **kwargs) + input = gtk.ComboBox(gtk.ListStore(gobject.TYPE_STRING)) + cell = gtk.CellRendererText() + input.pack_start(cell, True) + input.add_attribute(cell, 'text', 0) + for option in self.param.get_options(): input.append_text(option.get_name()) + input.set_active(int(self.param.get_option_keys().index(self.param.get_value()))) + input.connect("changed", self._handle_changed) + self.pack_start(input, False) + self.get_text = lambda: str(input.get_active()) #the get text parses the selected index to a string + +###################################################################################################### +# A Flow Graph Parameter +###################################################################################################### + +class Param(Element): + """The graphical parameter.""" + + def update(self): + """! + Called when an external change occurs. + Update the graphical input by calling the change handler. + """ + if hasattr(self, 'input'): self._handle_changed() + + def get_input_object(self, callback=None): + """! + Get the graphical gtk class to represent this parameter. + Create the input object with this data type and the handle changed method. + @param callback a function of one argument(this param) to be called from the change handler + @return gtk input object + """ + self.callback = callback + if self.is_enum(): input = EnumParam + elif self.get_type() in ('file_open', 'file_save'): input = FileParam + else: input = EntryParam + self.input = input(self, self._handle_changed) + return self.input + + def _handle_changed(self, widget=None): + """! + When the input changes, write the inputs to the data type. + Finish by calling the exteral callback. + """ + value = self.input.get_text() + if self.is_enum(): value = self.get_option_keys()[int(value)] + self.set_value(value) + #set the markup on the label, red for errors in corresponding data type. + name = '<span font_desc="%s">%s</span>'%(PARAM_LABEL_FONT, Utils.xml_encode(self.get_name())) + #special markups if param is involved in a callback + if hasattr(self.get_parent(), 'get_callbacks') and \ + filter(lambda c: self.get_key() in c, self.get_parent()._callbacks): + name = '<span underline="low">%s</span>'%name + if not self.is_valid(): + self.input.set_markup('<span foreground="red">%s</span>'%name) + tip = '- ' + '\n- '.join(self.get_error_messages()) + else: + self.input.set_markup(name) + tip = self.evaluate() + #hide/show + if self.get_hide() == 'all': self.input.hide_all() + else: self.input.show_all() + #set the tooltip + if self.input.tp: self.input.tp.set_tip(self.input.entry, str(tip)) + #execute the external callback + if self.callback: self.callback(self) + + def get_markup(self): + """! + Create a markup to display the Param as a label on the SignalBlock. + If the data type is an Enum type, use the cname of the Enum's current choice. + Otherwise, use parsed the data type and use its string representation. + If the data type is not valid, use a red foreground color. + @return pango markup string + """ + ########################################################################### + # display logic for numbers + ########################################################################### + def float_to_str(var): + if var-int(var) == 0: return '%d'%int(var) + if var*10-int(var*10) == 0: return '%.1f'%var + if var*100-int(var*100) == 0: return '%.2f'%var + if var*1000-int(var*1000) == 0: return '%.3f'%var + else: return '%.3g'%var + def to_str(var): + if isinstance(var, str): return var + elif isinstance(var, complex): + if var.imag == var.real == 0: return '0' #value is zero + elif var.imag == 0: return '%s'%float_to_str(var.real) #value is real + elif var.real == 0: return '%sj'%float_to_str(var.imag) #value is imaginary + elif var.imag < 0: return '%s-%sj'%(float_to_str(var.real), float_to_str(var.imag*-1)) + else: return '%s+%sj'%(float_to_str(var.real), float_to_str(var.imag)) + elif isinstance(var, float): return float_to_str(var) + elif isinstance(var, int): return '%d'%var + else: return str(var) + ########################################################################### + if self.is_valid(): + data = self.evaluate() + t = self.get_type() + if self.is_enum(): + dt_str = self.get_option(self.get_value()).get_name() + elif isinstance(data, (list, tuple, set)): #vector types + dt_str = ', '.join(map(to_str, data)) + else: dt_str = to_str(data) #other types + #truncate + max_len = max(42 - len(self.get_name()), 3) + if len(dt_str) > max_len: + dt_str = dt_str[:max_len-3] + '...' + return '<b>%s:</b> %s'%(Utils.xml_encode(self.get_name()), Utils.xml_encode(dt_str)) + else: return '<span foreground="red"><b>%s:</b> error</span>'%Utils.xml_encode(self.get_name()) + + def get_layout(self): + """! + Create a layout based on the current markup. + @return the pango layout + """ + layout = gtk.DrawingArea().create_pango_layout('') + layout.set_markup(self.get_markup()) + desc = pango.FontDescription(PARAM_FONT) + layout.set_font_description(desc) + return layout + diff --git a/grc/src/grc/gui/elements/Platform.py b/grc/src/grc/gui/elements/Platform.py new file mode 100644 index 000000000..be11e7dae --- /dev/null +++ b/grc/src/grc/gui/elements/Platform.py @@ -0,0 +1,52 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.elements.Platform +#Graphical platform to turn an existing platform into a gui platform. +#@author Josh Blum + +from FlowGraph import FlowGraph +from Connection import Connection +from Block import Block +from Port import Port +from Param import Param + +def conjoin_classes(name, c1, c2): + exec(""" +class %s(c1, c2): + def __init__(self, *args, **kwargs): + c1.__init__(self, *args, **kwargs) + c2.__init__(self, *args, **kwargs) +"""%name, locals()) + return locals()[name] + +def Platform(platform): + #combine with gui class + for attr, value in ( + ('FlowGraph', FlowGraph), + ('Connection', Connection), + ('Block', Block), + ('Source', Port), + ('Sink', Port), + ('Param', Param), + ): + old_value = getattr(platform, attr) + c = conjoin_classes(attr, old_value, value) + setattr(platform, attr, c) + return platform + diff --git a/grc/src/grc/gui/elements/Port.py b/grc/src/grc/gui/elements/Port.py new file mode 100644 index 000000000..c603db5bc --- /dev/null +++ b/grc/src/grc/gui/elements/Port.py @@ -0,0 +1,185 @@ +""" +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 +""" +##@package grc.gui.elements.Port +#The graphical input/output sockets of the signal block. +#@author Josh Blum + +from Element import Element +from grc.Constants import * +import Colors +import pygtk +pygtk.require('2.0') +import gtk +import pango + +class Port(Element): + """The graphical port.""" + + def __init__(self, *args, **kwargs): + """! + Port contructor. + Create list of connector coordinates. + """ + Element.__init__(self) + self.connector_coordinates = dict() + + def update(self): + """Create new areas and labels for the port.""" + self.clear() + self.BG_color = Colors.get_color(self.get_color()) + self._create_labels() + #get current rotation + rotation = self.get_rotation() + #get all sibling ports + if self.is_source(): ports = self.get_parent().get_sources() + elif self.is_sink(): ports = self.get_parent().get_sinks() + #get a numeric index for this port relative to its sibling ports + index = ports.index(self) + length = len(ports) + #reverse the order of ports for these rotations + if rotation in (180, 270): index = length-index-1 + offset = (self.get_parent().H - length*PORT_HEIGHT - (length-1)*PORT_SEPARATION)/2 + #create areas and connector coordinates + if (self.is_sink() and rotation == 0) or (self.is_source() and rotation == 180): + x = -1*PORT_WIDTH + y = (PORT_SEPARATION+PORT_HEIGHT)*index+offset + self.add_area((x, y), (PORT_WIDTH, PORT_HEIGHT)) + self._connector_coordinate = (x-1, y+PORT_HEIGHT/2) + elif (self.is_source() and rotation == 0) or (self.is_sink() and rotation == 180): + x = self.get_parent().W + y = (PORT_SEPARATION+PORT_HEIGHT)*index+offset + self.add_area((x, y), (PORT_WIDTH, PORT_HEIGHT)) + self._connector_coordinate = (x+1+PORT_WIDTH, y+PORT_HEIGHT/2) + elif (self.is_source() and rotation == 90) or (self.is_sink() and rotation == 270): + y = -1*PORT_WIDTH + x = (PORT_SEPARATION+PORT_HEIGHT)*index+offset + self.add_area((x, y), (PORT_HEIGHT, PORT_WIDTH)) + self._connector_coordinate = (x+PORT_HEIGHT/2, y-1) + elif (self.is_sink() and rotation == 90) or (self.is_source() and rotation == 270): + y = self.get_parent().W + x = (PORT_SEPARATION+PORT_HEIGHT)*index+offset + self.add_area((x, y), (PORT_HEIGHT, PORT_WIDTH)) + self._connector_coordinate = (x+PORT_HEIGHT/2, y+1+PORT_WIDTH) + #the connector length + self._connector_length = CONNECTOR_EXTENSION_INITIAL_LENGTH + CONNECTOR_EXTENSION_LENGTH*index + + def _create_labels(self): + """Create the labels for the socket.""" + #create the layout + layout = gtk.DrawingArea().create_pango_layout(self.get_name()) + desc = pango.FontDescription(PORT_FONT) + layout.set_font_description(desc) + w,h = self.w,self.h = layout.get_pixel_size() + #create the pixmap + pixmap = gtk.gdk.Pixmap(self.get_parent().get_parent().get_window(), w, h, -1) + gc = pixmap.new_gc() + gc.foreground = self.BG_color + pixmap.draw_rectangle(gc, True, 0, 0, w, h) + gc.foreground = Colors.TXT_COLOR + pixmap.draw_layout(gc, 0, 0, layout) + #create the images + self.horizontal_label = image = pixmap.get_image(0, 0, w, h) + if self.is_vertical(): + self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), h, w) + for i in range(w): + for j in range(h): vimage.put_pixel(j, w-i-1, image.get_pixel(i, j)) + + def draw(self, window): + """! + Draw the socket with a label. + @param window the gtk window to draw on + """ + Element.draw(self, window, BG_color=self.BG_color) + gc = self.get_gc() + gc.foreground = Colors.TXT_COLOR + X,Y = self.get_coordinate() + (x,y),(w,h) = self.areas_dict[self.get_rotation()][0] #use the first area's sizes to place the labels + if self.is_horizontal(): + window.draw_image(gc, self.horizontal_label, 0, 0, x+X+(PORT_WIDTH-self.w)/2, y+Y+(PORT_HEIGHT-self.h)/2, -1, -1) + elif self.is_vertical(): + window.draw_image(gc, self.vertical_label, 0, 0, x+X+(PORT_HEIGHT-self.h)/2, y+Y+(PORT_WIDTH-self.w)/2, -1, -1) + + def get_connector_coordinate(self): + """! + Get the coordinate where connections may attach to. + @return the connector coordinate (x, y) tuple + """ + x,y = self._connector_coordinate + X,Y = self.get_coordinate() + return (x+X, y+Y) + + def get_connector_direction(self): + """! + Get the direction that the socket points: 0,90,180,270. + This is the rotation degree if the socket is an output or + the rotation degree + 180 if the socket is an input. + @return the direction in degrees + """ + if self.is_source(): return self.get_rotation() + elif self.is_sink(): return (self.get_rotation() + 180)%360 + + def get_connector_length(self): + """! + Get the length of the connector. + The connector length increases as the port index changes. + @return the length in pixels + """ + return self._connector_length + + def get_rotation(self): + """! + Get the parent's rotation rather than self. + @return the parent's rotation + """ + return self.get_parent().get_rotation() + + def move(self, delta_coor): + """! + Move the parent rather than self. + @param delta_corr the (delta_x, delta_y) tuple + """ + self.get_parent().move(delta_coor) + + def rotate(self, direction): + """! + Rotate the parent rather than self. + @param direction degrees to rotate + """ + self.get_parent().rotate(direction) + + def get_coordinate(self): + """! + Get the parent's coordinate rather than self. + @return the parents coordinate + """ + return self.get_parent().get_coordinate() + + def set_highlighted(self, highlight): + """! + Set the parent highlight rather than self. + @param highlight true to enable highlighting + """ + self.get_parent().set_highlighted(highlight) + + def is_highlighted(self): + """! + Get the parent's is highlight rather than self. + @return the parent's highlighting status + """ + return self.get_parent().is_highlighted() diff --git a/grc/src/grc/gui/elements/Utils.py b/grc/src/grc/gui/elements/Utils.py new file mode 100644 index 000000000..34f084343 --- /dev/null +++ b/grc/src/grc/gui/elements/Utils.py @@ -0,0 +1,52 @@ +""" +Copyright 2008 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 +""" +##@package grc.gui.elements.Utils +#Shared functions for flow graph elements. +#@author Josh Blum + +def get_angle_from_coordinates((x1,y1), (x2,y2)): + """! + Given two points, calculate the vector direction from point1 to point2, directions are multiples of 90 degrees. + @param (x1,y1) the coordinate of point 1 + @param (x2,y2) the coordinate of point 2 + @return the direction in degrees + """ + if y1 == y2:#0 or 180 + if x2 > x1: return 0 + else: return 180 + else:#90 or 270 + if y2 > y1: return 270 + else: return 90 + +def xml_encode(string): + """ + Encode a string into an xml safe string by replacing special characters. + @param string the input string + @return output string with safe characters + """ + string = str(string) + for char, safe in ( + ('&', '&'), + ('<', '<'), + ('>', '>'), + ('"', '"'), + ("'", '''), + ): string = string.replace(char, safe) + return string + diff --git a/grc/src/grc/gui/elements/__init__.py b/grc/src/grc/gui/elements/__init__.py new file mode 100644 index 000000000..f8e099501 --- /dev/null +++ b/grc/src/grc/gui/elements/__init__.py @@ -0,0 +1,23 @@ +""" +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 +""" +##@package grc.gui.elements +#All graphical elements used in a flow graph. +#@author Josh Blum + + diff --git a/grc/src/grc_gnuradio/Block.py b/grc/src/grc_gnuradio/Block.py new file mode 100644 index 000000000..a14df8ec9 --- /dev/null +++ b/grc/src/grc_gnuradio/Block.py @@ -0,0 +1,131 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Block +#Flow graph block. +#@author Josh Blum + +from grc.elements.Block import Block as _Block +from grc import Utils +from utils import extract_docs + +class Block(_Block): + + ##for make source to keep track of indexes + _source_count = 0 + ##for make sink to keep track of indexes + _sink_count = 0 + + def __init__(self, flow_graph, n): + """ + Make a new block from nested data. + @param flow graph the parent element + @param n the nested odict + @return block a new block + """ + #grab the data + doc = Utils.exists_or_else(n, 'doc', '') + imports = map(lambda i: i.strip(), Utils.listify(n, 'import')) + make = n['make'] + checks = Utils.listify(n, 'check') + callbacks = Utils.listify(n, 'callback') + #build the block + _Block.__init__( + self, + flow_graph=flow_graph, + n=n, + ) + self._doc = doc + self._imports = imports + self._make = make + self._callbacks = callbacks + self._checks = checks + + def validate(self): + """! + Validate this block. + Call the base class validate. + Evaluate the checks: each check must evaluate to True. + Adjust the nports. + """ + _Block.validate(self) + #evaluate the checks + for check in self._checks: + check_res = self.resolve_dependencies(check) + try: + check_eval = self.get_parent().evaluate(check_res) + try: assert check_eval + except AssertionError: self._add_error_message('Check "%s" failed.'%check) + except: self._add_error_message('Check "%s" did not evaluate.'%check) + for ports, Port in ( + (self._sources, self.get_parent().get_parent().Source), + (self._sinks, self.get_parent().get_parent().Sink), + ): + #how many ports? + num_ports = len(ports) + #do nothing for 0 ports + if not num_ports: continue + #get the nports setting + port0 = ports[str(0)] + nports = port0.get_nports() + #do nothing for no nports + if not nports: continue + #do nothing if nports is already num ports + if nports == num_ports: continue + #remove excess ports and connections + if nports < num_ports: + #remove the connections + for key in map(str, range(nports, num_ports)): + port = ports[key] + for connection in port.get_connections(): + self.get_parent().remove_element(connection) + #remove the ports + for key in map(str, range(nports, num_ports)): ports.pop(key) + continue + #add more ports + if nports > num_ports: + for key in map(str, range(num_ports, nports)): + n = port0._n + n['key'] = key + port = Port(self, n) + ports[key] = port + continue + + def get_doc(self): + doc = self._doc.strip('\n').replace('\\\n', '') + #merge custom doc with doxygen docs + return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n') + + def get_imports(self): + """! + Resolve all import statements. + Split each import statement at newlines. + Combine all import statments into a list. + Filter empty imports. + @return a list of import statements + """ + return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), [])) + + def get_make(self): return self.resolve_dependencies(self._make) + + def get_callbacks(self): + """! + Get a list of function callbacks for this block. + @return a list of strings + """ + return map(lambda c: self.get_id() + '.' + self.resolve_dependencies(c), self._callbacks) diff --git a/grc/src/grc_gnuradio/Connection.py b/grc/src/grc_gnuradio/Connection.py new file mode 100644 index 000000000..c7d6a74c7 --- /dev/null +++ b/grc/src/grc_gnuradio/Connection.py @@ -0,0 +1,42 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Connection +#Flow graph connection. +#A connection exists between 2 ports. +#One port must be input, one output. +#The port decided whether it can have the connection. +#@author Josh Blum + +from grc.elements.Connection import Connection as _Connection + +class Connection(_Connection): + + def validate(self): + """ + Validate the connections. + The ports must match in type and vector length. + """ + _Connection.validate(self) #checks type + #check vector length + source_vlen = self.get_source().get_vlen() + sink_vlen = self.get_sink().get_vlen() + try: assert(source_vlen == sink_vlen) + except AssertionError: self._add_error_message('Source vector length "%s" does not match sink vector length "%s".'%(source_vlen, sink_vlen)) + + diff --git a/grc/src/grc_gnuradio/Constants.py.in b/grc/src/grc_gnuradio/Constants.py.in new file mode 100644 index 000000000..66b773e79 --- /dev/null +++ b/grc/src/grc_gnuradio/Constants.py.in @@ -0,0 +1,44 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Constants +#Global constants for grc gnuradio package +#@author Josh Blum + +import os +import sys +import stat + +PYEXEC = '@PYTHONW@' + +#setup paths +DOCS_DIR = os.path.join('@docdir@', 'xml') +DATA_DIR = '@datadir@' +BLOCKS_DIR = '@blocksdir@' +HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio') + +#file creation modes +TOP_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH +HIER_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH + +#data files +FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 'flow_graph.tmpl') +BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd') +BLOCK_TREE = os.path.join(DATA_DIR, 'block_tree.xml') +DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc.xml') + diff --git a/grc/src/grc_gnuradio/FlowGraph.py b/grc/src/grc_gnuradio/FlowGraph.py new file mode 100644 index 000000000..3e037305b --- /dev/null +++ b/grc/src/grc_gnuradio/FlowGraph.py @@ -0,0 +1,147 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.FlowGraph +#Primative flow graph. +#@author Josh Blum + +from utils import expr_utils +from grc.elements.FlowGraph import FlowGraph as _FlowGraph +from Block import Block +from Connection import Connection + +class FlowGraph(_FlowGraph): + + def _get_io_signature(self, pad_key): + """! + Get an io signature for this flow graph. + The pad key determines the directionality of the io signature. + @param pad_key a string of pad_source or pad_sink + @return a dict with: type, nports, vlen, size + """ + pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks()) + if not pads: return { + 'nports': '0', + 'type': '', + 'vlen': '0', + 'size': '0', + } + pad = pads[0] #take only the first, user should not have more than 1 + #load io signature + return { + 'nports': str(pad.get_param('nports').evaluate()), + 'type': str(pad.get_param('type').evaluate()), + 'vlen': str(pad.get_param('vlen').evaluate()), + 'size': pad.get_param('type').get_opt('size'), + } + + def get_input_signature(self): + """! + Get the io signature for the input side of this flow graph. + The io signature with be "0", "0" if no pad source is present. + @return a string tuple of type, num_ports, port_size + """ + return self._get_io_signature('pad_source') + + def get_output_signature(self): + """! + Get the io signature for the output side of this flow graph. + The io signature with be "0", "0" if no pad sink is present. + @return a string tuple of type, num_ports, port_size + """ + return self._get_io_signature('pad_sink') + + def get_imports(self): + """! + Get a set of all import statments in this flow graph namespace. + @return a set of import statements + """ + imports = sum([block.get_imports() for block in self.get_enabled_blocks()], []) + imports = sorted(set(imports)) + return imports + + def get_variables(self): + """! + Get a list of all variables in this flow graph namespace. + Exclude paramterized variables. + @return a sorted list of variable blocks in order of dependency (indep -> dep) + """ + variables = filter(lambda b: b.get_key() in ( + 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box' + ), self.get_enabled_blocks()) + #map var id to variable block + id2var = dict([(var.get_id(), var) for var in variables]) + #map var id to variable code + #variable code is a concatenation of all param code (without the id param) + id2expr = dict([(var.get_id(), + ' '.join([param.to_code() for param in filter(lambda p: p.get_key() != 'id',var.get_params())]) + ) for var in variables]) + #sort according to dependency + sorted_ids = expr_utils.sort_variables(id2expr) + #create list of sorted variable blocks + variables = [id2var[id] for id in sorted_ids] + return variables + + def get_parameters(self): + """! + Get a list of all paramterized variables in this flow graph namespace. + @return a list of paramterized variables + """ + parameters = filter(lambda b: b.get_key() == 'parameter', self.get_enabled_blocks()) + return parameters + + def evaluate(self, expr): + """! + Evaluate the expression. + @param expr the string expression + @throw Exception bad expression + @return the evaluated data + """ + if self.is_flagged(): + self.deflag() + #reload namespace + n = dict() + #load imports + for imp in self.get_imports(): + try: exec imp in n + except: pass + #load parameters + np = dict() + for parameter in self.get_parameters(): + try: + e = eval(parameter.get_param('value').to_code(), n, n) + np[parameter.get_id()] = e + except: pass + n.update(np) #merge param namespace + #load variables + for variable in self.get_variables(): + try: + if variable.get_key() == 'variable_chooser': + choices = variable.get_param('choices').to_code() + value_index = variable.get_param('value_index').to_code() + e = eval("%s[%s]"%(choices, value_index), n, n) + else: + e = eval(variable.get_param('value').to_code(), n, n) + n[variable.get_id()] = e + except: pass + #make namespace public + self.n = n + #evaluate + e = eval(expr, self.n, self.n) + return e + diff --git a/grc/src/grc_gnuradio/Generator.py b/grc/src/grc_gnuradio/Generator.py new file mode 100644 index 000000000..02c9de291 --- /dev/null +++ b/grc/src/grc_gnuradio/Generator.py @@ -0,0 +1,132 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Generator +#Create python based flow graphs. +#@author Josh Blum + +import os +import subprocess +from Cheetah.Template import Template +from utils import expr_utils +from Constants import * +from utils import convert_hier + +class Generator(object): + + def __init__(self, flow_graph, file_path): + """! + Initialize the generator object. + Determine the file to generate. + @param flow_graph the flow graph object + @param file_path the path to write the file to + """ + self._flow_graph = flow_graph + self._generate_options = self._flow_graph.get_option('generate_options') + if self._generate_options == 'hb': + self._mode = HIER_BLOCK_FILE_MODE + dirname = HIER_BLOCKS_LIB_PATH + else: + self._mode = TOP_BLOCK_FILE_MODE + dirname = os.path.dirname(file_path) + filename = self._flow_graph.get_option('id') + '.py' + self._file_path = os.path.join(dirname, filename) + + def get_file_path(self): return self._file_path + + def write(self): + #generate + open(self.get_file_path(), 'w').write(str(self)) + if self._generate_options == 'hb': + #convert hier block to xml wrapper + convert_hier.convert_hier(self._flow_graph, self.get_file_path()) + os.chmod(self.get_file_path(), self._mode) + + def get_popen(self): + """! + Execute this python flow graph. + @return a popen object + """ + #execute + cmds = [PYEXEC, self.get_file_path()] + if self._generate_options == 'no_gui': + cmds = ['xterm', '-e'] + cmds + p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True) + return p + + def __str__(self): + """! + Convert the flow graph to python code. + @return a string of python code + """ + imports = self._flow_graph.get_imports() + variables = self._flow_graph.get_variables() + parameters = self._flow_graph.get_parameters() + #list of blocks not including variables and imports and parameters and disabled + blocks = sorted(self._flow_graph.get_enabled_blocks(), lambda x, y: cmp(x.get_id(), y.get_id())) + blocks = filter(lambda b: b not in (imports + parameters + variables), blocks) + #list of connections where each endpoint is enabled + connections = self._flow_graph.get_enabled_connections() + #list of variable names + var_ids = [var.get_id() for var in parameters + variables] + #list of callbacks (prepend self.) + callbacks = [ + expr_utils.expr_prepend(cb, var_ids, 'self.') + for cb in sum([block.get_callbacks() for block in self._flow_graph.get_blocks()], []) + ] + #map var id to the expression (prepend self.) + var_id2expr = dict( + [(var.get_id(), expr_utils.expr_prepend(var.get_make().split('\n')[0], var_ids, 'self.')) + for var in parameters + variables] + ) + #create graph structure for variables + variable_graph = expr_utils.get_graph(var_id2expr) + #map var id to direct dependents + #for each var id, make a list of all 2nd order edges + #use all edges of that id that are not also 2nd order edges + #meaning: list variables the ONLY depend directly on this variable + #and not variables that also depend indirectly on this variable + var_id2deps = dict( + [(var_id, filter(lambda e: e not in sum([list(variable_graph.get_edges(edge)) + for edge in variable_graph.get_edges(var_id)], []), variable_graph.get_edges(var_id) + ) + ) + for var_id in var_ids] + ) + #map var id to callbacks + var_id2cbs = dict( + [(var_id, filter(lambda c: var_id in expr_utils.expr_split(c), callbacks)) + for var_id in var_ids] + ) + #load the namespace + namespace = { + 'imports': imports, + 'flow_graph': self._flow_graph, + 'variables': variables, + 'parameters': parameters, + 'blocks': blocks, + 'connections': connections, + 'generate_options': self._generate_options, + 'var_id2expr': var_id2expr, + 'var_id2deps': var_id2deps, + 'var_id2cbs': var_id2cbs, + } + #build the template + t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace) + return str(t) + diff --git a/grc/src/grc_gnuradio/Makefile.am b/grc/src/grc_gnuradio/Makefile.am new file mode 100644 index 000000000..a2ef0f4cc --- /dev/null +++ b/grc/src/grc_gnuradio/Makefile.am @@ -0,0 +1,53 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/grc/Makefile.common + +SUBDIRS = blks2 usrp utils wxgui + +ourpythondir = $(pythondir)/grc_gnuradio + +ourpython_PYTHON = \ + __init__.py \ + Constants.py \ + Block.py \ + Connection.py \ + FlowGraph.py \ + Generator.py \ + Platform.py \ + Param.py \ + Port.py + +docdir = $(prefix)/share/doc/@PACKAGE@-@VERSION@ + +BUILT_SOURCES = Constants.py + +Constants.py: Makefile $(srcdir)/Constants.py.in + sed \ + -e 's|@PYTHONW[@]|$(PYTHONW)|g' \ + -e 's|@datadir[@]|$(grc_gnuradio_data_dir)|g' \ + -e 's|@blocksdir[@]|$(grc_gnuradio_blocks_dir)|g' \ + -e 's|@docdir[@]|$(docdir)|g' \ + $(srcdir)/Constants.py.in > $@ + +EXTRA_DIST = Constants.py.in + +MOSTLYCLEANFILES = $(BUILT_SOURCES) diff --git a/grc/src/grc_gnuradio/Param.py b/grc/src/grc_gnuradio/Param.py new file mode 100644 index 000000000..207b29839 --- /dev/null +++ b/grc/src/grc_gnuradio/Param.py @@ -0,0 +1,255 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Param +#Flow graph block parameters. +#@author Josh Blum + +from utils import expr_utils +from grc.elements.Param import Param as _Param +import os + +class Param(_Param): + + _init = False + _hostage_cells = list() + + ##possible param types + TYPES = _Param.TYPES + [ + 'complex', 'real', 'int', + 'complex_vector', 'real_vector', 'int_vector', + 'hex', 'string', + 'file_open', 'file_save', + 'id', + 'grid_pos', 'import', + ] + + def get_hide(self): + """! + Get the hide value from the base class. + If hide was empty, and this is a type controller, set hide to part. + If hide was empty, and this is an id of a non variable, set hide to part. + @return hide the hide property string + """ + hide = _Param.get_hide(self) + #hide IO controlling params + if not hide and self.get_key() in ( + 'type', 'vlen', 'num_inputs', 'num_outputs' + ): hide = 'part' + #hide ID in non variable blocks + elif not hide and self.get_key() == 'id' and self.get_parent().get_key() not in ( + 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box', 'parameter', 'options' + ): hide = 'part' + return hide + + def evaluate(self): + """! + Evaluate the value. + @return evaluated type + """ + self._lisitify_flag = False + self._stringify_flag = False + self._hostage_cells = list() + def eval_string(v): + try: + e = self.get_parent().get_parent().evaluate(v) + assert(isinstance(e, str)) + return e + except: + self._stringify_flag = True + return v + t = self.get_type() + v = self.get_value() + ######################### + # Enum Type + ######################### + if self.is_enum(): return self.get_value() + ######################### + # Numeric Types + ######################### + elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex'): + #raise exception if python cannot evaluate this value + try: e = self.get_parent().get_parent().evaluate(v) + except: + self._add_error_message('Value "%s" cannot be evaluated.'%v) + raise Exception + #raise an exception if the data is invalid + if t == 'raw': return e + elif t == 'complex': + try: assert(isinstance(e, (complex, float, int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type complex.'%str(e)) + raise Exception + return e + elif t == 'real': + try: assert(isinstance(e, (float, int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type real.'%str(e)) + raise Exception + return e + elif t == 'int': + try: assert(isinstance(e, (int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type integer.'%str(e)) + raise Exception + return e + elif t == 'complex_vector': + if not isinstance(e, (tuple, list, set)): + self._lisitify_flag = True + e = [e] + try: + for ei in e: + assert(isinstance(ei, (complex, float, int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type complex vector.'%str(e)) + raise Exception + return e + elif t == 'real_vector': + if not isinstance(e, (tuple, list, set)): + self._lisitify_flag = True + e = [e] + try: + for ei in e: + assert(isinstance(ei, (float, int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type real vector.'%str(e)) + raise Exception + return e + elif t == 'int_vector': + if not isinstance(e, (tuple, list, set)): + self._lisitify_flag = True + e = [e] + try: + for ei in e: + assert(isinstance(ei, (int, long))) + except AssertionError: + self._add_error_message('Expression "%s" is invalid for type integer vector.'%str(e)) + raise Exception + return e + elif t == 'hex': + return hex(e) + else: raise TypeError, 'Type "%s" not handled'%t + ######################### + # String Types + ######################### + elif t in ('string', 'file_open', 'file_save'): + #do not check if file/directory exists, that is a runtime issue + e = eval_string(v) + return str(e) + ######################### + # Unique ID Type + ######################### + elif t == 'id': + #can python use this as a variable? + try: + assert(len(v) > 0) + assert(v[0].isalpha()) + for c in v: assert(c.isalnum() or c in ('_',)) + except AssertionError: + self._add_error_message('ID "%s" must be alpha-numeric or underscored, and begin with a letter.'%v) + raise Exception + params = self.get_all_params('id') + keys = [param.get_value() for param in params] + try: assert(len(keys) == len(set(keys))) + except: + self._add_error_message('ID "%s" is not unique.'%v) + raise Exception + return v + ######################### + # Grid Position Type + ######################### + elif t == 'grid_pos': + if not v: return '' #allow for empty grid pos + e = self.get_parent().get_parent().evaluate(v) + try: + assert(isinstance(e, (list, tuple)) and len(e) == 4) + for ei in e: assert(isinstance(ei, int)) + except AssertionError: + self._add_error_message('A grid position must be a list of 4 integers.') + raise Exception + row, col, row_span, col_span = e + #check row, col + try: assert(row >= 0 and col >= 0) + except AssertionError: + self._add_error_message('Row and column must be non-negative.') + raise Exception + #check row span, col span + try: assert(row_span > 0 and col_span > 0) + except AssertionError: + self._add_error_message('Row and column span must be greater than zero.') + raise Exception + #calculate hostage cells + for r in range(row_span): + for c in range(col_span): + self._hostage_cells.append((row+r, col+c)) + #avoid collisions + params = filter(lambda p: p is not self, self.get_all_params('grid_pos')) + for param in params: + for cell in param._hostage_cells: + if cell in self._hostage_cells: + self._add_error_message('Another graphical element is using cell "%s".'%str(cell)) + raise Exception + return e + ######################### + # Import Type + ######################### + elif t == 'import': + n = dict() #new namespace + try: exec v in n + except ImportError: + self._add_error_message('Import "%s" failed.'%v) + raise Exception + except Exception: + self._add_error_message('Bad import syntax: "%s".'%v) + raise Exception + return filter(lambda k: str(k) != '__builtins__', n.keys()) + ######################### + else: raise TypeError, 'Type "%s" not handled'%t + + def to_code(self): + """! + Convert the value to code. + @return a string representing the code + """ + #run init tasks in evaluate + if not self._init: + self.evaluate() + self._init = True + v = self.get_value() + t = self.get_type() + if t in ('string', 'file_open', 'file_save'): #string types + if self._stringify_flag: + return '"%s"'%v.replace('"', '\"') + else: + return v + elif t in ('complex_vector', 'real_vector', 'int_vector'): #vector types + if self._lisitify_flag: + return '(%s, )'%v + else: + return '(%s)'%v + else: + return v + + def get_all_params(self, type): + """! + Get all the params from the flowgraph that have the given type. + @param type the specified type + @return a list of params + """ + return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_blocks()], []) + diff --git a/grc/src/grc_gnuradio/Platform.py b/grc/src/grc_gnuradio/Platform.py new file mode 100644 index 000000000..22a4c7ecd --- /dev/null +++ b/grc/src/grc_gnuradio/Platform.py @@ -0,0 +1,74 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Platform +#Gnuradio python specific platform. +#@author Josh Blum + +import os +from grc.Constants import FLOW_GRAPH_FILE_EXTENSION +from grc.elements.Platform import Platform as _Platform +from FlowGraph import FlowGraph as _FlowGraph +from Connection import Connection as _Connection +from Block import Block as _Block +from Port import Source,Sink +from Param import Param as _Param +from Generator import Generator +from Constants import * + +class Platform(_Platform): + + def __init__(self, block_paths_internal_only=[], block_paths_external=[]): + """! + Make a platform for gnuradio. + The internal only list will replace the current block path. + @param block_paths_internal_only a list of blocks internal to this platform + @param block_paths_external a list of blocks to load in addition to the above blocks + """ + #ensure hier dir + if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR) + #handle internal/only + if block_paths_internal_only: + block_paths = map(lambda b: os.path.join(BLOCKS_DIR, b), ['options.xml'] + block_paths_internal_only) + else: block_paths = [BLOCKS_DIR] + #handle external + block_paths.extend(block_paths_external) + #append custom hiers + block_paths.append(HIER_BLOCKS_LIB_DIR) + #init + _Platform.__init__( + self, + name='GNURadio Python', + key='gnuradio_python', + block_paths=block_paths, + block_dtd=BLOCK_DTD, + block_tree=BLOCK_TREE, + default_flow_graph=DEFAULT_FLOW_GRAPH, + generator=Generator, + ) + + ############################################## + # Constructors + ############################################## + FlowGraph = _FlowGraph + Connection = _Connection + Block = _Block + Source = Source + Sink = Sink + Param = _Param + diff --git a/grc/src/grc_gnuradio/Port.py b/grc/src/grc_gnuradio/Port.py new file mode 100644 index 000000000..c8e899781 --- /dev/null +++ b/grc/src/grc_gnuradio/Port.py @@ -0,0 +1,135 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.Port +#Flow graph block port (source or sink). +#@author Josh Blum + +from grc.elements.Port import Port as _Port +from grc import Utils +from grc.Constants import MAX_NUM_PORTS + +class Port(_Port): + + ##possible port types + TYPES = ['complex', 'float', 'int', 'short', 'byte'] + + def __init__(self, block, n): + """ + Make a new port from nested data. + @param block the parent element + @param n the nested odict + @return a new port + """ + vlen = Utils.exists_or_else(n, 'vlen', '1') + nports = Utils.exists_or_else(n, 'nports', '') + optional = Utils.exists_or_else(n, 'optional', '') + #build the port + _Port.__init__( + self, + block=block, + n=n, + ) + self._nports = nports + self._vlen = vlen + self._optional = bool(optional) + + def get_vlen(self): + """ + Get the vector length. + If the evaluation of vlen cannot be cast to an integer, return 1. + @return the vector length or 1 + """ + vlen = self.get_parent().resolve_dependencies(self._vlen) + try: return int(self.get_parent().get_parent().evaluate(vlen)) + except: return 1 + + def get_nports(self): + """ + Get the number of ports. + If already blank, return a blank + If the evaluation of nports cannot be cast to an integer, return 1. + @return the number of ports or 1 + """ + nports = self.get_parent().resolve_dependencies(self._nports) + #return blank if nports is blank + if not nports: return '' + try: + nports = int(self.get_parent().get_parent().evaluate(nports)) + assert(0 < nports <= MAX_NUM_PORTS) + return nports + except: return 1 + + def get_optional(self): return bool(self._optional) + + def get_color(self): + """ + Get the color that represents this port's type. + Codes differ for ports where the vec length is 1 or greater than 1. + @return a hex color code. + """ + try: + if self.get_vlen() == 1: + return {#vlen is 1 + 'complex': '#3399FF', + 'float': '#FF8C69', + 'int': '#00FF99', + 'short': '#FFFF66', + 'byte': '#FF66FF', + }[self.get_type()] + return {#vlen is non 1 + 'complex': '#3399AA', + 'float': '#CC8C69', + 'int': '#00CC99', + 'short': '#CCCC33', + 'byte': '#CC66CC', + }[self.get_type()] + except: return _Port.get_color(self) + + def is_empty(self): + """! + Is this port empty? + An empty port has no connections. + Not empty of optional is set. + @return true if empty + """ + return not self.get_optional() and not self.get_connections() + +class Source(Port): + + def __init__(self, block, n): + self._n = n #save n + #key is port index + n['key'] = str(block._source_count) + block._source_count = block._source_count + 1 + Port.__init__(self, block, n) + + def __del__(self): + self.get_parent()._source_count = self.get_parent()._source_count - 1 + +class Sink(Port): + + def __init__(self, block, n): + self._n = n #save n + #key is port index + n['key'] = str(block._sink_count) + block._sink_count = block._sink_count + 1 + Port.__init__(self, block, n) + + def __del__(self): + self.get_parent()._sink_count = self.get_parent()._sink_count - 1 diff --git a/grc/src/grc_gnuradio/__init__.py b/grc/src/grc_gnuradio/__init__.py new file mode 100644 index 000000000..fe09e0d4b --- /dev/null +++ b/grc/src/grc_gnuradio/__init__.py @@ -0,0 +1,21 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio +#gnuradio overloaded elements and supplemental python modules +#@author Josh Blum diff --git a/grc/src/grc_gnuradio/blks2/Makefile.am b/grc/src/grc_gnuradio/blks2/Makefile.am new file mode 100644 index 000000000..307ec863f --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc_gnuradio/blks2 + +ourpython_PYTHON = \ + __init__.py \ + error_rate.py \ + packet.py \ + queue.py \ + selector.py diff --git a/grc/src/grc_gnuradio/blks2/__init__.py b/grc/src/grc_gnuradio/blks2/__init__.py new file mode 100644 index 000000000..cd1b793c4 --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/__init__.py @@ -0,0 +1,28 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from queue import queue_sink_thread +from queue import queue_sink_c, queue_sink_f, queue_sink_i, queue_sink_s, queue_sink_b +from queue import queue_source_c, queue_source_f, queue_source_i, queue_source_s, queue_source_b + +from selector import selector, valve +from packet import packet_encoder, packet_decoder +from error_rate import error_rate + diff --git a/grc/src/grc_gnuradio/blks2/error_rate.py b/grc/src/grc_gnuradio/blks2/error_rate.py new file mode 100644 index 000000000..eb09940cb --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/error_rate.py @@ -0,0 +1,138 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +default_win_size = 1000 + +from gnuradio import gr +import gnuradio.gr.gr_threading as _threading +import numpy + +#generate 1s counts array +_1s_counts = [sum([1&(i>>j) for j in range(8)]) for i in range(2**8)] + +class input_watcher(_threading.Thread): + """ + Read samples from the message queue and hand them to the callback. + """ + + def __init__(self, msgq, callback): + self._msgq = msgq + self._callback = callback + _threading.Thread.__init__(self) + self.setDaemon(1) + self.keep_running = True + self.start() + + def run(self): + r = '' + while True: + msg = self._msgq.delete_head() + itemsize = int(msg.arg1()) + nitems = int(msg.arg2()) + s = r + msg.to_string() + i = (nitems-nitems%2)*itemsize + r = s[i:] + s = s[:i] + samples = numpy.fromstring(s, numpy.int8) + self._callback(samples) + +class error_rate(gr.hier_block2): + """ + Sample the incoming data streams (byte) and calculate the bit or symbol error rate. + Write the running rate to the output data stream (float). + """ + + def __init__(self, type='BER', win_size=default_win_size, bits_per_symbol=2): + """! + Error rate constructor. + @param type a string 'BER' or 'SER' + @param win_size the number of samples to calculate over + @param bits_per_symbol the number of information bits per symbol (BER only) + """ + #init + gr.hier_block2.__init__( + self, 'error_rate', + gr.io_signature(2, 2, gr.sizeof_char), + gr.io_signature(1, 1, gr.sizeof_float), + ) + assert type in ('BER', 'SER') + self._max_samples = win_size + self._bits_per_symbol = bits_per_symbol + #setup message queue + msg_source = gr.message_source(gr.sizeof_float, 1) + self._msgq_source = msg_source.msgq() + msgq_sink = gr.msg_queue(2) + msg_sink = gr.message_sink(gr.sizeof_char, msgq_sink, False) #False -> blocking + inter = gr.interleave(gr.sizeof_char) + #start thread + self._num_errs = 0 + self._err_index = 0 + self._num_samps = 0 + self._err_array = numpy.zeros(self._max_samples, numpy.int8) + if type == 'BER': + input_watcher(msgq_sink, self._handler_ber) + elif type == 'SER': + input_watcher(msgq_sink, self._handler_ser) + #connect + self.connect(msg_source, self) + self.connect((self, 0), (inter, 0)) + self.connect((self, 1), (inter, 1)) + self.connect(inter, msg_sink) + + def _handler_ber(self, samples): + num = len(samples)/2 + arr = numpy.zeros(num, numpy.float32) + for i in range(num): + old_err = self._err_array[self._err_index] + #record error + self._err_array[self._err_index] = _1s_counts[samples[i*2] ^ samples[i*2 + 1]] + self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err + #increment index + self._err_index = (self._err_index + 1)%self._max_samples + self._num_samps = min(self._num_samps + 1, self._max_samples) + #write sample + arr[i] = float(self._num_errs)/float(self._num_samps*self._bits_per_symbol) + #write message + msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num) + self._msgq_source.insert_tail(msg) + + def _handler_ser(self, samples): + num = len(samples)/2 + arr = numpy.zeros(num, numpy.float32) + for i in range(num): + old_err = self._err_array[self._err_index] + #record error + ref = samples[i*2] + res = samples[i*2 + 1] + if ref == res: + self._err_array[self._err_index] = 0 + else: + self._err_array[self._err_index] = 1 + #update number of errors + self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err + #increment index + self._err_index = (self._err_index + 1)%self._max_samples + self._num_samps = min(self._num_samps + 1, self._max_samples) + #write sample + arr[i] = float(self._num_errs)/float(self._num_samps) + #write message + msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num) + self._msgq_source.insert_tail(msg) + diff --git a/grc/src/grc_gnuradio/blks2/packet.py b/grc/src/grc_gnuradio/blks2/packet.py new file mode 100644 index 000000000..5276de109 --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/packet.py @@ -0,0 +1,194 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, packet_utils +import gnuradio.gr.gr_threading as _threading + +##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 Encoder +####################################################################################### + +class _packet_encoder_thread(_threading.Thread): + + def __init__(self, msgq, payload_length, send): + self._msgq = msgq + self._payload_length = payload_length + self._send = send + _threading.Thread.__init__(self) + self.setDaemon(1) + self.keep_running = True + self.start() + + def run(self): + 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) + +class packet_encoder(gr.hier_block2): + """ + Hierarchical block for wrapping packet-based modulators. + """ + + def __init__(self, item_size_in, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True, payload_length=-1): + """! + packet_mod constructor. + @param item_size_in 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 access_code AKA sync vector + @param pad_for_usrp If true, packets are padded such that they end up a multiple of 128 samples + @param payload_length number of bytes in a data-stream slice + """ + #setup parameters + self._item_size_in = item_size_in + self._samples_per_symbol = samples_per_symbol + self._bits_per_symbol = bits_per_symbol + self._pad_for_usrp = pad_for_usrp + if not access_code: #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 + self._pad_for_usrp = pad_for_usrp + if payload_length < 0: #get payload length + payload_length = DEFAULT_PAYLOAD_LEN + if payload_length%self._item_size_in != 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, self._item_size_in) + self._payload_length = payload_length + #create blocks + msg_source = gr.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT) + self._msgq_out = msg_source.msgq() + self._msgq_in = gr.msg_queue(DEFAULT_MSGQ_LIMIT) + msg_sink = gr.message_sink(self._item_size_in, self._msgq_in, False) #False -> blocking + #initialize hier2 + gr.hier_block2.__init__( + self, + "packet_encoder", + gr.io_signature(1, 1, self._item_size_in), # 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 + _packet_encoder_thread(self._msgq_in, self._payload_length, self._send_packet) + + def _send_packet(self, payload): + """! + Wrap the payload in a packet and push onto the message queue. + @param payload string, 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) + +####################################################################################### +## Packet Decoder +####################################################################################### + +class _packet_decoder_thread(_threading.Thread): + + def __init__(self, msgq, callback): + _threading.Thread.__init__(self) + self.setDaemon(1) + self._msgq = msgq + self.callback = callback + self.keep_running = True + self.start() + + def run(self): + while self.keep_running: + msg = self._msgq.delete_head() + ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) + if self.callback: + self.callback(ok, payload) + +class packet_decoder(gr.hier_block2): + """ + Hierarchical block for wrapping packet-based demodulators. + """ + + def __init__(self, item_size_out, access_code='', threshold=-1): + """! + packet_demod constructor. + @param item_size_out the size of the output 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 + self._item_size_out = item_size_out + #access code + if not access_code: #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 < 0: threshold = DEFAULT_THRESHOLD + self._threshold = threshold + #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_out, DEFAULT_MSGQ_LIMIT) + self._msgq_out = msg_source.msgq() + #initialize hier2 + gr.hier_block2.__init__( + self, + "packet_decoder", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, self._item_size_out) # Output signature + ) + #connect + self.connect(self, correlator, framer_sink) + self.connect(msg_source, self) + #start thread + _packet_decoder_thread(self._msgq_in, self._recv_packet) + + def _recv_packet(self, ok, payload): + """! + Extract the payload from the packet and push onto message queue. + @param ok boolean ok + @param payload data received + """ + msg = gr.message_from_string(payload, 0, self._item_size_out, len(payload)/self._item_size_out) + if ok: self._msgq_out.insert_tail(msg) + + diff --git a/grc/src/grc_gnuradio/blks2/queue.py b/grc/src/grc_gnuradio/blks2/queue.py new file mode 100644 index 000000000..cec35e52a --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/queue.py @@ -0,0 +1,178 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +import gnuradio.gr.gr_threading as _threading +import numpy + +####################################################################################### +## Queue Sink Thread +####################################################################################### +class queue_sink_thread(_threading.Thread): + """! + Read samples from the queue sink and execute the callback. + """ + + def __init__(self, queue_sink, callback): + """! + Queue sink thread contructor. + @param queue_sink the queue to pop messages from + @param callback the function of one argument + """ + self._queue_sink = queue_sink + self._callback = callback + _threading.Thread.__init__(self) + self.setDaemon(1) + self.keep_running = True + self.start() + + def run(self): + while self.keep_running: + self._callback(self._queue_sink.pop()) + +####################################################################################### +## Queue Sink +####################################################################################### +class _queue_sink_base(gr.hier_block2): + """! + Queue sink base, a queue sink for any size queue. + Easy read access to a gnuradio data stream from python. + Call pop to read a sample from a gnuradio data stream. + Samples are cast as python data types, complex, float, or int. + """ + + def __init__(self, vlen=1): + """! + Queue sink base contructor. + @param vlen the vector length + """ + self._vlen = vlen + #initialize hier2 + gr.hier_block2.__init__( + self, + "queue_sink", + gr.io_signature(1, 1, self._item_size*self._vlen), # Input signature + gr.io_signature(0, 0, 0) # Output signature + ) + #create message sink + self._msgq = gr.msg_queue(1) + message_sink = gr.message_sink(self._item_size*self._vlen, self._msgq, False) #False -> blocking + #connect + self.connect(self, message_sink) + self.arr = '' + + def pop(self): + """! + Pop a new sample off the front of the queue. + @return a new sample + """ + while len(self.arr) < self._item_size*self._vlen: + msg = self._msgq.delete_head() + self.arr = self.arr + msg.to_string() + sample = self.arr[:self._item_size*self._vlen] + self.arr = self.arr[self._item_size*self._vlen:] + sample = map(self._cast, numpy.fromstring(sample, self._numpy)) + if self._vlen == 1: return sample[0] + return sample + +class queue_sink_c(_queue_sink_base): + _item_size = gr.sizeof_gr_complex + _numpy = numpy.complex64 + def _cast(self, arg): return complex(arg.real, arg.imag) + +class queue_sink_f(_queue_sink_base): + _item_size = gr.sizeof_float + _numpy = numpy.float32 + _cast = float + +class queue_sink_i(_queue_sink_base): + _item_size = gr.sizeof_int + _numpy = numpy.int32 + _cast = int + +class queue_sink_s(_queue_sink_base): + _item_size = gr.sizeof_short + _numpy = numpy.int16 + _cast = int + +class queue_sink_b(_queue_sink_base): + _item_size = gr.sizeof_char + _numpy = numpy.int8 + _cast = int + +####################################################################################### +## Queue Source +####################################################################################### +class _queue_source_base(gr.hier_block2): + """! + Queue source base, a queue source for any size queue. + Easy write access to a gnuradio data stream from python. + Call push to to write a sample into the gnuradio data stream. + """ + + def __init__(self, vlen=1): + """! + Queue source base contructor. + @param vlen the vector length + """ + self._vlen = vlen + #initialize hier2 + gr.hier_block2.__init__( + self, + "queue_source", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, self._item_size*self._vlen) # Output signature + ) + #create message sink + message_source = gr.message_source(self._item_size*self._vlen, 1) + self._msgq = message_source.msgq() + #connect + self.connect(message_source, self) + + def push(self, item): + """! + Push an item into the back of the queue. + @param item the item + """ + if self._vlen == 1: item = [item] + arr = numpy.array(item, self._numpy) + msg = gr.message_from_string(arr.tostring(), 0, self._item_size, self._vlen) + self._msgq.insert_tail(msg) + +class queue_source_c(_queue_source_base): + _item_size = gr.sizeof_gr_complex + _numpy = numpy.complex64 + +class queue_source_f(_queue_source_base): + _item_size = gr.sizeof_float + _numpy = numpy.float32 + +class queue_source_i(_queue_source_base): + _item_size = gr.sizeof_int + _numpy = numpy.int32 + +class queue_source_s(_queue_source_base): + _item_size = gr.sizeof_short + _numpy = numpy.int16 + +class queue_source_b(_queue_source_base): + _item_size = gr.sizeof_char + _numpy = numpy.int8 + diff --git a/grc/src/grc_gnuradio/blks2/selector.py b/grc/src/grc_gnuradio/blks2/selector.py new file mode 100644 index 000000000..787f6547f --- /dev/null +++ b/grc/src/grc_gnuradio/blks2/selector.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr + +class selector(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)] * num_inputs + self.output_terminators = [gr.head(item_size, 0)] * 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() + +class valve(selector): + """Wrapper for selector with 1 input and 1 output.""" + + def __init__(self, item_size, open): + """! + Constructor for valve. + @param item_size the size of the gr data stream in bytes + @param open true if initial valve state is open + """ + if open: output_index = -1 + else: output_index = 0 + selector.__init__(self, item_size, 1, 1, 0, output_index) + + def set_open(self, open): + """! + Callback to set open state. + @param open true to set valve state to open + """ + if open: output_index = -1 + else: output_index = 0 + self.set_output_index(output_index) + diff --git a/grc/src/grc_gnuradio/usrp/Makefile.am b/grc/src/grc_gnuradio/usrp/Makefile.am new file mode 100644 index 000000000..9689be8e0 --- /dev/null +++ b/grc/src/grc_gnuradio/usrp/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc_gnuradio/usrp + +ourpython_PYTHON = \ + __init__.py \ + simple_usrp.py diff --git a/grc/src/grc_gnuradio/usrp/__init__.py b/grc/src/grc_gnuradio/usrp/__init__.py new file mode 100644 index 000000000..0962df14c --- /dev/null +++ b/grc/src/grc_gnuradio/usrp/__init__.py @@ -0,0 +1,25 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from simple_usrp import simple_source_c, simple_source_s +from simple_usrp import dual_source_c, dual_source_s +from simple_usrp import simple_sink_c, simple_sink_s +from simple_usrp import dual_sink_c, dual_sink_s + diff --git a/grc/src/grc_gnuradio/usrp/simple_usrp.py b/grc/src/grc_gnuradio/usrp/simple_usrp.py new file mode 100644 index 000000000..118ccc16a --- /dev/null +++ b/grc/src/grc_gnuradio/usrp/simple_usrp.py @@ -0,0 +1,379 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import sys +from gnuradio import usrp, gr + +#################################################################### +# Helper Functions +#################################################################### + +def _set_frequency(u, which, subdev, frequency, verbose=False): + """! + Set the carrier frequency for the given subdevice. + @param u the usrp source/sink + @param which specifies the DDC/DUC number + @param frequency the carrier frequency in Hz + @param verbose if true, print usrp tuning information + """ + r = u.tune(which, subdev, frequency) + if not verbose: return + print subdev.side_and_name() + if r: + print " r.baseband_frequency =", r.baseband_freq + print " r.dxc_frequency =", r.dxc_freq + print " r.residual_frequency =", r.residual_freq + print " r.inverted =", r.inverted + else: print >> sys.stderr, 'Error calling tune on subdevice.' + +def _setup_rx_subdev(u, subdev_spec, ddc, gain, frequency, auto_tr=None, rx_ant=None): + """! + Setup a usrp receive subdevice by setting gain and frequency. + Add the gain and frequency callbacks to the flow graph. + FlexRF: Handle auto transmit/receive and set the receive antenna. + @param u the usrp object + @param subdev_spec the sub-device specification + @param ddc which ddc to use: 0 or 1 + @param gain the gain to set + @param frequency the frequency to tune + @param auto_tr auto transmit/receive True, False, or None + @param rx_ant the receive antenna: 'TX/RX', 'RX2', or None + @return the subdevice + """ + subdev = usrp.selected_subdev(u, subdev_spec)#get the subdev + subdev.set_gain(gain) + _set_frequency(u, ddc, subdev, frequency, verbose=True) + if auto_tr is not None: subdev.set_auto_tr(auto_tr) + if rx_ant is not None: subdev.select_rx_antenna(rx_ant) + return subdev + +def _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr=None, tx_enb=None): + """! + Setup a usrp receive subdevice by setting gain and frequency. + Add the gain and frequency callbacks to the flow graph. + FlexRF: Handle auto transmit/receive and enable the transmitter. + @param u the usrp object + @param subdev_spec the sub-device specification + @param gain the gain to set + @param frequency the frequency to tune + @param auto_tr auto transmit/receive True, False, or None + @param tx_enb the transmit enable: True, False, or None + @return the subdevice + """ + subdev = usrp.selected_subdev(u, subdev_spec)#get the subdev + subdev.set_gain(gain) + _set_frequency(u, subdev._which, subdev, frequency, verbose=True) + if auto_tr is not None: subdev.set_auto_tr(auto_tr) + if tx_enb is not None: subdev.set_enable(tx_enb) + return subdev + +##map the usrp contructors to IO sizes +constructor_to_size = { + usrp.source_c: gr.sizeof_gr_complex, + usrp.sink_c: gr.sizeof_gr_complex, + usrp.source_s: gr.sizeof_short, + usrp.sink_s: gr.sizeof_short, +} + +#################################################################### +#################################################################### +# Simple USRP Base Classes +#################################################################### +#################################################################### + +class _simple_usrp(object): + """A single usrp source/sink base class.""" + + def __init__(self, u, subdev, which): + """! + Create a simple usrp base class. + @param u the usrp object + @param subdev the subdevice object + @param which specifies the DDC/DUC number when tuning + """ + self._u = u + self._subdev = subdev + self._which = which + + def get_u(self): + """! + Get the underlying usrp object. + @return the usrp source/sink object. + """ + return self._u + + def get_subdev(self): + """! + Get the underlying subdevice. + @return the subdev object. + """ + return self._subdev + + def set_frequency(self, frequency): + """! + Set the frequency of the subdevice. + @param frequency the frequency to tune + """ + _set_frequency(self.get_u(), self._which, self.get_subdev(), frequency) + + def set_gain(self, gain): + """! + Set the gain of the subdevice. + @param gain the gain to set + """ + self.get_subdev().set_gain(gain) + +#################################################################### +# Simple USRP Source +#################################################################### +class _simple_source(gr.hier_block2, _simple_usrp): + """A single usrp source of IO type short or complex.""" + + def __init__(self, number, subdev_spec, frequency, decimation, gain, mux=None, auto_tr=None, rx_ant=None): + """! + USRP simple source contructor. + @param number the unit number + @param subdev_spec the sub-device specification tuple + @param frequency the frequency to tune + @param decimation the device decimation + @param gain the gain to set + @param mux the mux in hex or None + @param auto_tr auto transmit/receive True, False, or None + @param rx_ant the receive antenna: 'TX/RX', 'RX2', or None + """ + #initialize hier2 block + gr.hier_block2.__init__( + self, 'usrp_simple_source', + gr.io_signature(0, 0, 0), + gr.io_signature(1, 1, constructor_to_size[self.constructor]), + ) + #create usrp object + u = self.constructor(number, nchan=1) + if subdev_spec is None: subdev_spec = usrp.pick_rx_subdevice(u) + u.set_decim_rate(decimation) + if mux is None: mux = usrp.determine_rx_mux_value(u, subdev_spec) + u.set_mux(mux) + subdev = _setup_rx_subdev(u, subdev_spec, 0, gain, frequency, auto_tr, rx_ant) + _simple_usrp.__init__(self, u, subdev, 0) + #connect + self.connect(u, self) + + def set_decim_rate(self, decim): self.get_u().set_decim_rate(int(decim)) + +class simple_source_c(_simple_source): constructor = usrp.source_c +class simple_source_s(_simple_source): constructor = usrp.source_s + +#################################################################### +# Simple USRP Sink +#################################################################### +class _simple_sink(gr.hier_block2, _simple_usrp): + """A single usrp sink of IO type short or complex.""" + + def __init__(self, number, subdev_spec, frequency, interpolation, gain, mux=None, auto_tr=None, tx_enb=None): + """! + USRP simple sink contructor. + @param number the unit number + @param subdev_spec the sub-device specification tuple + @param frequency the frequency to tune + @param interpolation the device interpolation + @param gain the gain to set + @param mux the mux in hex or None + @param auto_tr auto transmit/receive True, False, or None + @param tx_enb the transmit enable: True, False, or None + """ + #initialize hier2 block + gr.hier_block2.__init__( + self, 'usrp_simple_sink', + gr.io_signature(1, 1, constructor_to_size[self.constructor]), + gr.io_signature(0, 0, 0), + ) + #create usrp object + u = self.constructor(number, nchan=1) + if subdev_spec is None: subdev_spec = usrp.pick_tx_subdevice(u) + u.set_interp_rate(interpolation) + if mux is None: mux = usrp.determine_tx_mux_value(u, subdev_spec) + u.set_mux(mux) + subdev = _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr, tx_enb) + _simple_usrp.__init__(self, u, subdev, subdev._which) + #connect + self.connect(self, u) + + def set_interp_rate(self, interp): self.get_u().set_interp_rate(int(interp)) + +class simple_sink_c(_simple_sink): constructor = usrp.sink_c +class simple_sink_s(_simple_sink): constructor = usrp.sink_s + +#################################################################### +#################################################################### +# Dual USRP Base Classes +#################################################################### +#################################################################### + +class _dual_usrp(object): + """A dual usrp source/sink base class.""" + + def __init__(self, u, subdev_a, subdev_b, which_a, which_b): + """! + Create a dual usrp base class. + @param u the usrp object + @param subdev_a the subdevice object side a + @param subdev_b the subdevice object side b + @param which_a specifies the DDC/DUC number when tuning side a + @param which_b specifies the DDC/DUC number when tuning side b + """ + self._u = u + self._subdev_a = subdev_a + self._subdev_b = subdev_b + self._which_a = which_a + self._which_b = which_b + + def get_u(self): + """! + Get the underlying usrp object. + @return the usrp source/sink object. + """ + return self._u + + def get_subdev_a(self): + """! + Get the underlying subdevice. + @return the subdev object. + """ + return self._subdev_a + + def get_subdev_b(self): + """! + Get the underlying subdevice. + @return the subdev object. + """ + return self._subdev_b + + def set_frequency_a(self, frequency): + """! + Set the frequency of the subdevice. + @param frequency the frequency to tune + """ + _set_frequency(self.get_u(), self._which_a, self.get_subdev_a(), frequency) + + def set_frequency_b(self, frequency): + """! + Set the frequency of the subdevice. + @param frequency the frequency to tune + """ + _set_frequency(self.get_u(), self._which_b, self.get_subdev_b(), frequency) + + def set_gain_a(self, gain): + """! + Set the gain of the subdevice. + @param gain the gain to set + """ + self.get_subdev_a().set_gain(gain) + + def set_gain_b(self, gain): + """! + Set the gain of the subdevice. + @param gain the gain to set + """ + self.get_subdev_b().set_gain(gain) + +#################################################################### +# Dual USRP Source +#################################################################### +class _dual_source(gr.hier_block2, _dual_usrp): + """A dual usrp source of IO type short or complex.""" + + def __init__(self, number, frequency_a, frequency_b, decimation, gain_a, gain_b, mux=0x3210, auto_tr=None, rx_ant_a=None, rx_ant_b=None): + """! + USRP dual source contructor. + @param number the unit number + @param frequency_a the frequency to tune side a + @param frequency_b the frequency to tune side b + @param decimation the device decimation + @param gain_a the gain to set side a + @param gain_b the gain to set side b + @param mux the mux in hex + @param auto_tr auto transmit/receive True, False, or None + @param rx_ant_a the receive antenna side a: 'TX/RX', 'RX2', or None + @param rx_ant_b the receive antenna side b: 'TX/RX', 'RX2', or None + """ + #initialize hier2 block + gr.hier_block2.__init__( + self, 'usrp_dual_source', + gr.io_signature(0, 0, 0), + gr.io_signature(2, 2, constructor_to_size[self.constructor]), + ) + #create usrp object + u = self.constructor(number, nchan=2) + u.set_decim_rate(decimation) + u.set_mux(mux) + subdev_a = _setup_rx_subdev(u, (0, 0), 0, gain_a, frequency_a, auto_tr, rx_ant_a) + subdev_b = _setup_rx_subdev(u, (1, 0), 1, gain_b, frequency_b, auto_tr, rx_ant_b) + _dual_usrp.__init__(self, u, subdev_a, subdev_b, 0, 1) + #connect + deinter = gr.deinterleave(constructor_to_size[self.constructor]) + self.connect(u, deinter) + for i in range(2): self.connect((deinter, i), (self, i)) + + def set_decim_rate(self, decim): self.get_u().set_decim_rate(int(decim)) + +class dual_source_c(_dual_source): constructor = usrp.source_c +class dual_source_s(_dual_source): constructor = usrp.source_s + +#################################################################### +# Dual USRP Sink +#################################################################### +class _dual_sink(gr.hier_block2, _dual_usrp): + """A dual usrp sink of IO type short or complex.""" + + def __init__(self, number, frequency_a, frequency_b, interpolation, gain_a, gain_b, mux=0xba98, auto_tr=None, tx_enb_a=None, tx_enb_b=None): + """! + USRP dual sink contructor. + @param number the unit number + @param subdev_spec the sub-device specification tuple + @param frequency the frequency to tune + @param interpolation the device interpolation + @param gain the gain to set + @param mux the mux in hex or None + @param auto_tr auto transmit/receive True, False, or None + @param tx_enb the transmit enable: True, False, or None + """ + #initialize hier2 block + gr.hier_block2.__init__( + self, 'usrp_dual_sink', + gr.io_signature(2, 2, constructor_to_size[self.constructor]), + gr.io_signature(0, 0, 0), + ) + #create usrp object + u = self.constructor(number, nchan=2) + u.set_interp_rate(interpolation) + u.set_mux(mux) + subdev_a = _setup_tx_subdev(u, (0, 0), gain_a, frequency_a, auto_tr, tx_enb_a) + subdev_b = _setup_tx_subdev(u, (1, 0), gain_b, frequency_b, auto_tr, tx_enb_b) + _dual_usrp.__init__(self, u, subdev_a, subdev_b, subdev_a._which, subdev_b._which) + #connect + inter = gr.interleave(constructor_to_size[self.constructor]) + self.connect(inter, u) + for i in range(2): self.connect((self, i), (inter, i)) + + def set_interp_rate(self, interp): self.get_u().set_interp_rate(int(interp)) + +class dual_sink_c(_dual_sink): constructor = usrp.sink_c +class dual_sink_s(_dual_sink): constructor = usrp.sink_s + diff --git a/grc/src/grc_gnuradio/utils/Makefile.am b/grc/src/grc_gnuradio/utils/Makefile.am new file mode 100644 index 000000000..01020139e --- /dev/null +++ b/grc/src/grc_gnuradio/utils/Makefile.am @@ -0,0 +1,30 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc_gnuradio/utils + +ourpython_PYTHON = \ + __init__.py \ + convert_hier.py \ + expr_utils.py \ + extract_docs.py diff --git a/grc/src/grc_gnuradio/utils/__init__.py b/grc/src/grc_gnuradio/utils/__init__.py new file mode 100644 index 000000000..b6402601c --- /dev/null +++ b/grc/src/grc_gnuradio/utils/__init__.py @@ -0,0 +1,22 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.utils +#utility functions and classes +#@author Josh Blum + diff --git a/grc/src/grc_gnuradio/utils/convert_hier.py b/grc/src/grc_gnuradio/utils/convert_hier.py new file mode 100644 index 000000000..a0f3c2a85 --- /dev/null +++ b/grc/src/grc_gnuradio/utils/convert_hier.py @@ -0,0 +1,81 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.utils.convert_hier +#Utility functions to convert a grc hier block to an xml wrapper +#@author Josh Blum + +from grc_gnuradio.Constants import BLOCK_DTD +from grc import ParseXML +from grc.Utils import odict + +def convert_hier(flow_graph, python_file): + #extract info from the flow graph + input_sig = flow_graph.get_input_signature() + output_sig = flow_graph.get_output_signature() + parameters = flow_graph.get_parameters() + block_key = flow_graph.get_option('id') + block_name = flow_graph.get_option('title') + block_category = flow_graph.get_option('category') + block_desc = flow_graph.get_option('description') + block_author = flow_graph.get_option('author') + #build the nested data + block_n = odict() + block_n['name'] = block_name + block_n['key'] = block_key + block_n['category'] = block_category + block_n['import'] = 'execfile("%s")'%python_file + #make data + block_n['make'] = '%s(\n\t%s,\n)'%( + block_key, + ',\n\t'.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]), + ) + #callback data + block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters] + #param data + params_n = list() + for param in parameters: + param_n = odict() + param_n['name'] = param.get_param('label').get_value() or param.get_id() + param_n['key'] = param.get_id() + param_n['value'] = param.get_param('value').get_value() + param_n['type'] = 'raw' + params_n.append(param_n) + block_n['param'] = params_n + #sink data + if int(input_sig['nports']): + sink_n = odict() + sink_n['name'] = 'in' + sink_n['type'] = input_sig['type'] + sink_n['vlen'] = input_sig['vlen'] + sink_n['nports'] = input_sig['nports'] + block_n['sink'] = sink_n + #source data + if int(output_sig['nports']): + source_n = odict() + source_n['name'] = 'out' + source_n['type'] = output_sig['type'] + source_n['vlen'] = output_sig['vlen'] + source_n['nports'] = output_sig['nports'] + block_n['source'] = source_n + #doc data + block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file) + #write the block_n to file + xml_file = python_file + '.xml' + ParseXML.to_file({'block': block_n}, xml_file) + ParseXML.validate_dtd(xml_file, BLOCK_DTD) diff --git a/grc/src/grc_gnuradio/utils/expr_utils.py b/grc/src/grc_gnuradio/utils/expr_utils.py new file mode 100644 index 000000000..8253f018a --- /dev/null +++ b/grc/src/grc_gnuradio/utils/expr_utils.py @@ -0,0 +1,140 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.utils.expr_utils +#Utility functions to comprehend variable expressions. +#@author Josh Blum + +import string +VAR_CHARS = string.letters + string.digits + '_' + +class graph(object): + """! + Simple graph structure held in a dictionary. + """ + + def __init__(self): self._graph = dict() + + def __str__(self): return str(self._graph) + + def add_node(self, node_key): + if self._graph.has_key(node_key): return + self._graph[node_key] = set() + + def remove_node(self, node_key): + if not self._graph.has_key(node_key): return + for edges in self._graph.values(): + if node_key in edges: edges.remove(node_key) + self._graph.pop(node_key) + + def add_edge(self, src_node_key, dest_node_key): + self._graph[src_node_key].add(dest_node_key) + + def remove_edge(self, src_node_key, dest_node_key): + self._graph[src_node_key].remove(dest_node_key) + + def get_nodes(self): return self._graph.keys() + + def get_edges(self, node_key): return self._graph[node_key] + +def expr_split(expr): + """! + Split up an expression by non alphanumeric characters, including underscore. + Leave strings in-tact. + #TODO ignore escaped quotes, use raw strings. + @param expr an expression string + @return a list of string tokens that form expr + """ + toks = list() + tok = '' + quote = '' + for char in expr: + if quote or char in VAR_CHARS: + if char == quote: quote = '' + tok += char + elif char in ("'", '"'): + toks.append(tok) + tok = char + quote = char + else: + toks.append(tok) + toks.append(char) + tok = '' + toks.append(tok) + return filter(lambda t: t, toks) + +def expr_prepend(expr, vars, prepend): + """! + Search for vars in the expression and add the prepend. + @param expr an expression string + @param vars a list of variable names + @param prepend the prepend string + @return a new expression with the prepend + """ + expr_splits = expr_split(expr) + for i, es in enumerate(expr_splits): + if es in vars: expr_splits[i] = prepend + es + return ''.join(expr_splits) + +def get_variable_dependencies(expr, vars): + """! + Return a set of variables used in this expression. + @param expr an expression string + @param vars a list of variable names + @return a subset of vars used in the expression + """ + expr_toks = expr_split(expr) + return set(filter(lambda v: v in expr_toks, vars)) + +def get_graph(exprs): + """! + Get a graph representing the variable dependencies + @param exprs a mapping of variable name to expression + @return a graph of variable deps + """ + vars = exprs.keys() + #get dependencies for each expression, load into graph + var_graph = graph() + for var in vars: var_graph.add_node(var) + for var, expr in exprs.iteritems(): + for dep in get_variable_dependencies(expr, vars): + var_graph.add_edge(dep, var) + return var_graph + +def sort_variables(exprs): + """! + Get a list of variables in order of dependencies. + @param exprs a mapping of variable name to expression + @return a list of variable names + @throws AssertionError circular dependencies + """ + var_graph = get_graph(exprs) + sorted_vars = list() + #determine dependency order + while var_graph.get_nodes(): + #get a list of nodes with no edges + indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes()) + assert indep_vars + #add the indep vars to the end of the list + sorted_vars.extend(sorted(indep_vars)) + #remove each edge-less node from the graph + for var in indep_vars: var_graph.remove_node(var) + return reversed(sorted_vars) + +if __name__ == '__main__': + for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i diff --git a/grc/src/grc_gnuradio/utils/extract_docs.py b/grc/src/grc_gnuradio/utils/extract_docs.py new file mode 100644 index 000000000..bc0dcd446 --- /dev/null +++ b/grc/src/grc_gnuradio/utils/extract_docs.py @@ -0,0 +1,109 @@ +""" +Copyright 2008 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 +""" +##@package grc_gnuradio.utils.extract_docs +#Extract documentation from the gnuradio doxygen files. +#@author Josh Blum + +from grc_gnuradio.Constants import * +from lxml import etree +import os + +DOXYGEN_NAME_XPATH = '/doxygen/compounddef/compoundname' +DOXYGEN_BRIEFDESC_GR_XPATH = '/doxygen/compounddef/briefdescription' +DOXYGEN_DETAILDESC_GR_XPATH = '/doxygen/compounddef/detaileddescription' +DOXYGEN_BRIEFDESC_BLKS2_XPATH = '/doxygen/compounddef/sectiondef[@kind="public-func"]/memberdef/briefdescription' +DOXYGEN_DETAILDESC_BLKS2_XPATH = '/doxygen/compounddef/sectiondef[@kind="public-func"]/memberdef/detaileddescription' + +def extract_txt(xml): + """! + Recursivly pull the text out of an xml tree. + @param xml the xml tree + @return a string + """ + text = xml.text or '' + if not len(xml): return text + return ''.join([text] + map(extract_txt, xml)) + +def is_match(key, file): + """! + Is the block key a match for the given file name? + @param key block key + @param file the xml file name + @return true if matches + """ + if not file.endswith('.xml'): return False + file = file.replace('.xml', '') #remove file ext + file = file.replace('__', '_') #doxygen xml files have 2 underscores + if key.startswith('gr_'): + if not file.startswith('classgr_'): return False + key = key.replace('gr_', 'classgr_') + elif key.startswith('trellis_'): + if not file.startswith('classtrellis_'): return False + key = key.replace('trellis_', 'classtrellis_') + elif key.startswith('blks2_'): + if not file.startswith('classgnuradio_'): return False + if 'blks2' not in file: return False + file = file.replace('_1_1', '_') #weird blks2 doxygen syntax + key = key.replace('blks2_', '') + else: return False + for k, f in zip(*map(reversed, map(lambda x: x.split('_'), [key, file]))): + if k == f: continue + ks = k.split('x') + if len(ks) == 2 and f.startswith(ks[0]) and f.endswith(ks[1]): continue + if len(ks) > 2 and all(ki in ('x', fi) for ki, fi in zip(k, f)): continue + return False + return True + +def extract(key): + """! + Extract the documentation from the doxygen generated xml files. + If multiple files match, combine the docs. + @param key the block key + @return a string with documentation + """ + #get potential xml file matches for the key + if os.path.exists(DOCS_DIR) and os.path.isdir(DOCS_DIR): + matches = filter(lambda f: is_match(key, f), os.listdir(DOCS_DIR)) + else: matches = list() + #combine all matches + doc_strs = list() + for match in matches: + try: + xml_file = DOCS_DIR + '/' + match + xml = etree.parse(xml_file) + #extract descriptions + comp_name = extract_txt(xml.xpath(DOXYGEN_NAME_XPATH)[0]).strip('\n') + comp_name = ' --- ' + comp_name + ' --- ' + if key.startswith('gr_') or key.startswith('trellis_'): + brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_GR_XPATH)[0]).strip('\n') + detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_GR_XPATH)[0]).strip('\n') + elif key.startswith('blks2_'): + brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_BLKS2_XPATH)[0]).strip('\n') + detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_BLKS2_XPATH)[0]).strip('\n') + else: + brief_desc = '' + detailed_desc = '' + #combine + doc_strs.append('\n'.join([comp_name, brief_desc, detailed_desc]).strip('\n')) + except IndexError: pass #bad format + return '\n\n'.join(doc_strs) + +if __name__ == '__main__': + import sys + print extract(sys.argv[1]) diff --git a/grc/src/grc_gnuradio/wxgui/Makefile.am b/grc/src/grc_gnuradio/wxgui/Makefile.am new file mode 100644 index 000000000..2e7072eae --- /dev/null +++ b/grc/src/grc_gnuradio/wxgui/Makefile.am @@ -0,0 +1,29 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +ourpythondir = $(pythondir)/grc_gnuradio/wxgui + +ourpython_PYTHON = \ + __init__.py \ + callback_controls.py \ + top_block_gui.py diff --git a/grc/src/grc_gnuradio/wxgui/__init__.py b/grc/src/grc_gnuradio/wxgui/__init__.py new file mode 100644 index 000000000..c0fdca52c --- /dev/null +++ b/grc/src/grc_gnuradio/wxgui/__init__.py @@ -0,0 +1,30 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from callback_controls import \ + button_control, \ + drop_down_control, \ + radio_buttons_horizontal_control, \ + radio_buttons_vertical_control, \ + slider_horizontal_control, \ + slider_vertical_control, \ + text_box_control +from top_block_gui import top_block_gui + diff --git a/grc/src/grc_gnuradio/wxgui/callback_controls.py b/grc/src/grc_gnuradio/wxgui/callback_controls.py new file mode 100644 index 000000000..c1ba784eb --- /dev/null +++ b/grc/src/grc_gnuradio/wxgui/callback_controls.py @@ -0,0 +1,281 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import wx +import sys + +class LabelText(wx.StaticText): + """Label text class for uniform labels among all controls.""" + + def __init__(self, window, label): + wx.StaticText.__init__(self, window, -1, str(label)) + font = self.GetFont() + font.SetWeight(wx.FONTWEIGHT_BOLD) + self.SetFont(font) + +class _control_base(wx.BoxSizer): + """Control base class""" + + def __init__(self, window, callback): + self.window = window + self.callback = callback + wx.BoxSizer.__init__(self, wx.VERTICAL) + + def get_window(self): return self.window + + def call(self): return self.callback(self.get_value()) + + def get_value(self): raise NotImplementedError + +class _chooser_control_base(_control_base): + """House a drop down or radio buttons for variable control.""" + + def __init__(self, window, callback, label='Label', index=0, choices=[0], labels=[]): + """! + Chooser contructor. + Create the slider, text box, and label. + @param window the wx parent window + @param callback call the callback on changes + @param label the label title + @param index the default choice index + @param choices a list of choices + @param labels the choice labels or empty list + """ + #initialize + _control_base.__init__(self, window, callback) + label_text = LabelText(self.get_window(), label) + self.Add(label_text, 0, wx.ALIGN_CENTER) + self.index = index + self.choices = choices + self.labels = map(str, labels or choices) + self._init() + + def _handle_changed(self, event=None): + """! + A change is detected. Call the callback. + """ + try: self.call() + except Exception, e: print >> sys.stderr, 'Error in exec callback from handle changed.\n', e + + def get_value(self): + """! + Update the chooser. + @return one of the possible choices + """ + self._update() + return self.choices[self.index] + +############################################################################################## +# Button Control +############################################################################################## +class button_control(_chooser_control_base): + """House a button for variable control.""" + + def _init(self): + self.button = wx.Button(self.get_window(), -1, self.labels[self.index]) + self.button.Bind(wx.EVT_BUTTON, self._handle_changed) + self.Add(self.button, 0, wx.ALIGN_CENTER) + + def _update(self): + self.index = (self.index + 1)%len(self.choices) #circularly increment index + self.button.SetLabel(self.labels[self.index]) + +############################################################################################## +# Drop Down Control +############################################################################################## +class drop_down_control(_chooser_control_base): + """House a drop down for variable control.""" + + def _init(self): + self.drop_down = wx.Choice(self.get_window(), -1, choices=self.labels) + self.Add(self.drop_down, 0, wx.ALIGN_CENTER) + self.drop_down.Bind(wx.EVT_CHOICE, self._handle_changed) + self.drop_down.SetSelection(self.index) + + def _update(self): + self.index = self.drop_down.GetSelection() + +############################################################################################## +# Radio Buttons Control +############################################################################################## +class _radio_buttons_control_base(_chooser_control_base): + """House radio buttons for variable control.""" + + def _init(self): + #create box for radio buttons + radio_box = wx.BoxSizer(self.radio_box_orientation) + panel = wx.Panel(self.get_window(), -1) + panel.SetSizer(radio_box) + self.Add(panel, 0, wx.ALIGN_CENTER) + #create radio buttons + self.radio_buttons = list() + for label in self.labels: + radio_button = wx.RadioButton(panel, -1, label) + radio_button.SetValue(False) + self.radio_buttons.append(radio_button) + radio_box.Add(radio_button, 0, self.radio_button_align) + radio_button.Bind(wx.EVT_RADIOBUTTON, self._handle_changed) + #set one radio button active + self.radio_buttons[self.index].SetValue(True) + + def _update(self): + selected_radio_button = filter(lambda rb: rb.GetValue(), self.radio_buttons)[0] + self.index = self.radio_buttons.index(selected_radio_button) + +class radio_buttons_horizontal_control(_radio_buttons_control_base): + radio_box_orientation = wx.HORIZONTAL + radio_button_align = wx.ALIGN_CENTER +class radio_buttons_vertical_control(_radio_buttons_control_base): + radio_box_orientation = wx.VERTICAL + radio_button_align = wx.ALIGN_LEFT + +############################################################################################## +# Slider Control +############################################################################################## +class _slider_control_base(_control_base): + """House a Slider and a Text Box for variable control.""" + + def __init__(self, window, callback, label='Label', value=50, min=0, max=100, num_steps=100): + """! + Slider contructor. + Create the slider, text box, and label. + @param window the wx parent window + @param callback call the callback on changes + @param label the label title + @param value the default value + @param min the min + @param max the max + @param num_steps the number of steps + """ + #initialize + _control_base.__init__(self, window, callback) + self.min = float(min) + self.max = float(max) + self.num_steps = int(num_steps) + #create gui elements + label_text_sizer = wx.BoxSizer(self.label_text_orientation) #label and text box container + label_text = LabelText(self.get_window(), '%s: '%str(label)) + self.text_box = text_box = wx.TextCtrl(self.get_window(), -1, str(value), style=wx.TE_PROCESS_ENTER) + text_box.Bind(wx.EVT_TEXT_ENTER, self._handle_enter) #bind this special enter hotkey event + for obj in (label_text, text_box): #fill the container with label and text entry box + label_text_sizer.Add(obj, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL) + self.Add(label_text_sizer, 0, wx.ALIGN_CENTER) + #make the slider + self.slider = slider = wx.Slider(self.get_window(), -1, size=wx.Size(*self.slider_size), style=self.slider_style) + try: slider.SetRange(0, num_steps) + except Exception, e: + print >> sys.stderr, 'Error in set slider range: "%s".'%e + sys.exit(-1) + slider.Bind(wx.EVT_SCROLL, self._handle_scroll) #bind the scrolling event + self.Add(slider, 0, wx.ALIGN_CENTER) + #init slider and text box + self._value = value + self._set_slider_value(self._value) #sets the slider's value + self.text_box.SetValue(str(self._value)) + + def get_value(self): + """! + Get the current set value. + @return the value (float) + """ + return self._value + + def _set_slider_value(self, real_value): + """! + Translate the real numerical value into a slider value and, + write the value to the slider. + @param real_value the numeric value the slider should represent + """ + slider_value = (float(real_value) - self.min)*self.num_steps/(self.max - self.min) + self.slider.SetValue(slider_value) + + def _handle_scroll(self, event=None): + """! + A scroll event is detected. Read the slider, call the callback. + """ + slider_value = self.slider.GetValue() + new_value = slider_value*(self.max - self.min)/self.num_steps + self.min + self.text_box.SetValue(str(new_value)) + self._value = new_value + try: self.call() + except Exception, e: print >> sys.stderr, 'Error in exec callback from handle scroll.\n', e + + def _handle_enter(self, event=None): + """! + An enter key was pressed. Read the text box, call the callback. + """ + new_value = float(self.text_box.GetValue()) + self._set_slider_value(new_value) + self._value = new_value + try: self.call() + except Exception, e: print >> sys.stderr, 'Error in exec callback from handle enter.\n', e + +class slider_horizontal_control(_slider_control_base): + label_text_orientation = wx.HORIZONTAL + slider_style = wx.SL_HORIZONTAL + slider_size = 200, 20 +class slider_vertical_control(_slider_control_base): + label_text_orientation = wx.VERTICAL + slider_style = wx.SL_VERTICAL + slider_size = 20, 200 + +############################################################################################## +# Text Box Control +############################################################################################## +class text_box_control(_control_base): + """House a Text Box for variable control.""" + + def __init__(self, window, callback, label='Label', value=50): + """! + Text box contructor. + Create the text box, and label. + @param window the wx parent window + @param callback call the callback on changes + @param label the label title + @param value the default value + """ + #initialize + _control_base.__init__(self, window, callback) + #create gui elements + label_text_sizer = wx.BoxSizer(wx.HORIZONTAL) #label and text box container + label_text = LabelText(self.get_window(), '%s: '%str(label)) + self.text_box = text_box = wx.TextCtrl(self.get_window(), -1, str(value), style=wx.TE_PROCESS_ENTER) + text_box.Bind(wx.EVT_TEXT_ENTER, self._handle_enter) #bind this special enter hotkey event + for obj in (label_text, text_box): #fill the container with label and text entry box + label_text_sizer.Add(obj, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL) + self.Add(label_text_sizer, 0, wx.ALIGN_CENTER) + self.text_box.SetValue(str(value)) + + def get_value(self): + """! + Get the current set value. + @return the value (float) + """ + return self._value + + def _handle_enter(self, event=None): + """! + An enter key was pressed. Read the text box, call the callback. + If the text cannot be evaluated, do not try callback. + """ + try: self._value = eval(self.text_box.GetValue()) + except: return + try: self.call() + except Exception, e: print >> sys.stderr, 'Error in exec callback from handle enter.\n', e diff --git a/grc/src/grc_gnuradio/wxgui/top_block_gui.py b/grc/src/grc_gnuradio/wxgui/top_block_gui.py new file mode 100644 index 000000000..d56d20056 --- /dev/null +++ b/grc/src/grc_gnuradio/wxgui/top_block_gui.py @@ -0,0 +1,99 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import wx +import sys, os +from gnuradio import gr + +default_gui_size = (200, 100) + +class top_block_gui(gr.top_block): + """gr top block with wx gui app and grid sizer.""" + + def __init__(self, title='', size=default_gui_size, icon=None): + """! + Initialize the gr top block. + Create the wx gui elements. + @param title the main window title + @param size the main window size tuple in pixels + @param icon the file path to an icon or None + """ + #initialize + gr.top_block.__init__(self) + self._size = size + #set the icon + if icon and os.path.isfile(icon): self._icon = icon + else: self._icon = None + #create gui elements + self._wx_app = wx.App() + self._wx_frame = wx.Frame(None , -1, title) + self._wx_grid = wx.GridBagSizer(5, 5) + self._wx_vbox = wx.BoxSizer(wx.VERTICAL) + + def GetWin(self): + """! + Get the window for wx elements to fit within. + @return the wx frame + """ + return self._wx_frame + + def Add(self, win): + """! + Add a window to the wx vbox. + @param win the wx window + """ + self._wx_vbox.Add(win, 0, wx.EXPAND) + + def GridAdd(self, win, row, col, row_span=1, col_span=1): + """! + Add a window to the wx grid at the given position. + @param win the wx window + @param row the row specification (integer >= 0) + @param col the column specification (integer >= 0) + @param row_span the row span specification (integer >= 1) + @param col_span the column span specification (integer >= 1) + """ + self._wx_grid.Add(win, wx.GBPosition(row, col), wx.GBSpan(row_span, col_span), wx.EXPAND) + + def Run(self): + """! + Setup the wx gui elements. + Start the gr top block. + Block with the wx main loop. + """ + #set wx app icon + if self._icon: self._wx_frame.SetIcon(wx.Icon(self._icon, wx.BITMAP_TYPE_ANY)) + #set minimal window size + self._wx_frame.SetSizeHints(*self._size) + #create callback for quit + def _quit(event): + gr.top_block.stop(self) + self._wx_frame.Destroy() + #setup app + self._wx_vbox.Add(self._wx_grid, 0, wx.EXPAND) + self._wx_frame.Bind(wx.EVT_CLOSE, _quit) + self._wx_frame.SetSizerAndFit(self._wx_vbox) + self._wx_frame.Show() + self._wx_app.SetTopWindow(self._wx_frame) + #start flow graph + gr.top_block.start(self) + #blocking main loop + self._wx_app.MainLoop() + |