summaryrefslogtreecommitdiff
path: root/grc
diff options
context:
space:
mode:
Diffstat (limited to 'grc')
-rw-r--r--grc/Makefile.am28
-rw-r--r--grc/Makefile.common41
-rw-r--r--grc/data/Makefile.am24
-rw-r--r--grc/data/grc/Makefile.am31
-rw-r--r--grc/data/grc/block_tree.dtd26
-rw-r--r--grc/data/grc/flow_graph.dtd36
-rw-r--r--grc/data/grc/grc-icon-256.pngbin0 -> 7843 bytes
-rw-r--r--grc/data/grc/grc-icon-256.svg216
-rw-r--r--grc/data/grc/grc-icon-32.pngbin0 -> 1060 bytes
-rw-r--r--grc/data/grc_gnuradio/Makefile.am32
-rw-r--r--grc/data/grc_gnuradio/block.dtd54
-rw-r--r--grc/data/grc_gnuradio/block_tree.xml271
-rw-r--r--grc/data/grc_gnuradio/blocks/Makefile.am205
-rw-r--r--grc/data/grc_gnuradio/blocks/audio_sink.xml83
-rw-r--r--grc/data/grc_gnuradio/blocks/audio_source.xml83
-rw-r--r--grc/data/grc_gnuradio/blocks/band_pass_filter.xml125
-rw-r--r--grc/data/grc_gnuradio/blocks/band_reject_filter.xml125
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_am_demod_cf.xml47
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_analysis_filterbank.xml32
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_channel_model.xml60
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_dxpsk_demod.xml95
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_dxpsk_mod.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_error_rate.xml66
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_fm_deemph.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_fm_demod_cf.xml68
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_fm_preemph.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_gmsk_demod.xml56
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_gmsk_mod.xml35
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_logpwrfft_x.xml89
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_nbfm_rx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_nbfm_tx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_packet_decoder.xml81
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_packet_encoder.xml117
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_qamx_demod.xml99
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_qamx_mod.xml71
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_rational_resampler_xxx.xml88
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_selector.xml97
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_standard_squelch.xml32
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_stream_to_vector_decimator.xml77
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_synthesis_filterbank.xml32
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_valve.xml72
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_wfm_rcv.xml33
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_wfm_rcv_pll.xml33
-rw-r--r--grc/data/grc_gnuradio/blocks/blks2_wfm_tx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_add_const_vxx.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_add_vxx.xml63
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_agc2_xx.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_agc_xx.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_and_xx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_argmax_xx.xml58
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_binary_slicer_fb.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_char_to_float.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_chunks_to_symbols.xml68
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_clock_recovery_mm_xx.xml64
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_cma_equalizer_cc.xml36
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_arg.xml29
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_float.xml36
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_imag.xml29
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_interleaved_short.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_mag.xml29
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_mag_squared.xml29
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_complex_to_real.xml29
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_conjugate_cc.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_constellation_decoder_cb.xml30
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_correlate_access_code_bb.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_costas_loop_cc.xml52
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_dd_mpsk_sync_cc.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_decode_ccsds_27_fb.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_deinterleave.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_delay.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_diff_decoder_bb.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_diff_encoder_bb.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_diff_phasor_cc.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_divide_xx.xml54
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_dpll_bb.xml30
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_encode_ccsds_27_bb.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_feedforward_agc_cc.xml32
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_fft_filter_xxx.xml52
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_fft_vxx.xml81
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_file_sink.xml60
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_file_source.xml74
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_filter_delay_fc.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_fir_filter_xxx.xml80
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_float_to_char.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_float_to_complex.xml26
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_float_to_short.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_float_to_uchar.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_fractional_interpolator_xx.xml46
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_freq_xlating_fir_filter_xxx.xml93
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_frequency_modulator_fc.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_glfsr_source_x.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_goertzel_fc.xml35
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_head.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_hilbert_fc.xml26
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_iir_filter_ffd.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_integrate_xx.xml50
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_interleave.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_interleaved_short_to_complex.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_interp_fir_filter_xxx.xml80
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_iqcomp_cc.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_keep_one_in_n.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_kludge_copy.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_map_bb.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_max_xx.xml58
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_moving_average_xx.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_mpsk_receiver_cc.xml81
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_mpsk_sync_cc.xml69
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_multiply_const_vxx.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_multiply_vxx.xml63
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_mute_xx.xml53
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_nlog10_ff.xml42
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_noise_source_x.xml76
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_nop.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_not_xx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_null_sink.xml54
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_null_source.xml54
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_or_xx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_packed_to_unpacked_xx.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_peak_detector2_fb.xml58
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_peak_detector_xb.xml64
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_phase_modulator_fc.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_pll_carriertracking_cc.xml40
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_pll_freqdet_cf.xml40
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_pll_refout_cc.xml40
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_pn_correlator_cc.xml35
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_pwr_squelch_xx.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_quadrature_demod_cf.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_rational_resampler_base_xxx.xml86
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_repeat.xml64
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_rms_xx.xml41
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_sample_and_hold_xx.xml49
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_short_to_float.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_sig_source_x.xml99
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_simple_correlator.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_simple_framer.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_simple_squelch_cc.xml32
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_single_pole_iir_filter_xx.xml51
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_skiphead.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_stream_to_streams.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_stream_to_vector.xml66
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_streams_to_stream.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_streams_to_vector.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_sub_xx.xml54
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_threshold_ff.xml38
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_throttle.xml65
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_uchar_to_float.xml20
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_udp_sink.xml85
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_udp_source.xml73
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_unpack_k_bits_bb.xml25
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_unpacked_to_packed_xx.xml59
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_vco_f.xml35
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_vector_sink_x.xml46
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_vector_source_x.xml71
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_vector_to_stream.xml66
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_vector_to_streams.xml67
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_wavfile_sink.xml42
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_wavfile_source.xml44
-rw-r--r--grc/data/grc_gnuradio/blocks/gr_xor_xx.xml48
-rw-r--r--grc/data/grc_gnuradio/blocks/high_pass_filter.xml120
-rw-r--r--grc/data/grc_gnuradio/blocks/import.xml26
-rw-r--r--grc/data/grc_gnuradio/blocks/low_pass_filter.xml120
-rw-r--r--grc/data/grc_gnuradio/blocks/note.xml17
-rw-r--r--grc/data/grc_gnuradio/blocks/options.xml89
-rw-r--r--grc/data/grc_gnuradio/blocks/pad_sink.xml68
-rw-r--r--grc/data/grc_gnuradio/blocks/pad_source.xml68
-rw-r--r--grc/data/grc_gnuradio/blocks/parameter.xml31
-rw-r--r--grc/data/grc_gnuradio/blocks/preferences.xml146
-rw-r--r--grc/data/grc_gnuradio/blocks/random_source_x.xml73
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_encoder_xx.xml74
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_metrics_x.xml84
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_permutation.xml74
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_siso_combined_f.xml112
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_siso_f.xml85
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_viterbi_combined_xx.xml122
-rw-r--r--grc/data/grc_gnuradio/blocks/trellis_viterbi_x.xml66
-rw-r--r--grc/data/grc_gnuradio/blocks/usrp_diagnostics.xml54
-rw-r--r--grc/data/grc_gnuradio/blocks/usrp_dual_sink_x.xml154
-rw-r--r--grc/data/grc_gnuradio/blocks/usrp_dual_source_x.xml154
-rw-r--r--grc/data/grc_gnuradio/blocks/usrp_simple_sink_x.xml140
-rw-r--r--grc/data/grc_gnuradio/blocks/usrp_simple_source_x.xml148
-rw-r--r--grc/data/grc_gnuradio/blocks/variable.xml21
-rw-r--r--grc/data/grc_gnuradio/blocks/variable_chooser.xml93
-rw-r--r--grc/data/grc_gnuradio/blocks/variable_sink.xml66
-rw-r--r--grc/data/grc_gnuradio/blocks/variable_slider.xml92
-rw-r--r--grc/data/grc_gnuradio/blocks/variable_text_box.xml51
-rw-r--r--grc/data/grc_gnuradio/blocks/wxgui_constellationsink2.xml74
-rw-r--r--grc/data/grc_gnuradio/blocks/wxgui_fftsink2.xml148
-rw-r--r--grc/data/grc_gnuradio/blocks/wxgui_numbersink2.xml173
-rw-r--r--grc/data/grc_gnuradio/blocks/wxgui_scopesink2.xml146
-rw-r--r--grc/data/grc_gnuradio/blocks/wxgui_waterfallsink2.xml128
-rw-r--r--grc/data/grc_gnuradio/blocks/xmlrpc_client.xml42
-rw-r--r--grc/data/grc_gnuradio/blocks/xmlrpc_server.xml39
-rw-r--r--grc/data/grc_gnuradio/default_flow_graph.grc.xml43
-rw-r--r--grc/data/grc_gnuradio/flow_graph.tmpl179
-rw-r--r--grc/examples/Makefile.am28
-rw-r--r--grc/examples/audio/Makefile.am26
-rw-r--r--grc/examples/audio/dial_tone.grc375
-rw-r--r--grc/examples/simple/Makefile.am26
-rw-r--r--grc/examples/simple/ber_simulation.grc540
-rw-r--r--grc/examples/usrp/Makefile.am28
-rw-r--r--grc/examples/usrp/usrp_two_tone_loopback.grc675
-rw-r--r--grc/examples/usrp/usrp_wbfm_receive.grc454
-rw-r--r--grc/examples/xmlrpc/Makefile.am30
-rw-r--r--grc/examples/xmlrpc/readme.txt18
-rw-r--r--grc/examples/xmlrpc/xmlrpc_client.grc312
-rw-r--r--grc/examples/xmlrpc/xmlrpc_client_script.py23
-rw-r--r--grc/examples/xmlrpc/xmlrpc_server.grc384
-rw-r--r--grc/scripts/Makefile.am26
-rwxr-xr-xgrc/scripts/grc43
-rwxr-xr-xgrc/scripts/usrp_diagnostics121
-rw-r--r--grc/src/Makefile.am24
-rw-r--r--grc/src/grc/ActionHandler.py442
-rw-r--r--grc/src/grc/Actions.py108
-rw-r--r--grc/src/grc/Constants.py.in154
-rw-r--r--grc/src/grc/Makefile.am50
-rw-r--r--grc/src/grc/Messages.py105
-rw-r--r--grc/src/grc/ParseXML.py103
-rw-r--r--grc/src/grc/Preferences.py134
-rw-r--r--grc/src/grc/StateCache.py98
-rw-r--r--grc/src/grc/Utils.py60
-rw-r--r--grc/src/grc/__init__.py22
-rw-r--r--grc/src/grc/converter.py251
-rw-r--r--grc/src/grc/elements/Block.py240
-rw-r--r--grc/src/grc/elements/Connection.py94
-rw-r--r--grc/src/grc/elements/Element.py97
-rw-r--r--grc/src/grc/elements/FlowGraph.py236
-rw-r--r--grc/src/grc/elements/Makefile.am34
-rw-r--r--grc/src/grc/elements/Param.py222
-rw-r--r--grc/src/grc/elements/Platform.py147
-rw-r--r--grc/src/grc/elements/Port.py109
-rw-r--r--grc/src/grc/elements/__init__.py22
-rw-r--r--grc/src/grc/gui/Bars.py143
-rw-r--r--grc/src/grc/gui/BlockTreeWindow.py154
-rw-r--r--grc/src/grc/gui/Dialogs.py149
-rw-r--r--grc/src/grc/gui/DrawingArea.py121
-rw-r--r--grc/src/grc/gui/FileDialogs.py155
-rw-r--r--grc/src/grc/gui/MainWindow.py321
-rw-r--r--grc/src/grc/gui/Makefile.am37
-rw-r--r--grc/src/grc/gui/NotebookPage.py176
-rw-r--r--grc/src/grc/gui/ParamsDialog.py135
-rw-r--r--grc/src/grc/gui/__init__.py27
-rw-r--r--grc/src/grc/gui/elements/Block.py195
-rw-r--r--grc/src/grc/gui/elements/Colors.py37
-rw-r--r--grc/src/grc/gui/elements/Connection.py170
-rw-r--r--grc/src/grc/gui/elements/Element.py234
-rw-r--r--grc/src/grc/gui/elements/FlowGraph.py566
-rw-r--r--grc/src/grc/gui/elements/Makefile.am36
-rw-r--r--grc/src/grc/gui/elements/Param.py224
-rw-r--r--grc/src/grc/gui/elements/Platform.py52
-rw-r--r--grc/src/grc/gui/elements/Port.py185
-rw-r--r--grc/src/grc/gui/elements/Utils.py52
-rw-r--r--grc/src/grc/gui/elements/__init__.py23
-rw-r--r--grc/src/grc_gnuradio/Block.py131
-rw-r--r--grc/src/grc_gnuradio/Connection.py42
-rw-r--r--grc/src/grc_gnuradio/Constants.py.in44
-rw-r--r--grc/src/grc_gnuradio/FlowGraph.py147
-rw-r--r--grc/src/grc_gnuradio/Generator.py132
-rw-r--r--grc/src/grc_gnuradio/Makefile.am53
-rw-r--r--grc/src/grc_gnuradio/Param.py255
-rw-r--r--grc/src/grc_gnuradio/Platform.py74
-rw-r--r--grc/src/grc_gnuradio/Port.py135
-rw-r--r--grc/src/grc_gnuradio/__init__.py21
-rw-r--r--grc/src/grc_gnuradio/blks2/Makefile.am31
-rw-r--r--grc/src/grc_gnuradio/blks2/__init__.py28
-rw-r--r--grc/src/grc_gnuradio/blks2/error_rate.py138
-rw-r--r--grc/src/grc_gnuradio/blks2/packet.py194
-rw-r--r--grc/src/grc_gnuradio/blks2/queue.py178
-rw-r--r--grc/src/grc_gnuradio/blks2/selector.py133
-rw-r--r--grc/src/grc_gnuradio/usrp/Makefile.am28
-rw-r--r--grc/src/grc_gnuradio/usrp/__init__.py25
-rw-r--r--grc/src/grc_gnuradio/usrp/simple_usrp.py379
-rw-r--r--grc/src/grc_gnuradio/utils/Makefile.am30
-rw-r--r--grc/src/grc_gnuradio/utils/__init__.py22
-rw-r--r--grc/src/grc_gnuradio/utils/convert_hier.py81
-rw-r--r--grc/src/grc_gnuradio/utils/expr_utils.py140
-rw-r--r--grc/src/grc_gnuradio/utils/extract_docs.py109
-rw-r--r--grc/src/grc_gnuradio/wxgui/Makefile.am29
-rw-r--r--grc/src/grc_gnuradio/wxgui/__init__.py30
-rw-r--r--grc/src/grc_gnuradio/wxgui/callback_controls.py281
-rw-r--r--grc/src/grc_gnuradio/wxgui/top_block_gui.py99
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
new file mode 100644
index 000000000..e4e8e54ae
--- /dev/null
+++ b/grc/data/grc/grc-icon-256.png
Binary files differ
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 &lt;patrick.strasser@tugraz.at&gt;</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
new file mode 100644
index 000000000..1e4f4f6c5
--- /dev/null
+++ b/grc/data/grc/grc-icon-32.png
Binary files differ
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 &lt; $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 &lt; $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>&quot;BER&quot;</key>
+ </option>
+ <option>
+ <name>Symbol Error Rate</name>
+ <key>&quot;SER&quot;</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 &gt; 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 &gt; 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 &gt; 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 &gt;= 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 &gt; 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 &gt; 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 &gt; 1</check>
+ <check>$vlen &gt; 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 &gt;= 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 &gt;= 2</check>
+ <check>$vlen &gt;= 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 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 &gt;= 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 &gt; 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 &gt; 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 &gt; 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 0</check>
+ <check>$vlen &gt; 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 &gt; 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 &gt;= 2</check>
+ <check>$vlen &gt;= 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 &gt; 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 &gt; 1</check>
+ <check>$vlen &gt; 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 &gt; 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 &gt;= 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 &gt; 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 &gt; 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 &gt;= 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 &gt; 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 &gt; 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 &gt; 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt;= 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 &gt; 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 &gt; 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 &gt; 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &gt; 0</check>
+ <check>$vlen &gt;= 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 &lt;= $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 &lt;= $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 &gt;= 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 &lt;= $(window_size)[0] &lt;= 2048</check>
+ <check>300 &lt;= $(window_size)[1] &lt;= 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 &gt; 0</check>
+ <check>0 &lt; $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 &gt; 0</check>
+ <check>0 &lt; $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 &gt; 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>&quot;TX/RX&quot;</key>
+ </option>
+ <option>
+ <name>RX2</name>
+ <key>&quot;RX2&quot;</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>&quot;TX/RX&quot;</key>
+ </option>
+ <option>
+ <name>RX2</name>
+ <key>&quot;RX2&quot;</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>&quot;TX/RX&quot;</key>
+ </option>
+ <option>
+ <name>RX2</name>
+ <key>&quot;RX2&quot;</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=&quot;$id&quot;,
+ #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 &gt; 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=&quot;$id&quot;,
+ #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 &lt;= $value &lt;= $max</check>
+ <check>$min &lt; $max</check>
+ <check>0 &lt; $num_steps &lt;= 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=&quot;$id&quot;,
+ #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(&quot;http://$(addr.eval):$(port)&quot;)</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(&quot;http://localhost:8080&quot;)
+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 (
+ ('&', '&amp;'),
+ ('<', '&lt;'),
+ ('>', '&gt;'),
+ ('"', '&quot;'),
+ ("'", '&apos;'),
+ ): 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()
+