From e692e71305ecd71d3681fe37f3d76f350d67e276 Mon Sep 17 00:00:00 2001 From: jcorgan Date: Tue, 18 Sep 2007 18:59:00 +0000 Subject: [PATCH] Merge r6461:6464 from jcorgan/t162-staging into trunk. * Final gr.top_block and gr.hier_block2 implementation inside gnuradio-core/src/lib/runtime * Implementation of gr.hier_block2 versions of all the old-style blocks in blks. These live in blks2. * Addition of gr.hier_block2 based versions of gr-wxgui blocks * Conversion of all the example code in gnuradio-examples to use this new code * Conversion of all the gr-utils scripts to use the new code The OFDM examples and related hierarchical blocks have not yet been converted. Code in the rest of the tree that is outside the core and example components has also not yet been converted. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6466 221aa14e-8319-0410-a670-987f0aec2ac5 --- config/grc_gnuradio_core.m4 | 2 +- config/grc_gnuradio_examples.m4 | 11 +- debian/gen-install-files.sh | 4 +- .../src/lib/runtime/gr_hier_block2.cc | 18 ++ .../src/lib/runtime/gr_hier_block2.h | 24 +- .../src/lib/runtime/gr_hier_block2.i | 34 +- .../src/lib/runtime/gr_hier_block2_detail.cc | 55 +++- .../src/lib/runtime/gr_hier_block2_detail.h | 58 ++-- gnuradio-core/src/lib/runtime/gr_top_block.cc | 6 + gnuradio-core/src/lib/runtime/gr_top_block.h | 5 + gnuradio-core/src/lib/runtime/gr_top_block.i | 1 + .../src/lib/runtime/gr_top_block_impl.h | 3 + gnuradio-core/src/python/gnuradio/Makefile.am | 2 +- .../src/python/gnuradio/blks2/__init__.py | 4 +- .../{blksimpl2 => blks2impl}/Makefile.am | 29 +- .../{blksimpl2 => blks2impl}/__init__.py | 0 .../src/python/gnuradio/blks2impl/am_demod.py | 76 +++++ .../gnuradio/blks2impl/channel_model.py | 59 ++++ .../src/python/gnuradio/blks2impl/cpm.py | 249 ++++++++++++++ .../{blksimpl2 => blks2impl}/d8psk.py | 112 ++++--- .../{blksimpl2 => blks2impl}/dbpsk.py | 108 ++++--- .../gnuradio/blks2impl/digital_voice.py.real | 102 ++++++ .../{blksimpl2 => blks2impl}/dqpsk.py | 110 ++++--- .../{blksimpl2 => blks2impl}/filterbank.py | 38 +-- .../src/python/gnuradio/blks2impl/fm_demod.py | 111 +++++++ .../src/python/gnuradio/blks2impl/fm_emph.py | 151 +++++++++ .../gnuradio/{blksimpl2 => blks2impl}/gmsk.py | 53 +-- .../src/python/gnuradio/blks2impl/nbfm_rx.py | 88 +++++ .../src/python/gnuradio/blks2impl/nbfm_tx.py | 92 ++++++ .../src/python/gnuradio/blks2impl/ofdm.py | 305 ++++++++++++++++++ .../gnuradio/blks2impl/ofdm_receiver.py | 64 ++++ .../gnuradio/blks2impl/ofdm_sync_fixed.py | 23 +- .../python/gnuradio/blks2impl/ofdm_sync_ml.py | 135 ++++++++ .../python/gnuradio/blks2impl/ofdm_sync_pn.py | 135 ++++++++ .../gnuradio/blks2impl/ofdm_sync_pnac.py | 126 ++++++++ .../gnuradio/{blksimpl2 => blks2impl}/pkt.py | 47 +-- .../gnuradio/{blksimpl2 => blks2impl}/psk.py | 14 +- .../src/python/gnuradio/blks2impl/qam.py | 113 +++++++ .../src/python/gnuradio/blks2impl/qam16.py | 208 ++++++++++++ .../src/python/gnuradio/blks2impl/qam256.py | 209 ++++++++++++ .../src/python/gnuradio/blks2impl/qam64.py | 208 ++++++++++++ .../src/python/gnuradio/blks2impl/qam8.py | 209 ++++++++++++ .../rational_resampler.py | 4 +- .../gnuradio/blks2impl/standard_squelch.py | 76 +++++ .../src/python/gnuradio/blks2impl/wfm_rcv.py | 69 ++++ .../python/gnuradio/blks2impl/wfm_rcv_pll.py | 192 +++++++++++ .../src/python/gnuradio/blks2impl/wfm_tx.py | 79 +++++ .../src/python/gnuradio/gr/hier_block2.py | 26 +- .../src/python/gnuradio/gr/qa_hier_block2.py | 53 +++ .../src/python/gnuradio/gr/top_block.py | 26 +- gnuradio-examples/python/Makefile.am | 20 +- .../python/apps/hf_explorer/hfx2.py | 56 ++-- gnuradio-examples/python/audio/audio_copy.py | 8 +- gnuradio-examples/python/audio/audio_fft.py | 16 +- gnuradio-examples/python/audio/audio_play.py | 8 +- .../python/audio/audio_to_file.py | 8 +- gnuradio-examples/python/audio/dial_tone.py | 8 +- gnuradio-examples/python/audio/mono_tone.py | 8 +- gnuradio-examples/python/audio/multi_tone.py | 8 +- gnuradio-examples/python/audio/noise.py | 6 +- .../python/audio/spectrum_inversion.py | 26 +- .../python/audio/test_resampler.py | 12 +- .../python/{hier => }/dect/Makefile.am | 5 + .../python/{hier => }/dect/README | 0 .../python/{hier => }/dect/dect_receiver.py | 7 +- .../python/{hier => }/dect/usrp_dect.py | 0 .../python/{hier => }/dect/usrp_source.py | 0 gnuradio-examples/python/digital/Makefile.am | 5 + .../python/digital/benchmark_loopback.py | 40 +-- .../python/digital/benchmark_rx.py | 19 +- .../python/digital/benchmark_tx.py | 24 +- .../python/digital/receive_path.py | 32 +- .../python/digital/receive_path_lb.py | 30 +- gnuradio-examples/python/digital/rx_voice.py | 29 +- .../python/digital/transmit_path.py | 25 +- .../python/digital/transmit_path_lb.py | 27 +- gnuradio-examples/python/digital/tunnel.py | 52 +-- gnuradio-examples/python/digital/tx_voice.py | 37 ++- .../python/digital_voice/cvsd_test.py | 18 +- .../python/digital_voice/encdec.py | 12 +- gnuradio-examples/python/hier/Makefile.am | 29 -- .../python/hier/audio/Makefile.am | 23 -- .../python/hier/audio/dial_tone2.py | 68 ---- gnuradio-examples/python/hier/dect/gmsk2.py | 278 ---------------- .../python/hier/digital/Makefile.am | 37 --- gnuradio-examples/python/hier/digital/README | 77 ----- .../python/hier/digital/benchmark_loopback.py | 181 ----------- .../python/hier/digital/benchmark_rx.py | 104 ------ .../python/hier/digital/benchmark_tx.py | 114 ------- .../python/hier/digital/fusb_options.py | 31 -- .../python/hier/digital/pick_bitrate.py | 143 -------- .../python/hier/digital/receive_path.py | 256 --------------- .../python/hier/digital/receive_path_lb.py | 136 -------- .../python/hier/digital/rx_voice.py | 136 -------- .../python/hier/digital/transmit_path.py | 229 ------------- .../python/hier/digital/transmit_path_lb.py | 118 ------- .../python/hier/digital/tunnel.py | 290 ----------------- .../python/hier/digital/tx_voice.py | 149 --------- .../python/hier/ofdm/Makefile.am | 22 -- .../python/hier/usrp/usrp_fft.py | 249 -------------- .../python/hier/usrp/usrp_siggen.py | 130 -------- .../python/{ => limbo}/networking/Makefile.am | 0 .../networking/measurement_slave.py | 0 .../{hier => limbo}/sounder/Makefile.am | 0 .../{hier => limbo}/sounder/sounder_rx.py | 0 .../{hier => limbo}/sounder/sounder_tx.py | 0 .../{hier => limbo}/sounder/usrp_sink.py | 0 .../sounder/usrp_sounder_rx.py | 0 .../sounder/usrp_sounder_tx.py | 0 .../{hier => limbo}/sounder/usrp_source.py | 0 .../{hier/networking => network}/Makefile.am | 5 + .../networking => network}/audio_sink.py | 0 .../networking => network}/audio_source.py | 0 .../networking => network}/dial_tone_sink.py | 0 .../dial_tone_source.py | 0 .../networking => network}/vector_sink.py | 0 .../networking => network}/vector_source.py | 0 gnuradio-examples/python/ofdm/Makefile.am | 7 +- gnuradio-examples/python/usrp/fm_tx4.py | 60 ++-- .../python/usrp/fm_tx_2_daughterboards.py | 57 +++- gnuradio-examples/python/usrp/max_power.py | 20 +- .../python/usrp/usrp_benchmark_usb.py | 8 +- .../python/usrp/usrp_nbfm_ptt.py | 64 ++-- .../python/usrp/usrp_nbfm_rcv.py | 65 ++-- .../python/usrp/usrp_spectrum_sense.py | 41 ++- .../python/usrp/usrp_test_loop_lfsr.py | 16 +- gnuradio-examples/python/usrp/usrp_tv_rcv.py | 30 +- .../python/usrp/usrp_tv_rcv_nogui.py | 26 +- gnuradio-examples/python/usrp/usrp_wfm_rcv.py | 38 ++- .../python/usrp/usrp_wfm_rcv2_nogui.py | 35 +- .../python/usrp/usrp_wfm_rcv_nogui.py | 32 +- .../python/usrp/usrp_wfm_rcv_pll.py | 56 ++-- .../python/usrp/usrp_wfm_rcv_sca.py | 25 +- .../python/usrp/usrp_wxapt_rcv.py | 38 ++- gr-cvsd-vocoder/src/python/Makefile.am | 2 +- gr-cvsd-vocoder/src/python/cvsd.py | 23 +- gr-cvsd-vocoder/src/python/encdec.py | 42 +-- gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py | 23 +- gr-pager/src/usrp_flex_band.py | 4 + gr-utils/src/python/usrp_fft.py | 16 +- gr-utils/src/python/usrp_oscope.py | 12 +- gr-utils/src/python/usrp_rx_cfile.py | 10 +- gr-utils/src/python/usrp_rx_nogui.py | 71 ++-- gr-utils/src/python/usrp_siggen.py | 36 +-- gr-utils/src/python/usrp_test_counting.py | 14 +- gr-utils/src/python/usrp_test_loopback.py | 20 +- 146 files changed, 4501 insertions(+), 3667 deletions(-) rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/Makefile.am (67%) rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/__init__.py (100%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/cpm.py rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/d8psk.py (78%) rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/dbpsk.py (79%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/dqpsk.py (77%) rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/filterbank.py (86%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/gmsk.py (88%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py rename gnuradio-examples/python/hier/usrp/Makefile.am => gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py (52%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/pkt.py (79%) rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/psk.py (92%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/qam.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/qam16.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/qam256.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/qam64.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/qam8.py rename gnuradio-core/src/python/gnuradio/{blksimpl2 => blks2impl}/rational_resampler.py (98%) create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py create mode 100644 gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py rename gnuradio-examples/python/{hier => }/dect/Makefile.am (89%) rename gnuradio-examples/python/{hier => }/dect/README (100%) rename gnuradio-examples/python/{hier => }/dect/dect_receiver.py (94%) rename gnuradio-examples/python/{hier => }/dect/usrp_dect.py (100%) rename gnuradio-examples/python/{hier => }/dect/usrp_source.py (100%) delete mode 100644 gnuradio-examples/python/hier/Makefile.am delete mode 100644 gnuradio-examples/python/hier/audio/Makefile.am delete mode 100755 gnuradio-examples/python/hier/audio/dial_tone2.py delete mode 100644 gnuradio-examples/python/hier/dect/gmsk2.py delete mode 100644 gnuradio-examples/python/hier/digital/Makefile.am delete mode 100644 gnuradio-examples/python/hier/digital/README delete mode 100755 gnuradio-examples/python/hier/digital/benchmark_loopback.py delete mode 100755 gnuradio-examples/python/hier/digital/benchmark_rx.py delete mode 100755 gnuradio-examples/python/hier/digital/benchmark_tx.py delete mode 100644 gnuradio-examples/python/hier/digital/fusb_options.py delete mode 100644 gnuradio-examples/python/hier/digital/pick_bitrate.py delete mode 100644 gnuradio-examples/python/hier/digital/receive_path.py delete mode 100644 gnuradio-examples/python/hier/digital/receive_path_lb.py delete mode 100755 gnuradio-examples/python/hier/digital/rx_voice.py delete mode 100644 gnuradio-examples/python/hier/digital/transmit_path.py delete mode 100644 gnuradio-examples/python/hier/digital/transmit_path_lb.py delete mode 100755 gnuradio-examples/python/hier/digital/tunnel.py delete mode 100755 gnuradio-examples/python/hier/digital/tx_voice.py delete mode 100644 gnuradio-examples/python/hier/ofdm/Makefile.am delete mode 100755 gnuradio-examples/python/hier/usrp/usrp_fft.py delete mode 100755 gnuradio-examples/python/hier/usrp/usrp_siggen.py rename gnuradio-examples/python/{ => limbo}/networking/Makefile.am (100%) rename gnuradio-examples/python/{ => limbo}/networking/measurement_slave.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/Makefile.am (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/sounder_rx.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/sounder_tx.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/usrp_sink.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/usrp_sounder_rx.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/usrp_sounder_tx.py (100%) rename gnuradio-examples/python/{hier => limbo}/sounder/usrp_source.py (100%) rename gnuradio-examples/python/{hier/networking => network}/Makefile.am (90%) rename gnuradio-examples/python/{hier/networking => network}/audio_sink.py (100%) rename gnuradio-examples/python/{hier/networking => network}/audio_source.py (100%) rename gnuradio-examples/python/{hier/networking => network}/dial_tone_sink.py (100%) rename gnuradio-examples/python/{hier/networking => network}/dial_tone_source.py (100%) rename gnuradio-examples/python/{hier/networking => network}/vector_sink.py (100%) rename gnuradio-examples/python/{hier/networking => network}/vector_source.py (100%) diff --git a/config/grc_gnuradio_core.m4 b/config/grc_gnuradio_core.m4 index c4774413..a005645c 100644 --- a/config/grc_gnuradio_core.m4 +++ b/config/grc_gnuradio_core.m4 @@ -46,7 +46,7 @@ AC_DEFUN([GRC_GNURADIO_CORE],[ gnuradio-core/src/python/gnuradio/blks/Makefile \ gnuradio-core/src/python/gnuradio/blksimpl/Makefile \ gnuradio-core/src/python/gnuradio/blks2/Makefile \ - gnuradio-core/src/python/gnuradio/blksimpl2/Makefile \ + gnuradio-core/src/python/gnuradio/blks2impl/Makefile \ gnuradio-core/src/python/gnuradio/gr/Makefile \ gnuradio-core/src/python/gnuradio/gr/run_tests \ gnuradio-core/src/python/gnuradio/gru/Makefile \ diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4 index 20d50fe5..fc758e89 100644 --- a/config/grc_gnuradio_examples.m4 +++ b/config/grc_gnuradio_examples.m4 @@ -28,19 +28,12 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/python/apps/hf_radio/Makefile \ gnuradio-examples/python/apps/Makefile \ gnuradio-examples/python/audio/Makefile \ + gnuradio-examples/python/dect/Makefile \ gnuradio-examples/python/digital/Makefile \ gnuradio-examples/python/digital_voice/Makefile \ - gnuradio-examples/python/hier/Makefile \ - gnuradio-examples/python/hier/audio/Makefile \ - gnuradio-examples/python/hier/networking/Makefile \ - gnuradio-examples/python/hier/digital/Makefile \ - gnuradio-examples/python/hier/dect/Makefile \ - gnuradio-examples/python/hier/ofdm/Makefile \ - gnuradio-examples/python/hier/sounder/Makefile \ - gnuradio-examples/python/hier/usrp/Makefile \ gnuradio-examples/python/multi-antenna/Makefile \ gnuradio-examples/python/multi_usrp/Makefile \ - gnuradio-examples/python/networking/Makefile \ + gnuradio-examples/python/network/Makefile \ gnuradio-examples/python/ofdm/Makefile \ gnuradio-examples/python/usrp/Makefile \ ]) diff --git a/debian/gen-install-files.sh b/debian/gen-install-files.sh index b7e9f91a..4ae877fe 100755 --- a/debian/gen-install-files.sh +++ b/debian/gen-install-files.sh @@ -41,7 +41,7 @@ $EXTRACT gnuradio-core/src/python/gnuradio/gr/Makefile grgrpython_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/blks/Makefile grblkspython_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/blks2/Makefile grblks2python_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/blksimpl/Makefile grblkspython_PYTHON >>$NAME -$EXTRACT gnuradio-core/src/python/gnuradio/blksimpl2/Makefile grblkspython_PYTHON >>$NAME +$EXTRACT gnuradio-core/src/python/gnuradio/blks2impl/Makefile grblkspython_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/gru/Makefile grblkspython_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/gruimpl/Makefile grupython_PYTHON >>$NAME $EXTRACT gnuradio-core/src/python/gnuradio/vocoder/Makefile grvocoderpython_PYTHON >>$NAME @@ -203,10 +203,12 @@ touch $NAME $EXTRACT gnuradio-examples/python/apps/hf_explorer/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/apps/hf_radio/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/audio/Makefile ourdata_DATA >>$NAME +$EXTRACT gnuradio-examples/python/dect/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/digital/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/digital_voice/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/multi-antenna/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/multi_usrp/Makefile ourdata_DATA >>$NAME +$EXTRACT gnuradio-examples/python/network/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/ofdm/Makefile ourdata_DATA >>$NAME $EXTRACT gnuradio-examples/python/usrp/Makefile ourdata_DATA >>$NAME diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc index f531e76a..23f274da 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc @@ -51,6 +51,12 @@ gr_hier_block2::~gr_hier_block2() delete d_detail; } +void +gr_hier_block2::connect(gr_basic_block_sptr block) +{ + d_detail->connect(block); +} + void gr_hier_block2::connect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port) @@ -58,6 +64,12 @@ gr_hier_block2::connect(gr_basic_block_sptr src, int src_port, d_detail->connect(src, src_port, dst, dst_port); } +void +gr_hier_block2::disconnect(gr_basic_block_sptr block) +{ + d_detail->disconnect(block); +} + void gr_hier_block2::disconnect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port) @@ -65,6 +77,12 @@ gr_hier_block2::disconnect(gr_basic_block_sptr src, int src_port, d_detail->disconnect(src, src_port, dst, dst_port); } +void +gr_hier_block2::disconnect_all() +{ + d_detail->disconnect_all(); +} + void gr_hier_block2::lock() { diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h index 7ecc0d77..6124e4d5 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.h +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h @@ -58,32 +58,18 @@ protected: public: virtual ~gr_hier_block2(); + void connect(gr_basic_block_sptr block); + void connect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port); + void disconnect(gr_basic_block_sptr block); + void disconnect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port); - /*! - * Lock a flowgraph in preparation for reconfiguration. When an equal - * number of calls to lock() and unlock() have occurred, the flowgraph - * will be restarted automatically. - * - * N.B. lock() and unlock() cannot be called from a flowgraph thread - * (E.g., gr_block::work method) or deadlock will occur when - * reconfiguration happens. - */ + void disconnect_all(); virtual void lock(); - - /*! - * Lock a flowgraph in preparation for reconfiguration. When an equal - * number of calls to lock() and unlock() have occurred, the flowgraph - * will be restarted automatically. - * - * N.B. lock() and unlock() cannot be called from a flowgraph thread - * (E.g., gr_block::work method) or deadlock will occur when - * reconfiguration happens. - */ virtual void unlock(); gr_flat_flowgraph_sptr flatten() const; diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i index b3882a6a..5278eefc 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.i +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i @@ -36,20 +36,24 @@ gr_hier_block2_sptr gr_make_hier_block2(const std::string name, class gr_hier_block2 : public gr_basic_block { private: - gr_hier_block2(const std::string name, - gr_io_signature_sptr input_signature, - gr_io_signature_sptr output_signature); - + gr_hier_block2(const std::string name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + public: - ~gr_hier_block2 (); - - // Add a named block to the container - void connect(gr_basic_block_sptr src, int src_port, - gr_basic_block_sptr dst, int dst_port) - throw (std::invalid_argument); - void disconnect(gr_basic_block_sptr src, int src_port, - gr_basic_block_sptr dst, int dst_port) - throw (std::invalid_argument); - void lock(); - void unlock(); + ~gr_hier_block2 (); + + void connect(gr_basic_block_sptr block) + throw (std::invalid_argument); + void connect(gr_basic_block_sptr src, int src_port, + gr_basic_block_sptr dst, int dst_port) + throw (std::invalid_argument); + void disconnect(gr_basic_block_sptr block) + throw (std::invalid_argument); + void disconnect(gr_basic_block_sptr src, int src_port, + gr_basic_block_sptr dst, int dst_port) + throw (std::invalid_argument); + void disconnect_all(); + void lock(); + void unlock(); }; diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc index 76d23cab..26a28fab 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc @@ -44,6 +44,27 @@ gr_hier_block2_detail::~gr_hier_block2_detail() d_owner = 0; // Don't use delete, we didn't allocate } +void +gr_hier_block2_detail::connect(gr_basic_block_sptr block) +{ + std::stringstream msg; + + // Check if duplicate + if (std::find(d_blocks.begin(), d_blocks.end(), block) != d_blocks.end()) { + msg << "Block " << block << " already connected."; + throw std::invalid_argument(msg.str()); + } + + // Check if has inputs or outputs + if (block->input_signature()->max_streams() != 0 || + block->output_signature()->max_streams() != 0) { + msg << "Block " << block << " must not have any input or output ports"; + throw std::invalid_argument(msg.str()); + } + + d_blocks.push_back(block); +} + void gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port) @@ -100,6 +121,21 @@ gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port, // TODO: connects to NC } +void +gr_hier_block2_detail::disconnect(gr_basic_block_sptr block) +{ + for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { + if (*p == block) { + d_blocks.erase(p); + return; + } + } + + std::stringstream msg; + msg << "cannot disconnect block " << block << ", not found"; + throw std::invalid_argument(msg.str()); +} + void gr_hier_block2_detail::disconnect(gr_basic_block_sptr src, int src_port, gr_basic_block_sptr dst, int dst_port) @@ -252,6 +288,15 @@ gr_hier_block2_detail::resolve_port(int port, bool is_input) return result; } +void +gr_hier_block2_detail::disconnect_all() +{ + d_fg->clear(); + d_blocks.clear(); + d_inputs.clear(); + d_outputs.clear(); +} + gr_endpoint gr_hier_block2_detail::resolve_endpoint(const gr_endpoint &endp, bool is_input) const { @@ -294,7 +339,15 @@ gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const sfg->connect(src_endp, dst_endp); } - gr_basic_block_vector_t blocks = d_fg->calc_used_blocks(); + // Construct unique list of blocks used either in edges or + // by themselves. I hate STL. + gr_basic_block_vector_t blocks, tmp = d_fg->calc_used_blocks(); + std::insert_iterator inserter(blocks, blocks.begin()); + std::vector::const_iterator p; // Because flatten_aux is const + for (p = d_blocks.begin(); p != d_blocks.end(); p++) + tmp.push_back(*p); + sort(tmp.begin(), tmp.end()); + unique_copy(tmp.begin(), tmp.end(), inserter); // Recurse hierarchical children for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h index b692d108..d31ae93e 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h @@ -27,37 +27,37 @@ class gr_hier_block2_detail : boost::noncopyable { -private: - friend class gr_hier_block2; - friend class gr_runtime_impl; - - // Constructor--it's private, only friends can instantiate - gr_hier_block2_detail(gr_hier_block2 *owner); - - // Private implementation data - gr_hier_block2 *d_owner; - gr_hier_block2_detail *d_parent_detail; - gr_flowgraph_sptr d_fg; - gr_endpoint_vector_t d_inputs; - gr_endpoint_vector_t d_outputs; +public: + gr_hier_block2_detail(gr_hier_block2 *owner); + ~gr_hier_block2_detail(); - // Private implementation methods - void connect(gr_basic_block_sptr src, int src_port, - gr_basic_block_sptr dst, int dst_port); - void disconnect(gr_basic_block_sptr, int src_port, - gr_basic_block_sptr, int dst_port); - void connect_input(int my_port, int port, gr_basic_block_sptr block); - void connect_output(int my_port, int port, gr_basic_block_sptr block); - void disconnect_input(int my_port, int port, gr_basic_block_sptr block); - void disconnect_output(int my_port, int port, gr_basic_block_sptr block); - void flatten_aux(gr_flat_flowgraph_sptr sfg) const; - gr_endpoint resolve_port(int port, bool is_input); - gr_endpoint resolve_endpoint(const gr_endpoint &endp, bool is_input) const; - void lock(); - void unlock(); + void connect(gr_basic_block_sptr block); + void connect(gr_basic_block_sptr src, int src_port, + gr_basic_block_sptr dst, int dst_port); + void disconnect(gr_basic_block_sptr block); + void disconnect(gr_basic_block_sptr, int src_port, + gr_basic_block_sptr, int dst_port); + void disconnect_all(); + void lock(); + void unlock(); + void flatten_aux(gr_flat_flowgraph_sptr sfg) const; -public: - ~gr_hier_block2_detail(); +private: + + // Private implementation data + gr_hier_block2 *d_owner; + gr_hier_block2_detail *d_parent_detail; + gr_flowgraph_sptr d_fg; + gr_endpoint_vector_t d_inputs; + gr_endpoint_vector_t d_outputs; + gr_basic_block_vector_t d_blocks; + + void connect_input(int my_port, int port, gr_basic_block_sptr block); + void connect_output(int my_port, int port, gr_basic_block_sptr block); + void disconnect_input(int my_port, int port, gr_basic_block_sptr block); + void disconnect_output(int my_port, int port, gr_basic_block_sptr block); + gr_endpoint resolve_port(int port, bool is_input); + gr_endpoint resolve_endpoint(const gr_endpoint &endp, bool is_input) const; }; #endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc index 91248d34..10e37720 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc @@ -88,3 +88,9 @@ gr_top_block::unlock() { d_impl->unlock(); } + +bool +gr_top_block::is_running() +{ + return d_impl->is_running(); +} diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.h b/gnuradio-core/src/lib/runtime/gr_top_block.h index d7490384..57c36ad3 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block.h @@ -97,6 +97,11 @@ public: * reconfiguration happens. */ virtual void unlock(); + + /*! + * Returns true if flowgraph is running + */ + bool is_running(); }; #endif /* INCLUDED_GR_TOP_BLOCK_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i index 63ceec8b..78c2e0b9 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.i +++ b/gnuradio-core/src/lib/runtime/gr_top_block.i @@ -46,6 +46,7 @@ public: void run(); void lock(); void unlock(); + bool is_running(); }; %{ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h index 8052ce4f..00cb7f97 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h @@ -53,6 +53,9 @@ public: // Unlock the top block at end of reconfiguration void unlock(); + // Return true if flowgraph is running + bool is_running() const { return d_running; } + private: bool d_running; diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index d9815b52..388681e5 100644 --- a/gnuradio-core/src/python/gnuradio/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = gr gru gruimpl blks blksimpl blks2 blksimpl2 vocoder +SUBDIRS = gr gru gruimpl blks blksimpl blks2 blks2impl vocoder grpython_PYTHON = \ __init__.py \ diff --git a/gnuradio-core/src/python/gnuradio/blks2/__init__.py b/gnuradio-core/src/python/gnuradio/blks2/__init__.py index 227e2bf7..89ebb922 100644 --- a/gnuradio-core/src/python/gnuradio/blks2/__init__.py +++ b/gnuradio-core/src/python/gnuradio/blks2/__init__.py @@ -27,11 +27,11 @@ import os.path # to manually update this file. for p in __path__: - filenames = glob.glob (os.path.join (p, "..", "blksimpl2", "*.py")) + filenames = glob.glob (os.path.join (p, "..", "blks2impl", "*.py")) for f in filenames: f = os.path.basename(f).lower() f = f[:-3] if f == '__init__': continue # print f - exec "from gnuradio.blksimpl2.%s import *" % (f,) + exec "from gnuradio.blks2impl.%s import *" % (f,) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am similarity index 67% rename from gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am rename to gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am index 3e635103..3fb23cae 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2005 Free Software Foundation, Inc. +# Copyright 2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,18 +24,41 @@ include $(top_srcdir)/Makefile.common # EXTRA_DIST = run_tests.in # TESTS = run_tests -grblkspythondir = $(grpythondir)/blksimpl2 +grblkspythondir = $(grpythondir)/blks2impl grblkspython_PYTHON = \ __init__.py \ + am_demod.py \ + channel_model.py \ dbpsk.py \ dqpsk.py \ d8psk.py \ filterbank.py \ + fm_demod.py \ + fm_emph.py \ gmsk.py \ + cpm.py \ + nbfm_rx.py \ + nbfm_tx.py \ + ofdm.py \ + ofdm_receiver.py \ + ofdm_sync_fixed.py \ + ofdm_sync_ml.py \ + ofdm_sync_pnac.py \ + ofdm_sync_pn.py \ pkt.py \ psk.py \ - rational_resampler.py + qam.py \ + qam8.py \ + qam16.py \ + qam64.py \ + qam256.py \ + rational_resampler.py \ + standard_squelch.py \ + wfm_rcv.py \ + wfm_rcv_pll.py \ + wfm_tx.py + noinst_PYTHON = diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/__init__.py b/gnuradio-core/src/python/gnuradio/blks2impl/__init__.py similarity index 100% rename from gnuradio-core/src/python/gnuradio/blksimpl2/__init__.py rename to gnuradio-core/src/python/gnuradio/blks2impl/__init__.py diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py new file mode 100644 index 00000000..b454f094 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py @@ -0,0 +1,76 @@ +# +# Copyright 2006,2007 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, optfir + +class am_demod_cf(gr.hier_block2): + """ + Generalized AM demodulation block with audio filtering. + + This block demodulates a band-limited, complex down-converted AM + channel into the the original baseband signal, applying low pass + filtering to the audio output. It produces a float stream in the + range [-1.0, +1.0]. + + @param channel_rate: incoming sample rate of the AM baseband + @type sample_rate: integer + @param audio_decim: input to output decimation rate + @type audio_decim: integer + @param audio_pass: audio low pass filter passband frequency + @type audio_pass: float + @param audio_stop: audio low pass filter stop frequency + @type audio_stop: float + """ + def __init__(self, channel_rate, audio_decim, audio_pass, audio_stop): + gr.hier_block2.__init__(self, "am_demod_cf", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Input signature + + MAG = gr.complex_to_mag() + DCR = gr.add_const_ff(-1.0) + + audio_taps = optfir.low_pass(0.5, # Filter gain + channel_rate, # Sample rate + audio_pass, # Audio passband + audio_stop, # Audio stopband + 0.1, # Passband ripple + 60) # Stopband attenuation + LPF = gr.fir_filter_fff(audio_decim, audio_taps) + + self.connect(self, MAG, DCR, LPF, self) + +class demod_10k0a3e_cf(am_demod_cf): + """ + AM demodulation block, 10 KHz channel. + + This block demodulates an AM channel conformant to 10K0A3E emission + standards, such as broadcast band AM transmissions. + + @param channel_rate: incoming sample rate of the AM baseband + @type sample_rate: integer + @param audio_decim: input to output decimation rate + @type audio_decim: integer + """ + def __init__(self, channel_rate, audio_decim): + am_demod_cf.__init__(self, channel_rate, audio_decim, + 5000, # Audio passband + 5500) # Audio stopband + \ No newline at end of file diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py b/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py new file mode 100644 index 00000000..21980a22 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# Copyright 2007 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 channel_model(gr.hier_block): + def __init__(self, fg, noise_voltage=0.0, frequency_offset=0.0, epsilon=1.0, taps=[1.0,0.0]): + ''' Creates a channel model that includes: + - AWGN noise power in terms of noise voltage + - A frequency offest in the channel in ratio + - A timing offset ratio to model clock difference (epsilon) + - Multipath taps + ''' + + print epsilon + self.timing_offset = gr.fractional_interpolator_cc(0, epsilon) + + self.multipath = gr.fir_filter_ccc(1, taps) + + self.noise_adder = gr.add_cc() + self.noise = gr.noise_source_c(gr.GR_GAUSSIAN,noise_voltage) + self.freq_offset = gr.sig_source_c(1, gr.GR_SIN_WAVE, frequency_offset, 1.0, 0.0) + self.mixer_offset = gr.multiply_cc() + + fg.connect(self.timing_offset, self.multipath) + fg.connect(self.multipath, (self.mixer_offset,0)) + fg.connect(self.freq_offset,(self.mixer_offset,1)) + fg.connect(self.mixer_offset, (self.noise_adder,1)) + fg.connect(self.noise, (self.noise_adder,0)) + + gr.hier_block.__init__(self, fg, self.timing_offset, self.noise_adder) + + def set_noise_voltage(noise_voltage): + self.noise.set_amplitude(noise_voltage) + + def set_frequency_offset(frequency_offset): + self.freq_offset.set_frequency(frequency_offset) + + def set_taps(taps): + self.multipath.set_taps(taps) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py b/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py new file mode 100644 index 00000000..8f593cd5 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py @@ -0,0 +1,249 @@ +# +# CPM modulation and demodulation. +# +# +# Copyright 2005,2006,2007 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. +# + +# See gnuradio-examples/python/digital for examples + +from gnuradio import gr +from gnuradio import modulation_utils +from math import pi +import numpy +from pprint import pprint +import inspect + +# default values (used in __init__ and add_options) +_def_samples_per_symbol = 2 +_def_bits_per_symbol = 1 +_def_h_numerator = 1 +_def_h_denominator = 2 +_def_cpm_type = 0 # 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL +_def_bt = 0.35 +_def_symbols_per_pulse = 1 +_def_generic_taps = numpy.empty(1) +_def_verbose = False +_def_log = False + + +# ///////////////////////////////////////////////////////////////////////////// +# CPM modulator +# ///////////////////////////////////////////////////////////////////////////// + +class cpm_mod(gr.hier_block2): + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + bits_per_symbol=_def_bits_per_symbol, + h_numerator=_def_h_numerator, + h_denominator=_def_h_denominator, + cpm_type=_def_cpm_type, + bt=_def_bt, + symbols_per_pulse=_def_symbols_per_pulse, + generic_taps=_def_generic_taps, + verbose=_def_verbose, + log=_def_log): + """ + Hierarchical block for Continuous Phase + modulation. + + The input is a byte stream (unsigned char) + representing packed bits and the + output is the complex modulated signal at baseband. + + See Proakis for definition of generic CPM signals: + s(t)=exp(j phi(t)) + phi(t)= 2 pi h int_0^t f(t') dt' + f(t)=sum_k a_k g(t-kT) + (normalizing assumption: int_0^infty g(t) dt = 1/2) + + @param samples_per_symbol: samples per baud >= 2 + @type samples_per_symbol: integer + @param bits_per_symbol: bits per symbol + @type bits_per_symbol: integer + @param h_numerator: numerator of modulation index + @type h_numerator: integer + @param h_denominator: denominator of modulation index (numerator and denominator must be relative primes) + @type h_denominator: integer + @param cpm_type: supported types are: 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL + @type cpm_type: integer + @param bt: bandwidth symbol time product for GMSK + @type bt: float + @param symbols_per_pulse: shaping pulse duration in symbols + @type symbols_per_pulse: integer + @param generic_taps: define a generic CPM pulse shape (sum = samples_per_symbol/2) + @type generic_taps: array of floats + + @param verbose: Print information about modulator? + @type verbose: bool + @param debug: Print modulation data to files? + @type debug: bool + """ + + gr.hier_block2.__init__("cpm_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + self._samples_per_symbol = samples_per_symbol + self._bits_per_symbol = bits_per_symbol + self._h_numerator = h_numerator + self._h_denominator = h_denominator + self._cpm_type = cpm_type + self._bt=bt + if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic + self._symbols_per_pulse = symbols_per_pulse + elif cpm_type == 1: # GMSK + self._symbols_per_pulse = 4 + else: + raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) + + self._generic_taps=numpy.array(generic_taps) + + if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: + raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) + + self.nsymbols = 2**bits_per_symbol + self.sym_alphabet=numpy.arange(-(self.nsymbols-1),self.nsymbols,2) + + + self.ntaps = self._symbols_per_pulse * samples_per_symbol + sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol + + # Unpack Bytes into bits_per_symbol groups + self.B2s = gr.packed_to_unpacked_bb(bits_per_symbol,gr.GR_MSB_FIRST) + + + # Turn it into symmetric PAM data. + self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet,1) + + # Generate pulse (sum of taps = samples_per_symbol/2) + if cpm_type == 0: # CPFSK + self.taps= (1.0/self._symbols_per_pulse/2,) * self.ntaps + elif cpm_type == 1: # GMSK + gaussian_taps = gr.firdes.gaussian( + 1.0/2, # gain + samples_per_symbol, # symbol_rate + bt, # bandwidth * symbol time + self.ntaps # number of taps + ) + sqwave = (1,) * samples_per_symbol # rectangular window + self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave)) + elif cpm_type == 2: # Raised Cosine + # generalize it for arbitrary roll-off factor + self.taps = (1-numpy.cos(2*pi*numpy.arange(0,self.ntaps)/samples_per_symbol/self._symbols_per_pulse))/(2*self._symbols_per_pulse) + elif cpm_type == 3: # Generic CPM + self.taps = generic_taps + else: + raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) + + self.filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) + + # FM modulation + self.fmmod = gr.frequency_modulator_fc(sensitivity) + + if verbose: + self._print_verbage() + + if log: + self._setup_logging() + + # Connect + self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self) + + #def samples_per_symbol(self): + #return self._samples_per_symbol + + #def bits_per_symbol(self): + #return self._bits_per_symbol + + #def h_numerator(self): + #return self._h_numerator + + #def h_denominator(self): + #return self._h_denominator + + #def cpm_type(self): + #return self._cpm_type + + #def bt(self): + #return self._bt + + #def symbols_per_pulse(self): + #return self._symbols_per_pulse + + + def _print_verbage(self): + print "Samples per symbol = %d" % self._samples_per_symbol + print "Bits per symbol = %d" % self._bits_per_symbol + print "h = " , self._h_numerator , " / " , self._h_denominator + print "Symbol alphabet = " , self.sym_alphabet + print "Symbols per pulse = %d" % self._symbols_per_pulse + print "taps = " , self.taps + + print "CPM type = %d" % self._cpm_type + if self._cpm_type == 1: + print "Gaussian filter BT = %.2f" % self._bt + + + def _setup_logging(self): + print "Modulation logging turned on." + self.connect(self.B2s, + gr.file_sink(gr.sizeof_float, "symbols.dat")) + self.connect(self.pam, + gr.file_sink(gr.sizeof_float, "pam.dat")) + self.connect(self.filter, + gr.file_sink(gr.sizeof_float, "filter.dat")) + self.connect(self.fmmod, + gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) + + + def add_options(parser): + """ + Adds CPM modulation-specific options to the standard parser + """ + parser.add_option("", "--bt", type="float", default=_def_bt, + help="set bandwidth-time product [default=%default] (GMSK)") + add_options=staticmethod(add_options) + + + def extract_kwargs_from_options(options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + return modulation_utils.extract_kwargs_from_options(cpm_mod.__init__, + ('self',), options) + extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) + + + +# ///////////////////////////////////////////////////////////////////////////// +# CPM demodulator +# ///////////////////////////////////////////////////////////////////////////// +# +# Not yet implemented +# + + + +# +# Add these to the mod/demod registry +# +modulation_utils.add_type_1_mod('cpm', cpm_mod) +#modulation_utils.add_type_1_demod('cpm', cpm_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/d8psk.py b/gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py similarity index 78% rename from gnuradio-core/src/python/gnuradio/blksimpl2/d8psk.py rename to gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py index f5461653..67cf9f56 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/d8psk.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py @@ -38,14 +38,14 @@ _def_gray_code = True _def_verbose = False _def_log = False -_def_costas_alpha = 0.01 -_def_gain_mu = 0.05 +_def_costas_alpha = 0.175 +_def_gain_mu = 0.175 _def_mu = 0.5 _def_omega_relative_limit = 0.005 # ///////////////////////////////////////////////////////////////////////////// -# DQPSK modulator +# D8PSK modulator # ///////////////////////////////////////////////////////////////////////////// class d8psk_mod(gr.hier_block2): @@ -74,10 +74,10 @@ class d8psk_mod(gr.hier_block2): @type debug: bool """ - gr.hier_block2.__init__(self, "d8psk_mod", - gr.io_signature(1,1,gr.sizeof_char), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature - + gr.hier_block2.__init__(self, "d8psk_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._gray_code = gray_code @@ -114,16 +114,15 @@ class d8psk_mod(gr.hier_block2): self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - # Connect components - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.chunks2symbols, - self.rrc_filter, self) - if verbose: self._print_verbage() if log: self._setup_logging() + # Connect & Initialize base class + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) def samples_per_symbol(self): return self._samples_per_symbol @@ -133,17 +132,22 @@ class d8psk_mod(gr.hier_block2): bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM def _print_verbage(self): - print "\nModulator:" print "bits per symbol = %d" % self.bits_per_symbol() print "Gray code = %s" % self._gray_code print "RS roll-off factor = %f" % self._excess_bw def _setup_logging(self): print "Modulation logging turned on." - self.connect(self.bytes2chunks, gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.dat")) - self.connect(self.chunks2symbols, gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) def add_options(parser): """ @@ -162,7 +166,7 @@ class d8psk_mod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options(d8psk_mod.__init__, - ('self', 'fg'), options) + ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) @@ -172,7 +176,6 @@ class d8psk_mod(gr.hier_block2): # Differentially coherent detection of differentially encoded 8psk # ///////////////////////////////////////////////////////////////////////////// -WITH_SYNC = False class d8psk_demod(gr.hier_block2): def __init__(self, @@ -210,10 +213,10 @@ class d8psk_demod(gr.hier_block2): @param debug: Print modualtion data to files? @type debug: bool """ - - gr.hier_block2.__init__(self, "d8psk_demod", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_char)) # Output signature + + gr.hier_block2.__init__(self, "d8psk_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw @@ -231,8 +234,9 @@ class d8psk_demod(gr.hier_block2): # Automatic gain control scale = (1.0/16384.0) self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - self.agc = gr.feedforward_agc_cc(16, 1.0) + #self.agc = gr.agc_cc(1e-2, 1, 1, 100) + self.agc = gr.agc2_cc(1e-1, 1e-2, 1, 1, 100) + #self.agc = gr.feedforward_agc_cc(16, 1.0) # RRC data filter ntaps = 11 * samples_per_symbol @@ -248,17 +252,18 @@ class d8psk_demod(gr.hier_block2): self._mm_omega = self._samples_per_symbol self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.05 - fmax = 0.05 + fmin = -0.025 + fmax = 0.025 self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) + self._costas_alpha, self._costas_beta, + fmin, fmax, + self._mm_mu, self._mm_gain_mu, + self._mm_omega, self._mm_gain_omega, + self._mm_omega_relative_limit) - #self.diffdec = gr.diff_decoder_bb(arity) + # Perform Differential decoding on the constellation + self.diffdec = gr.diff_phasor_cc() # find closest constellation point rot = 1 @@ -274,17 +279,15 @@ class d8psk_demod(gr.hier_block2): # unpack the k bit vector into a stream of bits self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - # Connect and Initialize base class - self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.slicer, self.symbol_mapper, self.unpack, self) - if verbose: self._print_verbage() if log: self._setup_logging() - + + # Connect + self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, + self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) def samples_per_symbol(self): return self._samples_per_symbol @@ -308,14 +311,23 @@ class d8psk_demod(gr.hier_block2): def _setup_logging(self): - print "Demodulation logging turned on." - self.connect(self.pre_scaler, gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.slicer, gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) + print "Modulation logging turned on." + self.connect(self.pre_scaler, + gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) + self.connect(self.agc, + gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) + self.connect(self.receiver, + gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) + self.connect(self.diffdec, + gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) + self.connect(self.slicer, + gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) + self.connect(self.unpack, + gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) def add_options(parser): """ @@ -326,7 +338,7 @@ class d8psk_demod(gr.hier_block2): parser.add_option("", "--no-gray-code", dest="gray_code", action="store_false", default=_def_gray_code, help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=None, + parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") @@ -339,7 +351,7 @@ class d8psk_demod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options( - d8psk_demod.__init__, ('self', 'fg'), options) + d8psk_demod.__init__, ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) @@ -347,5 +359,5 @@ class d8psk_demod(gr.hier_block2): # Add these to the mod/demod registry # # NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('d8psk', d8psk_mod) -#modulation_utils.add_type_1_demod('d8psk', d8psk_demod) +modulation_utils.add_type_1_mod('d8psk', d8psk_mod) +modulation_utils.add_type_1_demod('d8psk', d8psk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/dbpsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py similarity index 79% rename from gnuradio-core/src/python/gnuradio/blksimpl2/dbpsk.py rename to gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py index 90b7632c..27063767 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/dbpsk.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py @@ -38,8 +38,8 @@ _def_gray_code = True _def_verbose = False _def_log = False -_def_costas_alpha = 0.15 -_def_gain_mu = 0.1 +_def_costas_alpha = 0.1 +_def_gain_mu = None _def_mu = 0.5 _def_omega_relative_limit = 0.005 @@ -49,6 +49,7 @@ _def_omega_relative_limit = 0.005 # ///////////////////////////////////////////////////////////////////////////// class dbpsk_mod(gr.hier_block2): + def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, @@ -73,9 +74,9 @@ class dbpsk_mod(gr.hier_block2): @type log: bool """ - gr.hier_block2.__init__(self, "dbpsk_mod", - gr.io_signature(1,1,gr.sizeof_char), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature + gr.hier_block2.__init__(self, "dbpsk_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw @@ -112,15 +113,16 @@ class dbpsk_mod(gr.hier_block2): self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - # Connect components - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) + # Connect + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) if verbose: self._print_verbage() if log: self._setup_logging() + def samples_per_symbol(self): return self._samples_per_symbol @@ -145,23 +147,28 @@ class dbpsk_mod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options(dbpsk_mod.__init__, - ('self', 'fg'), options) + ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) def _print_verbage(self): print "\nModulator:" - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRC roll-off factor = %.2f" % self._excess_bw + print "bits per symbol: %d" % self.bits_per_symbol() + print "Gray code: %s" % self._gray_code + print "RRC roll-off factor: %.2f" % self._excess_bw def _setup_logging(self): print "Modulation logging turned on." - self.connect(self.bytes2chunks, gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.dat")) - self.connect(self.diffenc, gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) # ///////////////////////////////////////////////////////////////////////////// @@ -207,12 +214,11 @@ class dbpsk_demod(gr.hier_block2): @param debug: Print modualtion data to files? @type debug: bool """ - - gr.hier_block2.__init__(self, "dbpsk_demod", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_char)) # Output signature - + gr.hier_block2.__init__(self, "dbpsk_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature + self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._costas_alpha = costas_alpha @@ -230,9 +236,8 @@ class dbpsk_demod(gr.hier_block2): scale = (1.0/16384.0) self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - self.agc = gr.feedforward_agc_cc(16, 1.0) + self.agc = gr.feedforward_agc_cc(16, 2.0) - # RRC data filter ntaps = 11 * samples_per_symbol self.rrc_taps = gr.firdes.root_raised_cosine( @@ -244,20 +249,23 @@ class dbpsk_demod(gr.hier_block2): self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) # symbol clock recovery + if not self._mm_gain_mu: + self._mm_gain_mu = 0.1 + self._mm_omega = self._samples_per_symbol self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.02 - fmax = 0.02 + fmin = -0.025 + fmax = 0.025 self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) + self._costas_alpha, self._costas_beta, + fmin, fmax, + self._mm_mu, self._mm_gain_mu, + self._mm_omega, self._mm_gain_omega, + self._mm_omega_relative_limit) - # Using differential decoding + # Do differential decoding based on phase change of symbols self.diffdec = gr.diff_phasor_cc() # find closest constellation point @@ -273,16 +281,16 @@ class dbpsk_demod(gr.hier_block2): # unpack the k bit vector into a stream of bits self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - # Connect and Initialize base class - self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if verbose: self._print_verbage() if log: self._setup_logging() + # Connect and Initialize base class + self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, + self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) + def samples_per_symbol(self): return self._samples_per_symbol @@ -304,15 +312,23 @@ class dbpsk_demod(gr.hier_block2): print "M&M omega limit: %.2f" % self._mm_omega_relative_limit def _setup_logging(self): - print "Demodulation logging turned on." - self.connect(self.pre_scaler, gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.diffdec, gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) + print "Modulation logging turned on." + self.connect(self.pre_scaler, + gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) + self.connect(self.agc, + gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) + self.connect(self.receiver, + gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) + self.connect(self.diffdec, + gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) + self.connect(self.slicer, + gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) + self.connect(self.unpack, + gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) def add_options(parser): """ @@ -338,7 +354,7 @@ class dbpsk_demod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options( - dbpsk_demod.__init__, ('self'), options) + dbpsk_demod.__init__, ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) # # Add these to the mod/demod registry diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real b/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real new file mode 100644 index 00000000..6ec66825 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# +# Copyright 2005 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. +# + +""" +Digital voice Tx and Rx using GSM 13kbit vocoder and GMSK. + +Runs channel at 32kbit/sec. Currently uses fake channel coding, +but there's room for a rate 1/2 coder. +""" + +from gnuradio import gr, gru +from gnuradio.blksimpl.gmsk import gmsk_mod, gmsk_demod + +from gnuradio.vocoder import gsm_full_rate + +# Size of gsm full rate speech encoder output packet in bytes + +GSM_FRAME_SIZE = 33 + +# Size of packet in bytes that we send to GMSK modulator: +# +# Target: 256kS/sec air rate. +# +# 256kS 1 sym 1 bit 1 byte 0.020 sec 80 bytes +# ---- * ----- * ----- * ------ * --------- = -------- +# sec 8 S 1 sym 8 bits frame frame +# +# gr_simple_framer add 10 bytes of overhead. + +AIR_FRAME_SIZE = 70 + + +class digital_voice_tx(gr.hier_block): + """ + Hierarchical block for digital voice tranmission. + + The input is 8kS/sec floating point audio in the range [-1,+1] + The output is 256kS/sec GMSK modulated complex baseband signal in the range [-1,+1]. + """ + def __init__(self, fg): + samples_per_symbol = 8 + symbol_rate = 32000 + bt = 0.3 # Gaussian filter bandwidth * symbol time + + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short() + voice_coder = gsm_full_rate.encode_sp() + + channel_coder = gr.fake_channel_encoder_pp(GSM_FRAME_SIZE, AIR_FRAME_SIZE) + p2s = gr.parallel_to_serial(gr.sizeof_char, AIR_FRAME_SIZE) + + mod = gmsk_mod(fg, sps=samples_per_symbol, + symbol_rate=symbol_rate, bt=bt, + p_size=AIR_FRAME_SIZE) + + fg.connect(src_scale, f2s, voice_coder, channel_coder, p2s, mod) + gr.hier_block.__init__(self, fg, src_scale, mod) + + +class digital_voice_rx(gr.hier_block): + """ + Hierarchical block for digital voice reception. + + The input is 256kS/sec GMSK modulated complex baseband signal. + The output is 8kS/sec floating point audio in the range [-1,+1] + """ + def __init__(self, fg): + samples_per_symbol = 8 + symbol_rate = 32000 + + demod = gmsk_demod(fg, sps=samples_per_symbol, + symbol_rate=symbol_rate, + p_size=AIR_FRAME_SIZE) + + s2p = gr.serial_to_parallel(gr.sizeof_char, AIR_FRAME_SIZE) + channel_decoder = gr.fake_channel_decoder_pp(AIR_FRAME_SIZE, GSM_FRAME_SIZE) + + voice_decoder = gsm_full_rate.decode_ps() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + + fg.connect(demod, s2p, channel_decoder, voice_decoder, s2f, sink_scale) + gr.hier_block.__init__(self, fg, demod, sink_scale) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/dqpsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py similarity index 77% rename from gnuradio-core/src/python/gnuradio/blksimpl2/dqpsk.py rename to gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py index cc82cd2f..8c15d217 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/dqpsk.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py @@ -39,7 +39,7 @@ _def_verbose = False _def_log = False _def_costas_alpha = 0.15 -_def_gain_mu = 0.1 +_def_gain_mu = None _def_mu = 0.5 _def_omega_relative_limit = 0.005 @@ -49,6 +49,7 @@ _def_omega_relative_limit = 0.005 # ///////////////////////////////////////////////////////////////////////////// class dqpsk_mod(gr.hier_block2): + def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, @@ -73,9 +74,9 @@ class dqpsk_mod(gr.hier_block2): @type debug: bool """ - gr.hier_block2.__init__(self, "dqpsk_mod", - gr.io_signature(1,1,gr.sizeof_char), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature + gr.hier_block2.__init__(self, "dqpsk_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw @@ -112,16 +113,16 @@ class dqpsk_mod(gr.hier_block2): ntaps) self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - # Connect components - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) if verbose: self._print_verbage() if log: self._setup_logging() + + # Connect & Initialize base class + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) def samples_per_symbol(self): return self._samples_per_symbol @@ -132,17 +133,22 @@ class dqpsk_mod(gr.hier_block2): def _print_verbage(self): print "\nModulator:" - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw + print "bits per symbol: %d" % self.bits_per_symbol() + print "Gray code: %s" % self._gray_code + print "RRS roll-off factor: %f" % self._excess_bw def _setup_logging(self): print "Modulation logging turned on." - self.connect(self.bytes2chunks, gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.dat")) - self.connect(self.diffenc, gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) def add_options(parser): """ @@ -161,7 +167,7 @@ class dqpsk_mod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options(dqpsk_mod.__init__, - ('self', 'fg'), options) + ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) @@ -173,7 +179,7 @@ class dqpsk_mod(gr.hier_block2): class dqpsk_demod(gr.hier_block2): - def __init__(self, + def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, costas_alpha=_def_costas_alpha, @@ -209,9 +215,9 @@ class dqpsk_demod(gr.hier_block2): @type debug: bool """ - gr.hier_block2.__init__(self, "dqpsk_demod", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_char)) # Output signature + gr.hier_block2.__init__(self, "dqpsk_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw @@ -229,6 +235,7 @@ class dqpsk_demod(gr.hier_block2): # Automatic gain control scale = (1.0/16384.0) self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 + #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) self.agc = gr.feedforward_agc_cc(16, 2.0) # RRC data filter @@ -241,23 +248,26 @@ class dqpsk_demod(gr.hier_block2): ntaps) self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - # symbol clock recovery + if not self._mm_gain_mu: + sbs_to_mm = {2: 0.050, 3: 0.075, 4: 0.11, 5: 0.125, 6: 0.15, 7: 0.15} + self._mm_gain_mu = sbs_to_mm[samples_per_symbol] + self._mm_omega = self._samples_per_symbol self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.01 - fmax = 0.01 + fmin = -0.025 + fmax = 0.025 self.receiver=gr.mpsk_receiver_cc(arity, pi/4.0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - + self._costas_alpha, self._costas_beta, + fmin, fmax, + self._mm_mu, self._mm_gain_mu, + self._mm_omega, self._mm_gain_omega, + self._mm_omega_relative_limit) + # Perform Differential decoding on the constellation self.diffdec = gr.diff_phasor_cc() - + # find closest constellation point rot = 1 rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) @@ -271,15 +281,15 @@ class dqpsk_demod(gr.hier_block2): # unpack the k bit vector into a stream of bits self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - # Connect and Initialize base class - self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, self.diffdec, - self.slicer, self.symbol_mapper, self.unpack, self) - if verbose: self._print_verbage() if log: self._setup_logging() + + # Connect & Initialize base class + self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, + self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) def samples_per_symbol(self): return self._samples_per_symbol @@ -302,15 +312,23 @@ class dqpsk_demod(gr.hier_block2): print "M&M omega limit: %.2f" % self._mm_omega_relative_limit def _setup_logging(self): - print "Demodulation logging turned on." - self.connect(self.pre_scaler, gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.diffdec, gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) + print "Modulation logging turned on." + self.connect(self.pre_scaler, + gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) + self.connect(self.agc, + gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) + self.connect(self.receiver, + gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) + self.connect(self.diffdec, + gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) + self.connect(self.slicer, + gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) + self.connect(self.unpack, + gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) def add_options(parser): """ @@ -321,7 +339,7 @@ class dqpsk_demod(gr.hier_block2): parser.add_option("", "--no-gray-code", dest="gray_code", action="store_false", default=_def_gray_code, help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=None, + parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") @@ -334,7 +352,7 @@ class dqpsk_demod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options( - dqpsk_demod.__init__, ('self', 'fg'), options) + dqpsk_demod.__init__, ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py b/gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py similarity index 86% rename from gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py rename to gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py index 0cff78be..c1284565 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py @@ -1,5 +1,5 @@ # -# Copyright 2005 Free Software Foundation, Inc. +# Copyright 2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -45,7 +45,6 @@ class synthesis_filterbank(gr.hier_block2): Takes M complex streams in, produces single complex stream out that runs at M times the input sample rate - @param fg: flow_graph @param mpoints: number of freq bins/interpolation factor/subbands @param taps: filter taps for subband filter @@ -83,9 +82,10 @@ class synthesis_filterbank(gr.hier_block2): utility. """ item_size = gr.sizeof_gr_complex - gr.hier_block2.__init__(self, "synthesis_filterbank", - gr.io_signature(mpoints, mpoints, item_size), - gr.io_signature(1, 1, item_size)) + gr.hier_block2.__init__(self, "synthesis_filterbank", + gr.io_signature(mpoints, mpoints, item_size), # Input signature + gr.io_signature(1, 1, item_size)) # Output signature + if taps is None: taps = _generate_synthesis_taps(mpoints) @@ -104,9 +104,9 @@ class synthesis_filterbank(gr.hier_block2): # mpoints filters go in here... self.ss2s = gr.streams_to_stream(item_size, mpoints) - for i in range(mpoints): - self.connect((self, i), (self.ss2v, i)) - + for i in range(mpoints): + self.connect((self, i), (self.ss2v, i)) + self.connect(self.ss2v, self.ifft, self.v2ss, self) # build mpoints fir filters... @@ -127,17 +127,16 @@ class analysis_filterbank(gr.hier_block2): Takes 1 complex stream in, produces M complex streams out that runs at 1/M times the input sample rate - @param fg: flow_graph @param mpoints: number of freq bins/interpolation factor/subbands @param taps: filter taps for subband filter Same channel to frequency mapping as described above. """ item_size = gr.sizeof_gr_complex - gr.hier_block2.__init__(self, "analysis_filterbank", - gr.io_signature(1, 1, item_size), - gr.io_signature(mpoints, mpoints, item_size)) - + gr.hier_block2.__init__(self, "analysis_filterbank", + gr.io_signature(1, 1, item_size), # Input signature + gr.io_signature(mpoints, mpoints, item_size)) # Output signature + if taps is None: taps = _generate_synthesis_taps(mpoints) @@ -157,18 +156,13 @@ class analysis_filterbank(gr.hier_block2): self.fft = gr.fft_vcc(mpoints, True, []) self.v2ss = gr.vector_to_streams(item_size, mpoints) - self.connect(self, self.s2ss) - + self.connect(self, self.s2ss) + # build mpoints fir filters... for i in range(mpoints): f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1]) self.connect((self.s2ss, i), f) self.connect(f, (self.ss2v, i)) - + self.connect((self.v2ss, i), (self, i)) + self.connect(self.ss2v, self.fft, self.v2ss) - - for i in range(mpoints): - self.connect((self.v2ss, i), (self, i)) - - - diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py new file mode 100644 index 00000000..1910b501 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py @@ -0,0 +1,111 @@ +# +# Copyright 2006,2007 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, optfir +from gnuradio.blks2impl.fm_emph import fm_deemph +from math import pi + +class fm_demod_cf(gr.hier_block2): + """ + Generalized FM demodulation block with deemphasis and audio + filtering. + + This block demodulates a band-limited, complex down-converted FM + channel into the the original baseband signal, optionally applying + deemphasis. Low pass filtering is done on the resultant signal. It + produces an output float strem in the range of [-1.0, +1.0]. + + @param channel_rate: incoming sample rate of the FM baseband + @type sample_rate: integer + @param deviation: maximum FM deviation (default = 5000) + @type deviation: float + @param audio_decim: input to output decimation rate + @type audio_decim: integer + @param audio_pass: audio low pass filter passband frequency + @type audio_pass: float + @param audio_stop: audio low pass filter stop frequency + @type audio_stop: float + @param gain: gain applied to audio output (default = 1.0) + @type gain: float + @param tau: deemphasis time constant (default = 75e-6), specify 'None' + to prevent deemphasis + """ + def __init__(self, channel_rate, audio_decim, deviation, + audio_pass, audio_stop, gain=1.0, tau=75e-6): + gr.hier_block2.__init__(self, "fm_demod_cf", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + k = channel_rate/(2*pi*deviation) + QUAD = gr.quadrature_demod_cf(k) + + audio_taps = optfir.low_pass(gain, # Filter gain + channel_rate, # Sample rate + audio_pass, # Audio passband + audio_stop, # Audio stopband + 0.1, # Passband ripple + 60) # Stopband attenuation + LPF = gr.fir_filter_fff(audio_decim, audio_taps) + + if tau is not None: + DEEMPH = fm_deemph(channel_rate, tau) + self.connect(self, QUAD, DEEMPH, LPF, self) + else: + self.connect(self, QUAD, LPF, self) + +class demod_20k0f3e_cf(fm_demod_cf): + """ + NBFM demodulation block, 20 KHz channels + + This block demodulates a complex, downconverted, narrowband FM + channel conforming to 20K0F3E emission standards, outputting + floats in the range [-1.0, +1.0]. + + @param sample_rate: incoming sample rate of the FM baseband + @type sample_rate: integer + @param audio_decim: input to output decimation rate + @type audio_decim: integer + """ + def __init__(self, channel_rate, audio_decim): + fm_demod_cf.__init__(self, channel_rate, audio_decim, + 5000, # Deviation + 3000, # Audio passband frequency + 4000) # Audio stopband frequency + +class demod_200kf3e_cf(fm_demod_cf): + """ + WFM demodulation block, mono. + + This block demodulates a complex, downconverted, wideband FM + channel conforming to 200KF3E emission standards, outputting + floats in the range [-1.0, +1.0]. + + @param sample_rate: incoming sample rate of the FM baseband + @type sample_rate: integer + @param audio_decim: input to output decimation rate + @type audio_decim: integer + """ + def __init__(self, channel_rate, audio_decim): + fm_demod_cf.__init__(self, channel_rate, audio_decim, + 75000, # Deviation + 15000, # Audio passband + 16000, # Audio stopband + 20.0) # Audio gain diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py new file mode 100644 index 00000000..fd19f5fd --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py @@ -0,0 +1,151 @@ +# +# Copyright 2005,2007 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 math + + +# +# 1 +# H(s) = ------- +# 1 + s +# +# tau is the RC time constant. +# critical frequency: w_p = 1/tau +# +# We prewarp and use the bilinear z-transform to get our IIR coefficients. +# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis +# + +class fm_deemph(gr.hier_block2): + """ + FM Deemphasis IIR filter. + """ + + + def __init__(self, fs, tau=75e-6): + """ + @param fs: sampling frequency in Hz + @type fs: float + @param tau: Time constant in seconds (75us in US, 50us in EUR) + @type tau: float + """ + gr.hier_block2.__init__(self, "fm_deemph", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + w_p = 1/tau + w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq + + a1 = (w_pp - 1)/(w_pp + 1) + b0 = w_pp/(1 + w_pp) + b1 = b0 + + btaps = [b0, b1] + ataps = [1, a1] + + if 0: + print "btaps =", btaps + print "ataps =", ataps + global plot1 + plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) + + deemph = gr.iir_filter_ffd(btaps, ataps) + self.connect(self, deemph, self) + +# +# 1 + s*t1 +# H(s) = ---------- +# 1 + s*t2 +# +# I think this is the right transfer function. +# +# +# This fine ASCII rendition is based on Figure 5-15 +# in "Digital and Analog Communication Systems", Leon W. Couch II +# +# +# R1 +# +-----||------+ +# | | +# o------+ +-----+--------o +# | C1 | | +# +----/\/\/\/--+ \ +# / +# \ R2 +# / +# \ +# | +# o--------------------------+--------o +# +# f1 = 1/(2*pi*t1) = 1/(2*pi*R1*C) +# +# 1 R1 + R2 +# f2 = ------- = ------------ +# 2*pi*t2 2*pi*R1*R2*C +# +# t1 is 75us in US, 50us in EUR +# f2 should be higher than our audio bandwidth. +# +# +# The Bode plot looks like this: +# +# +# /---------------- +# / +# / <-- slope = 20dB/decade +# / +# -------------/ +# f1 f2 +# +# We prewarp and use the bilinear z-transform to get our IIR coefficients. +# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis +# + +class fm_preemph(gr.hier_block2): + """ + FM Preemphasis IIR filter. + """ + def __init__(self, fs, tau=75e-6): + """ + @param fs: sampling frequency in Hz + @type fs: float + @param tau: Time constant in seconds (75us in US, 50us in EUR) + @type tau: float + """ + + gr.hier_block2.__init__(self, "fm_deemph", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + # FIXME make this compute the right answer + + btaps = [1] + ataps = [1] + + if 0: + print "btaps =", btaps + print "ataps =", ataps + global plot2 + plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) + + preemph = gr.iir_filter_ffd(btaps, ataps) + self.connect(self, preemph, self) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/gmsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py similarity index 88% rename from gnuradio-core/src/python/gnuradio/blksimpl2/gmsk.py rename to gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py index d1cf55c7..3b6c016a 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/gmsk.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py @@ -37,7 +37,7 @@ _def_bt = 0.35 _def_verbose = False _def_log = False -_def_gain_mu = 0.05 +_def_gain_mu = None _def_mu = 0.5 _def_freq_error = 0.0 _def_omega_relative_limit = 0.005 @@ -71,9 +71,9 @@ class gmsk_mod(gr.hier_block2): @type debug: bool """ - gr.hier_block2.__init__(self, "gmsk_mod", - gr.io_signature(1,1,gr.sizeof_char), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature + gr.hier_block2.__init__(self, "gmsk_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._samples_per_symbol = samples_per_symbol self._bt = bt @@ -103,15 +103,15 @@ class gmsk_mod(gr.hier_block2): # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) - # Connect components - self.connect(self, self.nrz, self.gaussian_filter, self.fmmod, self) - if verbose: self._print_verbage() if log: self._setup_logging() + # Connect & Initialize base class + self.connect(self, self.nrz, self.gaussian_filter, self.fmmod, self) + def samples_per_symbol(self): return self._samples_per_symbol @@ -127,9 +127,13 @@ class gmsk_mod(gr.hier_block2): def _setup_logging(self): print "Modulation logging turned on." - self.connect(self.nrz, gr.file_sink(gr.sizeof_float, "tx_nrz.dat")) - self.connect(self.gaussian_filter, gr.file_sink(gr.sizeof_float, "tx_gaussian_filter.dat")) - self.connect(self.fmmod, gr.file_sink(gr.sizeof_gr_complex, "tx_fmmod.dat")) + self.connect(self.nrz, + gr.file_sink(gr.sizeof_float, "nrz.dat")) + self.connect(self.gaussian_filter, + gr.file_sink(gr.sizeof_float, "gaussian_filter.dat")) + self.connect(self.fmmod, + gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) + def add_options(parser): """ @@ -145,7 +149,7 @@ class gmsk_mod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options(gmsk_mod.__init__, - ('self', 'fg'), options) + ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) @@ -190,9 +194,9 @@ class gmsk_demod(gr.hier_block2): @param float """ - gr.hier_block2.__init__(self, "gmsk_demod", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_char)) # Output signature + gr.hier_block2.__init__(self, "gmsk_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self._samples_per_symbol = samples_per_symbol self._gain_mu = gain_mu @@ -205,6 +209,9 @@ class gmsk_demod(gr.hier_block2): self._omega = samples_per_symbol*(1+self._freq_error) + if not self._gain_mu: + self._gain_mu = 0.175 + self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped # Demodulate FM @@ -220,15 +227,15 @@ class gmsk_demod(gr.hier_block2): # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample self.slicer = gr.binary_slicer_fb() - # Connect components - self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self) - if verbose: self._print_verbage() if log: self._setup_logging() + # Connect & Initialize base class + self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self) + def samples_per_symbol(self): return self._samples_per_symbol @@ -236,6 +243,7 @@ class gmsk_demod(gr.hier_block2): return 1 bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. + def _print_verbage(self): print "bits per symbol = %d" % self.bits_per_symbol() print "M&M clock recovery omega = %f" % self._omega @@ -247,9 +255,12 @@ class gmsk_demod(gr.hier_block2): def _setup_logging(self): print "Demodulation logging turned on." - self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, "rx_fmdemod.dat")) - self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, "rx_clock_recovery.dat")) - self.connect(self.slicer, gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) + self.connect(self.fmdemod, + gr.file_sink(gr.sizeof_float, "fmdemod.dat")) + self.connect(self.clock_recovery, + gr.file_sink(gr.sizeof_float, "clock_recovery.dat")) + self.connect(self.slicer, + gr.file_sink(gr.sizeof_char, "slicer.dat")) def add_options(parser): """ @@ -270,7 +281,7 @@ class gmsk_demod(gr.hier_block2): Given command line options, create dictionary suitable for passing to __init__ """ return modulation_utils.extract_kwargs_from_options(gmsk_demod.__init__, - ('self', 'fg'), options) + ('self',), options) extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py new file mode 100644 index 00000000..8a170400 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py @@ -0,0 +1,88 @@ +# +# Copyright 2005 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 math +from gnuradio import gr, optfir +from gnuradio.blks2impl.fm_emph import fm_deemph +#from gnuradio.blks2impl.standard_squelch import standard_squelch + +class nbfm_rx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): + """ + Narrow Band FM Receiver. + + Takes a single complex baseband input stream and produces a single + float output stream of audio sample in the range [-1, +1]. + + @param audio_rate: sample rate of audio stream, >= 16k + @type audio_rate: integer + @param quad_rate: sample rate of output stream + @type quad_rate: integer + @param tau: preemphasis time constant (default 75e-6) + @type tau: float + @param max_dev: maximum deviation in Hz (default 5e3) + @type max_dev: float + + quad_rate must be an integer multiple of audio_rate. + + Exported sub-blocks (attributes): + squelch + quad_demod + deemph + audio_filter + """ + + gr.hier_block2.__init__(self, "nbfm_rx", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + squelch_threshold = 20 # dB + #self.squelch = gr.simple_squelch_cc(squelch_threshold, 0.001) + + # FM Demodulator input: complex; output: float + k = quad_rate/(2*math.pi*max_dev) + self.quad_demod = gr.quadrature_demod_cf(k) + + # FM Deemphasis IIR filter + self.deemph = fm_deemph (quad_rate, tau=tau) + + # compute FIR taps for audio filter + audio_decim = quad_rate // audio_rate + audio_taps = gr.firdes.low_pass (1.0, # gain + quad_rate, # sampling rate + 4.5e3, # Audio LPF cutoff + 2.5e3, # Transition band + gr.firdes.WIN_HAMMING) # filter type + + print "len(audio_taps) =", len(audio_taps) + + # Decimating audio filter + # input: float; output: float; taps: float + self.audio_filter = gr.fir_filter_fff(audio_decim, audio_taps) + + self.connect(self, self.quad_demod, self.deemph, self.audio_filter, self) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py new file mode 100644 index 00000000..15818c20 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py @@ -0,0 +1,92 @@ +# +# Copyright 2005 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 math +from gnuradio import gr, optfir +from gnuradio.blks2impl.fm_emph import fm_preemph + +#from gnuradio import ctcss + +class nbfm_tx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): + """ + Narrow Band FM Transmitter. + + Takes a single float input stream of audio samples in the range [-1,+1] + and produces a single FM modulated complex baseband output. + + @param audio_rate: sample rate of audio stream, >= 16k + @type audio_rate: integer + @param quad_rate: sample rate of output stream + @type quad_rate: integer + @param tau: preemphasis time constant (default 75e-6) + @type tau: float + @param max_dev: maximum deviation in Hz (default 5e3) + @type max_dev: float + + quad_rate must be an integer multiple of audio_rate. + """ + + gr.hier_block2.__init__(self, "nbfm_tx", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + + do_interp = audio_rate != quad_rate + + if do_interp: + interp_factor = quad_rate / audio_rate + interp_taps = optfir.low_pass (interp_factor, # gain + quad_rate, # Fs + 4500, # passband cutoff + 7000, # stopband cutoff + 0.1, # passband ripple dB + 40) # stopband atten dB + + #print "len(interp_taps) =", len(interp_taps) + self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps) + + self.preemph = fm_preemph (quad_rate, tau=tau) + + k = 2 * math.pi * max_dev / quad_rate + self.modulator = gr.frequency_modulator_fc (k) + + if do_interp: + self.connect (self, self.interpolator, self.preemph, self.modulator, self) + else: + self.connect(self, self.preemph, self.modulator, self) + + +class ctcss_gen_f(gr.hier_block2): + def __init__(self, sample_rate, tone_freq): + gr.hier_block2.__init__(self, "ctcss_gen_f", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + self.plgen = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, tone_freq, 0.1, 0.0) + self.connect(self.plgen, self) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py new file mode 100644 index 00000000..b040d8c7 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py @@ -0,0 +1,305 @@ + +# +# Copyright 2006,2007 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 math +from numpy import fft +from gnuradio import gr, ofdm_packet_utils +import gnuradio.gr.gr_threading as _threading +import psk, qam + +from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver + + +# ///////////////////////////////////////////////////////////////////////////// +# mod/demod with packets as i/o +# ///////////////////////////////////////////////////////////////////////////// + +class ofdm_mod(gr.hier_block): + """ + Modulates an OFDM stream. Based on the options fft_length, occupied_tones, and + cp_length, this block creates OFDM symbols using a specified modulation option. + + Send packets by calling send_pkt + """ + def __init__(self, fg, options, msgq_limit=2, pad_for_usrp=True): + """ + Hierarchical block for sending packets + + Packets to be sent are enqueued by calling send_pkt. + The output is the complex modulated signal at baseband. + + @param fg: flow graph + @type fg: flow graph + @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) + @param msgq_limit: maximum number of messages in message queue + @type msgq_limit: int + @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples + """ + + self._pad_for_usrp = pad_for_usrp + self._modulation = options.modulation + self._fft_length = options.fft_length + self._occupied_tones = options.occupied_tones + self._cp_length = options.cp_length + + win = [] #[1 for i in range(self._fft_length)] + + # Use freq domain to get doubled-up known symbol for correlation in time domain + zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) + ksfreq = known_symbols_4512_3[0:self._occupied_tones] + for i in range(len(ksfreq)): + if((zeros_on_left + i) & 1): + ksfreq[i] = 0 + + # hard-coded known symbols + preambles = (ksfreq, + known_symbols_4512_1[0:self._occupied_tones], + known_symbols_4512_2[0:self._occupied_tones]) + + padded_preambles = list() + for pre in preambles: + padded = self._fft_length*[0,] + padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre + padded_preambles.append(padded) + + symbol_length = options.fft_length + options.cp_length + + mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} + arity = mods[self._modulation] + + rot = 1 + if self._modulation == "qpsk": + rot = (0.707+0.707j) + + if(self._modulation.find("psk") >= 0): + rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + elif(self._modulation.find("qam") >= 0): + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + #print rotated_const + self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit, + options.occupied_tones, options.fft_length) + + self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles) + self.ifft = gr.fft_vcc(self._fft_length, False, win, True) + self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, symbol_length) + self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length)) + + fg.connect((self._pkt_input, 0), (self.preambles, 0)) + fg.connect((self._pkt_input, 1), (self.preambles, 1)) + fg.connect(self.preambles, self.ifft, self.cp_adder, self.scale) + + if options.verbose: + self._print_verbage() + + if options.log: + fg.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, + "ofdm_mapper_c.dat")) + + gr.hier_block.__init__(self, fg, None, self.scale) + + def send_pkt(self, payload='', eof=False): + """ + Send the payload. + + @param payload: data to send + @type payload: string + """ + if eof: + msg = gr.message(1) # tell self._pkt_input we're not sending any more packets + else: + # print "original_payload =", string_to_hex_list(payload) + pkt = ofdm_packet_utils.make_packet(payload, 1, 1, self._pad_for_usrp, whitening=True) + + #print "pkt =", string_to_hex_list(pkt) + msg = gr.message_from_string(pkt) + self._pkt_input.msgq().insert_tail(msg) + + def add_options(normal, expert): + """ + Adds OFDM-specific options to the Options Parser + """ + normal.add_option("-m", "--modulation", type="string", default="bpsk", + help="set modulation type (bpsk or qpsk) [default=%default]") + expert.add_option("", "--fft-length", type="intx", default=512, + help="set the number of FFT bins [default=%default]") + expert.add_option("", "--occupied-tones", type="intx", default=200, + help="set the number of occupied FFT bins [default=%default]") + expert.add_option("", "--cp-length", type="intx", default=128, + help="set the number of bits in the cyclic prefix [default=%default]") + # Make a static method to call before instantiation + add_options = staticmethod(add_options) + + def _print_verbage(self): + """ + Prints information about the OFDM modulator + """ + print "\nOFDM Modulator:" + print "Modulation Type: %s" % (self._modulation) + print "FFT length: %3d" % (self._fft_length) + print "Occupied Tones: %3d" % (self._occupied_tones) + print "CP length: %3d" % (self._cp_length) + + +class ofdm_demod(gr.hier_block): + """ + Demodulates a received OFDM stream. Based on the options fft_length, occupied_tones, and + cp_length, this block performs synchronization, FFT, and demodulation of incoming OFDM + symbols and passes packets up the a higher layer. + + The input is complex baseband. When packets are demodulated, they are passed to the + app via the callback. + """ + + def __init__(self, fg, options, callback=None): + """ + Hierarchical block for demodulating and deframing packets. + + The input is the complex modulated signal at baseband. + Demodulated packets are sent to the handler. + + @param fg: flow graph + @type fg: flow graph + @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) + @param callback: function of two args: ok, payload + @type callback: ok: bool; payload: string + """ + self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY + + self._modulation = options.modulation + self._fft_length = options.fft_length + self._occupied_tones = options.occupied_tones + self._cp_length = options.cp_length + self._snr = options.snr + + + # Use freq domain to get doubled-up known symbol for correlation in time domain + ksfreq = known_symbols_4512_3[0:self._occupied_tones] + for i in range(len(ksfreq)): + if(i&1): + ksfreq[i] = 0 + + zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) + zeros_on_right = self._fft_length - self._occupied_tones - zeros_on_left + ks0 = zeros_on_left*[0.0,] + ks0.extend(ksfreq) + ks0.extend(zeros_on_right*[0.0,]) + + ks0time = fft.ifft(ks0) + # ADD SCALING FACTOR + ks0time = ks0time.tolist() + + # hard-coded known symbols + preambles = (ks0time, + known_symbols_4512_1[0:self._occupied_tones], + known_symbols_4512_2[0:self._occupied_tones]) + + symbol_length = self._fft_length + self._cp_length + self.ofdm_recv = ofdm_receiver(fg, self._fft_length, self._cp_length, + self._occupied_tones, self._snr, preambles, + options.log) + + mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} + arity = mods[self._modulation] + + rot = 1 + if self._modulation == "qpsk": + rot = (0.707+0.707j) + + if(self._modulation.find("psk") >= 0): + rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + elif(self._modulation.find("qam") >= 0): + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + #print rotated_const + self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity), + self._rcvd_pktq, + self._occupied_tones) + + fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0)) + fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1)) + + if options.verbose: + self._print_verbage() + + gr.hier_block.__init__(self, fg, self.ofdm_recv, None) + self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) + + + def add_options(normal, expert): + """ + Adds OFDM-specific options to the Options Parser + """ + normal.add_option("-m", "--modulation", type="string", default="bpsk", + help="set modulation type (bpsk or qpsk) [default=%default]") + expert.add_option("", "--fft-length", type="intx", default=512, + help="set the number of FFT bins [default=%default]") + expert.add_option("", "--occupied-tones", type="intx", default=200, + help="set the number of occupied FFT bins [default=%default]") + expert.add_option("", "--cp-length", type="intx", default=128, + help="set the number of bits in the cyclic prefix [default=%default]") + # Make a static method to call before instantiation + add_options = staticmethod(add_options) + + def _print_verbage(self): + """ + Prints information about the OFDM demodulator + """ + print "\nOFDM Demodulator:" + print "Modulation Type: %s" % (self._modulation) + print "FFT length: %3d" % (self._fft_length) + print "Occupied Tones: %3d" % (self._occupied_tones) + print "CP length: %3d" % (self._cp_length) + + + +class _queue_watcher_thread(_threading.Thread): + def __init__(self, rcvd_pktq, callback): + _threading.Thread.__init__(self) + self.setDaemon(1) + self.rcvd_pktq = rcvd_pktq + self.callback = callback + self.keep_running = True + self.start() + + + def run(self): + while self.keep_running: + msg = self.rcvd_pktq.delete_head() + ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string()) + if self.callback: + self.callback(ok, payload) + +# Generating known symbols with: +# i = [2*random.randint(0,1)-1 for i in range(4512)] + +known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0] + +known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0] + + +known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1] + +known_symbols_4512_2 = [1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1] + + +known_symbols_4512_impulse = 4512*[1,] + +known_symbols_4512_3 = [-1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1] diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py new file mode 100644 index 00000000..d16d2e29 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# Copyright 2006, 2007 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 math +from gnuradio import gr +from gnuradio.blksimpl.ofdm_sync_ml import ofdm_sync_ml +from gnuradio.blksimpl.ofdm_sync_pn import ofdm_sync_pn +from gnuradio.blksimpl.ofdm_sync_pnac import ofdm_sync_pnac + +class ofdm_receiver(gr.hier_block): + def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks, logging=False): + self.fg = fg + + bw = (float(occupied_tones) / float(fft_length)) / 2.0 + tb = bw*0.08 + chan_coeffs = gr.firdes.low_pass (1.0, # gain + 1.0, # sampling rate + bw+tb, # midpoint of trans. band + tb, # width of trans. band + gr.firdes.WIN_HAMMING) # filter type + self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs) + + win = [1 for i in range(fft_length)] + + SYNC = "pn" + if SYNC == "ml": + self.ofdm_sync = ofdm_sync_ml(fg, fft_length, cp_length, snr, logging) + elif SYNC == "pn": + self.ofdm_sync = ofdm_sync_pn(fg, fft_length, cp_length, logging) + elif SYNC == "pnac": + self.ofdm_sync = ofdm_sync_pnac(fg, fft_length, cp_length, ks[0]) + + self.fft_demod = gr.fft_vcc(fft_length, True, win, True) + self.ofdm_corr = gr.ofdm_correlator(occupied_tones, fft_length, + cp_length, ks[1], ks[2]) + + self.fg.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, self.ofdm_corr) + + if logging: + self.fg.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "chan_filt_c.dat")) + self.fg.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "fft_out_c.dat")) + self.fg.connect(self.ofdm_corr, gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_corr_out_c.dat")) + self.fg.connect((self.ofdm_corr,1), gr.file_sink(1, "found_corr_b.dat")) + + gr.hier_block.__init__(self, fg, self.chan_filt, self.ofdm_corr) diff --git a/gnuradio-examples/python/hier/usrp/Makefile.am b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py similarity index 52% rename from gnuradio-examples/python/hier/usrp/Makefile.am rename to gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py index 3d4ea30d..b56f6566 100644 --- a/gnuradio-examples/python/hier/usrp/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # # Copyright 2007 Free Software Foundation, Inc. # @@ -19,8 +20,22 @@ # Boston, MA 02110-1301, USA. # -EXTRA_DIST = \ - usrp_fft.py \ - usrp_siggen.py +import math +from gnuradio import gr -MOSTLYCLEANFILES = *.pyc *~ +class ofdm_sync_fixed(gr.hier_block): + def __init__(self, fg, fft_length, cp_length, snr): + self.fg = fg + + # Use a fixed trigger point instead of sync block + data = (fft_length+cp_len)*[0,] + data[(fft_length+cp_len)-1] = 1 + peak_trigger = gr.vector_source_b(data, True) + + self.fg.connect(peak_trigger, (self.sampler,1)) + + if 1: + self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, + "ofdm_sync_fixed-sampler_c.dat")) + + gr.hier_block.__init__(self, fg, (self.sampler,0), self.sampler) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py new file mode 100644 index 00000000..d58f56cf --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# Copyright 2007 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 math +from gnuradio import gr + +class ofdm_sync_ml(gr.hier_block): + def __init__(self, fg, fft_length, cp_length, snr, logging): + ''' Maximum Likelihood OFDM synchronizer: + J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation + of Time and Frequency Offset in OFDM Systems," IEEE Trans. + Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997. + ''' + + self.fg = fg + + # FIXME: when converting to hier_block2's, the output signature + # should be the output of the divider (the normalized peaks) and + # the angle value out of the sample and hold block + + self.input = gr.add_const_cc(0) + + SNR = 10.0**(snr/10.0) + rho = SNR / (SNR + 1.0) + symbol_length = fft_length + cp_length + + # ML Sync + + # Energy Detection from ML Sync + + # Create a delay line + self.delay = gr.delay(gr.sizeof_gr_complex, fft_length) + self.fg.connect(self.input, self.delay) + + # magnitude squared blocks + self.magsqrd1 = gr.complex_to_mag_squared() + self.magsqrd2 = gr.complex_to_mag_squared() + self.adder = gr.add_ff() + + moving_sum_taps = [rho/2 for i in range(cp_length)] + self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps) + + self.fg.connect(self.input,self.magsqrd1) + self.fg.connect(self.delay,self.magsqrd2) + self.fg.connect(self.magsqrd1,(self.adder,0)) + self.fg.connect(self.magsqrd2,(self.adder,1)) + self.fg.connect(self.adder,self.moving_sum_filter) + + + # Correlation from ML Sync + self.conjg = gr.conjugate_cc(); + self.mixer = gr.multiply_cc(); + + movingsum2_taps = [1.0 for i in range(cp_length)] + self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps) + + # Correlator data handler + self.c2mag = gr.complex_to_mag() + self.angle = gr.complex_to_arg() + self.fg.connect(self.input,(self.mixer,1)) + self.fg.connect(self.delay,self.conjg,(self.mixer,0)) + self.fg.connect(self.mixer,self.movingsum2,self.c2mag) + self.fg.connect(self.movingsum2,self.angle) + + # ML Sync output arg, need to find maximum point of this + self.diff = gr.sub_ff() + self.fg.connect(self.c2mag,(self.diff,0)) + self.fg.connect(self.moving_sum_filter,(self.diff,1)) + + #ML measurements input to sampler block and detect + nco_sensitivity = -1.0/fft_length + self.f2c = gr.float_to_complex() + self.sampler = gr.ofdm_sampler(fft_length,symbol_length) + self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005) + self.sample_and_hold = gr.sample_and_hold_ff() + self.nco = gr.frequency_modulator_fc(nco_sensitivity) + self.sigmix = gr.multiply_cc() + + # Mix the signal with an NCO controlled by the sync loop + self.fg.connect(self.input, (self.sigmix,0)) + self.fg.connect(self.nco, (self.sigmix,1)) + self.fg.connect(self.sigmix, (self.sampler,0)) + + # use the sync loop values to set the sampler and the NCO + # self.diff = theta + # self.angle = epsilon + + self.fg.connect(self.diff, self.pk_detect) + + use_dpll = 1 + if use_dpll: + self.dpll = gr.dpll_bb(float(symbol_length),0.01) + self.fg.connect(self.pk_detect, self.dpll) + self.fg.connect(self.dpll, (self.sampler,1)) + self.fg.connect(self.dpll, (self.sample_and_hold,1)) + else: + self.fg.connect(self.pk_detect, (self.sampler,1)) + self.fg.connect(self.pk_detect, (self.sample_and_hold,1)) + + self.fg.connect(self.angle, (self.sample_and_hold,0)) + self.fg.connect(self.sample_and_hold, self.nco) + + if logging: + self.fg.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat")) + self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-epsilon_f.dat")) + self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-peaks_b.dat")) + if use_dpll: + self.fg.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat")) + + self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-sigmix_c.dat")) + self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat")) + self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat")) + self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-nco_c.dat")) + self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat")) + + gr.hier_block.__init__(self, fg, self.input, self.sampler) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py new file mode 100644 index 00000000..56425868 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# Copyright 2007 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 math +from numpy import fft +from gnuradio import gr + +class ofdm_sync_pn(gr.hier_block): + def __init__(self, fg, fft_length, cp_length, logging=False): + ''' OFDM synchronization using PN Correlation: + T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing + Synchonization for OFDM," IEEE Trans. Communications, vol. 45, + no. 12, 1997. + ''' + + self.fg = fg + + # FIXME: when converting to hier_block2's, the output signature + # should be the output of the divider (the normalized peaks) and + # the angle value out of the sample and hold block + + self.input = gr.add_const_cc(0) + + symbol_length = fft_length + cp_length + + # PN Sync + + # Create a delay line + self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) + + # Correlation from ML Sync + self.conjg = gr.conjugate_cc(); + self.corr = gr.multiply_cc(); + + # Create a moving sum filter for the corr output + if 1: + moving_sum_taps = [1.0 for i in range(fft_length//2)] + self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) + else: + moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)] + self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps) + + # Create a moving sum filter for the input + self.inputmag2 = gr.complex_to_mag_squared() + movingsum2_taps = [1.0 for i in range(fft_length//2)] + + if 1: + self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) + else: + self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps) + + self.square = gr.multiply_ff() + self.normalize = gr.divide_ff() + + # Get magnitude (peaks) and angle (phase/freq error) + self.c2mag = gr.complex_to_mag_squared() + self.angle = gr.complex_to_arg() + + self.sample_and_hold = gr.sample_and_hold_ff() + + # Mix the signal with an NCO controlled by the sync loop + nco_sensitivity = -2.0/fft_length + self.nco = gr.frequency_modulator_fc(nco_sensitivity) + self.sigmix = gr.multiply_cc() + + #ML measurements input to sampler block and detect + self.sub1 = gr.add_const_ff(-1) + self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005) + self.regen = gr.regenerate_bb(symbol_length) + + self.sampler = gr.ofdm_sampler(fft_length,symbol_length) + + self.fg.connect(self.input, self.delay) + self.fg.connect(self.input, (self.corr,0)) + self.fg.connect(self.delay, self.conjg) + self.fg.connect(self.conjg, (self.corr,1)) + self.fg.connect(self.corr, self.moving_sum_filter) + self.fg.connect(self.moving_sum_filter, self.c2mag) + self.fg.connect(self.moving_sum_filter, self.angle) + self.fg.connect(self.angle, (self.sample_and_hold,0)) + self.fg.connect(self.sample_and_hold, self.nco) + + self.fg.connect(self.input, (self.sigmix,0)) + self.fg.connect(self.nco, (self.sigmix,1)) + self.fg.connect(self.sigmix, (self.sampler,0)) + + self.fg.connect(self.input, self.inputmag2, self.inputmovingsum) + self.fg.connect(self.inputmovingsum, (self.square,0)) + self.fg.connect(self.inputmovingsum, (self.square,1)) + self.fg.connect(self.square, (self.normalize,1)) + self.fg.connect(self.c2mag, (self.normalize,0)) + + # Create a moving sum filter for the corr output + matched_filter_taps = [1.0/cp_length for i in range(cp_length)] + self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps) + self.fg.connect(self.normalize, self.matched_filter) + + self.fg.connect(self.matched_filter, self.sub1, self.pk_detect) + self.fg.connect(self.pk_detect, self.regen) + self.fg.connect(self.regen, (self.sampler,1)) + self.fg.connect(self.pk_detect, (self.sample_and_hold,1)) + + + if logging: + self.fg.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) + self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) + self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) + self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) + self.fg.connect(self.regen, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-regen_b.dat")) + self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-sigmix_c.dat")) + self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_pn-sampler_c.dat")) + self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) + self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-nco_c.dat")) + self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat")) + + gr.hier_block.__init__(self, fg, self.input, self.sampler) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py new file mode 100644 index 00000000..e3774e34 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# +# Copyright 2007 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 math +from numpy import fft +from gnuradio import gr + +class ofdm_sync_pnac(gr.hier_block): + def __init__(self, fg, fft_length, cp_length, ks): + self.fg = fg + + # FIXME: when converting to hier_block2's, the output signature + # should be the output of the divider (the normalized peaks) and + # the angle value out of the sample and hold block + + self.input = gr.add_const_cc(0) + + symbol_length = fft_length + cp_length + + # PN Sync + + # autocorrelate with the known symbol + ks = ks[0:fft_length//2] + ks.reverse() + self.crosscorr_filter = gr.fir_filter_ccc(1, ks) + self.fg.connect(self.crosscorr_filter, gr.file_sink(gr.sizeof_gr_complex, "crosscorr.dat")) + + # Create a delay line + self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) + + # Correlation from ML Sync + self.conjg = gr.conjugate_cc(); + self.corr = gr.multiply_cc(); + + # Create a moving sum filter for the corr output + moving_sum_taps = [1.0 for i in range(fft_length//2)] + self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) + + # Create a moving sum filter for the input + self.inputmag2 = gr.complex_to_mag_squared() + movingsum2_taps = [1.0 for i in range(fft_length/2)] + self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) + self.square = gr.multiply_ff() + self.normalize = gr.divide_ff() + + # Get magnitude (peaks) and angle (phase/freq error) + self.c2mag = gr.complex_to_mag_squared() + self.angle = gr.complex_to_arg() + + self.sample_and_hold = gr.sample_and_hold_ff() + + # Mix the signal with an NCO controlled by the sync loop + nco_sensitivity = -1.0/fft_length + self.nco = gr.frequency_modulator_fc(nco_sensitivity) + self.sigmix = gr.multiply_cc() + + #ML measurements input to sampler block and detect + self.sub1 = gr.add_const_ff(-1) + self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005) + + self.sampler = gr.ofdm_sampler(fft_length,symbol_length) + + self.fg.connect(self.input, self.crosscorr_filter) + self.fg.connect(self.crosscorr_filter, self.delay) + self.fg.connect(self.crosscorr_filter, (self.corr,0)) + self.fg.connect(self.delay, self.conjg) + self.fg.connect(self.conjg, (self.corr,1)) + self.fg.connect(self.corr, self.moving_sum_filter) + self.fg.connect(self.moving_sum_filter, self.c2mag) + self.fg.connect(self.moving_sum_filter, self.angle) + self.fg.connect(self.angle, (self.sample_and_hold,0)) + self.fg.connect(self.sample_and_hold, self.nco) + + self.fg.connect(self.input, (self.sigmix,0)) + self.fg.connect(self.nco, (self.sigmix,1)) + self.fg.connect(self.sigmix, (self.sampler,0)) + + self.fg.connect(self.input, self.inputmag2, self.inputmovingsum) + self.fg.connect(self.inputmovingsum, (self.square,0)) + self.fg.connect(self.inputmovingsum, (self.square,1)) + self.fg.connect(self.square, (self.normalize,1)) + self.fg.connect(self.c2mag, (self.normalize,0)) + self.fg.connect(self.normalize, self.sub1, self.pk_detect) + + self.fg.connect(self.pk_detect, (self.sampler,1)) + self.fg.connect(self.pk_detect, (self.sample_and_hold,1)) + + + if 1: + self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float, + "ofdm_sync_pnac-theta_f.dat")) + self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, + "ofdm_sync_pnac-epsilon_f.dat")) + self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, + "ofdm_sync_pnac-peaks_b.dat")) + self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, + "ofdm_sync_pnac-sigmix_c.dat")) + self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, + "ofdm_sync_pnac-sampler_c.dat")) + self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, + "ofdm_sync_pnac-sample_and_hold_f.dat")) + self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, + "ofdm_sync_pnac-nco_c.dat")) + self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, + "ofdm_sync_pnac-input_c.dat")) + + gr.hier_block.__init__(self, fg, self.input, self.sampler) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/pkt.py b/gnuradio-core/src/python/gnuradio/blks2impl/pkt.py similarity index 79% rename from gnuradio-core/src/python/gnuradio/blksimpl2/pkt.py rename to gnuradio-core/src/python/gnuradio/blks2impl/pkt.py index 70eab5bf..908437ef 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/pkt.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pkt.py @@ -1,5 +1,5 @@ # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -34,29 +34,34 @@ class mod_pkts(gr.hier_block2): Send packets by calling send_pkt """ - def __init__(self, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True): + def __init__(self, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True, use_whitener_offset=False): """ Hierarchical block for sending packets Packets to be sent are enqueued by calling send_pkt. The output is the complex modulated signal at baseband. - @param modulator: instance of modulator class (gr_block or hier_block) + @param modulator: instance of modulator class (gr_block or hier_block2) @type modulator: complex baseband out @param access_code: AKA sync vector @type access_code: string of 1's and 0's between 1 and 64 long @param msgq_limit: maximum number of messages in message queue @type msgq_limit: int @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples + @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet + + See gmsk_mod for remaining parameters """ - gr.hier_block2.__init__(self, "mod_pkts", - gr.io_signature(0,0,0), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature + gr.hier_block2.__init__(self, "mod_pkts", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._modulator = modulator self._pad_for_usrp = pad_for_usrp - + self._use_whitener_offset = use_whitener_offset + self._whitener_offset = 0 + if access_code is None: access_code = packet_utils.default_access_code if not packet_utils.is_1_0_string(access_code): @@ -65,7 +70,7 @@ class mod_pkts(gr.hier_block2): # accepts messages from the outside world self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit) - self.connect(self._pkt_input, self._modulator, self) + self.connect(self._pkt_input, self._modulator, self) def send_pkt(self, payload='', eof=False): """ @@ -82,9 +87,13 @@ class mod_pkts(gr.hier_block2): self._modulator.samples_per_symbol(), self._modulator.bits_per_symbol(), self._access_code, - self._pad_for_usrp) + self._pad_for_usrp, + self._whitener_offset) #print "pkt =", string_to_hex_list(pkt) msg = gr.message_from_string(pkt) + if self._use_whitener_offset is True: + self._whitener_offset = (self._whitener_offset + 1) % 16 + self._pkt_input.msgq().insert_tail(msg) @@ -104,7 +113,7 @@ class demod_pkts(gr.hier_block2): The input is the complex modulated signal at baseband. Demodulated packets are sent to the handler. - @param demodulator: instance of demodulator class (gr_block or hier_block) + @param demodulator: instance of demodulator class (gr_block or hier_block2) @type demodulator: complex baseband in @param access_code: AKA sync vector @type access_code: string of 1's and 0's @@ -114,10 +123,10 @@ class demod_pkts(gr.hier_block2): @type threshold: int """ - gr.hier_block2.__init__(self, "demod_pkts", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(0,0,0)) # Output signature - + gr.hier_block2.__init__(self, "demod_pkts", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + self._demodulator = demodulator if access_code is None: access_code = packet_utils.default_access_code @@ -129,11 +138,11 @@ class demod_pkts(gr.hier_block2): threshold = 12 # FIXME raise exception self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY + self.correlator = gr.correlate_access_code_bb(access_code, threshold) - self._correlator = gr.correlate_access_code_bb(access_code, threshold) - self._framer_sink = gr.framer_sink_1(self._rcvd_pktq) - self.connect(self, self._demodulator, self._correlator, self._framer_sink) - + self.framer_sink = gr.framer_sink_1(self._rcvd_pktq) + self.connect(self, self._demodulator, self.correlator, self.framer_sink) + self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) @@ -150,6 +159,6 @@ class _queue_watcher_thread(_threading.Thread): def run(self): while self.keep_running: msg = self.rcvd_pktq.delete_head() - ok, payload = packet_utils.unmake_packet(msg.to_string()) + ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) if self.callback: self.callback(ok, payload) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/psk.py b/gnuradio-core/src/python/gnuradio/blks2impl/psk.py similarity index 92% rename from gnuradio-core/src/python/gnuradio/blksimpl2/psk.py rename to gnuradio-core/src/python/gnuradio/blks2impl/psk.py index 69899ebe..acedf3b6 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/psk.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/psk.py @@ -38,14 +38,14 @@ def make_gray_constellation(m): re = math.cos(theta) im = math.sin(theta) const_map.append(complex(re, im)) # plug it into the constellation - + # return the constellation; by default, it is normalized return const_map # This makes a constellation that increments around the unit circle def make_constellation(m): return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)] - + # Common definition of constellations for Tx and Rx constellation = { 2 : make_constellation(2), # BPSK @@ -53,6 +53,12 @@ constellation = { 8 : make_constellation(8) # 8PSK } +gray_constellation = { + 2 : make_gray_constellation(2), # BPSK + 4 : make_gray_constellation(4), # QPSK + 8 : make_gray_constellation(8) # 8PSK + } + # ----------------------- # Do Gray code # ----------------------- @@ -62,7 +68,7 @@ binary_to_gray = { 4 : [0,1,3,2], 8 : [0, 1, 3, 2, 7, 6, 4, 5] } - + # gray to binary gray_to_binary = { 2 : range(2), @@ -79,7 +85,7 @@ binary_to_ungray = { 4 : range(4), 8 : range(8) } - + # identity mapping ungray_to_binary = { 2 : range(2), diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam.py new file mode 100644 index 00000000..22b1e1da --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam.py @@ -0,0 +1,113 @@ +# +# Copyright 2005,2006 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 math import pi, sqrt +import math + +# These constellations are generated for Gray coding when symbos [1, ..., m] are used +# Mapping to Gray coding is therefore unnecessary + +def make_constellation(m): + # number of bits/symbol (log2(M)) + k = int(math.log10(m) / math.log10(2.0)) + + coeff = 1 + const_map = [] + for i in range(m): + a = (i&(0x01 << k-1)) >> k-1 + b = (i&(0x01 << k-2)) >> k-2 + bits_i = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(2, k, 2)] + bits_q = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(3, k, 2)] + + ss = 0 + ll = len(bits_i) + for ii in range(ll): + rr = 0 + for jj in range(ll-ii): + rr = abs(bits_i[jj] - rr) + ss += rr*pow(2.0, ii+1) + re = (2*a-1)*(ss+1) + + ss = 0 + ll = len(bits_q) + for ii in range(ll): + rr = 0 + for jj in range(ll-ii): + rr = abs(bits_q[jj] - rr) + ss += rr*pow(2.0, ii+1) + im = (2*b-1)*(ss+1) + + a = max(re, im) + if a > coeff: + coeff = a + const_map.append(complex(re, im)) + + norm_map = [complex(i.real/coeff, i.imag/coeff) for i in const_map] + return norm_map + +# Common definition of constellations for Tx and Rx +constellation = { + 4 : make_constellation(4), # QAM4 (QPSK) + 8 : make_constellation(8), # QAM8 + 16: make_constellation(16), # QAM16 + 64: make_constellation(64), # QAM64 + 256: make_constellation(256) # QAM256 + } + +# ----------------------- +# Do Gray code +# ----------------------- +# binary to gray coding +binary_to_gray = { + 4 : range(4), + 8 : range(8), + 16: range(16), + 64: range(64), + 256: range(256) + } + +# gray to binary +gray_to_binary = { + 4 : range(4), + 8 : range(8), + 16: range(16), + 64: range(64), + 256: range(256) + } + +# ----------------------- +# Don't Gray code +# ----------------------- +# identity mapping +binary_to_ungray = { + 4 : range(4), + 8 : range(8), + 16: range(16), + 64: range(64) + } + +# identity mapping +ungray_to_binary = { + 4 : range(4), + 8 : range(8), + 16: range(16), + 64: range(64) + } diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py new file mode 100644 index 00000000..0bdb9c6f --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py @@ -0,0 +1,208 @@ +# +# Copyright 2005,2006,2007 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. +# + +# See gnuradio-examples/python/digital for examples + +""" +QAM16 modulation and demodulation. +""" + +from gnuradio import gr, gru, modulation_utils +from math import pi, sqrt +import qam +import cmath +from pprint import pprint + +# default values (used in __init__ and add_options) +_def_samples_per_symbol = 2 +_def_excess_bw = 0.35 +_def_gray_code = True +_def_verbose = False +_def_log = False + +_def_costas_alpha = None +_def_gain_mu = 0.03 +_def_mu = 0.05 +_def_omega_relative_limit = 0.005 + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM16 modulator +# ///////////////////////////////////////////////////////////////////////////// + +class qam16_mod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + """ + Hierarchical block for RRC-filtered QPSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + @param samples_per_symbol: samples per symbol >= 2 + @type samples_per_symbol: integer + @param excess_bw: Root-raised cosine filter excess bandwidth + @type excess_bw: float + @param gray_code: Tell modulator to Gray code the bits + @type gray_code: bool + @param verbose: Print information about modulator? + @type verbose: bool + @param debug: Print modualtion data to files? + @type debug: bool + """ + + gr.hier_block2.__init__(self, "qam16_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + self._samples_per_symbol = samples_per_symbol + self._excess_bw = excess_bw + self._gray_code = gray_code + + if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: + raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) + + ntaps = 11 * samples_per_symbol + + arity = pow(2, self.bits_per_symbol()) + + # turn bytes into k-bit vectors + self.bytes2chunks = \ + gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) + + if self._gray_code: + self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) + else: + self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) + + self.diffenc = gr.diff_encoder_bb(arity) + + rot = 1.0 + print "constellation with %d arity" % arity + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) + + # pulse shaping filter + self.rrc_taps = gr.firdes.root_raised_cosine( + self._samples_per_symbol, # gain (sps since we're interpolating by sps) + self._samples_per_symbol, # sampling rate + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) + ntaps) + + self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + + if verbose: + self._print_verbage() + + if log: + self._setup_logging() + + # Connect + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) + + def samples_per_symbol(self): + return self._samples_per_symbol + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 4 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + + def _print_verbage(self): + print "bits per symbol = %d" % self.bits_per_symbol() + print "Gray code = %s" % self._gray_code + print "RRS roll-off factor = %f" % self._excess_bw + + def _setup_logging(self): + print "Modulation logging turned on." + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) + + def add_options(parser): + """ + Adds QAM modulation-specific options to the standard parser + """ + parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, + help="set RRC excess bandwith factor [default=%default] (PSK)") + parser.add_option("", "--no-gray-code", dest="gray_code", + action="store_false", default=_def_gray_code, + help="disable gray coding on modulated bits (PSK)") + add_options=staticmethod(add_options) + + + def extract_kwargs_from_options(options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + return modulation_utils.extract_kwargs_from_options(qam16_mod.__init__, + ('self',), options) + extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM16 demodulator +# +# ///////////////////////////////////////////////////////////////////////////// + +class qam16_demod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + costas_alpha=_def_costas_alpha, + gain_mu=_def_gain_mu, + mu=_def_mu, + omega_relative_limit=_def_omega_relative_limit, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + gr.hier_block2.__init__(self, "qam16_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature + # do this + pass + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 4 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + +# +# Add these to the mod/demod registry +# +# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK +#modulation_utils.add_type_1_mod('qam16', qam16_mod) +#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py new file mode 100644 index 00000000..fc455f17 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py @@ -0,0 +1,209 @@ +# +# Copyright 2005,2006,2007 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. +# + +# See gnuradio-examples/python/digital for examples + +""" +QAM256 modulation and demodulation. +""" + +from gnuradio import gr, gru, modulation_utils +from math import pi, sqrt +import qam +import cmath +from pprint import pprint + +# default values (used in __init__ and add_options) +_def_samples_per_symbol = 2 +_def_excess_bw = 0.35 +_def_gray_code = True +_def_verbose = False +_def_log = False + +_def_costas_alpha = None +_def_gain_mu = 0.03 +_def_mu = 0.05 +_def_omega_relative_limit = 0.005 + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM256 modulator +# ///////////////////////////////////////////////////////////////////////////// + +class qam256_mod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + """ + Hierarchical block for RRC-filtered QPSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + @param samples_per_symbol: samples per symbol >= 2 + @type samples_per_symbol: integer + @param excess_bw: Root-raised cosine filter excess bandwidth + @type excess_bw: float + @param gray_code: Tell modulator to Gray code the bits + @type gray_code: bool + @param verbose: Print information about modulator? + @type verbose: bool + @param debug: Print modualtion data to files? + @type debug: bool + """ + + gr.hier_block2.__init__(self, "qam256_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + self._samples_per_symbol = samples_per_symbol + self._excess_bw = excess_bw + self._gray_code = gray_code + + if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: + raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) + + ntaps = 11 * samples_per_symbol + + arity = pow(2, self.bits_per_symbol()) + + # turn bytes into k-bit vectors + self.bytes2chunks = \ + gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) + + if self._gray_code: + self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) + else: + self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) + + self.diffenc = gr.diff_encoder_bb(arity) + + rot = 1.0 + print "constellation with %d arity" % arity + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) + + # pulse shaping filter + self.rrc_taps = gr.firdes.root_raised_cosine( + self._samples_per_symbol, # gain (sps since we're interpolating by sps) + self._samples_per_symbol, # sampling rate + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) + ntaps) + + self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + + if verbose: + self._print_verbage() + + if log: + self._setup_logging() + + # Connect + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) + + def samples_per_symbol(self): + return self._samples_per_symbol + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 8 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + + def _print_verbage(self): + print "bits per symbol = %d" % self.bits_per_symbol() + print "Gray code = %s" % self._gray_code + print "RRS roll-off factor = %f" % self._excess_bw + + def _setup_logging(self): + print "Modulation logging turned on." + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) + + def add_options(parser): + """ + Adds QAM modulation-specific options to the standard parser + """ + parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, + help="set RRC excess bandwith factor [default=%default] (PSK)") + parser.add_option("", "--no-gray-code", dest="gray_code", + action="store_false", default=_def_gray_code, + help="disable gray coding on modulated bits (PSK)") + add_options=staticmethod(add_options) + + + def extract_kwargs_from_options(options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + return modulation_utils.extract_kwargs_from_options(qam256_mod.__init__, + ('self',), options) + extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM256 demodulator +# +# ///////////////////////////////////////////////////////////////////////////// + +class qam256_demod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + costas_alpha=_def_costas_alpha, + gain_mu=_def_gain_mu, + mu=_def_mu, + omega_relative_limit=_def_omega_relative_limit, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + gr.hier_block2.__init__(self, "qam256_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature + + # do this + pass + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 8 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + +# +# Add these to the mod/demod registry +# +# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK +#modulation_utils.add_type_1_mod('qam256', qam256_mod) +#modulation_utils.add_type_1_demod('qam256', qam256_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py new file mode 100644 index 00000000..5509f374 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py @@ -0,0 +1,208 @@ +# +# Copyright 2005,2006,2007 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. +# + +# See gnuradio-examples/python/digital for examples + +""" +differential QPSK modulation and demodulation. +""" + +from gnuradio import gr, gru, modulation_utils +from math import pi, sqrt +import qam +import cmath +from pprint import pprint + +# default values (used in __init__ and add_options) +_def_samples_per_symbol = 2 +_def_excess_bw = 0.35 +_def_gray_code = True +_def_verbose = False +_def_log = False + +_def_costas_alpha = None +_def_gain_mu = 0.03 +_def_mu = 0.05 +_def_omega_relative_limit = 0.005 + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM64 modulator +# ///////////////////////////////////////////////////////////////////////////// + +class qam64_mod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + """ + Hierarchical block for RRC-filtered QPSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + @param samples_per_symbol: samples per symbol >= 2 + @type samples_per_symbol: integer + @param excess_bw: Root-raised cosine filter excess bandwidth + @type excess_bw: float + @param gray_code: Tell modulator to Gray code the bits + @type gray_code: bool + @param verbose: Print information about modulator? + @type verbose: bool + @param debug: Print modualtion data to files? + @type debug: bool + """ + + gr.hier_block2.__init__(self, "qam64_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + self._samples_per_symbol = samples_per_symbol + self._excess_bw = excess_bw + self._gray_code = gray_code + + if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: + raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) + + ntaps = 11 * samples_per_symbol + + arity = pow(2, self.bits_per_symbol()) + + # turn bytes into k-bit vectors + self.bytes2chunks = \ + gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) + + if self._gray_code: + self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) + else: + self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) + + self.diffenc = gr.diff_encoder_bb(arity) + + rot = 1.0 + print "constellation with %d arity" % arity + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) + + # pulse shaping filter + self.rrc_taps = gr.firdes.root_raised_cosine( + self._samples_per_symbol, # gain (sps since we're interpolating by sps) + self._samples_per_symbol, # sampling rate + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) + ntaps) + + self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + + if verbose: + self._print_verbage() + + if log: + self._setup_logging() + + # Connect + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) + + def samples_per_symbol(self): + return self._samples_per_symbol + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 6 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + + def _print_verbage(self): + print "bits per symbol = %d" % self.bits_per_symbol() + print "Gray code = %s" % self._gray_code + print "RRS roll-off factor = %f" % self._excess_bw + + def _setup_logging(self): + print "Modulation logging turned on." + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) + + def add_options(parser): + """ + Adds QAM modulation-specific options to the standard parser + """ + parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, + help="set RRC excess bandwith factor [default=%default] (PSK)") + parser.add_option("", "--no-gray-code", dest="gray_code", + action="store_false", default=_def_gray_code, + help="disable gray coding on modulated bits (PSK)") + add_options=staticmethod(add_options) + + + def extract_kwargs_from_options(options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + return modulation_utils.extract_kwargs_from_options(qam64_mod.__init__, + ('self',), options) + extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM16 demodulator +# +# ///////////////////////////////////////////////////////////////////////////// + +class qam64_demod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + costas_alpha=_def_costas_alpha, + gain_mu=_def_gain_mu, + mu=_def_mu, + omega_relative_limit=_def_omega_relative_limit, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + gr.hier_block2.__init__(self, "qam64_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature + + # do this + pass + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 6 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + +# +# Add these to the mod/demod registry +# +# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK +#modulation_utils.add_type_1_mod('qam64', qam64_mod) +#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py new file mode 100644 index 00000000..977dec93 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py @@ -0,0 +1,209 @@ +# +# Copyright 2005,2006,2007 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. +# + +# See gnuradio-examples/python/digital for examples + +""" +QAM8 modulation and demodulation. +""" + +from gnuradio import gr, gru, modulation_utils +from math import pi, sqrt +import qam +import cmath +from pprint import pprint + +# default values (used in __init__ and add_options) +_def_samples_per_symbol = 2 +_def_excess_bw = 0.35 +_def_gray_code = True +_def_verbose = False +_def_log = False + +_def_costas_alpha = None +_def_gain_mu = 0.03 +_def_mu = 0.05 +_def_omega_relative_limit = 0.005 + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM8 modulator +# ///////////////////////////////////////////////////////////////////////////// + +class qam8_mod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + """ + Hierarchical block for RRC-filtered QPSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + @param samples_per_symbol: samples per symbol >= 2 + @type samples_per_symbol: integer + @param excess_bw: Root-raised cosine filter excess bandwidth + @type excess_bw: float + @param gray_code: Tell modulator to Gray code the bits + @type gray_code: bool + @param verbose: Print information about modulator? + @type verbose: bool + @param debug: Print modualtion data to files? + @type debug: bool + """ + + gr.hier_block2.__init__(self, "qam8_mod", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + self._samples_per_symbol = samples_per_symbol + self._excess_bw = excess_bw + self._gray_code = gray_code + + if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: + raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) + + ntaps = 11 * samples_per_symbol + + arity = pow(2, self.bits_per_symbol()) + + # turn bytes into k-bit vectors + self.bytes2chunks = \ + gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) + + if self._gray_code: + self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) + else: + self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) + + self.diffenc = gr.diff_encoder_bb(arity) + + rot = 1.0 + print "constellation with %d arity" % arity + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) + + # pulse shaping filter + self.rrc_taps = gr.firdes.root_raised_cosine( + self._samples_per_symbol, # gain (sps since we're interpolating by sps) + self._samples_per_symbol, # sampling rate + 1.0, # symbol rate + self._excess_bw, # excess bandwidth (roll-off factor) + ntaps) + + self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + + if verbose: + self._print_verbage() + + if log: + self._setup_logging() + + # Connect + self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, + self.chunks2symbols, self.rrc_filter, self) + + def samples_per_symbol(self): + return self._samples_per_symbol + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 3 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + + def _print_verbage(self): + print "bits per symbol = %d" % self.bits_per_symbol() + print "Gray code = %s" % self._gray_code + print "RRS roll-off factor = %f" % self._excess_bw + + def _setup_logging(self): + print "Modulation logging turned on." + self.connect(self.bytes2chunks, + gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) + self.connect(self.symbol_mapper, + gr.file_sink(gr.sizeof_char, "graycoder.dat")) + self.connect(self.diffenc, + gr.file_sink(gr.sizeof_char, "diffenc.dat")) + self.connect(self.chunks2symbols, + gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) + self.connect(self.rrc_filter, + gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) + + def add_options(parser): + """ + Adds QAM modulation-specific options to the standard parser + """ + parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, + help="set RRC excess bandwith factor [default=%default] (PSK)") + parser.add_option("", "--no-gray-code", dest="gray_code", + action="store_false", default=_def_gray_code, + help="disable gray coding on modulated bits (PSK)") + add_options=staticmethod(add_options) + + + def extract_kwargs_from_options(options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + return modulation_utils.extract_kwargs_from_options(qam8_mod.__init__, + ('self',), options) + extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) + + +# ///////////////////////////////////////////////////////////////////////////// +# QAM8 demodulator +# +# ///////////////////////////////////////////////////////////////////////////// + +class qam8_demod(gr.hier_block2): + + def __init__(self, + samples_per_symbol=_def_samples_per_symbol, + excess_bw=_def_excess_bw, + costas_alpha=_def_costas_alpha, + gain_mu=_def_gain_mu, + mu=_def_mu, + omega_relative_limit=_def_omega_relative_limit, + gray_code=_def_gray_code, + verbose=_def_verbose, + log=_def_log): + + gr.hier_block2.__init__(self, "qam8_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_char)) # Output signature + + # do this + pass + + def bits_per_symbol(self=None): # staticmethod that's also callable on an instance + return 3 + bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM + +# +# Add these to the mod/demod registry +# +# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK +modulation_utils.add_type_1_mod('qam8', qam8_mod) +#modulation_utils.add_type_1_demod('qam8', qam8_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py similarity index 98% rename from gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py rename to gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py index cbd59b08..b7de0de7 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py @@ -96,9 +96,9 @@ class _rational_resampler_base(gr.hier_block2): taps = design_filter(interpolation, decimation, fractional_bw) resampler = resampler_base(interpolation, decimation, taps) - gr.hier_block2.__init__(self, resampler.name(), + gr.hier_block2.__init__(self, "rational_resampler", gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)), - gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(1))) + gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(0))) self.connect(self, resampler, self) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py b/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py new file mode 100644 index 00000000..c5fdc01d --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py @@ -0,0 +1,76 @@ +# +# Copyright 2005,2007 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 math +from gnuradio import gr, optfir + +class standard_squelch(gr.hier_block2): + def __init__(self, audio_rate): + gr.hier_block2.__init__(self, "standard_squelch", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + self.input_node = gr.add_const_ff(0) # FIXME kludge + + self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) + self.low_square = gr.multiply_ff() + self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant + + self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) + self.hi_square = gr.multiply_ff() + self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) + + self.sub = gr.sub_ff(); + self.add = gr.add_ff(); + self.gate = gr.threshold_ff(0.3,0.43,0) + self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) + + self.div = gr.divide_ff() + self.squelch_mult = gr.multiply_ff() + + self.connect (self, self.input_node) + self.connect (self.input_node, (self.squelch_mult, 0)) + + self.connect (self.input_node,self.low_iir) + self.connect (self.low_iir,(self.low_square,0)) + self.connect (self.low_iir,(self.low_square,1)) + self.connect (self.low_square,self.low_smooth,(self.sub,0)) + self.connect (self.low_smooth, (self.add,0)) + + self.connect (self.input_node,self.hi_iir) + self.connect (self.hi_iir,(self.hi_square,0)) + self.connect (self.hi_iir,(self.hi_square,1)) + self.connect (self.hi_square,self.hi_smooth,(self.sub,1)) + self.connect (self.hi_smooth, (self.add,1)) + + self.connect (self.sub, (self.div, 0)) + self.connect (self.add, (self.div, 1)) + self.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) + self.connect (self.squelch_mult, self) + + def set_threshold(self, threshold): + self.gate.set_hi(threshold) + + def threshold(self): + return self.gate.hi() + + def squelch_range(self): + return (0.0, 1.0, 1.0/100) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py new file mode 100644 index 00000000..3bdb22cc --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py @@ -0,0 +1,69 @@ +# +# Copyright 2005,2007 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 +from gnuradio.blks2impl.fm_emph import fm_deemph +import math + +class wfm_rcv(gr.hier_block2): + def __init__ (self, quad_rate, audio_decimation): + """ + Hierarchical block for demodulating a broadcast FM signal. + + The input is the downconverted complex baseband signal (gr_complex). + The output is the demodulated audio (float). + + @param quad_rate: input sample rate of complex baseband input. + @type quad_rate: float + @param audio_decimation: how much to decimate quad_rate to get to audio. + @type audio_decimation: integer + """ + gr.hier_block2.__init__(self, "wfm_rcv", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + volume = 20. + + max_dev = 75e3 + fm_demod_gain = quad_rate/(2*math.pi*max_dev) + audio_rate = quad_rate / audio_decimation + + + # We assign to self so that outsiders can grab the demodulator + # if they need to. E.g., to plot its output. + # + # input: complex; output: float + self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain) + + # input: float; output: float + self.deemph = fm_deemph (audio_rate) + + # compute FIR filter taps for audio filter + width_of_transition_band = audio_rate / 32 + audio_coeffs = gr.firdes.low_pass (1.0, # gain + quad_rate, # sampling rate + audio_rate/2 - width_of_transition_band, + width_of_transition_band, + gr.firdes.WIN_HAMMING) + # input: float; output: float + self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) + + self.connect (self, self.fm_demod, self.audio_filter, self.deemph, self) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py new file mode 100644 index 00000000..d7a93075 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py @@ -0,0 +1,192 @@ +# +# Copyright 2005,2006 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 +from gnuradio.blks2impl.fm_emph import fm_deemph +import math + +class wfm_rcv_pll(gr.hier_block2): + def __init__ (self, demod_rate, audio_decimation): + """ + Hierarchical block for demodulating a broadcast FM signal. + + The input is the downconverted complex baseband signal (gr_complex). + The output is two streams of the demodulated audio (float) 0=Left, 1=Right. + + @param demod_rate: input sample rate of complex baseband input. + @type demod_rate: float + @param audio_decimation: how much to decimate demod_rate to get to audio. + @type audio_decimation: integer + """ + gr.hier_block2.__init__(self, "wfm_rcv_pll", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 2, gr.sizeof_float)) # Output signature + bandwidth = 200e3 + audio_rate = demod_rate / audio_decimation + + + # We assign to self so that outsiders can grab the demodulator + # if they need to. E.g., to plot its output. + # + # input: complex; output: float + alpha = 0.25*bandwidth * math.pi / demod_rate + beta = alpha * alpha / 4.0 + max_freq = 2.0*math.pi*100e3/demod_rate + + self.fm_demod = gr.pll_freqdet_cf (alpha,beta,max_freq,-max_freq) + + # input: float; output: float + self.deemph_Left = fm_deemph (audio_rate) + self.deemph_Right = fm_deemph (audio_rate) + + # compute FIR filter taps for audio filter + width_of_transition_band = audio_rate / 32 + audio_coeffs = gr.firdes.low_pass (1.0 , # gain + demod_rate, # sampling rate + 15000 , + width_of_transition_band, + gr.firdes.WIN_HAMMING) + # input: float; output: float + self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) + if 1: + # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain + # We pick off the negative frequency half because we want to base band by it! + ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS + + stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0, + demod_rate, + -19020, + -18980, + width_of_transition_band, + gr.firdes.WIN_HAMMING) + + #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) + #print "stereo carrier filter ", stereo_carrier_filter_coeffs + #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate + + # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain + + stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0, + demod_rate, + 38000-15000/2, + 38000+15000/2, + width_of_transition_band, + gr.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + # construct overlap add filter system from coefficients for stereo carrier + + self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) + + # carrier is twice the picked off carrier so arrange to do a commplex multiply + + self.stereo_carrier_generator = gr.multiply_cc(); + + # Pick off the rds signal + + stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0, + demod_rate, + 57000 - 1500, + 57000 + 1500, + width_of_transition_band, + gr.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + # construct overlap add filter system from coefficients for stereo carrier + + self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) + self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs) + + + + + + + self.rds_carrier_generator = gr.multiply_cc(); + self.rds_signal_generator = gr.multiply_cc(); + self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex); + + + + alpha = 5 * 0.25 * math.pi / (audio_rate) + beta = alpha * alpha / 4.0 + max_freq = -2.0*math.pi*18990/audio_rate; + min_freq = -2.0*math.pi*19010/audio_rate; + + self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq); + #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now + + + # set up mixer (multiplier) to get the L-R signal at baseband + + self.stereo_basebander = gr.multiply_cc(); + + # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero + + self.LmR_real = gr.complex_to_real(); + self.Make_Left = gr.add_ff(); + self.Make_Right = gr.sub_ff(); + + self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs) + + + if 1: + + # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier + self.connect (self, self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0)) + # send the already filtered carrier to the otherside of the carrier + self.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) + # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz. + + # send the new carrier to one side of the mixer (multiplier) + self.connect (self.stereo_carrier_generator, (self.stereo_basebander,0)) + # send the demphasized audio to the DSBSC pick off filter, the complex + # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier + self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) + # the result is BASEBANDED DSBSC with phase zero! + + # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer + self.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) + #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter + self.connect (self.LmR_real,(self.Make_Right,1)) + + # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone + self.connect (self.stereo_basebander,(self.rds_carrier_generator,0)) + self.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) + # take signal, filter off rds, send into mixer 0 channel + self.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) + # take rds_carrier_generator output and send into mixer 1 channel + self.connect (self.rds_carrier_generator,(self.rds_signal_generator,1)) + # send basebanded rds signal and send into "processor" which for now is a null sink + self.connect (self.rds_signal_generator,self_rds_signal_processor) + + + if 1: + # pick off the audio, L+R that is what we used to have and send it to the summer + self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) + # take the picked off L+R audio and send it to the PLUS side of the subtractor + self.connect(self.audio_filter,(self.Make_Right, 0)) + # The result of Make_Left gets (L+R) + (L-R) and results in 2*L + # The result of Make_Right gets (L+R) - (L-R) and results in 2*R + self.connect(self.Make_Left , self.deemph_Left, (self, 0)) + self.connect(self.Make_Right, self.deemph_Right, (self, 1)) + else: + self.connect (self.fm_demod, self.audio_filter, self) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py new file mode 100644 index 00000000..c7c831ca --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py @@ -0,0 +1,79 @@ +# +# Copyright 2005,2007 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 math +from gnuradio import gr, optfir +from gnuradio.blks2impl.fm_emph import fm_preemph + +class wfm_tx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=75e3): + """ + Wide Band FM Transmitter. + + Takes a single float input stream of audio samples in the range [-1,+1] + and produces a single FM modulated complex baseband output. + + @param audio_rate: sample rate of audio stream, >= 16k + @type audio_rate: integer + @param quad_rate: sample rate of output stream + @type quad_rate: integer + @param tau: preemphasis time constant (default 75e-6) + @type tau: float + @param max_dev: maximum deviation in Hz (default 75e3) + @type max_dev: float + + quad_rate must be an integer multiple of audio_rate. + """ + gr.hier_block2.__init__(self, "wfm_tx", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + + do_interp = audio_rate != quad_rate + + if do_interp: + interp_factor = quad_rate / audio_rate + interp_taps = optfir.low_pass (interp_factor, # gain + quad_rate, # Fs + 16000, # passband cutoff + 18000, # stopband cutoff + 0.1, # passband ripple dB + 40) # stopband atten dB + + print "len(interp_taps) =", len(interp_taps) + self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps) + + self.preemph = fm_preemph (quad_rate, tau=tau) + + k = 2 * math.pi * max_dev / quad_rate + self.modulator = gr.frequency_modulator_fc (k) + + if do_interp: + self.connect (self, self.interpolator, self.preemph, self.modulator, self) + else: + self.connect(self, self.preemph, self.modulator, self) diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py index bc6402b8..1c096b70 100644 --- a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py +++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py @@ -37,13 +37,17 @@ class hier_block2(object): return getattr(self._hb, name) def connect(self, *points): - '''connect requires two or more arguments that can be coerced to endpoints. + '''connect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are connected together successively. ''' - if len (points) < 2: - raise ValueError, ("connect requires at least two endpoints; %d provided." % (len (points),)) - for i in range (1, len (points)): - self._connect(points[i-1], points[i]) + if len (points) < 1: + raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) + else: + if len(points) == 1: + self._hb.connect(points[0].basic_block()) + else: + for i in range (1, len (points)): + self._connect(points[i-1], points[i]) def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) @@ -61,13 +65,17 @@ class hier_block2(object): raise ValueError("unable to coerce endpoint") def disconnect(self, *points): - '''connect requires two or more arguments that can be coerced to endpoints. + '''connect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are disconnected successively. ''' - if len (points) < 2: + if len (points) < 1: raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) - for i in range (1, len (points)): - self._disconnect(points[i-1], points[i]) + else: + if len (points) == 1: + self._hb.disconnect(points[0].basic_block()) + else: + for i in range (1, len (points)): + self._disconnect(points[i-1], points[i]) def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py index d07d4cb3..7249a219 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py @@ -187,5 +187,58 @@ class test_hier_block2(gr_unittest.TestCase): hblock.run() self.assertEquals(data, dst.data()) + def test_021_connect_single(self): + hblock = gr.top_block("test_block") + blk = gr.hier_block2("block", + gr.io_signature(0, 0, 0), + gr.io_signature(0, 0, 0)) + hblock.connect(blk) + + def test_022_connect_single_with_ports(self): + hblock = gr.top_block("test_block") + blk = gr.hier_block2("block", + gr.io_signature(1, 1, 1), + gr.io_signature(1, 1, 1)) + self.assertRaises(ValueError, + lambda: hblock.connect(blk)) + + def test_023_connect_single_twice(self): + hblock = gr.top_block("test_block") + blk = gr.hier_block2("block", + gr.io_signature(0, 0, 0), + gr.io_signature(0, 0, 0)) + hblock.connect(blk) + self.assertRaises(ValueError, + lambda: hblock.connect(blk)) + + def test_024_disconnect_single(self): + hblock = gr.top_block("test_block") + blk = gr.hier_block2("block", + gr.io_signature(0, 0, 0), + gr.io_signature(0, 0, 0)) + hblock.connect(blk) + hblock.disconnect(blk) + + def test_025_disconnect_single_not_connected(self): + hblock = gr.top_block("test_block") + blk = gr.hier_block2("block", + gr.io_signature(0, 0, 0), + gr.io_signature(0, 0, 0)) + self.assertRaises(ValueError, + lambda: hblock.disconnect(blk)) + + def test_026_run_single(self): + expected_data = (1.0,) + tb = gr.top_block("top_block") + hb = gr.hier_block2("block", + gr.io_signature(0, 0, 0), + gr.io_signature(0, 0, 0)) + src = gr.vector_source_f(expected_data) + dst = gr.vector_sink_f() + hb.connect(src, dst) + tb.connect(hb) + tb.run() + self.assertEquals(expected_data, dst.data()) + if __name__ == "__main__": gr_unittest.main() diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py index 9b709c01..8bd4052c 100644 --- a/gnuradio-core/src/python/gnuradio/gr/top_block.py +++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py @@ -51,13 +51,17 @@ class top_block(object): # in the original C++ class (gr_hier_block2), then they would all be inherited here def connect(self, *points): - '''connect requires two or more arguments that can be coerced to endpoints. + '''connect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are connected together successively. ''' - if len (points) < 2: - raise ValueError, ("connect requires at least two endpoints; %d provided." % (len (points),)) - for i in range (1, len (points)): - self._connect(points[i-1], points[i]) + if len (points) < 1: + raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) + else: + if len(points) == 1: + self._tb.connect(points[0].basic_block()) + else: + for i in range (1, len (points)): + self._connect(points[i-1], points[i]) def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) @@ -75,13 +79,17 @@ class top_block(object): raise ValueError("unable to coerce endpoint") def disconnect(self, *points): - '''connect requires two or more arguments that can be coerced to endpoints. + '''connect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are disconnected successively. ''' - if len (points) < 2: + if len (points) < 1: raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) - for i in range (1, len (points)): - self._disconnect(points[i-1], points[i]) + else: + if len(points) == 1: + self._tb.disconnect(points[0].basic_block()) + else: + for i in range (1, len (points)): + self._disconnect(points[i-1], points[i]) def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am index c9db48d6..e20bfafd 100644 --- a/gnuradio-examples/python/Makefile.am +++ b/gnuradio-examples/python/Makefile.am @@ -22,16 +22,16 @@ include $(top_srcdir)/Makefile.common SUBDIRS = \ - apps \ - audio \ - digital_voice \ - digital \ - multi-antenna \ - multi_usrp \ - networking \ - usrp \ - hier \ - ofdm + apps \ + audio \ + dect \ + digital \ + digital_voice \ + multi-antenna \ + multi_usrp \ + network \ + ofdm \ + usrp # Make example scripts with #! executable install-data-local: diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx2.py b/gnuradio-examples/python/apps/hf_explorer/hfx2.py index c46f2e14..00b1eddf 100755 --- a/gnuradio-examples/python/apps/hf_explorer/hfx2.py +++ b/gnuradio-examples/python/apps/hf_explorer/hfx2.py @@ -80,7 +80,7 @@ AM_SYNC_DISPLAY = False import os, wx, sys, math import wx.lib.evtmgr as em -from gnuradio.wxgui import powermate, fftsink +from gnuradio.wxgui import powermate, fftsink2 from gnuradio import gr, audio, eng_notation, usrp, gru from gnuradio.eng_option import eng_option from optparse import OptionParser @@ -209,7 +209,7 @@ class MyFrame(wx.Frame): self.xdata = [] self.ydata = [] - self.fg = gr.flow_graph() + self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center @@ -260,7 +260,7 @@ class MyFrame(wx.Frame): # save radio data to a file if SAVE_RADIO_TO_FILE: file = gr.file_sink(gr.sizeof_short, options.radio_file) - self.fg.connect (self.src, file) + self.tb.connect (self.src, file) # 2nd DDC xlate_taps = gr.firdes.low_pass ( \ @@ -273,11 +273,11 @@ class MyFrame(wx.Frame): s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() - self.fg.connect(self.src,s2ss) - self.fg.connect((s2ss,0),s2f1) - self.fg.connect((s2ss,1),s2f2) - self.fg.connect(s2f1,(src_f2c,0)) - self.fg.connect(s2f2,(src_f2c,1)) + self.tb.connect(self.src,s2ss) + self.tb.connect((s2ss,0),s2f1) + self.tb.connect((s2ss,1),s2f2) + self.tb.connect(s2f1,(src_f2c,0)) + self.tb.connect(s2f2,(src_f2c,1)) # Complex Audio filter @@ -294,11 +294,11 @@ class MyFrame(wx.Frame): self.audio_filter = gr.fir_filter_ccc ( 1, audio_coeffs) # Main +/- 16Khz spectrum display - self.fft = fftsink.fft_sink_c (self.fg, self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) + self.fft = fftsink2.fft_sink_c (self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) # AM Sync carrier if AM_SYNC_DISPLAY: - self.fft2 = fftsink.fft_sink_c (self.fg, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) + self.fft2 = fftsink.fft_sink_c (self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) c2f = gr.complex_to_float() @@ -342,30 +342,30 @@ class MyFrame(wx.Frame): self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate)) - self.fg.connect(src_f2c,self.xlate,self.fft) - self.fg.connect(self.xlate,self.audio_filter,self.sel_am,(am_det,0)) - self.fg.connect(self.sel_am,pll,self.pll_carrier_scale,self.pll_carrier_filter,c2f3) - self.fg.connect((c2f3,0),phaser1,(f2c,0)) - self.fg.connect((c2f3,1),phaser2,(f2c,1)) - self.fg.connect(f2c,(am_det,1)) - self.fg.connect(am_det,c2f2,(combine,0)) - self.fg.connect(self.audio_filter,c2f,self.sel_sb,(combine,1)) + self.tb.connect(src_f2c,self.xlate,self.fft) + self.tb.connect(self.xlate,self.audio_filter,self.sel_am,(am_det,0)) + self.tb.connect(self.sel_am,pll,self.pll_carrier_scale,self.pll_carrier_filter,c2f3) + self.tb.connect((c2f3,0),phaser1,(f2c,0)) + self.tb.connect((c2f3,1),phaser2,(f2c,1)) + self.tb.connect(f2c,(am_det,1)) + self.tb.connect(am_det,c2f2,(combine,0)) + self.tb.connect(self.audio_filter,c2f,self.sel_sb,(combine,1)) if AM_SYNC_DISPLAY: - self.fg.connect(self.pll_carrier_filter,self.fft2) - self.fg.connect(combine,self.scale) - self.fg.connect(self.scale,(sqr1,0)) - self.fg.connect(self.scale,(sqr1,1)) - self.fg.connect(sqr1, intr, offset, (agc, 1)) - self.fg.connect(self.scale,(agc, 0)) - self.fg.connect(agc,dst) + self.tb.connect(self.pll_carrier_filter,self.fft2) + self.tb.connect(combine,self.scale) + self.tb.connect(self.scale,(sqr1,0)) + self.tb.connect(self.scale,(sqr1,1)) + self.tb.connect(sqr1, intr, offset, (agc, 1)) + self.tb.connect(self.scale,(agc, 0)) + self.tb.connect(agc,dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short,options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() - self.fg.connect(agc,sc1,f2s1,f_out) + self.tb.connect(agc,sc1,f2s1,f_out) - self.fg.start() + self.tb.start() # for mouse position reporting on fft display em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win) @@ -482,7 +482,7 @@ class MyFrame(wx.Frame): # Menu exit def TimeToQuit(self, event): - self.fg.stop() + self.tb.stop() self.Close(True) # Powermate being turned diff --git a/gnuradio-examples/python/audio/audio_copy.py b/gnuradio-examples/python/audio/audio_copy.py index 88dd0883..3094c9f7 100755 --- a/gnuradio-examples/python/audio/audio_copy.py +++ b/gnuradio-examples/python/audio/audio_copy.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -25,10 +25,10 @@ from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-I", "--audio-input", type="string", default="", @@ -58,7 +58,7 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/audio_fft.py b/gnuradio-examples/python/audio/audio_fft.py index 7c54dd55..f7f1c2e8 100755 --- a/gnuradio-examples/python/audio/audio_fft.py +++ b/gnuradio-examples/python/audio/audio_fft.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -23,14 +23,14 @@ from gnuradio import gr, gru, audio from gnuradio import eng_notation from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider from optparse import OptionParser import wx import sys -class app_flow_graph(stdgui.gui_flow_graph): +class app_top_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__(self) + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -57,11 +57,11 @@ class app_flow_graph(stdgui.gui_flow_graph): # build the graph if options.waterfall: self.scope = \ - waterfallsink.waterfall_sink_f (self, panel, fft_size=1024, sample_rate=sample_rate) + waterfallsink2.waterfall_sink_f (panel, fft_size=1024, sample_rate=sample_rate) elif options.oscilloscope: - self.scope = scopesink.scope_sink_f(self, panel, sample_rate=sample_rate) + self.scope = scopesink2.scope_sink_f(panel, sample_rate=sample_rate) else: - self.scope = fftsink.fft_sink_f (self, panel, fft_size=1024, sample_rate=sample_rate, fft_rate=30) + self.scope = fftsink2.fft_sink_f (panel, fft_size=1024, sample_rate=sample_rate, fft_rate=30) self.src = audio.source (sample_rate, options.audio_input) @@ -130,7 +130,7 @@ class app_flow_graph(stdgui.gui_flow_graph): def main (): - app = stdgui.stdapp(app_flow_graph, "Audio FFT", nstatus=1) + app = stdgui2.stdapp(app_top_block, "Audio FFT", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gnuradio-examples/python/audio/audio_play.py b/gnuradio-examples/python/audio/audio_play.py index 37b2abda..f9520c7c 100755 --- a/gnuradio-examples/python/audio/audio_play.py +++ b/gnuradio-examples/python/audio/audio_play.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -26,10 +26,10 @@ from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-F", "--filename", type="string", default="audio.dat", @@ -52,6 +52,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/audio_to_file.py b/gnuradio-examples/python/audio/audio_to_file.py index 7aa49e7f..0d54f7bd 100755 --- a/gnuradio-examples/python/audio/audio_to_file.py +++ b/gnuradio-examples/python/audio/audio_to_file.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -25,10 +25,10 @@ from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) usage="%prog: [options] output_filename" parser = OptionParser(option_class=eng_option, usage=usage) @@ -58,6 +58,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/dial_tone.py b/gnuradio-examples/python/audio/dial_tone.py index 1ec1b000..65c5e50b 100755 --- a/gnuradio-examples/python/audio/dial_tone.py +++ b/gnuradio-examples/python/audio/dial_tone.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -25,10 +25,10 @@ from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", @@ -52,6 +52,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/mono_tone.py b/gnuradio-examples/python/audio/mono_tone.py index d5c7e638..869c2e5f 100755 --- a/gnuradio-examples/python/audio/mono_tone.py +++ b/gnuradio-examples/python/audio/mono_tone.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -29,10 +29,10 @@ from optparse import OptionParser #print os.getpid() #raw_input('Attach gdb and press Enter: ') -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", @@ -61,6 +61,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/multi_tone.py b/gnuradio-examples/python/audio/multi_tone.py index 4cf99338..7d47dd5d 100755 --- a/gnuradio-examples/python/audio/multi_tone.py +++ b/gnuradio-examples/python/audio/multi_tone.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2006 Free Software Foundation, Inc. +# Copyright 2004,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -29,10 +29,10 @@ from optparse import OptionParser #print os.getpid() #raw_input('Attach gdb and press Enter: ') -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", @@ -85,6 +85,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/noise.py b/gnuradio-examples/python/audio/noise.py index 6e9b69be..75f74108 100755 --- a/gnuradio-examples/python/audio/noise.py +++ b/gnuradio-examples/python/audio/noise.py @@ -25,10 +25,10 @@ from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", @@ -50,6 +50,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/spectrum_inversion.py b/gnuradio-examples/python/audio/spectrum_inversion.py index 9bb87aa4..021e23f2 100755 --- a/gnuradio-examples/python/audio/spectrum_inversion.py +++ b/gnuradio-examples/python/audio/spectrum_inversion.py @@ -1,4 +1,24 @@ #!/usr/bin/env python +# +# Copyright 2004,2005,2007 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. + # # Gang - Here's a simple script that demonstrates spectrum inversion # using the multiply by [1,-1] method (mixing with Nyquist frequency). @@ -11,10 +31,10 @@ from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-I", "--audio-input", type="string", default="", @@ -43,6 +63,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/audio/test_resampler.py b/gnuradio-examples/python/audio/test_resampler.py index 710b0fa6..4644c5e2 100755 --- a/gnuradio-examples/python/audio/test_resampler.py +++ b/gnuradio-examples/python/audio/test_resampler.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,16 +20,16 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, blks +from gnuradio import gr, gru, blks2 from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", @@ -54,13 +54,13 @@ class my_graph(gr.flow_graph): ampl = 0.1 src0 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 650, ampl) - rr = blks.rational_resampler_fff(self, interp, decim) + rr = blks2.rational_resampler_fff(interp, decim) dst = audio.sink (output_rate, options.audio_output) self.connect (src0, rr, (dst, 0)) if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/hier/dect/Makefile.am b/gnuradio-examples/python/dect/Makefile.am similarity index 89% rename from gnuradio-examples/python/hier/dect/Makefile.am rename to gnuradio-examples/python/dect/Makefile.am index 5ab1589a..c65bd4c4 100644 --- a/gnuradio-examples/python/hier/dect/Makefile.am +++ b/gnuradio-examples/python/dect/Makefile.am @@ -19,10 +19,15 @@ # Boston, MA 02110-1301, USA. # +include $(top_srcdir)/Makefile.common + EXTRA_DIST = \ README \ dect_receiver.py \ usrp_source.py \ usrp_dect.py +ourdatadir = $(exampledir)/dect +ourdata_DATA = $(EXTRA_DIST) + MOSTLYCLEANFILES = *.pyc *~ diff --git a/gnuradio-examples/python/hier/dect/README b/gnuradio-examples/python/dect/README similarity index 100% rename from gnuradio-examples/python/hier/dect/README rename to gnuradio-examples/python/dect/README diff --git a/gnuradio-examples/python/hier/dect/dect_receiver.py b/gnuradio-examples/python/dect/dect_receiver.py similarity index 94% rename from gnuradio-examples/python/hier/dect/dect_receiver.py rename to gnuradio-examples/python/dect/dect_receiver.py index 80ea9379..89e60c94 100644 --- a/gnuradio-examples/python/hier/dect/dect_receiver.py +++ b/gnuradio-examples/python/dect/dect_receiver.py @@ -20,9 +20,8 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, optfir +from gnuradio import gr, optfir, blks2 from usrp_source import usrp_source_c -from gmsk2 import gmsk2_demod _dect_symbol_rate = 1.152e6 _dect_occupied_bandwidth = _dect_symbol_rate * 1.03 # BT=0.5 @@ -60,8 +59,8 @@ class dect_receiver(gr.top_block): 0.0, # Offset frequency if_rate) # Sample rate - self._demod = gmsk2_demod(samples_per_symbol=if_rate/_dect_symbol_rate, - verbose=options.verbose) + self._demod = blks2.gmsk_demod(samples_per_symbol=if_rate/_dect_symbol_rate, + verbose=options.verbose) self._sink = gr.null_sink(gr.sizeof_char) self.connect(self._usrp, self._channel_filter, self._demod, self._sink) diff --git a/gnuradio-examples/python/hier/dect/usrp_dect.py b/gnuradio-examples/python/dect/usrp_dect.py similarity index 100% rename from gnuradio-examples/python/hier/dect/usrp_dect.py rename to gnuradio-examples/python/dect/usrp_dect.py diff --git a/gnuradio-examples/python/hier/dect/usrp_source.py b/gnuradio-examples/python/dect/usrp_source.py similarity index 100% rename from gnuradio-examples/python/hier/dect/usrp_source.py rename to gnuradio-examples/python/dect/usrp_source.py diff --git a/gnuradio-examples/python/digital/Makefile.am b/gnuradio-examples/python/digital/Makefile.am index 1db2f847..ed941e4f 100644 --- a/gnuradio-examples/python/digital/Makefile.am +++ b/gnuradio-examples/python/digital/Makefile.am @@ -23,17 +23,22 @@ include $(top_srcdir)/Makefile.common EXTRA_DIST = \ README \ + benchmark_loopback.py \ benchmark_rx.py \ benchmark_tx.py \ fusb_options.py \ gen_whitener.py \ pick_bitrate.py \ receive_path.py \ + receive_path_lb.py \ rx_voice.py \ run_length.py \ transmit_path.py \ + transmit_path_lb.py \ tunnel.py \ tx_voice.py ourdatadir = $(exampledir)/digital ourdata_DATA = $(EXTRA_DIST) + +MOSTLYCLEANFILES = *.pyc *.pyo *~ diff --git a/gnuradio-examples/python/digital/benchmark_loopback.py b/gnuradio-examples/python/digital/benchmark_loopback.py index 34d25812..7dd36b98 100755 --- a/gnuradio-examples/python/digital/benchmark_loopback.py +++ b/gnuradio-examples/python/digital/benchmark_loopback.py @@ -32,10 +32,13 @@ from transmit_path_lb import transmit_path from receive_path_lb import receive_path import fusb_options -class awgn_channel(gr.hier_block): - def __init__(self, fg, sample_rate, noise_voltage, frequency_offset, seed=False): - self.input = gr.add_const_cc(0) # dummy input device - +class awgn_channel(gr.hier_block2): + def __init__(self, sample_rate, noise_voltage, frequency_offset, seed=False): + + gr.hier_block2.__init__(self, "awgn_channel", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + # Create the Gaussian noise source if not seed: self.noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_voltage) @@ -51,16 +54,15 @@ class awgn_channel(gr.hier_block): self.mixer = gr.multiply_cc() # Connect the components - fg.connect(self.input, (self.mixer, 0)) - fg.connect(self.offset, (self.mixer, 1)) - fg.connect(self.mixer, (self.adder, 0)) - fg.connect(self.noise, (self.adder, 1)) - - gr.hier_block.__init__(self, fg, self.input, self.adder) + self.connect(self, (self.mixer, 0)) + self.connect(self.offset, (self.mixer, 1)) + self.connect(self.mixer, (self.adder, 0)) + self.connect(self.noise, (self.adder, 1)) + self.connect(self.adder, self) -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self, mod_class, demod_class, rx_callback, options): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) channelon = True; @@ -71,12 +73,12 @@ class my_graph(gr.flow_graph): noise_power = power_in_signal/SNR noise_voltage = math.sqrt(noise_power) - self.txpath = transmit_path(self, mod_class, options) + self.txpath = transmit_path(mod_class, options) self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate) - self.rxpath = receive_path(self, demod_class, rx_callback, options) + self.rxpath = receive_path(demod_class, rx_callback, options) if channelon: - self.channel = awgn_channel(self, options.sample_rate, noise_voltage, + self.channel = awgn_channel(options.sample_rate, noise_voltage, frequency_offset, options.seed) if options.discontinuous: @@ -121,7 +123,7 @@ def main(): # print payload[2:len(payload)] def send_pkt(payload='', eof=False): - return fg.txpath.send_pkt(payload, eof) + return tb.txpath.send_pkt(payload, eof) mods = modulation_utils.type_1_mods() @@ -171,8 +173,8 @@ def main(): print "Warning: failed to enable realtime scheduling" # Create an instance of a hierarchical block - fg = my_graph(mods[options.modulation], demods[options.modulation], rx_callback, options) - fg.start() + tb = my_top_block(mods[options.modulation], demods[options.modulation], rx_callback, options) + tb.start() # generate and send packets nbytes = int(1e6 * options.megabytes) @@ -187,7 +189,7 @@ def main(): send_pkt(eof=True) - fg.wait() + tb.wait() if __name__ == '__main__': try: diff --git a/gnuradio-examples/python/digital/benchmark_rx.py b/gnuradio-examples/python/digital/benchmark_rx.py index e375bc0f..be183957 100755 --- a/gnuradio-examples/python/digital/benchmark_rx.py +++ b/gnuradio-examples/python/digital/benchmark_rx.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -38,12 +38,11 @@ import fusb_options #print os.getpid() #raw_input('Attach and press enter: ') - -class my_graph(gr.flow_graph): - - def __init__(self, demod_class, rx_callback, options): - gr.flow_graph.__init__(self) - self.rxpath = receive_path(self, demod_class, rx_callback, options) +class my_top_block(gr.top_block): + def __init__(self, demodulator, rx_callback, options): + gr.top_block.__init__(self) + self.rxpath = receive_path(demodulator, rx_callback, options) + self.connect(self.rxpath) # ///////////////////////////////////////////////////////////////////////////// # main @@ -98,14 +97,14 @@ def main(): # build the graph - fg = my_graph(demods[options.modulation], rx_callback, options) + tb = my_top_block(demods[options.modulation], rx_callback, options) r = gr.enable_realtime_scheduling() if r != gr.RT_OK: print "Warning: Failed to enable realtime scheduling." - fg.start() # start flow graph - fg.wait() # wait for it to finish + tb.start() # start flow graph + tb.wait() # wait for it to finish if __name__ == '__main__': try: diff --git a/gnuradio-examples/python/digital/benchmark_tx.py b/gnuradio-examples/python/digital/benchmark_tx.py index d2cba4fd..a0a10d78 100755 --- a/gnuradio-examples/python/digital/benchmark_tx.py +++ b/gnuradio-examples/python/digital/benchmark_tx.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005, 2006 Free Software Foundation, Inc. +# Copyright 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -36,12 +36,11 @@ import fusb_options #print os.getpid() #raw_input('Attach and press enter') - -class my_graph(gr.flow_graph): - def __init__(self, modulator_class, options): - gr.flow_graph.__init__(self) - self.txpath = transmit_path(self, modulator_class, options) - +class my_top_block(gr.top_block): + def __init__(self, modulator, options): + gr.top_block.__init__(self) + self.txpath = transmit_path(modulator, options) + self.connect(self.txpath) # ///////////////////////////////////////////////////////////////////////////// # main @@ -50,7 +49,7 @@ class my_graph(gr.flow_graph): def main(): def send_pkt(payload='', eof=False): - return fg.txpath.send_pkt(payload, eof) + return tb.txpath.send_pkt(payload, eof) def rx_callback(ok, payload): print "ok = %r, payload = '%s'" % (ok, payload) @@ -95,14 +94,14 @@ def main(): source_file = open(options.from_file, 'r') # build the graph - fg = my_graph(mods[options.modulation], options) + tb = my_top_block(mods[options.modulation], options) r = gr.enable_realtime_scheduling() if r != gr.RT_OK: print "Warning: failed to enable realtime scheduling" - fg.start() # start flow graph - + tb.start() # start flow graph + # generate and send packets nbytes = int(1e6 * options.megabytes) n = 0 @@ -126,7 +125,8 @@ def main(): pktno += 1 send_pkt(eof=True) - fg.wait() # wait for it to finish + + tb.wait() # wait for it to finish if __name__ == '__main__': try: diff --git a/gnuradio-examples/python/digital/receive_path.py b/gnuradio-examples/python/digital/receive_path.py index 5cf4e59e..29f1f834 100644 --- a/gnuradio-examples/python/digital/receive_path.py +++ b/gnuradio-examples/python/digital/receive_path.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, blks +from gnuradio import gr, gru, blks2 from gnuradio import usrp from gnuradio import eng_notation import copy @@ -33,8 +33,12 @@ from pick_bitrate import pick_rx_bitrate # receive path # ///////////////////////////////////////////////////////////////////////////// -class receive_path(gr.hier_block): - def __init__(self, fg, demod_class, rx_callback, options): +class receive_path(gr.hier_block2): + def __init__(self, demod_class, rx_callback, options): + + gr.hier_block2.__init__(self, "receive_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify @@ -96,11 +100,10 @@ class receive_path(gr.hier_block): # receiver self.packet_receiver = \ - blks.demod_pkts(fg, - self._demod_class(fg, **demod_kwargs), - access_code=None, - callback=self._rx_callback, - threshold=-1) + blks2.demod_pkts(self._demod_class(**demod_kwargs), + access_code=None, + callback=self._rx_callback, + threshold=-1) # Carrier Sensing Blocks alpha = 0.001 @@ -109,17 +112,16 @@ class receive_path(gr.hier_block): if options.log_rx_power == True: self.probe = gr.probe_avg_mag_sqrd_cf(thresh,alpha) self.power_sink = gr.file_sink(gr.sizeof_float, "rxpower.dat") - fg.connect(self.chan_filt, self.probe, self.power_sink) + self.connect(self.chan_filt, self.probe, self.power_sink) else: self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha) - fg.connect(self.chan_filt, self.probe) + self.connect(self.chan_filt, self.probe) # Display some information about the setup if self._verbose: self._print_verbage() - fg.connect(self.u, self.chan_filt, self.packet_receiver) - gr.hier_block.__init__(self, fg, None, None) + self.connect(self.u, self.chan_filt, self.packet_receiver) def _setup_usrp_source(self): self.u = usrp.source_c (fusb_block_size=self._fusb_block_size, @@ -246,6 +248,10 @@ class receive_path(gr.hier_block): print "decim: %3d" % (self._decim) print "Rx Frequency: %s" % (eng_notation.num_to_str(self._rx_freq)) # print "Rx Frequency: %f" % (self._rx_freq) + + def __del__(self): + # Avoid weak reference error + del self.subdev def add_freq_option(parser): """ diff --git a/gnuradio-examples/python/digital/receive_path_lb.py b/gnuradio-examples/python/digital/receive_path_lb.py index 17643c6c..a6bffeea 100644 --- a/gnuradio-examples/python/digital/receive_path_lb.py +++ b/gnuradio-examples/python/digital/receive_path_lb.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, blks +from gnuradio import gr, gru, blks2 from gnuradio import eng_notation import copy import sys @@ -29,8 +29,12 @@ import sys # receive path # ///////////////////////////////////////////////////////////////////////////// -class receive_path(gr.hier_block): - def __init__(self, fg, demod_class, rx_callback, options): +class receive_path(gr.hier_block2): + def __init__(self, demod_class, rx_callback, options): + gr.hier_block2.__init__(self, "receive_path", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + options = copy.copy(options) # make a copy so we can destructively modify @@ -55,11 +59,10 @@ class receive_path(gr.hier_block): # receiver self.packet_receiver = \ - blks.demod_pkts(fg, - self._demod_class(fg, **demod_kwargs), - access_code=None, - callback=self._rx_callback, - threshold=-1) + blks2.demod_pkts(self._demod_class(**demod_kwargs), + access_code=None, + callback=self._rx_callback, + threshold=-1) # Carrier Sensing Blocks alpha = 0.001 @@ -70,13 +73,14 @@ class receive_path(gr.hier_block): if self._verbose: self._print_verbage() + # connect block input to channel filter + self.connect(self, self.channel_filter) + # connect the channel input filter to the carrier power detector - fg.connect(self.channel_filter, self.probe) + self.connect(self.channel_filter, self.probe) # connect channel filter to the packet receiver - fg.connect(self.channel_filter, self.packet_receiver) - - gr.hier_block.__init__(self, fg, self.channel_filter, None) + self.connect(self.channel_filter, self.packet_receiver) def bitrate(self): return self._bitrate diff --git a/gnuradio-examples/python/digital/rx_voice.py b/gnuradio-examples/python/digital/rx_voice.py index c9c33c3d..b3280d43 100755 --- a/gnuradio-examples/python/digital/rx_voice.py +++ b/gnuradio-examples/python/digital/rx_voice.py @@ -31,6 +31,7 @@ from gnuradio.vocoder import gsm_full_rate import random import struct +import sys # from current dir from receive_path import receive_path @@ -41,27 +42,30 @@ import fusb_options #raw_input('Attach and press enter') -class audio_tx(gr.hier_block): - def __init__(self, fg, audio_output_dev): +class audio_tx(gr.hier_block2): + def __init__(self, audio_output_dev): + gr.hier_block2.__init__(self, "audio_tx", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + self.packet_src = gr.message_source(33) voice_decoder = gsm_full_rate.decode_ps() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) audio_sink = audio.sink(8000, audio_output_dev) - fg.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink) - gr.hier_block.__init__(self, fg, self.packet_src, audio_sink) + self.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink) def msgq(self): return self.packet_src.msgq() -class my_graph(gr.flow_graph): - +class my_top_block(gr.top_block): def __init__(self, demod_class, rx_callback, options): - gr.flow_graph.__init__(self) - self.rxpath = receive_path(self, demod_class, rx_callback, options) - self.audio_tx = audio_tx(self, options.audio_output) - + gr.top_block.__init__(self) + self.rxpath = receive_path(demod_class, rx_callback, options) + self.audio_tx = audio_tx(options.audio_output) + self.connect(self.rxpath) + self.connect(self.audio_tx) # ///////////////////////////////////////////////////////////////////////////// # main @@ -120,14 +124,13 @@ def main(): # build the graph - fg = my_graph(demods[options.modulation], rx_callback, options) + tb = my_top_block(demods[options.modulation], rx_callback, options) r = gr.enable_realtime_scheduling() if r != gr.RT_OK: print "Warning: Failed to enable realtime scheduling." - fg.start() # start flow graph - fg.wait() # wait for it to finish + tb.run() if __name__ == '__main__': try: diff --git a/gnuradio-examples/python/digital/transmit_path.py b/gnuradio-examples/python/digital/transmit_path.py index d8bdd039..4adf0577 100644 --- a/gnuradio-examples/python/digital/transmit_path.py +++ b/gnuradio-examples/python/digital/transmit_path.py @@ -1,5 +1,5 @@ # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, blks +from gnuradio import gr, gru, blks2 from gnuradio import usrp from gnuradio import eng_notation @@ -33,11 +33,14 @@ from pick_bitrate import pick_tx_bitrate # transmit path # ///////////////////////////////////////////////////////////////////////////// -class transmit_path(gr.hier_block): - def __init__(self, fg, modulator_class, options): +class transmit_path(gr.hier_block2): + def __init__(self, modulator_class, options): ''' See below for what options should hold ''' + gr.hier_block2.__init__(self, "transmit_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify @@ -77,12 +80,11 @@ class transmit_path(gr.hier_block): # transmitter self.packet_transmitter = \ - blks.mod_pkts(fg, - self._modulator_class(fg, **mod_kwargs), - access_code=None, - msgq_limit=4, - pad_for_usrp=True, - use_whitener_offset=options.use_whitener_offset) + blks2.mod_pkts(self._modulator_class(**mod_kwargs), + access_code=None, + msgq_limit=4, + pad_for_usrp=True, + use_whitener_offset=options.use_whitener_offset) # Set the USRP for maximum transmit gain @@ -100,8 +102,7 @@ class transmit_path(gr.hier_block): self._print_verbage() # Create and setup transmit path flow graph - fg.connect(self.packet_transmitter, self.amp, self.u) - gr.hier_block.__init__(self, fg, None, None) + self.connect(self.packet_transmitter, self.amp, self.u) def _setup_usrp_sink(self): """ diff --git a/gnuradio-examples/python/digital/transmit_path_lb.py b/gnuradio-examples/python/digital/transmit_path_lb.py index 322d46af..49f53076 100644 --- a/gnuradio-examples/python/digital/transmit_path_lb.py +++ b/gnuradio-examples/python/digital/transmit_path_lb.py @@ -1,5 +1,5 @@ # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, blks +from gnuradio import gr, gru, blks2 from gnuradio import eng_notation import copy @@ -29,11 +29,14 @@ import sys # transmit path # ///////////////////////////////////////////////////////////////////////////// -class transmit_path(gr.hier_block): - def __init__(self, fg, modulator_class, options): +class transmit_path(gr.hier_block2): + def __init__(self, modulator_class, options): ''' See below for what options should hold ''' + gr.hier_block2.__init__(self, "transmit_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify @@ -48,12 +51,14 @@ class transmit_path(gr.hier_block): mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) # transmitter + print self._modulator_class + print mod_kwargs + modulator = self._modulator_class(**mod_kwargs) self.packet_transmitter = \ - blks.mod_pkts(fg, - self._modulator_class(fg, **mod_kwargs), - access_code=None, - msgq_limit=4, - pad_for_usrp=True) + blks2.mod_pkts(modulator, + access_code=None, + msgq_limit=4, + pad_for_usrp=True) self.amp = gr.multiply_const_cc(1) self.set_tx_amplitude(self._tx_amplitude) @@ -63,9 +68,7 @@ class transmit_path(gr.hier_block): self._print_verbage() # Connect components in the flowgraph - fg.connect(self.packet_transmitter, self.amp) - - gr.hier_block.__init__(self, fg, None, self.amp) + self.connect(self.packet_transmitter, self.amp, self) def set_tx_amplitude(self, ampl): """ diff --git a/gnuradio-examples/python/digital/tunnel.py b/gnuradio-examples/python/digital/tunnel.py index 7d17ff95..111ed0db 100755 --- a/gnuradio-examples/python/digital/tunnel.py +++ b/gnuradio-examples/python/digital/tunnel.py @@ -86,14 +86,14 @@ def open_tun_interface(tun_device_filename): # the flow graph # ///////////////////////////////////////////////////////////////////////////// -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self, mod_class, demod_class, rx_callback, options): - gr.flow_graph.__init__(self) - self.txpath = transmit_path(self, mod_class, options) - self.rxpath = receive_path(self, demod_class, rx_callback, options) + gr.top_block.__init__(self) + self.txpath = transmit_path(mod_class, options) + self.rxpath = receive_path(demod_class, rx_callback, options) def send_pkt(self, payload='', eof=False): return self.txpath.send_pkt(payload, eof) @@ -123,10 +123,10 @@ class cs_mac(object): def __init__(self, tun_fd, verbose=False): self.tun_fd = tun_fd # file descriptor for TUN/TAP interface self.verbose = verbose - self.fg = None # flow graph (access to PHY) + self.tb = None # top block (access to PHY) - def set_flow_graph(self, fg): - self.fg = fg + def set_top_block(self, tb): + self.tb = tb def phy_rx_callback(self, ok, payload): """ @@ -152,20 +152,20 @@ class cs_mac(object): while 1: payload = os.read(self.tun_fd, 10*1024) if not payload: - self.fg.send_pkt(eof=True) + self.tb.send_pkt(eof=True) break if self.verbose: print "Tx: len(payload) = %4d" % (len(payload),) delay = min_delay - while self.fg.carrier_sensed(): + while self.tb.carrier_sensed(): sys.stderr.write('B') time.sleep(delay) if delay < 0.050: delay = delay * 2 # exponential back-off - self.fg.send_pkt(payload) + self.tb.send_pkt(payload) # ///////////////////////////////////////////////////////////////////////////// @@ -243,26 +243,26 @@ def main(): # build the graph (PHY) - fg = my_graph(mods[options.modulation], - demods[options.modulation], - mac.phy_rx_callback, - options) + tb = my_top_block(mods[options.modulation], + demods[options.modulation], + mac.phy_rx_callback, + options) - mac.set_flow_graph(fg) # give the MAC a handle for the PHY + mac.set_top_block(tb) # give the MAC a handle for the PHY - if fg.txpath.bitrate() != fg.rxpath.bitrate(): + if tb.txpath.bitrate() != tb.rxpath.bitrate(): print "WARNING: Transmit bitrate = %sb/sec, Receive bitrate = %sb/sec" % ( - eng_notation.num_to_str(fg.txpath.bitrate()), - eng_notation.num_to_str(fg.rxpath.bitrate())) + eng_notation.num_to_str(tb.txpath.bitrate()), + eng_notation.num_to_str(tb.rxpath.bitrate())) print "modulation: %s" % (options.modulation,) print "freq: %s" % (eng_notation.num_to_str(options.tx_freq)) - print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),) - print "samples/symbol: %3d" % (fg.txpath.samples_per_symbol(),) - #print "interp: %3d" % (fg.txpath.interp(),) - #print "decim: %3d" % (fg.rxpath.decim(),) + print "bitrate: %sb/sec" % (eng_notation.num_to_str(tb.txpath.bitrate()),) + print "samples/symbol: %3d" % (tb.txpath.samples_per_symbol(),) + #print "interp: %3d" % (tb.txpath.interp(),) + #print "decim: %3d" % (tb.rxpath.decim(),) - fg.rxpath.set_carrier_threshold(options.carrier_threshold) + tb.rxpath.set_carrier_threshold(options.carrier_threshold) print "Carrier sense threshold:", options.carrier_threshold, "dB" print @@ -275,12 +275,12 @@ def main(): print - fg.start() # Start executing the flow graph (runs in separate threads) + tb.start() # Start executing the flow graph (runs in separate threads) mac.main_loop() # don't expect this to return... - fg.stop() # but if it does, tell flow graph to stop. - fg.wait() # wait for it to finish + tb.stop() # but if it does, tell flow graph to stop. + tb.wait() # wait for it to finish if __name__ == '__main__': diff --git a/gnuradio-examples/python/digital/tx_voice.py b/gnuradio-examples/python/digital/tx_voice.py index 09b1c584..c97e2f08 100755 --- a/gnuradio-examples/python/digital/tx_voice.py +++ b/gnuradio-examples/python/digital/tx_voice.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -43,8 +43,11 @@ import fusb_options #raw_input('Attach and press enter') -class audio_rx(gr.hier_block): - def __init__(self, fg, audio_input_dev): +class audio_rx(gr.hier_block2): + def __init__(self, audio_input_dev): + gr.hier_block2.__init__(self, "audio_rx", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature sample_rate = 8000 src = audio.source(sample_rate, audio_input_dev) src_scale = gr.multiply_const_ff(32767) @@ -52,20 +55,20 @@ class audio_rx(gr.hier_block): voice_coder = gsm_full_rate.encode_sp() self.packets_from_encoder = gr.msg_queue() packet_sink = gr.message_sink(33, self.packets_from_encoder, False) - fg.connect(src, src_scale, f2s, voice_coder, packet_sink) - gr.hier_block.__init__(self, fg, src, packet_sink) + self.connect(src, src_scale, f2s, voice_coder, packet_sink) def get_encoded_voice_packet(self): return self.packets_from_encoder.delete_head() -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self, modulator_class, options): - gr.flow_graph.__init__(self) - self.txpath = transmit_path(self, modulator_class, options) - self.audio_rx = audio_rx(self, options.audio_input) - + gr.top_block.__init__(self) + self.txpath = transmit_path(modulator_class, options) + self.audio_rx = audio_rx(options.audio_input) + self.connect(self.txpath) + self.connect(self.audio_rx) # ///////////////////////////////////////////////////////////////////////////// @@ -75,7 +78,7 @@ class my_graph(gr.flow_graph): def main(): def send_pkt(payload='', eof=False): - return fg.txpath.send_pkt(payload, eof) + return tb.txpath.send_pkt(payload, eof) def rx_callback(ok, payload): print "ok = %r, payload = '%s'" % (ok, payload) @@ -115,14 +118,14 @@ def main(): # build the graph - fg = my_graph(mods[options.modulation], options) + tb = my_top_block(mods[options.modulation], options) r = gr.enable_realtime_scheduling() if r != gr.RT_OK: print "Warning: failed to enable realtime scheduling" - fg.start() # start flow graph + tb.start() # start flow graph # generate and send packets nbytes = int(1e6 * options.megabytes) @@ -130,7 +133,7 @@ def main(): pktno = 0 while nbytes == 0 or n < nbytes: - packet = fg.audio_rx.get_encoded_voice_packet() + packet = tb.audio_rx.get_encoded_voice_packet() s = packet.to_string() send_pkt(s) n += len(s) @@ -138,12 +141,12 @@ def main(): pktno += 1 send_pkt(eof=True) - fg.wait() # wait for it to finish - fg.txpath.set_auto_tr(False) + tb.wait() # wait for it to finish + tb.txpath.set_auto_tr(False) if __name__ == '__main__': try: main() except KeyboardInterrupt: - pass + pass \ No newline at end of file diff --git a/gnuradio-examples/python/digital_voice/cvsd_test.py b/gnuradio-examples/python/digital_voice/cvsd_test.py index 843201d6..f8f1b9cc 100755 --- a/gnuradio-examples/python/digital_voice/cvsd_test.py +++ b/gnuradio-examples/python/digital_voice/cvsd_test.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, blks +from gnuradio import gr, blks2 from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser @@ -41,25 +41,21 @@ def main(): parser.print_help() raise SystemExit, 1 - fg = gr.flow_graph() + tb = gr.top_block() src = audio.source(int(options.sample_rate), options.audio_input) - tx = blks.cvsd_encode(fg, options.resample_rate) + tx = blks2.cvsd_encode(options.resample_rate) # todo: add noise - rx = blks.cvsd_decode(fg, options.resample_rate) + rx = blks2.cvsd_decode(options.resample_rate) dst = audio.sink(int(options.sample_rate), options.audio_output) - fg.connect(src, tx, rx, dst) + tb.connect(src, tx, rx, dst) + tb.run() - fg.start() - - raw_input ('Press Enter to exit: ') - fg.stop() - - if __name__ == '__main__': + print "Enter CTRL-C to exit" try: main() except KeyboardInterrupt: diff --git a/gnuradio-examples/python/digital_voice/encdec.py b/gnuradio-examples/python/digital_voice/encdec.py index a2e9d1e4..e87d57e2 100755 --- a/gnuradio-examples/python/digital_voice/encdec.py +++ b/gnuradio-examples/python/digital_voice/encdec.py @@ -20,15 +20,15 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, blks +from gnuradio import gr, blks2 from gnuradio import audio from gnuradio.eng_option import eng_option from optparse import OptionParser -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-I", "--audio-input", type="string", default="", @@ -42,10 +42,10 @@ class my_graph(gr.flow_graph): sample_rate = 8000 src = audio.source(sample_rate, options.audio_input) - tx = blks.digital_voice_tx(self) + tx = blks2.digital_voice_tx(self) if_gain = gr.multiply_const_cc(10000) # channel simulator here... - rx = blks.digital_voice_rx(self) + rx = blks2.digital_voice_rx(self) dst = audio.sink(sample_rate, options.audio_output) self.connect(src, tx, if_gain, rx, dst) @@ -53,6 +53,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/hier/Makefile.am b/gnuradio-examples/python/hier/Makefile.am deleted file mode 100644 index 10bda3b4..00000000 --- a/gnuradio-examples/python/hier/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2006 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. -# - -SUBDIRS = \ - audio \ - dect \ - digital \ - ofdm \ - networking \ - sounder \ - usrp diff --git a/gnuradio-examples/python/hier/audio/Makefile.am b/gnuradio-examples/python/hier/audio/Makefile.am deleted file mode 100644 index 34538d18..00000000 --- a/gnuradio-examples/python/hier/audio/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2006 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. -# - -EXTRA_DIST = \ - dial_tone2.py diff --git a/gnuradio-examples/python/hier/audio/dial_tone2.py b/gnuradio-examples/python/hier/audio/dial_tone2.py deleted file mode 100755 index 70d1e53d..00000000 --- a/gnuradio-examples/python/hier/audio/dial_tone2.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2006 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 -from gnuradio import audio -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -# Top-level block creating a dial tone -# Derives from new class gr.hier_block2 -class dial_tone(gr.top_block): - def __init__(self, - sample_rate, # Audio output sample rate (int) - audio_output, # Audio output device - amplitude): # Output volume (0.0-1.0) - - gr.top_block.__init__(self, "dial_tone") - - src0 = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, 350, amplitude) - src1 = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, 440, amplitude) - dst = audio.sink(sample_rate, audio_output) - - self.connect(src0, (dst, 0)) - self.connect(src1, (dst, 1)) - -if __name__ == '__main__': - parser = OptionParser(option_class=eng_option) - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm output device name. E.g., hw:0,0 or /dev/dsp") - parser.add_option("-r", "--sample-rate", type="eng_float", default=48000, - help="set sample rate to RATE (48000)") - parser.add_option("-a", "--amplitude", type="eng_float", default=0.1, - help="set output volume to AMPLITUDE (0.1)") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - # Create an instance of a hierarchical block - top = dial_tone(int(options.sample_rate), - options.audio_output, - options.amplitude) - - try: - # Run forever - top.run() - except KeyboardInterrupt: - # Ctrl-C exits - pass diff --git a/gnuradio-examples/python/hier/dect/gmsk2.py b/gnuradio-examples/python/hier/dect/gmsk2.py deleted file mode 100644 index f26c5665..00000000 --- a/gnuradio-examples/python/hier/dect/gmsk2.py +++ /dev/null @@ -1,278 +0,0 @@ -# -# GMSK modulation and demodulation. -# -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -from gnuradio import gr -from gnuradio import modulation_utils -from math import pi -import numpy -from pprint import pprint -import inspect - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_bt = 0.35 -_def_verbose = False -_def_log = False - -_def_gain_mu = 0.05 -_def_mu = 0.5 -_def_freq_error = 0.0 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk2_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - bt=_def_bt, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param bt: Gaussian filter bandwidth * symbol time - @type bt: float - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - gr.hier_block2.__init__(self, - "gmsk2_mod", # Block typename - gr.io_signature(1,1,gr.sizeof_char), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._bt = bt - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) - - ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once - sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 - - # Turn it into NRZ data. - self.nrz = gr.bytes_to_syms() - - # Form Gaussian filter - # Generate Gaussian response (Needs to be convolved with window below). - self.gaussian_taps = gr.firdes.gaussian( - 1, # gain - samples_per_symbol, # symbol_rate - bt, # bandwidth * symbol time - ntaps # number of taps - ) - - self.sqwave = (1,) * samples_per_symbol # rectangular window - self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) - self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) - - # FM modulation - self.fmmod = gr.frequency_modulator_fc(sensitivity) - - if verbose: - self._print_verbage() - - self.connect(self, self.nrz, self.gaussian_filter, self.fmmod, self) - - if log: - self._setup_logging() - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gaussian filter bt = %.2f" % self._bt - - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.nrz, gr.file_sink(gr.sizeof_float, "nrz.dat")) - self.connect(self.gaussian_filter, gr.file_sink(gr.sizeof_float, "gaussian_filter.dat")) - self.connect(self.fmmod, gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) - - def add_options(parser): - """ - Adds GMSK modulation-specific options to the standard parser - """ - parser.add_option("", "--bt", type="float", default=_def_bt, - help="set bandwidth-time product [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - # FIXME: figure out what has to change for gr.hier_block2 version - #def extract_kwargs_from_options(options): - # """ - # Given command line options, create dictionary suitable for passing to __init__ - # """ - # return modulation_utils.extract_kwargs_from_options(gmsk_mod.__init__, - # ('self', 'fg'), options) - #extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK demodulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk2_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - freq_error=_def_freq_error, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - demodulation. - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (the LSB) - - @param samples_per_symbol: samples per baud - @type samples_per_symbol: integer - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - - Clock recovery parameters. These all have reasonble defaults. - - @param gain_mu: controls rate of mu adjustment - @type gain_mu: float - @param mu: fractional delay [0.0, 1.0] - @type mu: float - @param omega_relative_limit: sets max variation in omega - @type omega_relative_limit: float, typically 0.000200 (200 ppm) - @param freq_error: bit rate error as a fraction - @param float - """ - - gr.hier_block2.__init__(self, - "gmsk2_demod", # Block typename - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_char)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._gain_mu = gain_mu - self._mu = mu - self._omega_relative_limit = omega_relative_limit - self._freq_error = freq_error - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol - - self._omega = samples_per_symbol*(1+self._freq_error) - - self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped - - # Demodulate FM - sensitivity = (pi / 2) / samples_per_symbol - self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) - - # the clock recovery block tracks the symbol clock and resamples as needed. - # the output of the block is a stream of soft symbols (float) - self.clock_recovery = gr.clock_recovery_mm_ff(self._omega, self._gain_omega, - self._mu, self._gain_mu, - self._omega_relative_limit) - - # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample - self.slicer = gr.binary_slicer_fb() - - if verbose: - self._print_verbage() - - self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self) - - if log: - self._setup_logging() - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "M&M clock recovery omega = %f" % self._omega - print "M&M clock recovery gain mu = %f" % self._gain_mu - print "M&M clock recovery mu = %f" % self._mu - print "M&M clock recovery omega rel. limit = %f" % self._omega_relative_limit - print "frequency error = %f" % self._freq_error - - - def _setup_logging(self): - print "Demodulation logging turned on." - self.connect(fmdemod, gr.file_sink(gr.sizeof_float, "fmdemod.dat")) - self.connect(clock_recovery, gr.file_sink(gr.sizeof_float, "clock_recovery.dat")) - self.connect(slicer, gr.file_sink(gr.sizeof_char, "slicer.dat")) - - def add_options(parser): - """ - Adds GMSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="M&M clock recovery gain mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="M&M clock recovery mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--omega-relative-limit", type="float", default=_def_omega_relative_limit, - help="M&M clock recovery omega relative limit [default=%default] (GMSK/PSK)") - parser.add_option("", "--freq-error", type="float", default=_def_freq_error, - help="M&M clock recovery frequency error [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - # FIXME: figure out what this is for gr.hier_block2 version - #def extract_kwargs_from_options(options): - # """ - # Given command line options, create dictionary suitable for passing to __init__ - # """ - # return modulation_utils.extract_kwargs_from_options(gmsk_demod.__init__, - # ('self', 'fg'), options) - #extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('gmsk2', gmsk2_mod) -modulation_utils.add_type_1_demod('gmsk2', gmsk2_demod) diff --git a/gnuradio-examples/python/hier/digital/Makefile.am b/gnuradio-examples/python/hier/digital/Makefile.am deleted file mode 100644 index 35824b13..00000000 --- a/gnuradio-examples/python/hier/digital/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright 2004 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. -# - -EXTRA_DIST = \ - README \ - benchmark_loopback.py \ - benchmark_rx.py \ - benchmark_tx.py \ - fusb_options.py \ - pick_bitrate.py \ - receive_path.py \ - receive_path_lb.py \ - rx_voice.py \ - transmit_path.py \ - transmit_path_lb.py \ - tunnel.py \ - tx_voice.py - -MOSTLYCLEANFILES = *~ *.pyc *.dat diff --git a/gnuradio-examples/python/hier/digital/README b/gnuradio-examples/python/hier/digital/README deleted file mode 100644 index 9d8a4049..00000000 --- a/gnuradio-examples/python/hier/digital/README +++ /dev/null @@ -1,77 +0,0 @@ -Quick overview of what's here: - -* benchmark_tx.py: generates packets of the size you -specify and sends them across the air using the USRP. Known to work -well using the USRP with the RFX transceiver daughterboards. -You can specify the bitrate to use with the -r command line -parameter. The default is 500k. Some machines will do 1M or more. -You can select the modulation to use with the -m command -line argument. The legal values for are gmsk, dbpsk and dqpsk. - -* benchmark_rx.py: the receiver half of benchmark_tx.py. -Command line arguments are pretty much the same as rx. Works well -with a USRP and RFX transceiver daughterboards. Will also work -with TVRX daugherboard, but you'll need to fiddle with the gain. See -below. Prints a summary of each packet received and keeps a running -total of packets received, and how many of them were error free. -There are two levels of error reporting going on. If the access code -(PN code) and header of a packet were properly detected, then you'll -get an output line. If the CRC32 of the payload was correct you get -"ok = True", else "ok = False". The "pktno" is extracted from the -received packet. If there are skipped numbers, you're missing some -packets. Be sure you've got a suitable antenna connected to the TX/RX -port on each board. For the RFX-400, "70 cm" / 420 MHz antennas for ham -handi-talkies work great. These are available at ham radio supplies, -etc. The boards need to be at least 3m apart. You can also try -experimenting with the rx gain (-g command line option). - -Generally speaking, I start the rx first on one machine, and then fire -up the tx on the other machine. The tx also supports a discontinous -transmission mode where it sends bursts of 5 packets and then waits 1 -second. This is useful for ensuring that all the receiver control -loops lock up fast enough. - -* tunnel.py: This program provides a framework for building your own -MACs. It creates a "TAP" interface in the kernel, typically gr0, -and sends and receives ethernet frames through it. See -/usr/src/linux/Documentation/networking/tuntap.txt and/or Google for -"universal tun tap". The Linux 2.6 kernel includes the tun module, you -don't have to build it. You may have to "modprobe tun" if it's not -loaded by default. If /dev/net/tun doesn't exist, try "modprobe tun". - -To run this program you'll need to be root or running with the -appropriate capability to open the tun interface. You'll need to fire -up two copies on different machines. Once each is running you'll need -to ifconfig the gr0 interface to set the IP address. - -This will allow two machines to talk, but anything beyond the two -machines depends on your networking setup. Left as an exercise... - -On machine A: - - $ su - # ./tunnel.py --freq 423.0M --bitrate 500k - # # in another window on A, also as root... - # ifconfig gr0 192.168.200.1 - - -On machine B: - - $ su - # ./tunnel.py --freq 423.0M --bitrate 500k - # # in another window on B, also as root... - # ifconfig gr0 192.168.200.2 - -Now, on machine A you shold be able to ping machine B: - - $ ping 192.168.200.2 - -and you should see some output for each packet in the -tunnel.py window if you used the -v option. - -Likewise, on machine B: - - $ ping 192.168.200.1 - -This now uses a carrier sense MAC, so you should be able to ssh -between the machines, web browse, etc. diff --git a/gnuradio-examples/python/hier/digital/benchmark_loopback.py b/gnuradio-examples/python/hier/digital/benchmark_loopback.py deleted file mode 100755 index 31dfb991..00000000 --- a/gnuradio-examples/python/hier/digital/benchmark_loopback.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/env python -#!/usr/bin/env python -# -# Copyright 2005, 2006,2007 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, gru, modulation_utils -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random, time, struct, sys, math - -# from current dir -from transmit_path_lb import transmit_path -from receive_path_lb import receive_path -import fusb_options - -class awgn_channel(gr.hier_block2): - def __init__(self, sample_rate, noise_voltage, frequency_offset, seed=False): - gr.hier_block2.__init__(self, "awgn_channel", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature - - # Create the Gaussian noise source - if not seed: - self.noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_voltage) - else: - rseed = int(time.time()) - self.noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_voltage, rseed) - self.adder = gr.add_cc() - - # Create the frequency offset - self.offset = gr.sig_source_c((sample_rate*1.0), gr.GR_SIN_WAVE, frequency_offset, 1.0, 0.0) - self.mixer = gr.multiply_cc() - - # Connect the components - self.connect(self, (self.mixer, 0)) - self.connect(self.offset, (self.mixer, 1)) - self.connect(self.mixer, (self.adder, 0)) - self.connect(self.noise, (self.adder, 1)) - self.connect(self.adder, self) - - -class my_graph(gr.top_block): - def __init__(self, mod_class, demod_class, rx_callback, options): - gr.top_block.__init__(self, "my_graph") - - channelon = True; - - SNR = 10.0**(options.snr/10.0) - frequency_offset = options.frequency_offset - - power_in_signal = abs(options.tx_amplitude)**2 - noise_power = power_in_signal/SNR - noise_voltage = math.sqrt(noise_power) - - self.txpath = transmit_path(mod_class, options) - self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate) - self.rxpath = receive_path(demod_class, rx_callback, options) - - if channelon: - self.channel = awgn_channel(options.sample_rate, noise_voltage, frequency_offset, options.seed) - self.connect(self.txpath, self.throttle, self.channel, self.rxpath) - else: - self.connect(self.txpath, self.throttle, self.rxpath) - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - def send_pkt(payload='', eof=False): - return top_block.txpath.send_pkt(payload, eof) - - - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - channel_grp = parser.add_option_group("Channel") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='dbpsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - - channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5, - help="set speed of channel/simulation rate to RATE [default=%default]") - channel_grp.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0, - help="set frequency offset introduced by channel [default=%default]") - channel_grp.add_option("", "--seed", action="store_true", default=False, - help="use a random seed for AWGN noise [default=%default]") - - transmit_path.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - for demod in demods.values(): - demod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - # Create an instance of a hierarchical block - top_block = my_graph(mods[options.modulation], demods[options.modulation], rx_callback, options) - top_block.start() - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - pkt_size = int(options.size) - - while n < nbytes: - send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff)) - n += pkt_size - if options.discontinuous and pktno % 5 == 4: - time.sleep(1) - pktno += 1 - - send_pkt(eof=True) - - top_block.wait() - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/digital/benchmark_rx.py b/gnuradio-examples/python/hier/digital/benchmark_rx.py deleted file mode 100755 index c92d487b..00000000 --- a/gnuradio-examples/python/hier/digital/benchmark_rx.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random -import struct -import sys - -# from current dir -from receive_path import receive_path -import fusb_options - -#import os -#print os.getpid() -#raw_input('Attach and press enter: ') - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - demods = modulation_utils.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - - receive_path.add_options(parser, expert_grp) - - for mod in demods.values(): - mod.add_options(expert_grp) - - fusb_options.add_options(expert_grp) - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - # Create an instance of a hierarchical block - top_block = receive_path(demods[options.modulation], rx_callback, options) - top_block.run() - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/digital/benchmark_tx.py b/gnuradio-examples/python/hier/digital/benchmark_tx.py deleted file mode 100755 index 752cdff5..00000000 --- a/gnuradio-examples/python/hier/digital/benchmark_tx.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005, 2006,2007 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random, time, struct, sys - -# from current dir -from transmit_path import transmit_path -import fusb_options - -#import os -#print os.getpid() -#raw_input('Attach and press enter') - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - def send_pkt(payload='', eof=False): - return top_block.send_pkt(payload, eof) - - def rx_callback(ok, payload): - print "ok = %r, payload = '%s'" % (ok, payload) - - mods = modulation_utils.type_1_mods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - - transmit_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - - fusb_options.add_options(expert_grp) - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.tx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - # Create an instance of a hierarchical block - top_block = transmit_path(mods[options.modulation], options) - top_block.start() - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - pkt_size = int(options.size) - - while n < nbytes: - send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff)) - n += pkt_size - sys.stderr.write('.') - if options.discontinuous and pktno % 5 == 4: - time.sleep(1) - pktno += 1 - - send_pkt(eof=True) - top_block.wait() - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/digital/fusb_options.py b/gnuradio-examples/python/hier/digital/fusb_options.py deleted file mode 100644 index 153e06be..00000000 --- a/gnuradio-examples/python/hier/digital/fusb_options.py +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright 2006 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. -# - -def add_options(parser): - """ - Add Fast USB specifc options to command line parser. - - @param parser: instance of OptionParser - """ - parser.add_option("-B", "--fusb-block-size", type="int", default=0, - help="specify fast usb block size [default=%default]") - parser.add_option("-N", "--fusb-nblocks", type="int", default=0, - help="specify number of fast usb blocks [default=%default]") diff --git a/gnuradio-examples/python/hier/digital/pick_bitrate.py b/gnuradio-examples/python/hier/digital/pick_bitrate.py deleted file mode 100644 index 82a47688..00000000 --- a/gnuradio-examples/python/hier/digital/pick_bitrate.py +++ /dev/null @@ -1,143 +0,0 @@ -# -# Copyright 2005,2006 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_bitrate = 500e3 - -_valid_samples_per_symbol = (2,3,4,5,6,7) - -def _gen_tx_info(converter_rate): - results = [] - for samples_per_symbol in _valid_samples_per_symbol: - for interp in range(16, 512 + 1, 4): - bitrate = converter_rate / interp / samples_per_symbol - results.append((bitrate, samples_per_symbol, interp)) - results.sort() - return results - -def _gen_rx_info(converter_rate): - results = [] - for samples_per_symbol in _valid_samples_per_symbol: - for decim in range(8, 256 + 1, 2): - bitrate = converter_rate / decim / samples_per_symbol - results.append((bitrate, samples_per_symbol, decim)) - results.sort() - return results - -def _filter_info(info, samples_per_symbol, xrate): - if samples_per_symbol is not None: - info = [x for x in info if x[1] == samples_per_symbol] - if xrate is not None: - info = [x for x in info if x[2] == xrate] - return info - -def _pick_best(target_bitrate, bits_per_symbol, info): - """ - @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) - """ - if len(info) == 0: - raise RuntimeError, "info is zero length!" - - if target_bitrate is None: # return the fastest one - return info[-1] - - # convert bit rate to symbol rate - target_symbolrate = target_bitrate / bits_per_symbol - - # Find the closest matching symbol rate. - # In the event of a tie, the one with the lowest samples_per_symbol wins. - # (We already sorted them, so the first one is the one we take) - - best = info[0] - best_delta = abs(target_symbolrate - best[0]) - for x in info[1:]: - delta = abs(target_symbolrate - x[0]) - if delta < best_delta: - best_delta = delta - best = x - - # convert symbol rate back to bit rate - return ((best[0] * bits_per_symbol),) + best[1:] - -def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - xrate, converter_rate, gen_info): - """ - @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) - """ - if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1: - raise ValueError, "bits_per_symbol must be an int >= 1" - - if samples_per_symbol is not None and xrate is not None: # completely determined - return (float(converter_rate) / xrate / samples_per_symbol, - samples_per_symbol, xrate) - - if bitrate is None and samples_per_symbol is None and xrate is None: - bitrate = _default_bitrate - - # now we have a target bitrate and possibly an xrate or - # samples_per_symbol constraint, but not both of them. - - return _pick_best(bitrate, bits_per_symbol, - _filter_info(gen_info(converter_rate), samples_per_symbol, xrate)) - -# --------------------------------------------------------------------------------------- - -def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate=128e6): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param interp_rate: USRP interpolation factor - @type interp_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - - @returns tuple (bitrate, samples_per_symbol, interp_rate) - """ - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate, _gen_tx_info) - - -def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate=64e6): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param decim_rate: USRP decimation factor - @type decim_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - - @returns tuple (bitrate, samples_per_symbol, decim_rate) - """ - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate, _gen_rx_info) diff --git a/gnuradio-examples/python/hier/digital/receive_path.py b/gnuradio-examples/python/hier/digital/receive_path.py deleted file mode 100644 index 917ed1aa..00000000 --- a/gnuradio-examples/python/hier/digital/receive_path.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007 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, gru, blks2 -from gnuradio import usrp -from gnuradio import eng_notation -import copy -import sys - -# from current dir -from pick_bitrate import pick_rx_bitrate - -# ///////////////////////////////////////////////////////////////////////////// -# receive path -# ///////////////////////////////////////////////////////////////////////////// - -class receive_path(gr.top_block): - def __init__(self, demod_class, rx_callback, options): - gr.top_block.__init__(self, "receive_path") - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._rx_freq = options.rx_freq # receiver's center frequency - self._rx_gain = options.rx_gain # receiver's gain - self._rx_subdev_spec = options.rx_subdev_spec # daughterboard to use - self._bitrate = options.bitrate # desired bit rate - self._decim = options.decim # Decimating rate for the USRP (prelim) - self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol - self._fusb_block_size = options.fusb_block_size # usb info for USRP - self._fusb_nblocks = options.fusb_nblocks # usb info for USRP - - self._rx_callback = rx_callback # this callback is fired when there's a packet available - self._demod_class = demod_class # the demodulator_class we're using - - if self._rx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") - raise SystemExit - - # Set up USRP source; also adjusts decim, samples_per_symbol, and bitrate - self._setup_usrp_source() - - g = self.subdev.gain_range() - if options.show_rx_gain_range: - print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g" \ - % (g[0], g[1], g[2]) - - self.set_gain(options.rx_gain) - - self.set_auto_tr(True) # enable Auto Transmit/Receive switching - - # Set RF frequency - ok = self.set_freq(self._rx_freq) - if not ok: - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq)) - raise ValueError, eng_notation.num_to_str(self._rx_freq) - - # copy the final answers back into options for use by demodulator - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - options.decim = self._decim - - # Get demod_kwargs - demod_kwargs = self._demod_class.extract_kwargs_from_options(options) - - # Design filter to get actual channel we want - sw_decim = 1 - chan_coeffs = gr.firdes.low_pass (1.0, # gain - sw_decim * self._samples_per_symbol, # sampling rate - 1.0, # midpoint of trans. band - 0.5, # width of trans. band - gr.firdes.WIN_HANN) # filter type - - # Decimating channel filter - # complex in and out, float taps - self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs) - #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs) - # receiver - self.packet_receiver = \ - blks2.demod_pkts(self._demod_class(**demod_kwargs), - access_code=None, - callback=self._rx_callback, - threshold=-1) - - # Carrier Sensing Blocks - alpha = 0.001 - thresh = 30 # in dB, will have to adjust - self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs) - - # connect the channel input filter to the carrier power detector - self.connect(self.u, self.channel_filter, self.probe) - - # connect channel filter to the packet receiver - self.connect(self.channel_filter, self.packet_receiver) - - - def _setup_usrp_source(self): - self.u = usrp.source_c (fusb_block_size=self._fusb_block_size, - fusb_nblocks=self._fusb_nblocks) - adc_rate = self.u.adc_rate() - - # derive values of bitrate, samples_per_symbol, and decim from desired info - (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(self._bitrate, self._demod_class.bits_per_symbol(), \ - self._samples_per_symbol, self._decim, adc_rate) - - self.u.set_decim_rate(self._decim) - - # determine the daughterboard subdevice we're using - if self._rx_subdev_spec is None: - self._rx_subdev_spec = usrp.pick_rx_subdevice(self.u) - self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec)) - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. - """ - r = self.u.tune(0, self.subdev, target_freq) - if r: - return True - - return False - - def set_gain(self, gain): - """ - Sets the analog gain in the USRP - """ - if gain is None: - r = self.subdev.gain_range() - gain = (r[0] + r[1])/2 # set gain to midpoint - self.gain = gain - return self.subdev.set_gain(gain) - - def set_auto_tr(self, enable): - return self.subdev.set_auto_tr(enable) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def decim(self): - return self._decim - - def carrier_sensed(self): - """ - Return True if we think carrier is present. - """ - #return self.probe.level() > X - return self.probe.unmuted() - - def carrier_threshold(self): - """ - Return current setting in dB. - """ - return self.probe.threshold() - - def set_carrier_threshold(self, threshold_in_db): - """ - Set carrier threshold. - - @param threshold_in_db: set detection threshold - @type threshold_in_db: float (dB) - """ - self.probe.set_threshold(threshold_in_db) - - - def add_options(normal, expert): - """ - Adds receiver-specific options to the Options Parser - """ - add_freq_option(normal) - if not normal.has_option("--bitrate"): - normal.add_option("-r", "--bitrate", type="eng_float", default=None, - help="specify bitrate. samples-per-symbol and interp/decim will be derived.") - normal.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B") - normal.add_option("", "--rx-gain", type="eng_float", default=None, metavar="GAIN", - help="set receiver gain in dB [default=midpoint]. See also --show-rx-gain-range") - normal.add_option("", "--show-rx-gain-range", action="store_true", default=False, - help="print min and max Rx gain available on selected daughterboard") - normal.add_option("-v", "--verbose", action="store_true", default=False) - expert.add_option("-S", "--samples-per-symbol", type="int", default=None, - help="set samples/symbol [default=%default]") - expert.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - expert.add_option("-d", "--decim", type="intx", default=None, - help="set fpga decimation rate to DECIM [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to files (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - - def _print_verbage(self): - """ - Prints information about the receive path - """ - print "\nReceive Path:" - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - print "Rx gain: %g" % (self.gain,) - print "modulation: %s" % (self._demod_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) - print "decim: %3d" % (self._decim) - print "Rx Frequency: %s" % (eng_notation.num_to_str(self._rx_freq)) - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") diff --git a/gnuradio-examples/python/hier/digital/receive_path_lb.py b/gnuradio-examples/python/hier/digital/receive_path_lb.py deleted file mode 100644 index 1138f4c8..00000000 --- a/gnuradio-examples/python/hier/digital/receive_path_lb.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006 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, gru, blks2 -from gnuradio import eng_notation -import copy -import sys - -# ///////////////////////////////////////////////////////////////////////////// -# receive path -# ///////////////////////////////////////////////////////////////////////////// - -class receive_path(gr.hier_block2): - def __init__(self, demod_class, rx_callback, options): - gr.hier_block2.__init__(self, "receive_path", - gr.io_signature(1,1,gr.sizeof_gr_complex), # Input signature - gr.io_signature(0,0,0)) # Output signature - - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._bitrate = options.bitrate # desired bit rate - self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol - - self._rx_callback = rx_callback # this callback is fired when there's a packet available - self._demod_class = demod_class # the demodulator_class we're using - - # Get demod_kwargs - demod_kwargs = self._demod_class.extract_kwargs_from_options(options) - - # Design filter to get actual channel we want - sw_decim = 1 - chan_coeffs = gr.firdes.low_pass (1.0, # gain - sw_decim * self._samples_per_symbol, # sampling rate - 1.0, # midpoint of trans. band - 0.5, # width of trans. band - gr.firdes.WIN_HANN) # filter type - - # receiver - self.packet_receiver = \ - blks2.demod_pkts(self._demod_class(**demod_kwargs), - access_code=None, - callback=self._rx_callback, - threshold=-1) - - # Carrier Sensing Blocks - alpha = 0.001 - thresh = 30 # in dB, will have to adjust - self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs) - - # connect the channel input filter to the carrier power detector - self.connect(self, self.channel_filter, self.probe) - - # connect channel filter to the packet receiver - self.connect(self.channel_filter, self.packet_receiver) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def carrier_sensed(self): - """ - Return True if we think carrier is present. - """ - #return self.probe.level() > X - return self.probe.unmuted() - - def carrier_threshold(self): - """ - Return current setting in dB. - """ - return self.probe.threshold() - - def set_carrier_threshold(self, threshold_in_db): - """ - Set carrier threshold. - - @param threshold_in_db: set detection threshold - @type threshold_in_db: float (dB) - """ - self.probe.set_threshold(threshold_in_db) - - - def add_options(normal, expert): - """ - Adds receiver-specific options to the Options Parser - """ - if not normal.has_option("--bitrate"): - normal.add_option("-r", "--bitrate", type="eng_float", default=100e3, - help="specify bitrate [default=%default].") - normal.add_option("", "--show-rx-gain-range", action="store_true", default=False, - help="print min and max Rx gain available on selected daughterboard") - normal.add_option("-v", "--verbose", action="store_true", default=False) - expert.add_option("-S", "--samples-per-symbol", type="int", default=2, - help="set samples/symbol [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to files (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - - def _print_verbage(self): - """ - Prints information about the receive path - """ - print "modulation: %s" % (self._demod_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) diff --git a/gnuradio-examples/python/hier/digital/rx_voice.py b/gnuradio-examples/python/hier/digital/rx_voice.py deleted file mode 100755 index c9c33c3d..00000000 --- a/gnuradio-examples/python/hier/digital/rx_voice.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import audio -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -from gnuradio.vocoder import gsm_full_rate - -import random -import struct - -# from current dir -from receive_path import receive_path -import fusb_options - -#import os -#print os.getpid() -#raw_input('Attach and press enter') - - -class audio_tx(gr.hier_block): - def __init__(self, fg, audio_output_dev): - self.packet_src = gr.message_source(33) - voice_decoder = gsm_full_rate.decode_ps() - s2f = gr.short_to_float () - sink_scale = gr.multiply_const_ff(1.0/32767.) - audio_sink = audio.sink(8000, audio_output_dev) - fg.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink) - gr.hier_block.__init__(self, fg, self.packet_src, audio_sink) - - def msgq(self): - return self.packet_src.msgq() - - -class my_graph(gr.flow_graph): - - def __init__(self, demod_class, rx_callback, options): - gr.flow_graph.__init__(self) - self.rxpath = receive_path(self, demod_class, rx_callback, options) - self.audio_tx = audio_tx(self, options.audio_output) - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - n_rcvd += 1 - if ok: - n_right += 1 - - fg.audio_tx.msgq().insert_tail(gr.message_from_string(payload)) - - print "ok = %r n_rcvd = %4d n_right = %4d" % ( - ok, n_rcvd, n_right) - - demods = modulation_utils.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm output device name. E.g., hw:0,0 or /dev/dsp") - - receive_path.add_options(parser, expert_grp) - - for mod in demods.values(): - mod.add_options(expert_grp) - - fusb_options.add_options(expert_grp) - - parser.set_defaults(bitrate=50e3) # override default bitrate default - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - fg = my_graph(demods[options.modulation], rx_callback, options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - fg.start() # start flow graph - fg.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/digital/transmit_path.py b/gnuradio-examples/python/hier/digital/transmit_path.py deleted file mode 100644 index 18fecd3d..00000000 --- a/gnuradio-examples/python/hier/digital/transmit_path.py +++ /dev/null @@ -1,229 +0,0 @@ -# -# Copyright 2005,2006,2007 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, gru, blks2 -from gnuradio import usrp -from gnuradio import eng_notation - -import copy -import sys - -# from current dir -from pick_bitrate import pick_tx_bitrate - -# ///////////////////////////////////////////////////////////////////////////// -# transmit path -# ///////////////////////////////////////////////////////////////////////////// - -class transmit_path(gr.top_block): - def __init__(self, modulator_class, options): - ''' - See below for what options should hold - ''' - - gr.top_block.__init__(self, "transmit_path") - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._tx_freq = options.tx_freq # tranmitter's center frequency - self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP - self._tx_subdev_spec = options.tx_subdev_spec # daughterboard to use - self._bitrate = options.bitrate # desired bit rate - self._interp = options.interp # interpolating rate for the USRP (prelim) - self._samples_per_symbol = options.samples_per_symbol # desired samples/baud - self._fusb_block_size = options.fusb_block_size # usb info for USRP - self._fusb_nblocks = options.fusb_nblocks # usb info for USRP - - self._modulator_class = modulator_class # the modulator_class we are using - - if self._tx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n") - raise SystemExit - - # Set up USRP sink; also adjusts interp, samples_per_symbol, and bitrate - self._setup_usrp_sink() - - # copy the final answers back into options for use by modulator - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - options.interp = self._interp - - # Get mod_kwargs - mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) - - # Set center frequency of USRP - ok = self.set_freq(self._tx_freq) - if not ok: - print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(self._tx_freq),) - raise ValueError - - # transmitter - self.packet_transmitter = \ - blks2.mod_pkts(self._modulator_class(**mod_kwargs), - access_code=None, - msgq_limit=4, - pad_for_usrp=True) - - # Set the USRP for maximum transmit gain - # (Note that on the RFX cards this is a nop.) - self.set_gain(self.subdev.gain_range()[0]) - - self.amp = gr.multiply_const_cc(1) - self.set_tx_amplitude(self._tx_amplitude) - - # enable Auto Transmit/Receive switching - self.set_auto_tr(True) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - self.connect(self.packet_transmitter, self.amp, self.u) - - def _setup_usrp_sink(self): - """ - Creates a USRP sink, determines the settings for best bitrate, - and attaches to the transmitter's subdevice. - """ - self.u = usrp.sink_c(fusb_block_size=self._fusb_block_size, - fusb_nblocks=self._fusb_nblocks) - dac_rate = self.u.dac_rate(); - - # derive values of bitrate, samples_per_symbol, and interp from desired info - (self._bitrate, self._samples_per_symbol, self._interp) = \ - pick_tx_bitrate(self._bitrate, self._modulator_class.bits_per_symbol(), - self._samples_per_symbol, self._interp, dac_rate) - - self.u.set_interp_rate(self._interp) - - # determine the daughterboard subdevice we're using - if self._tx_subdev_spec is None: - self._tx_subdev_spec = usrp.pick_tx_subdevice(self.u) - self.u.set_mux(usrp.determine_tx_mux_value(self.u, self._tx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, self._tx_subdev_spec) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. - """ - r = self.u.tune(self.subdev._which, self.subdev, target_freq) - if r: - return True - - return False - - def set_gain(self, gain): - """ - Sets the analog gain in the USRP - """ - self.gain = gain - self.subdev.set_gain(gain) - - def set_tx_amplitude(self, ampl): - """ - Sets the transmit amplitude sent to the USRP - @param: ampl 0 <= ampl < 32768. Try 8000 - """ - self._tx_amplitude = max(0.0, min(ampl, 32767.0)) - self.amp.set_k(self._tx_amplitude) - - def set_auto_tr(self, enable): - """ - Turns on auto transmit/receive of USRP daughterboard (if exits; else ignored) - """ - return self.subdev.set_auto_tr(enable) - - def send_pkt(self, payload='', eof=False): - """ - Calls the transmitter method to send a packet - """ - return self.packet_transmitter.send_pkt(payload, eof) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def interp(self): - return self._interp - - def add_options(normal, expert): - """ - Adds transmitter-specific options to the Options Parser - """ - add_freq_option(normal) - if not normal.has_option('--bitrate'): - normal.add_option("-r", "--bitrate", type="eng_float", default=None, - help="specify bitrate. samples-per-symbol and interp/decim will be derived.") - normal.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, - help="select USRP Tx side A or B") - normal.add_option("", "--tx-amplitude", type="eng_float", default=12000, metavar="AMPL", - help="set transmitter digital amplitude: 0 <= AMPL < 32768 [default=%default]") - normal.add_option("-v", "--verbose", action="store_true", default=False) - - expert.add_option("-S", "--samples-per-symbol", type="int", default=None, - help="set samples/symbol [default=%default]") - expert.add_option("", "--tx-freq", type="eng_float", default=None, - help="set transmit frequency to FREQ [default=%default]", metavar="FREQ") - expert.add_option("-i", "--interp", type="intx", default=None, - help="set fpga interpolation rate to INTERP [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to file (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - def _print_verbage(self): - """ - Prints information about the transmit path - """ - print "Using TX d'board %s" % (self.subdev.side_and_name(),) - print "Tx amplitude %s" % (self._tx_amplitude) - print "modulation: %s" % (self._modulator_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) - print "interp: %3d" % (self._interp) - print "Tx Frequency: %s" % (eng_notation.num_to_str(self._tx_freq)) - - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") diff --git a/gnuradio-examples/python/hier/digital/transmit_path_lb.py b/gnuradio-examples/python/hier/digital/transmit_path_lb.py deleted file mode 100644 index 5a05b880..00000000 --- a/gnuradio-examples/python/hier/digital/transmit_path_lb.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright 2005,2006,2007 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, gru, blks2 -from gnuradio import eng_notation - -import copy -import sys - -# ///////////////////////////////////////////////////////////////////////////// -# transmit path -# ///////////////////////////////////////////////////////////////////////////// - -class transmit_path(gr.hier_block2): - def __init__(self, modulator_class, options): - ''' - See below for what options should hold - ''' - - gr.hier_block2.__init__(self, "transmit_path", - gr.io_signature(0,0,0), # Input signature - gr.io_signature(1,1,gr.sizeof_gr_complex)) # Output signature - - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP - self._bitrate = options.bitrate # desired bit rate - self._samples_per_symbol = options.samples_per_symbol # desired samples/baud - - self._modulator_class = modulator_class # the modulator_class we are using - - # Get mod_kwargs - mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) - - # transmitter - self.packet_transmitter = \ - blks2.mod_pkts(self._modulator_class(**mod_kwargs), - access_code=None, - msgq_limit=4, - pad_for_usrp=True) - - self.amp = gr.multiply_const_cc(1) - self.set_tx_amplitude(self._tx_amplitude) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - # Connect blocks in the flowgraph; set amp component to the output of this block - self.connect(self.packet_transmitter, self.amp, self) - - def set_tx_amplitude(self, ampl): - """ - Sets the transmit amplitude sent to the USRP - @param: ampl 0 <= ampl < 32768. Try 8000 - """ - self._tx_amplitude = max(0.0, min(ampl, 32767.0)) - self.amp.set_k(self._tx_amplitude) - - def send_pkt(self, payload='', eof=False): - """ - Calls the transmitter method to send a packet - """ - return self.packet_transmitter.send_pkt(payload, eof) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def add_options(normal, expert): - """ - Adds transmitter-specific options to the Options Parser - """ - if not normal.has_option('--bitrate'): - normal.add_option("-r", "--bitrate", type="eng_float", default=100e3, - help="specify bitrate [default=%default].") - normal.add_option("", "--tx-amplitude", type="eng_float", default=12000, metavar="AMPL", - help="set transmitter digital amplitude: 0 <= AMPL < 32768 [default=%default]") - normal.add_option("-v", "--verbose", action="store_true", default=False) - - expert.add_option("-S", "--samples-per-symbol", type="int", default=2, - help="set samples/symbol [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to file (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - def _print_verbage(self): - """ - Prints information about the transmit path - """ - print "Tx amplitude %s" % (self._tx_amplitude) - print "modulation: %s" % (self._modulator_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) - diff --git a/gnuradio-examples/python/hier/digital/tunnel.py b/gnuradio-examples/python/hier/digital/tunnel.py deleted file mode 100755 index 7d17ff95..00000000 --- a/gnuradio-examples/python/hier/digital/tunnel.py +++ /dev/null @@ -1,290 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006 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. -# - - -# ///////////////////////////////////////////////////////////////////////////// -# -# This code sets up up a virtual ethernet interface (typically gr0), -# and relays packets between the interface and the GNU Radio PHY+MAC -# -# What this means in plain language, is that if you've got a couple -# of USRPs on different machines, and if you run this code on those -# machines, you can talk between them using normal TCP/IP networking. -# -# ///////////////////////////////////////////////////////////////////////////// - - -from gnuradio import gr, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random -import time -import struct -import sys -import os - -# from current dir -from transmit_path import transmit_path -from receive_path import receive_path -import fusb_options - -#print os.getpid() -#raw_input('Attach and press enter') - - -# ///////////////////////////////////////////////////////////////////////////// -# -# Use the Universal TUN/TAP device driver to move packets to/from kernel -# -# See /usr/src/linux/Documentation/networking/tuntap.txt -# -# ///////////////////////////////////////////////////////////////////////////// - -# Linux specific... -# TUNSETIFF ifr flags from - -IFF_TUN = 0x0001 # tunnel IP packets -IFF_TAP = 0x0002 # tunnel ethernet frames -IFF_NO_PI = 0x1000 # don't pass extra packet info -IFF_ONE_QUEUE = 0x2000 # beats me ;) - -def open_tun_interface(tun_device_filename): - from fcntl import ioctl - - mode = IFF_TAP | IFF_NO_PI - TUNSETIFF = 0x400454ca - - tun = os.open(tun_device_filename, os.O_RDWR) - ifs = ioctl(tun, TUNSETIFF, struct.pack("16sH", "gr%d", mode)) - ifname = ifs[:16].strip("\x00") - return (tun, ifname) - - -# ///////////////////////////////////////////////////////////////////////////// -# the flow graph -# ///////////////////////////////////////////////////////////////////////////// - -class my_graph(gr.flow_graph): - - def __init__(self, mod_class, demod_class, - rx_callback, options): - - gr.flow_graph.__init__(self) - self.txpath = transmit_path(self, mod_class, options) - self.rxpath = receive_path(self, demod_class, rx_callback, options) - - def send_pkt(self, payload='', eof=False): - return self.txpath.send_pkt(payload, eof) - - def carrier_sensed(self): - """ - Return True if the receive path thinks there's carrier - """ - return self.rxpath.carrier_sensed() - - -# ///////////////////////////////////////////////////////////////////////////// -# Carrier Sense MAC -# ///////////////////////////////////////////////////////////////////////////// - -class cs_mac(object): - """ - Prototype carrier sense MAC - - Reads packets from the TUN/TAP interface, and sends them to the PHY. - Receives packets from the PHY via phy_rx_callback, and sends them - into the TUN/TAP interface. - - Of course, we're not restricted to getting packets via TUN/TAP, this - is just an example. - """ - def __init__(self, tun_fd, verbose=False): - self.tun_fd = tun_fd # file descriptor for TUN/TAP interface - self.verbose = verbose - self.fg = None # flow graph (access to PHY) - - def set_flow_graph(self, fg): - self.fg = fg - - def phy_rx_callback(self, ok, payload): - """ - Invoked by thread associated with PHY to pass received packet up. - - @param ok: bool indicating whether payload CRC was OK - @param payload: contents of the packet (string) - """ - if self.verbose: - print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload)) - if ok: - os.write(self.tun_fd, payload) - - def main_loop(self): - """ - Main loop for MAC. - Only returns if we get an error reading from TUN. - - FIXME: may want to check for EINTR and EAGAIN and reissue read - """ - min_delay = 0.001 # seconds - - while 1: - payload = os.read(self.tun_fd, 10*1024) - if not payload: - self.fg.send_pkt(eof=True) - break - - if self.verbose: - print "Tx: len(payload) = %4d" % (len(payload),) - - delay = min_delay - while self.fg.carrier_sensed(): - sys.stderr.write('B') - time.sleep(delay) - if delay < 0.050: - delay = delay * 2 # exponential back-off - - self.fg.send_pkt(payload) - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() - - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-v","--verbose", action="store_true", default=False) - expert_grp.add_option("-c", "--carrier-threshold", type="eng_float", default=30, - help="set carrier detect threshold (dB) [default=%default]") - expert_grp.add_option("","--tun-device-filename", default="/dev/net/tun", - help="path to tun device file [default=%default]") - - transmit_path.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - - for demod in demods.values(): - demod.add_options(expert_grp) - - fusb_options.add_options(expert_grp) - - (options, args) = parser.parse_args () - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None or options.tx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - # open the TUN/TAP interface - (tun_fd, tun_ifname) = open_tun_interface(options.tun_device_filename) - - # Attempt to enable realtime scheduling - r = gr.enable_realtime_scheduling() - if r == gr.RT_OK: - realtime = True - else: - realtime = False - print "Note: failed to enable realtime scheduling" - - - # If the user hasn't set the fusb_* parameters on the command line, - # pick some values that will reduce latency. - - if options.fusb_block_size == 0 and options.fusb_nblocks == 0: - if realtime: # be more aggressive - options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) - else: - options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - - #print "fusb_block_size =", options.fusb_block_size - #print "fusb_nblocks =", options.fusb_nblocks - - # instantiate the MAC - mac = cs_mac(tun_fd, verbose=True) - - - # build the graph (PHY) - fg = my_graph(mods[options.modulation], - demods[options.modulation], - mac.phy_rx_callback, - options) - - mac.set_flow_graph(fg) # give the MAC a handle for the PHY - - if fg.txpath.bitrate() != fg.rxpath.bitrate(): - print "WARNING: Transmit bitrate = %sb/sec, Receive bitrate = %sb/sec" % ( - eng_notation.num_to_str(fg.txpath.bitrate()), - eng_notation.num_to_str(fg.rxpath.bitrate())) - - print "modulation: %s" % (options.modulation,) - print "freq: %s" % (eng_notation.num_to_str(options.tx_freq)) - print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),) - print "samples/symbol: %3d" % (fg.txpath.samples_per_symbol(),) - #print "interp: %3d" % (fg.txpath.interp(),) - #print "decim: %3d" % (fg.rxpath.decim(),) - - fg.rxpath.set_carrier_threshold(options.carrier_threshold) - print "Carrier sense threshold:", options.carrier_threshold, "dB" - - print - print "Allocated virtual ethernet interface: %s" % (tun_ifname,) - print "You must now use ifconfig to set its IP address. E.g.," - print - print " $ sudo ifconfig %s 192.168.200.1" % (tun_ifname,) - print - print "Be sure to use a different address in the same subnet for each machine." - print - - - fg.start() # Start executing the flow graph (runs in separate threads) - - mac.main_loop() # don't expect this to return... - - fg.stop() # but if it does, tell flow graph to stop. - fg.wait() # wait for it to finish - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/digital/tx_voice.py b/gnuradio-examples/python/hier/digital/tx_voice.py deleted file mode 100755 index 09b1c584..00000000 --- a/gnuradio-examples/python/hier/digital/tx_voice.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import audio -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -from gnuradio.vocoder import gsm_full_rate - -import random -import time -import struct -import sys - -# from current dir -from transmit_path import transmit_path -import fusb_options - -#import os -#print os.getpid() -#raw_input('Attach and press enter') - - -class audio_rx(gr.hier_block): - def __init__(self, fg, audio_input_dev): - sample_rate = 8000 - src = audio.source(sample_rate, audio_input_dev) - src_scale = gr.multiply_const_ff(32767) - f2s = gr.float_to_short() - voice_coder = gsm_full_rate.encode_sp() - self.packets_from_encoder = gr.msg_queue() - packet_sink = gr.message_sink(33, self.packets_from_encoder, False) - fg.connect(src, src_scale, f2s, voice_coder, packet_sink) - gr.hier_block.__init__(self, fg, src, packet_sink) - - def get_encoded_voice_packet(self): - return self.packets_from_encoder.delete_head() - - -class my_graph(gr.flow_graph): - - def __init__(self, modulator_class, options): - gr.flow_graph.__init__(self) - self.txpath = transmit_path(self, modulator_class, options) - self.audio_rx = audio_rx(self, options.audio_input) - - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - def send_pkt(payload='', eof=False): - return fg.txpath.send_pkt(payload, eof) - - def rx_callback(ok, payload): - print "ok = %r, payload = '%s'" % (ok, payload) - - mods = modulation_utils.type_1_mods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - parser.add_option("-M", "--megabytes", type="eng_float", default=0, - help="set megabytes to transmit [default=inf]") - parser.add_option("-I", "--audio-input", type="string", default="", - help="pcm input device name. E.g., hw:0,0 or /dev/dsp") - - transmit_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - - fusb_options.add_options(expert_grp) - - parser.set_defaults(bitrate=50e3) # override default bitrate default - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.tx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - fg = my_graph(mods[options.modulation], options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - - fg.start() # start flow graph - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - - while nbytes == 0 or n < nbytes: - packet = fg.audio_rx.get_encoded_voice_packet() - s = packet.to_string() - send_pkt(s) - n += len(s) - sys.stderr.write('.') - pktno += 1 - - send_pkt(eof=True) - fg.wait() # wait for it to finish - fg.txpath.set_auto_tr(False) - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/hier/ofdm/Makefile.am b/gnuradio-examples/python/hier/ofdm/Makefile.am deleted file mode 100644 index b3ebfe6a..00000000 --- a/gnuradio-examples/python/hier/ofdm/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright 2006 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. -# - -EXTRA_DIST = \ No newline at end of file diff --git a/gnuradio-examples/python/hier/usrp/usrp_fft.py b/gnuradio-examples/python/hier/usrp/usrp_fft.py deleted file mode 100755 index 2dc059e5..00000000 --- a/gnuradio-examples/python/hier/usrp/usrp_fft.py +++ /dev/null @@ -1,249 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007 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, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys - - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db[1][0].dbid() >= 0: - return (1, 0) - return (0, 0) - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.show_debug_info = True - - self.u = usrp.source_c(decim_rate=options.decim) - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - - if options.width_8: - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - print "format =", hex(format) - r = self.u.set_format(format) - print "set_format =", r - - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - - input_rate = self.u.adc_freq() / self.u.decim_rate() - - - if options.waterfall: - self.scope = waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) - elif options.oscilloscope: - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) - else: - self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, sample_rate=input_rate) - - self.connect(self.u, self.scope) - - self._build_gui(vbox) - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - # if no freq was specified, use the mid-point - r = self.subdev.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - self.myform['dbname'].set_value(self.subdev.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.tune(0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim_rate(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - return ok - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/hier/usrp/usrp_siggen.py b/gnuradio-examples/python/hier/usrp/usrp_siggen.py deleted file mode 100755 index 91a7a7af..00000000 --- a/gnuradio-examples/python/hier/usrp/usrp_siggen.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from gnuradio import eng_notation -from optparse import OptionParser -import sys - -class my_graph(gr.top_block): - def __init__ (self, type, ampl, wfreq, offset, subdev_spec, interp, rf_freq): - gr.top_block.__init__(self, "usrp_siggen") - - # controllable values - self.interp = interp - self.waveform_type = type - self.waveform_ampl = ampl - self.waveform_freq = wfreq - self.waveform_offset = offset - - self.u = usrp.sink_c (0, self.interp) - - # determine the daughterboard subdevice we're using - if subdev_spec is None: - ubdev_spec = usrp.pick_tx_subdevice(self.u) - m = usrp.determine_tx_mux_value(self.u, subdev_spec) - self.u.set_mux(m) - self.subdev = usrp.selected_subdev(self.u, subdev_spec) - self.subdev.set_gain(self.subdev.gain_range()[1]) # set max Tx gain - self.subdev.set_enable(True) # enable transmitter - print "Using TX d'board %s" % (self.subdev.side_and_name(),) - - if not self.set_freq(rf_freq): - sys.stderr.write('Failed to set RF frequency\n') - raise SystemExit - - if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE: - self.src = gr.sig_source_c (self.usb_freq (), - gr.GR_SIN_WAVE, - self.waveform_freq, - self.waveform_ampl, - self.waveform_offset) - - elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN: - self.src = gr.noise_source_c (gr.GR_UNIFORM, - self.waveform_ampl) - - else: - raise ValueError, type - - self.connect (self.src, self.u) - - - def usb_freq (self): - return self.u.dac_freq() / self.interp - - def usb_throughput (self): - return self.usb_freq () * 4 - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. - """ - r = self.u.tune(self.subdev._which, self.subdev, target_freq) - if r: - #print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq) - #print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq) - #print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq) - #print "r.inverted =", r.inverted - return True - - return False - - - -def main (): - parser = OptionParser (option_class=eng_option) - parser.add_option ("-T", "--tx-subdev-spec", type="subdev", default=(0, 0), - help="select USRP Tx side A or B") - parser.add_option ("-f", "--rf-freq", type="eng_float", default=None, - help="set RF center frequency to FREQ") - parser.add_option ("-i", "--interp", type="int", default=64, - help="set fgpa interpolation rate to INTERP [default=%default]") - - parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, - help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE) - parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, - help="generate a constant output") - parser.add_option ("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN, - help="generate Gaussian random output") - parser.add_option ("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM, - help="generate Uniform random output") - - parser.add_option ("-w", "--waveform-freq", type="eng_float", default=100e3, - help="set waveform frequency to FREQ [default=%default]") - parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3, - help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL") - parser.add_option ("-o", "--offset", type="eng_float", default=0, - help="set waveform offset to OFFSET [default=%default]") - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - raise SystemExit - - if options.rf_freq is None: - sys.stderr.write("usrp_siggen: must specify RF center frequency with -f RF_FREQ\n") - parser.print_help() - raise SystemExit - - top_block = my_graph(options.type, options.amplitude, options.waveform_freq, options.offset, - options.tx_subdev_spec, options.interp, options.rf_freq) - - try: - # Run forever - top_block.run() - except KeyboardInterrupt: - # Ctrl-C exits - pass - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/networking/Makefile.am b/gnuradio-examples/python/limbo/networking/Makefile.am similarity index 100% rename from gnuradio-examples/python/networking/Makefile.am rename to gnuradio-examples/python/limbo/networking/Makefile.am diff --git a/gnuradio-examples/python/networking/measurement_slave.py b/gnuradio-examples/python/limbo/networking/measurement_slave.py similarity index 100% rename from gnuradio-examples/python/networking/measurement_slave.py rename to gnuradio-examples/python/limbo/networking/measurement_slave.py diff --git a/gnuradio-examples/python/hier/sounder/Makefile.am b/gnuradio-examples/python/limbo/sounder/Makefile.am similarity index 100% rename from gnuradio-examples/python/hier/sounder/Makefile.am rename to gnuradio-examples/python/limbo/sounder/Makefile.am diff --git a/gnuradio-examples/python/hier/sounder/sounder_rx.py b/gnuradio-examples/python/limbo/sounder/sounder_rx.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/sounder_rx.py rename to gnuradio-examples/python/limbo/sounder/sounder_rx.py diff --git a/gnuradio-examples/python/hier/sounder/sounder_tx.py b/gnuradio-examples/python/limbo/sounder/sounder_tx.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/sounder_tx.py rename to gnuradio-examples/python/limbo/sounder/sounder_tx.py diff --git a/gnuradio-examples/python/hier/sounder/usrp_sink.py b/gnuradio-examples/python/limbo/sounder/usrp_sink.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/usrp_sink.py rename to gnuradio-examples/python/limbo/sounder/usrp_sink.py diff --git a/gnuradio-examples/python/hier/sounder/usrp_sounder_rx.py b/gnuradio-examples/python/limbo/sounder/usrp_sounder_rx.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/usrp_sounder_rx.py rename to gnuradio-examples/python/limbo/sounder/usrp_sounder_rx.py diff --git a/gnuradio-examples/python/hier/sounder/usrp_sounder_tx.py b/gnuradio-examples/python/limbo/sounder/usrp_sounder_tx.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/usrp_sounder_tx.py rename to gnuradio-examples/python/limbo/sounder/usrp_sounder_tx.py diff --git a/gnuradio-examples/python/hier/sounder/usrp_source.py b/gnuradio-examples/python/limbo/sounder/usrp_source.py similarity index 100% rename from gnuradio-examples/python/hier/sounder/usrp_source.py rename to gnuradio-examples/python/limbo/sounder/usrp_source.py diff --git a/gnuradio-examples/python/hier/networking/Makefile.am b/gnuradio-examples/python/network/Makefile.am similarity index 90% rename from gnuradio-examples/python/hier/networking/Makefile.am rename to gnuradio-examples/python/network/Makefile.am index 95ced728..57862309 100644 --- a/gnuradio-examples/python/hier/networking/Makefile.am +++ b/gnuradio-examples/python/network/Makefile.am @@ -19,6 +19,8 @@ # Boston, MA 02110-1301, USA. # +include $(top_srcdir)/Makefile.common + EXTRA_DIST = \ audio_sink.py \ audio_source.py \ @@ -27,4 +29,7 @@ EXTRA_DIST = \ vector_sink.py \ vector_source.py +ourdatadir = $(exampledir)/network +ourdata_DATA = $(EXTRA_DIST) + MOSTLYCLEANFILES = *.pyc *~ diff --git a/gnuradio-examples/python/hier/networking/audio_sink.py b/gnuradio-examples/python/network/audio_sink.py similarity index 100% rename from gnuradio-examples/python/hier/networking/audio_sink.py rename to gnuradio-examples/python/network/audio_sink.py diff --git a/gnuradio-examples/python/hier/networking/audio_source.py b/gnuradio-examples/python/network/audio_source.py similarity index 100% rename from gnuradio-examples/python/hier/networking/audio_source.py rename to gnuradio-examples/python/network/audio_source.py diff --git a/gnuradio-examples/python/hier/networking/dial_tone_sink.py b/gnuradio-examples/python/network/dial_tone_sink.py similarity index 100% rename from gnuradio-examples/python/hier/networking/dial_tone_sink.py rename to gnuradio-examples/python/network/dial_tone_sink.py diff --git a/gnuradio-examples/python/hier/networking/dial_tone_source.py b/gnuradio-examples/python/network/dial_tone_source.py similarity index 100% rename from gnuradio-examples/python/hier/networking/dial_tone_source.py rename to gnuradio-examples/python/network/dial_tone_source.py diff --git a/gnuradio-examples/python/hier/networking/vector_sink.py b/gnuradio-examples/python/network/vector_sink.py similarity index 100% rename from gnuradio-examples/python/hier/networking/vector_sink.py rename to gnuradio-examples/python/network/vector_sink.py diff --git a/gnuradio-examples/python/hier/networking/vector_source.py b/gnuradio-examples/python/network/vector_source.py similarity index 100% rename from gnuradio-examples/python/hier/networking/vector_source.py rename to gnuradio-examples/python/network/vector_source.py diff --git a/gnuradio-examples/python/ofdm/Makefile.am b/gnuradio-examples/python/ofdm/Makefile.am index e9ff3bac..c951dd16 100644 --- a/gnuradio-examples/python/ofdm/Makefile.am +++ b/gnuradio-examples/python/ofdm/Makefile.am @@ -29,7 +29,12 @@ EXTRA_DIST = \ fusb_options.py \ pick_bitrate.py \ receive_path.py \ - transmit_path.py + transmit_path.py \ + ofdm_mod_demod_test.py \ + ofdm_sync.m \ + ofdm_sync_pn.m \ + plot_ofdm.m \ + tunnel.py ourdatadir = $(exampledir)/ofdm ourdata_DATA = $(EXTRA_DIST) diff --git a/gnuradio-examples/python/usrp/fm_tx4.py b/gnuradio-examples/python/usrp/fm_tx4.py index 7e5023dd..e97468d5 100755 --- a/gnuradio-examples/python/usrp/fm_tx4.py +++ b/gnuradio-examples/python/usrp/fm_tx4.py @@ -1,4 +1,24 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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. +# """ Transmit N simultaneous narrow band FM signals. @@ -15,14 +35,14 @@ audio_to_file.py from gnuradio import gr, eng_notation from gnuradio import usrp from gnuradio import audio -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser from usrpm import usrp_dbid import math import sys -from gnuradio.wxgui import stdgui, fftsink +from gnuradio.wxgui import stdgui2, fftsink2 from gnuradio import tx_debug_gui import wx @@ -30,12 +50,15 @@ import wx ######################################################## # instantiate one transmit chain for each call -class pipeline(gr.hier_block): - def __init__(self, fg, filename, lo_freq, audio_rate, if_rate): +class pipeline(gr.hier_block2): + def __init__(self, filename, lo_freq, audio_rate, if_rate): + + gr.hier_block2.__init__(self, "pipeline", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature src = gr.file_source (gr.sizeof_float, filename, True) - fmtx = blks.nbfm_tx (fg, audio_rate, if_rate, - max_dev=5e3, tau=75e-6) + fmtx = blks2.nbfm_tx (audio_rate, if_rate, max_dev=5e3, tau=75e-6) # Local oscillator lo = gr.sig_source_c (if_rate, # sample rate @@ -45,17 +68,14 @@ class pipeline(gr.hier_block): 0) # DC Offset mixer = gr.multiply_cc () - fg.connect (src, fmtx, (mixer, 0)) - fg.connect (lo, (mixer, 1)) - - gr.hier_block.__init__(self, fg, src, mixer) - + self.connect (src, fmtx, (mixer, 0)) + self.connect (lo, (mixer, 1)) -class fm_tx_graph (stdgui.gui_flow_graph): +class fm_tx_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): MAX_CHANNELS = 7 - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) + stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, @@ -119,9 +139,9 @@ class fm_tx_graph (stdgui.gui_flow_graph): step = 25e3 offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step) for i in range (options.nchannels): - t = pipeline (self, "audio-%d.dat" % (i % 4), offset[i], - self.audio_rate, self.usrp_rate) - self.connect (t, (sum, i)) + t = pipeline("audio-%d.dat" % (i % 4), offset[i], + self.audio_rate, self.usrp_rate) + self.connect(t, (sum, i)) gain = gr.multiply_const_cc (4000.0 / options.nchannels) @@ -131,9 +151,9 @@ class fm_tx_graph (stdgui.gui_flow_graph): # plot an FFT to verify we are sending what we want if 1: - post_mod = fftsink.fft_sink_c(self, panel, title="Post Modulation", - fft_size=512, sample_rate=self.usrp_rate, - y_per_div=20, ref_level=40) + post_mod = fftsink2.fft_sink_c(panel, title="Post Modulation", + fft_size=512, sample_rate=self.usrp_rate, + y_per_div=20, ref_level=40) self.connect (sum, post_mod) vbox.Add (post_mod.win, 1, wx.EXPAND) @@ -170,7 +190,7 @@ class fm_tx_graph (stdgui.gui_flow_graph): return False def main (): - app = stdgui.stdapp (fm_tx_graph, "Multichannel FM Tx") + app = stdgui2.stdapp(fm_tx_block, "Multichannel FM Tx", nstatus=1) app.MainLoop () if __name__ == '__main__': diff --git a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py index 66ee9f02..499c7230 100755 --- a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py +++ b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py @@ -1,4 +1,24 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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. +# """ Transmit 2 signals, one out each daughterboard. @@ -14,7 +34,7 @@ from gnuradio import gr from gnuradio.eng_notation import num_to_str, str_to_num from gnuradio import usrp from gnuradio import audio -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser from usrpm import usrp_dbid @@ -22,11 +42,14 @@ import math import sys -class example_signal_0(gr.hier_block): +class example_signal_0(gr.hier_block2): """ Sinusoid at 600 Hz. """ - def __init__(self, fg, sample_rate): + def __init__(self, sample_rate): + gr.hier_block2.__init__(self, "example_signal_0", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature src = gr.sig_source_c (sample_rate, # sample rate gr.GR_SIN_WAVE, # waveform type @@ -34,14 +57,17 @@ class example_signal_0(gr.hier_block): 1.0, # amplitude 0) # DC Offset - gr.hier_block.__init__(self, fg, None, src) + self.connect(src, self) -class example_signal_1(gr.hier_block): +class example_signal_1(gr.hier_block2): """ North American dial tone (350 + 440 Hz). """ - def __init__(self, fg, sample_rate): + def __init__(self, sample_rate): + gr.hier_block2.__init__(self, "example_signal_1", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature src0 = gr.sig_source_c (sample_rate, # sample rate gr.GR_SIN_WAVE, # waveform type @@ -55,17 +81,14 @@ class example_signal_1(gr.hier_block): 1.0, # amplitude 0) # DC Offset sum = gr.add_cc() - fg.connect(src0, (sum, 0)) - fg.connect(src1, (sum, 1)) - - gr.hier_block.__init__(self, fg, None, sum) - - + self.connect(src0, (sum, 0)) + self.connect(src1, (sum, 1)) + self.connect(sum, self) -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__ (self) + gr.top_block.__init__(self) usage="%prog: [options] side-A-tx-freq side-B-tx-freq" parser = OptionParser (option_class=eng_option, usage=usage) @@ -108,8 +131,8 @@ class my_graph(gr.flow_graph): # ---------------------------------------------------------------- # build two signal sources, interleave them, amplify and connect them to usrp - sig0 = example_signal_0(self, self.usrp_rate) - sig1 = example_signal_1(self, self.usrp_rate) + sig0 = example_signal_0(self.usrp_rate) + sig1 = example_signal_1(self.usrp_rate) intl = gr.interleave(gr.sizeof_gr_complex) self.connect(sig0, (intl, 0)) @@ -155,6 +178,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/max_power.py b/gnuradio-examples/python/usrp/max_power.py index 46df7254..91005e53 100755 --- a/gnuradio-examples/python/usrp/max_power.py +++ b/gnuradio-examples/python/usrp/max_power.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -30,12 +30,12 @@ from gnuradio import usrp from gnuradio.eng_option import eng_option from optparse import OptionParser -def ramp_source (fg): +def ramp_source (): period = 2**16 src = gr.vector_source_s (range (-period/2, period/2, 1), True) return src -def build_graph (tx_enable, rx_enable): +def build_block (tx_enable, rx_enable): max_usb_rate = 8e6 # 8 MS/sec dac_freq = 128e6 adc_freq = 64e6 @@ -48,23 +48,23 @@ def build_graph (tx_enable, rx_enable): rx_mux = 0x00003210 rx_decim = int ((adc_freq * rx_nchan) / (max_usb_rate/2)) # 32 - fg = gr.flow_graph () + tb = gr.top_block () if tx_enable: tx_src0 = gr.sig_source_c (dac_freq/tx_interp, gr.GR_CONST_WAVE, 0, 16e3, 0) usrp_tx = usrp.sink_c (0, tx_interp, tx_nchan, tx_mux) usrp_tx.set_tx_freq (0, 10e6) usrp_tx.set_tx_freq (1, 9e6) - fg.connect (tx_src0, usrp_tx) + tb.connect (tx_src0, usrp_tx) if rx_enable: usrp_rx = usrp.source_c (0, rx_decim, rx_nchan, rx_mux) usrp_rx.set_rx_freq (0, 5.5e6) usrp_rx.set_rx_freq (1, 6.5e6) rx_dst0 = gr.null_sink (gr.sizeof_gr_complex) - fg.connect (usrp_rx, rx_dst0) + tb.connect (usrp_rx, rx_dst0) - return fg + return tb def main (): parser = OptionParser (option_class=eng_option) @@ -73,11 +73,11 @@ def main (): parser.add_option ("-r", action="store_true", dest="rx_enable", default=False, help="enable Rx path") (options, args) = parser.parse_args () - fg = build_graph (options.tx_enable, options.rx_enable) + tb = build_block (options.tx_enable, options.rx_enable) - fg.start () + tb.start () raw_input ('Press Enter to quit: ') - fg.stop () + tb.stop () if __name__ == '__main__': main () diff --git a/gnuradio-examples/python/usrp/usrp_benchmark_usb.py b/gnuradio-examples/python/usrp/usrp_benchmark_usb.py index fc01514a..4ea84f76 100755 --- a/gnuradio-examples/python/usrp/usrp_benchmark_usb.py +++ b/gnuradio-examples/python/usrp/usrp_benchmark_usb.py @@ -55,21 +55,21 @@ def run_test (usb_throughput, verbose): # print "tx_interp =", tx_interp, "rx_decim =", rx_decim assert (tx_interp == 2 * rx_decim) - fg = gr.flow_graph () + tb = gr.top_block () # Build the Tx pipeline data_src = gr.lfsr_32k_source_s () src_head = gr.head (gr.sizeof_short, int (stream_length * 2)) usrp_tx = usrp.sink_s (0, tx_interp) - fg.connect (data_src, src_head, usrp_tx) + tb.connect (data_src, src_head, usrp_tx) # and the Rx pipeline usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) head = gr.head (gr.sizeof_short, stream_length) check = gr.check_lfsr_32k_s () - fg.connect (usrp_rx, head, check) + tb.connect (usrp_rx, head, check) - fg.run () + tb.run () ntotal = check.ntotal () nright = check.nright () diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py index 03333fa1..35f01521 100755 --- a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py +++ b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005 Free Software Foundation, Inc. +# Copyright 2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -28,9 +28,9 @@ from optparse import OptionParser from gnuradio import gr, gru, eng_notation from gnuradio import usrp from gnuradio import audio -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui, fftsink, scopesink, slider, form +from gnuradio.wxgui import stdgui2, fftsink2, scopesink2, slider, form from usrpm import usrp_dbid from numpy import convolve, array @@ -43,9 +43,9 @@ from numpy import convolve, array # Control Stuff # //////////////////////////////////////////////////////////////////////// -class ptt_graph(stdgui.gui_flow_graph): +class ptt_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) + stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) self.frame = frame self.space_bar_pressed = False @@ -73,8 +73,11 @@ class ptt_graph(stdgui.gui_flow_graph): if options.freq < 1e6: options.freq *= 1e6 - self.txpath = transmit_path(self, options.tx_subdev_spec, options.audio_input) - self.rxpath = receive_path(self, options.rx_subdev_spec, options.rx_gain, options.audio_output) + self.txpath = transmit_path(options.tx_subdev_spec, options.audio_input) + self.rxpath = receive_path(options.rx_subdev_spec, options.rx_gain, options.audio_output) + self.connect(self.txpath) + self.connect(self.rxpath) + self._build_gui(frame, panel, vbox, argv, options.no_gui) self.set_transmit(False) @@ -142,29 +145,29 @@ class ptt_graph(stdgui.gui_flow_graph): panel.SetFocus() if 1 and not(no_gui): - rx_fft = fftsink.fft_sink_c (self, panel, title="Rx Input", fft_size=512, + rx_fft = fftsink2.fft_sink_c(panel, title="Rx Input", fft_size=512, sample_rate=self.rxpath.if_rate, ref_level=80, y_per_div=20) self.connect (self.rxpath.u, rx_fft) vbox.Add (rx_fft.win, 1, wx.EXPAND) if 1 and not(no_gui): - rx_fft = fftsink.fft_sink_c (self, panel, title="Post s/w DDC", + rx_fft = fftsink2.fft_sink_c(panel, title="Post s/w DDC", fft_size=512, sample_rate=self.rxpath.quad_rate, ref_level=80, y_per_div=20) self.connect (self.rxpath.ddc, rx_fft) vbox.Add (rx_fft.win, 1, wx.EXPAND) if 0 and not(no_gui): - foo = scopesink.scope_sink_f (self, panel, title="Squelch", - sample_rate=32000) + foo = scopesink2.scope_sink_f(panel, title="Squelch", + sample_rate=32000) self.connect (self.rxpath.fmrx.div, (foo,0)) self.connect (self.rxpath.fmrx.gate, (foo,1)) self.connect (self.rxpath.fmrx.squelch_lpf, (foo,2)) vbox.Add (foo.win, 1, wx.EXPAND) if 0 and not(no_gui): - tx_fft = fftsink.fft_sink_c (self, panel, title="Tx Output", + tx_fft = fftsink2.fft_sink_c(panel, title="Tx Output", fft_size=512, sample_rate=self.txpath.usrp_rate) self.connect (self.txpath.amp, tx_fft) vbox.Add (tx_fft.win, 1, wx.EXPAND) @@ -265,9 +268,12 @@ class ptt_graph(stdgui.gui_flow_graph): # Transmit Path # //////////////////////////////////////////////////////////////////////// -class transmit_path(gr.hier_block): - def __init__(self, fg, subdev_spec, audio_input): - +class transmit_path(gr.hier_block2): + def __init__(self, subdev_spec, audio_input): + gr.hier_block2.__init__(self, "transmit_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + self.u = usrp.sink_c () dac_rate = self.u.dac_rate(); @@ -298,11 +304,11 @@ class transmit_path(gr.hier_block): audio_taps = convolve(array(lpf),array(hpf)) self.audio_filt = gr.fir_filter_fff(1,audio_taps) - self.pl = blks.ctcss_gen_f(fg, self.audio_rate,123.0) + self.pl = blks2.ctcss_gen_f(self.audio_rate,123.0) self.add_pl = gr.add_ff() - fg.connect(self.pl,(self.add_pl,1)) + self.connect(self.pl,(self.add_pl,1)) - self.fmtx = blks.nbfm_tx(fg, self.audio_rate, self.if_rate) + self.fmtx = blks2.nbfm_tx(self.audio_rate, self.if_rate) self.amp = gr.multiply_const_cc (self.normal_gain) # determine the daughterboard subdevice we're using @@ -312,10 +318,8 @@ class transmit_path(gr.hier_block): self.subdev = usrp.selected_subdev(self.u, subdev_spec) print "TX using", self.subdev.name() - fg.connect(self.audio, self.audio_amp, self.audio_filt, - (self.add_pl,0), self.fmtx, self.amp, self.u) - - gr.hier_block.__init__(self, fg, None, None) + self.connect(self.audio, self.audio_amp, self.audio_filt, + (self.add_pl,0), self.fmtx, self.amp, self.u) self.set_gain(self.subdev.gain_range()[1]) # set max Tx gain @@ -357,8 +361,11 @@ class transmit_path(gr.hier_block): # Receive Path # //////////////////////////////////////////////////////////////////////// -class receive_path(gr.hier_block): - def __init__(self, fg, subdev_spec, gain, audio_output): +class receive_path(gr.hier_block2): + def __init__(self, subdev_spec, gain, audio_output): + gr.hier_block2.__init__(self, "receive_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature self.u = usrp.source_c () adc_rate = self.u.adc_rate() @@ -395,10 +402,10 @@ class receive_path(gr.hier_block): self.if_rate) # input sample rate # instantiate the guts of the single channel receiver - self.fmrx = blks.nbfm_rx(fg, audio_rate, self.quad_rate) + self.fmrx = blks2.nbfm_rx(audio_rate, self.quad_rate) # standard squelch block - self.squelch = blks.standard_squelch(fg, audio_rate) + self.squelch = blks2.standard_squelch(audio_rate) # audio gain / mute block self._audio_gain = gr.multiply_const_ff(1.0) @@ -407,8 +414,7 @@ class receive_path(gr.hier_block): audio_sink = audio.sink (int(audio_rate), audio_output) # now wire it all together - fg.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink) - gr.hier_block.__init__(self, fg, self.u, audio_sink) + self.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink) if gain is None: # if no gain was specified, use the mid-point in dB @@ -484,7 +490,7 @@ class receive_path(gr.hier_block): # //////////////////////////////////////////////////////////////////////// def main(): - app = stdgui.stdapp(ptt_graph, "NBFM Push to Talk") + app = stdgui2.stdapp(ptt_block, "NBFM Push to Talk") app.MainLoop() if __name__ == '__main__': diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py b/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py index 868dee5c..c63bef0c 100755 --- a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py +++ b/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py @@ -1,12 +1,32 @@ #!/usr/bin/env python +# +# Copyright 2005,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form +from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -18,9 +38,9 @@ import wx # Control Stuff #//////////////////////////////////////////////////////////////////////// -class my_graph (stdgui.gui_flow_graph): +class my_top_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -50,8 +70,9 @@ class my_graph (stdgui.gui_flow_graph): self.freq = 0 self.freq_step = 25e3 - self.rxpath = receive_path(self, options.rx_subdev_spec, options.gain, options.audio_output) - + self.rxpath = receive_path(options.rx_subdev_spec, options.gain, options.audio_output) + self.connect(self.rxpath) + self._build_gui(vbox, options.no_gui) # set initial values @@ -79,28 +100,27 @@ class my_graph (stdgui.gui_flow_graph): self.src_fft = None if 1 and not(no_gui): - self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", + self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=self.rxpath.if_rate, ref_level=80, y_per_div=20) self.connect (self.rxpath.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) - if 1 and not(no_gui): - rx_fft = fftsink.fft_sink_c (self, self.panel, title="Post s/w DDC", + rx_fft = fftsink2.fft_sink_c(self.panel, title="Post s/w DDC", fft_size=512, sample_rate=self.rxpath.quad_rate, ref_level=80, y_per_div=20) self.connect (self.rxpath.ddc, rx_fft) vbox.Add (rx_fft.win, 4, wx.EXPAND) if 1 and not(no_gui): - post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph", + post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", fft_size=512, sample_rate=self.rxpath.audio_rate, y_per_div=10, ref_level=-40) self.connect (self.rxpath.fmrx.deemph, post_deemph_fft) vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) if 0: - post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", + post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Filter", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-40) self.connect (self.guts.audio_filter, post_filt) @@ -225,8 +245,11 @@ class my_graph (stdgui.gui_flow_graph): USE_SIMPLE_SQUELCH = False -class receive_path(gr.hier_block): - def __init__(self, fg, subdev_spec, gain, audio_output): +class receive_path(gr.hier_block2): + def __init__(self, subdev_spec, gain, audio_output): + gr.hier_block2.__init__(self, "receive_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature self.u = usrp.source_c () adc_rate = self.u.adc_rate() @@ -266,10 +289,10 @@ class receive_path(gr.hier_block): if USE_SIMPLE_SQUELCH: self.squelch = gr.simple_squelch_cc(20) else: - self.squelch = blks.standard_squelch(fg, self.audio_rate) + self.squelch = blks2.standard_squelch(self.audio_rate) # instantiate the guts of the single channel receiver - self.fmrx = blks.nbfm_rx(fg, self.audio_rate, self.quad_rate) + self.fmrx = blks2.nbfm_rx(self.audio_rate, self.quad_rate) # audio gain / mute block self._audio_gain = gr.multiply_const_ff(1.0) @@ -279,13 +302,11 @@ class receive_path(gr.hier_block): # now wire it all together if USE_SIMPLE_SQUELCH: - fg.connect (self.u, self.ddc, self.squelch, self.fmrx, - self._audio_gain, audio_sink) + self.connect (self.u, self.ddc, self.squelch, self.fmrx, + self._audio_gain, audio_sink) else: - fg.connect (self.u, self.ddc, self.fmrx, self.squelch, - self._audio_gain, audio_sink) - - gr.hier_block.__init__(self, fg, self.u, audio_sink) + self.connect (self.u, self.ddc, self.fmrx, self.squelch, + self._audio_gain, audio_sink) if gain is None: # if no gain was specified, use the mid-point in dB @@ -358,5 +379,5 @@ class receive_path(gr.hier_block): # //////////////////////////////////////////////////////////////////////// if __name__ == '__main__': - app = stdgui.stdapp (my_graph, "USRP NBFM RX") + app = stdgui2.stdapp (my_top_block, "USRP NBFM RX") app.MainLoop () diff --git a/gnuradio-examples/python/usrp/usrp_spectrum_sense.py b/gnuradio-examples/python/usrp/usrp_spectrum_sense.py index 1d86e03c..90adf167 100755 --- a/gnuradio-examples/python/usrp/usrp_spectrum_sense.py +++ b/gnuradio-examples/python/usrp/usrp_spectrum_sense.py @@ -1,9 +1,28 @@ #!/usr/bin/env python +# +# Copyright 2005,2007 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, gru, eng_notation, optfir, window from gnuradio import audio from gnuradio import usrp -from gnuradio import blks from gnuradio.eng_option import eng_option from optparse import OptionParser from usrpm import usrp_dbid @@ -16,9 +35,9 @@ class tune(gr.feval_dd): """ This class allows C++ code to callback into python. """ - def __init__(self, fg): + def __init__(self, tb): gr.feval_dd.__init__(self) - self.fg = fg + self.tb = tb def eval(self, ignore): """ @@ -36,7 +55,7 @@ class tune(gr.feval_dd): # # message on stderr. Not exactly helpful ;) - new_freq = self.fg.set_next_freq() + new_freq = self.tb.set_next_freq() return new_freq except Exception, e: @@ -55,10 +74,10 @@ class parse_msg(object): self.data = struct.unpack('%df' % (self.vlen,), t) -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) usage = "usage: %prog [options] min_freq max_freq" parser = OptionParser(option_class=eng_option, usage=usage) @@ -213,12 +232,12 @@ class my_graph(gr.flow_graph): self.subdev.set_gain(gain) -def main_loop(fg): +def main_loop(tb): while 1: # Get the next message sent from the C++ code (blocking call). # It contains the center frequency and the mag squared of the fft - m = parse_msg(fg.msgq.delete_head()) + m = parse_msg(tb.msgq.delete_head()) # Print center freq so we know that something is happening... print m.center_freq @@ -233,10 +252,10 @@ def main_loop(fg): if __name__ == '__main__': - fg = my_graph() + tb = my_top_block() try: - fg.start() # start executing flow graph in another thread... - main_loop(fg) + tb.start() # start executing flow graph in another thread... + main_loop(tb) except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py b/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py index 446ca30a..696c1a24 100755 --- a/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py +++ b/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,29 +32,29 @@ def build_graph (): tx_interp = 32 # tx should be twice rx rx_decim = 16 - fg = gr.flow_graph () + tb = gr.top_block () data_src = gr.lfsr_32k_source_s () # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98) usrp_tx = usrp.sink_s (0, tx_interp) - fg.connect (data_src, usrp_tx) + tb.connect (data_src, usrp_tx) usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) sink = gr.check_lfsr_32k_s () - fg.connect (usrp_rx, sink) + tb.connect (usrp_rx, sink) # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat") - # fg.connect (usrp_rx, file_sink) + # tb.connect (usrp_rx, file_sink) - return fg + return tb def main (): - fg = build_graph () + tb = build_graph () try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv.py b/gnuradio-examples/python/usrp/usrp_tv_rcv.py index 8fabc2b4..537e339b 100755 --- a/gnuradio-examples/python/usrp/usrp_tv_rcv.py +++ b/gnuradio-examples/python/usrp/usrp_tv_rcv.py @@ -1,4 +1,25 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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. +# + """ Realtime capture and display of analog Tv stations. Can also use a file as source or sink @@ -16,10 +37,9 @@ except: print "FYI: gr-video-sdl is not installed" print "realtime SDL video output window will not be available" from gnuradio import usrp -from gnuradio import blks from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form +from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -45,9 +65,9 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class tv_rx_graph (stdgui.gui_flow_graph): +class tv_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \ "Make sure your input capture file containes interleaved shorts not complex floats" @@ -391,5 +411,5 @@ class tv_rx_graph (stdgui.gui_flow_graph): if __name__ == '__main__': - app = stdgui.stdapp (tv_rx_graph, "USRP TV RX black-and-white") + app = stdgui2.stdapp (tv_rx_block, "USRP TV RX black-and-white") app.MainLoop () diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py index e563188b..e6a8de1b 100755 --- a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py +++ b/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py @@ -1,4 +1,24 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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. +# """ Reads from a file and generates PAL TV pictures in black and white @@ -24,10 +44,10 @@ except: print "realtime \"sdl\" video output window will not be available" -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \ "You then need to have gr-video-sdl installed. \n" \ @@ -174,6 +194,6 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv.py index 9ffb41fb..40e4d838 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py +++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv.py @@ -1,12 +1,32 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form +from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -26,9 +46,9 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class wfm_rx_graph (stdgui.gui_flow_graph): +class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -84,7 +104,7 @@ class wfm_rx_graph (stdgui.gui_flow_graph): #print len(chan_filt_coeffs) chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation) + self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) self.volume_control = gr.multiply_const_ff(self.vol) @@ -129,20 +149,20 @@ class wfm_rx_graph (stdgui.gui_flow_graph): if 1: - self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", + self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1: - post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod", + post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", fft_size=1024, sample_rate=usrp_rate, y_per_div=10, ref_level=0) self.connect (self.guts.fm_demod, post_filt_fft) vbox.Add (post_filt_fft.win, 4, wx.EXPAND) if 0: - post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph", + post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect (self.guts.deemph, post_deemph_fft) @@ -266,5 +286,5 @@ class wfm_rx_graph (stdgui.gui_flow_graph): if __name__ == '__main__': - app = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX") + app = stdgui2.stdapp (wfm_rx_block, "USRP WFM RX") app.MainLoop () diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py index efb0448f..942fd070 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py +++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py @@ -1,9 +1,29 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser from usrpm import usrp_dbid @@ -22,10 +42,10 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class wfm_rx_graph (gr.flow_graph): +class wfm_rx_block (gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -107,7 +127,7 @@ class wfm_rx_graph (gr.flow_graph): for n in range(2): chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - guts = blks.wfm_rcv (self, demod_rate, audio_decimation) + guts = blks2.wfm_rcv (demod_rate, audio_decimation) volume_control = gr.multiply_const_ff(self.vol) self.connect((di, n), chan_filt) self.connect(chan_filt, guts, volume_control) @@ -135,10 +155,13 @@ class wfm_rx_graph (gr.flow_graph): def set_gain(self, gain): self.subdev.set_gain(gain) + def __del__(self): + # Avoid weak-reference error + del self.subdev if __name__ == '__main__': - fg = wfm_rx_graph() + tb = wfm_rx_block() try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py index 9aeae117..44f86885 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py +++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py @@ -1,9 +1,29 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser from usrpm import usrp_dbid @@ -23,10 +43,10 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class wfm_rx_graph (gr.flow_graph): +class wfm_rx_block (gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -78,7 +98,7 @@ class wfm_rx_graph (gr.flow_graph): #print len(chan_filt_coeffs) chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation) + self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) self.volume_control = gr.multiply_const_ff(self.vol) @@ -147,8 +167,8 @@ class wfm_rx_graph (gr.flow_graph): if __name__ == '__main__': - fg = wfm_rx_graph() + tb = wfm_rx_block() try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py index 58b59084..a85bcdbf 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py +++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py @@ -1,12 +1,32 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form, scopesink +from gnuradio.wxgui import stdgui2, fftsink2, form, scopesink2 from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -25,9 +45,9 @@ def pick_subdevice(u): usrp_dbid.TV_RX_REV_3, usrp_dbid.BASIC_RX)) -class wfm_rx_graph (stdgui.gui_flow_graph): +class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -86,8 +106,8 @@ class wfm_rx_graph (stdgui.gui_flow_graph): chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - #self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation) - self.guts = blks.wfm_rcv_pll (self, demod_rate, audio_decimation) + #self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) + self.guts = blks2.wfm_rcv_pll (demod_rate, audio_decimation) # FIXME rework {add,multiply}_const_* to handle multiple streams self.volume_control_l = gr.multiply_const_ff(self.vol) @@ -146,34 +166,34 @@ class wfm_rx_graph (stdgui.gui_flow_graph): if 1: - self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", + self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1: - post_fm_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post FM Demod", - fft_size=512, sample_rate=demod_rate, - y_per_div=10, ref_level=0) + post_fm_demod_fft = fftsink2.fft_sink_f(self.panel, title="Post FM Demod", + fft_size=512, sample_rate=demod_rate, + y_per_div=10, ref_level=0) self.connect (self.guts.fm_demod, post_fm_demod_fft) vbox.Add (post_fm_demod_fft.win, 4, wx.EXPAND) if 0: - post_stereo_carrier_generator_fft = fftsink.fft_sink_c (self, self.panel, title="Post Stereo_carrier_generator", + post_stereo_carrier_generator_fft = fftsink2.fft_sink_c (self.panel, title="Post Stereo_carrier_generator", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0) self.connect (self.guts.stereo_carrier_generator, post_stereo_carrier_generator_fft) vbox.Add (post_stereo_carrier_generator_fft.win, 4, wx.EXPAND) if 0: - post_deemphasis_left = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Left", + post_deemphasis_left = fftsink2.fft_sink_f (self.panel, title="Post_Deemphasis_Left", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0) self.connect (self.guts.deemph_Left, post_deemphasis_left) vbox.Add (post_deemphasis_left.win, 4, wx.EXPAND) if 0: - post_deemphasis_right = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Right", + post_deemphasis_right = fftsink2.fft_sink_f(self.panel, title="Post_Deemphasis_Right", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect (self.guts.deemph_Left, post_deemphasis_right) @@ -181,14 +201,14 @@ class wfm_rx_graph (stdgui.gui_flow_graph): if 0: - LmR_fft = fftsink.fft_sink_f (self, self.panel, title="LmR", - fft_size=512, sample_rate=audio_rate, - y_per_div=10, ref_level=-20) + LmR_fft = fftsink2.fft_sink_f(self.panel, title="LmR", + fft_size=512, sample_rate=audio_rate, + y_per_div=10, ref_level=-20) self.connect (self.guts.LmR_real,LmR_fft) vbox.Add (LmR_fft.win, 4, wx.EXPAND) if 0: - self.scope = scopesink.scope_sink_f(self, self.panel, sample_rate=demod_rate) + self.scope = scopesink2.scope_sink_f(self.panel, sample_rate=demod_rate) self.connect (self.guts.fm_demod_a,self.scope) vbox.Add (self.scope.win,4,wx.EXPAND) @@ -322,5 +342,5 @@ class wfm_rx_graph (stdgui.gui_flow_graph): if __name__ == '__main__': - app = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX") + app = stdgui2.stdapp (wfm_rx_block, "USRP WFM RX") app.MainLoop () diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py index 64d51e22..1d39c769 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py +++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py @@ -53,11 +53,10 @@ OFDM. from gnuradio import gr, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks -from gnuradio.blksimpl.fm_emph import fm_deemph +from gnuradio.blks2impl.fm_emph import fm_deemph from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form +from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -76,9 +75,9 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class wfm_rx_sca_graph (stdgui.gui_flow_graph): +class wfm_rx_sca_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -179,7 +178,7 @@ class wfm_rx_sca_graph (stdgui.gui_flow_graph): self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) # Create deemphasis block that is applied after SCA demodulation - self.deemph = fm_deemph (self, audio_rate, sca_tau) + self.deemph = fm_deemph (audio_rate, sca_tau) self.volume_control = gr.multiply_const_ff(self.vol) @@ -228,27 +227,27 @@ class wfm_rx_sca_graph (stdgui.gui_flow_graph): return self.set_sca_freq(kv['sca_freq']) if 1: - self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", + self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1: - post_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post FM Demod", - fft_size=2048, sample_rate=demod_rate, - y_per_div=10, ref_level=0) + post_demod_fft = fftsink2.fft_sink_f(self.panel, title="Post FM Demod", + fft_size=2048, sample_rate=demod_rate, + y_per_div=10, ref_level=0) self.connect (self.fm_demod, post_demod_fft) vbox.Add (post_demod_fft.win, 4, wx.EXPAND) if 0: - post_demod_sca_fft = fftsink.fft_sink_f (self, self.panel, title="Post SCA Demod", + post_demod_sca_fft = fftsink2.fft_sink_f(self.panel, title="Post SCA Demod", fft_size=1024, sample_rate=sca_demod_rate, y_per_div=10, ref_level=0) self.connect (self.fm_demod_sca, post_demod_sca_fft) vbox.Add (post_demod_sca_fft.win, 4, wx.EXPAND) if 0: - post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post SCA Deemph", + post_deemph_fft = fftsink2.fft_sink_f (self.panel, title="Post SCA Deemph", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect (self.deemph, post_deemph_fft) @@ -395,5 +394,5 @@ class wfm_rx_sca_graph (stdgui.gui_flow_graph): if __name__ == '__main__': - app = stdgui.stdapp (wfm_rx_sca_graph, "USRP WFM SCA RX") + app = stdgui2.stdapp (wfm_rx_sca_block, "USRP WFM SCA RX") app.MainLoop () diff --git a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py b/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py index 39ad688e..983e3ec9 100755 --- a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py +++ b/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py @@ -1,12 +1,32 @@ #!/usr/bin/env python +# +# Copyright 2005,2006,2007 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, gru, eng_notation, optfir from gnuradio import audio from gnuradio import usrp -from gnuradio import blks +from gnuradio import blks2 from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui, fftsink, form +from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser from usrpm import usrp_dbid import sys @@ -26,9 +46,9 @@ def pick_subdevice(u): usrp_dbid.BASIC_RX)) -class wxapt_rx_graph (stdgui.gui_flow_graph): +class wxapt_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): - stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv) + stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, @@ -84,7 +104,7 @@ class wxapt_rx_graph (stdgui.gui_flow_graph): #print len(chan_filt_coeffs) chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation) + self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) self.volume_control = gr.multiply_const_ff(self.vol) @@ -127,20 +147,20 @@ class wxapt_rx_graph (stdgui.gui_flow_graph): if 1: - self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", + self.src_fft = fftsink2.fft_sink_c (self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1: - post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph", + post_deemph_fft = fftsink2.fft_sink_f (self.panel, title="Post Deemph", fft_size=512, sample_rate=demod_rate, y_per_div=10, ref_level=-20) self.connect (self.guts.deemph, post_deemph_fft) vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) if 1: - post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", + post_filt_fft = fftsink2.fft_sink_f (self.panel, title="Post Filter", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0) self.connect (self.guts.audio_filter, post_filt_fft) @@ -264,5 +284,5 @@ class wxapt_rx_graph (stdgui.gui_flow_graph): if __name__ == '__main__': - app = stdgui.stdapp (wxapt_rx_graph, "USRP WXAPT RX") + app = stdgui2.stdapp (wxapt_rx_block, "USRP WXAPT RX") app.MainLoop () diff --git a/gr-cvsd-vocoder/src/python/Makefile.am b/gr-cvsd-vocoder/src/python/Makefile.am index de8c351c..e22ad323 100644 --- a/gr-cvsd-vocoder/src/python/Makefile.am +++ b/gr-cvsd-vocoder/src/python/Makefile.am @@ -28,7 +28,7 @@ TESTS = \ run_tests -grblkspythondir = $(grpythondir)/blksimpl +grblkspythondir = $(grpythondir)/blks2impl grblkspython_PYTHON = \ cvsd.py diff --git a/gr-cvsd-vocoder/src/python/cvsd.py b/gr-cvsd-vocoder/src/python/cvsd.py index a69c783a..4defbf9a 100644 --- a/gr-cvsd-vocoder/src/python/cvsd.py +++ b/gr-cvsd-vocoder/src/python/cvsd.py @@ -23,7 +23,7 @@ from gnuradio import gr from gnuradio.vocoder import cvsd_vocoder -class cvsd_encode(gr.hier_block): +class cvsd_encode(gr.hier_block2): ''' This is a wrapper for the CVSD encoder that performs interpolation and filtering necessary to work with the vocoding. It converts an incoming float (+-1) to a short, scales @@ -33,11 +33,16 @@ class cvsd_encode(gr.hier_block): higher the interpolation rate are, the better the sound quality. ''' - def __init__(self, fg, resample=8, bw=0.5): + def __init__(self, resample=8, bw=0.5): ''' When using the CVSD vocoder, appropriate sampling rates are from 8k to 64k with resampling rates from 1 to 8. A rate of 8k with a resampling rate of 8 provides a good quality signal. ''' + + gr.hier_block2.__init__(self, "cvsd_encode", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_char)) # Output signature + scale_factor = 32000.0 self.interp = resample @@ -47,11 +52,10 @@ class cvsd_encode(gr.hier_block): f2s = gr.float_to_short() enc = cvsd_vocoder.encode_sb() - fg.connect(src_scale, interp, f2s, enc) - gr.hier_block.__init__(self, fg, src_scale, enc) + self.connect(self, src_scale, interp, f2s, enc, self) -class cvsd_decode(gr.hier_block): +class cvsd_decode(gr.hier_block2): ''' This is a wrapper for the CVSD decoder that performs decimation and filtering necessary to work with the vocoding. It converts an incoming CVSD-encoded short to a float, decodes it @@ -61,11 +65,15 @@ class cvsd_decode(gr.hier_block): higher the interpolation rate are, the better the sound quality. ''' - def __init__(self, fg, resample=8, bw=0.5): + def __init__(self, resample=8, bw=0.5): ''' When using the CVSD vocoder, appropriate sampling rates are from 8k to 64k with resampling rates from 1 to 8. A rate of 8k with a resampling rate of 8 provides a good quality signal. ''' + gr.hier_block2.__init__(self, "cvsd_decode", + gr.io_signature(1, 1, gr.sizeof_char), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + scale_factor = 32000.0 self.decim = resample @@ -75,6 +83,5 @@ class cvsd_decode(gr.hier_block): decim = gr.fir_filter_fff(self.decim, taps) sink_scale = gr.multiply_const_ff(1.0/scale_factor) - fg.connect(dec, s2f, decim, sink_scale) - gr.hier_block.__init__(self, fg, dec, sink_scale) + self.connect(self, dec, s2f, decim, sink_scale, self) diff --git a/gr-cvsd-vocoder/src/python/encdec.py b/gr-cvsd-vocoder/src/python/encdec.py index 0046857e..34c153b0 100755 --- a/gr-cvsd-vocoder/src/python/encdec.py +++ b/gr-cvsd-vocoder/src/python/encdec.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, blks +from gnuradio import gr, blks2 from gnuradio import audio from gnuradio.vocoder import cvsd_vocoder @@ -28,40 +28,42 @@ def build_graph(): sample_rate = 8000 scale_factor = 32000 - fg = gr.flow_graph() + tb = gr.top_block() src = audio.source(sample_rate, "plughw:0,0") src_scale = gr.multiply_const_ff(scale_factor) - interp = blks.rational_resampler_fff(fg, 8, 1) + interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short () enc = cvsd_vocoder.encode_sb() dec = cvsd_vocoder.decode_bs() s2f = gr.short_to_float () - decim = blks.rational_resampler_fff(fg, 1, 8) + decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0/scale_factor) sink = audio.sink(sample_rate, "plughw:0,0") - fg.connect(src, src_scale, interp, f2s, enc) - fg.connect(enc, dec, s2f, decim, sink_scale, sink) + tb.connect(src, src_scale, interp, f2s, enc) + tb.connect(enc, dec, s2f, decim, sink_scale, sink) if 0: # debug - fg.connect(src, gr.file_sink(gr.sizeof_float, "source.dat")) - fg.connect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) - fg.connect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) - fg.connect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) - fg.connect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) - fg.connect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) - fg.connect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) - fg.connect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) - fg.connect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) + tb.conect(src, gr.file_sink(gr.sizeof_float, "source.dat")) + tb.conect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) + tb.conect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) + tb.conect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) + tb.conect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) + tb.conect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) + tb.conect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) + tb.conect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) + tb.conect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) - return fg + return tb if __name__ == '__main__': - fg = build_graph() - fg.start() - raw_input ('Press Enter to exit: ') - fg.stop() + tb = build_graph() + print "Enter CTRL-C to stop" + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py b/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py index fc4a0d30..1a39f636 100755 --- a/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py +++ b/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py @@ -20,17 +20,18 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gr_unittest, blks +from gnuradio import gr, gr_unittest, blks2 import cvsd_vocoder class qa_cvsd_test (gr_unittest.TestCase): def setUp (self): - self.fg = gr.flow_graph () + self.tb = gr.top_block() def tearDown (self): - self.fg = None + self.tb = None + """ Disable for now def test01(self): sample_rate = 8000 scale_factor = 32000 @@ -90,23 +91,25 @@ class qa_cvsd_test (gr_unittest.TestCase): head = gr.head(gr.sizeof_float, 100) src_scale = gr.multiply_const_ff(scale_factor) - interp = blks.rational_resampler_fff(self.fg, 8, 1) + interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short () enc = cvsd_vocoder.encode_sb() dec = cvsd_vocoder.decode_bs() s2f = gr.short_to_float () - decim = blks.rational_resampler_fff(self.fg, 1, 8) + decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0/scale_factor) sink = gr.vector_sink_f() - self.fg.connect(src, head, src_scale, interp, f2s, enc) - self.fg.connect(enc, dec, s2f, decim, sink_scale, sink) - self.fg.run() - + self.tb.connect(src, src_scale, interp, f2s, enc) + self.tb.connect(enc, dec, s2f, decim, sink_scale, head, sink) + self.tb.run() + print sink.data() + self.assertFloatTuplesAlmostEqual (expected_data, sink.data(), 5) - + """ + if __name__ == '__main__': gr_unittest.main () diff --git a/gr-pager/src/usrp_flex_band.py b/gr-pager/src/usrp_flex_band.py index 7f494191..2f272575 100755 --- a/gr-pager/src/usrp_flex_band.py +++ b/gr-pager/src/usrp_flex_band.py @@ -53,6 +53,10 @@ class app_top_block(gr.top_block): if options.log: self.connect((bank, i), gr.file_sink(gr.sizeof_gr_complex, 'chan_'+'%3.3f'%(freq/1e6)+'.dat')) + def __del__(self): + # Avoid weak-ref error + del self.subdev + def main(): parser = OptionParser(option_class=eng_option) parser.add_option("-f", "--frequency", type="eng_float", default=929.5e6, diff --git a/gr-utils/src/python/usrp_fft.py b/gr-utils/src/python/usrp_fft.py index a8466092..bdec44ce 100755 --- a/gr-utils/src/python/usrp_fft.py +++ b/gr-utils/src/python/usrp_fft.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,7 +24,7 @@ from gnuradio import gr, gru from gnuradio import usrp from gnuradio import eng_notation from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider from optparse import OptionParser import wx import sys @@ -44,9 +44,9 @@ def pick_subdevice(u): return (0, 0) -class app_flow_graph(stdgui.gui_flow_graph): +class app_top_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__(self) + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -100,11 +100,11 @@ class app_flow_graph(stdgui.gui_flow_graph): if options.waterfall: self.scope = \ - waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate) + waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) elif options.oscilloscope: - self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate) + self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) else: - self.scope = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate) + self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, sample_rate=input_rate) self.connect(self.u, self.scope) @@ -253,7 +253,7 @@ class app_flow_graph(stdgui.gui_flow_graph): return ok def main (): - app = stdgui.stdapp(app_flow_graph, "USRP FFT", nstatus=1) + app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gr-utils/src/python/usrp_oscope.py b/gr-utils/src/python/usrp_oscope.py index 5d714928..7c202136 100755 --- a/gr-utils/src/python/usrp_oscope.py +++ b/gr-utils/src/python/usrp_oscope.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005,2006 Free Software Foundation, Inc. +# Copyright 2004,2005,2006,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -26,7 +26,7 @@ from gnuradio import gr, gru from gnuradio import usrp from gnuradio import eng_notation from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider +from gnuradio.wxgui import stdgui2, scopesink2, form, slider from optparse import OptionParser import wx import sys @@ -46,9 +46,9 @@ def pick_subdevice(u): return (0, 0) -class app_flow_graph(stdgui.gui_flow_graph): +class app_top_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__(self) + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -97,7 +97,7 @@ class app_flow_graph(stdgui.gui_flow_graph): input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate, + self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale) @@ -245,7 +245,7 @@ class app_flow_graph(stdgui.gui_flow_graph): return ok def main (): - app = stdgui.stdapp(app_flow_graph, "USRP O'scope", nstatus=1) + app = stdgui2.stdapp(app_top_block, "USRP O'scope", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gr-utils/src/python/usrp_rx_cfile.py b/gr-utils/src/python/usrp_rx_cfile.py index 306e101d..23a7a94d 100755 --- a/gr-utils/src/python/usrp_rx_cfile.py +++ b/gr-utils/src/python/usrp_rx_cfile.py @@ -11,11 +11,12 @@ from gnuradio import audio from gnuradio import usrp from gnuradio.eng_option import eng_option from optparse import OptionParser +import sys -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) usage="%prog: [options] output_filename" parser = OptionParser(option_class=eng_option, usage=usage) @@ -99,9 +100,12 @@ class my_graph(gr.flow_graph): sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 + def __del__(self): + # Avoid weak reference error + del self.subdev if __name__ == '__main__': try: - my_graph().run() + my_top_block().run() except KeyboardInterrupt: pass diff --git a/gr-utils/src/python/usrp_rx_nogui.py b/gr-utils/src/python/usrp_rx_nogui.py index b33d626e..a5d792c8 100755 --- a/gr-utils/src/python/usrp_rx_nogui.py +++ b/gr-utils/src/python/usrp_rx_nogui.py @@ -1,8 +1,29 @@ #!/usr/bin/env python - -from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks +# +# Copyright 2006,2007 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, gru, usrp, optfir, audio, eng_notation, blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser +import sys """ This example application demonstrates receiving and demodulating @@ -47,12 +68,12 @@ blocks. # (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod) demod_params = { - 'AM' : (250, 16, 1, 5000, 8000, blks.demod_10k0a3e_cf), - 'FM' : (250, 8, 4, 8000, 9000, blks.demod_20k0f3e_cf), - 'WFM' : (250, 1, 8, 90000, 100000, blks.demod_200kf3e_cf) + 'AM' : (250, 16, 1, 5000, 8000, blks2.demod_10k0a3e_cf), + 'FM' : (250, 8, 4, 8000, 9000, blks2.demod_20k0f3e_cf), + 'WFM' : (250, 1, 8, 90000, 100000, blks2.demod_200kf3e_cf) } -class usrp_source_c(gr.hier_block): +class usrp_src(gr.hier_block2): """ Create a USRP source object supplying complex floats. @@ -61,7 +82,11 @@ class usrp_source_c(gr.hier_block): Calibration value is the offset from the tuned frequency to the actual frequency. """ - def __init__(self, fg, subdev_spec, decim, gain=None, calibration=0.0): + def __init__(self, subdev_spec, decim, gain=None, calibration=0.0): + gr.hier_block2.__init__(self, "usrp_src", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + self._decim = decim self._src = usrp.source_c() if subdev_spec is None: @@ -77,7 +102,7 @@ class usrp_source_c(gr.hier_block): self._subdev.set_gain(gain) self._cal = calibration - gr.hier_block.__init__(self, fg, self._src, self._src) + self.connect(self._src, self) def tune(self, freq): result = usrp.tune(self._src, 0, self._subdev, freq+self._cal) @@ -86,20 +111,18 @@ class usrp_source_c(gr.hier_block): def rate(self): return self._src.adc_rate()/self._decim -class app_flow_graph(gr.flow_graph): - def __init__(self, options, args): - gr.flow_graph.__init__(self) +class app_top_block(gr.top_block): + def __init__(self, options): + gr.top_block.__init__(self) self.options = options - self.args = args (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod) = demod_params[options.modulation] - USRP = usrp_source_c(self, # Flow graph - options.rx_subdev_spec, # Daugherboard spec - usrp_decim, # IF decimation ratio - options.gain, # Receiver gain - options.calibration) # Frequency offset + USRP = usrp_src(options.rx_subdev_spec, # Daugherboard spec + usrp_decim, # IF decimation ratio + options.gain, # Receiver gain + options.calibration) # Frequency offset USRP.tune(options.frequency) if_rate = USRP.rate() @@ -128,7 +151,7 @@ class app_flow_graph(gr.flow_graph): 1.0, # Initial gain 1.0) # Maximum gain - DEMOD = demod(self, channel_rate, audio_decim) + DEMOD = demod(channel_rate, audio_decim) # From RF to audio self.connect(USRP, CHAN, RFSQL, AGC, DEMOD) @@ -145,7 +168,7 @@ class app_flow_graph(gr.flow_graph): out_lcm = gru.lcm(audio_rate, options.output_rate) out_interp = int(out_lcm // audio_rate) out_decim = int(out_lcm // options.output_rate) - RSAMP = blks.rational_resampler_fff(self, out_interp, out_decim) + RSAMP = blks2.rational_resampler_fff(out_interp, out_decim) self.connect(tail, RSAMP) tail = RSAMP @@ -155,7 +178,7 @@ class app_flow_graph(gr.flow_graph): def main(): parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--frequency", type="eng_float", + parser.add_option("-f", "--frequency", type="eng_float", default=None, help="set receive frequency to Hz", metavar="Hz") parser.add_option("-R", "--rx-subdev-spec", type="subdev", help="select USRP Rx side A or B", metavar="SUBDEV") @@ -173,12 +196,16 @@ def main(): help="set CTCSS squelch to FREQ", metavar="FREQ") (options, args) = parser.parse_args() + if options.frequency is None: + print "Must supply receive frequency with -f" + sys.exit(1) + if options.frequency < 1e6: options.frequency *= 1e6 - fg = app_flow_graph(options, args) + tb = app_top_block(options) try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gr-utils/src/python/usrp_siggen.py b/gr-utils/src/python/usrp_siggen.py index c2929939..af6eee16 100755 --- a/gr-utils/src/python/usrp_siggen.py +++ b/gr-utils/src/python/usrp_siggen.py @@ -8,9 +8,9 @@ from optparse import OptionParser import sys -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__ (self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) # controllable values self.interp = 64 @@ -148,36 +148,36 @@ def main (): parser.print_help() raise SystemExit - fg = my_graph() - fg.set_interpolator (options.interp) - fg.set_waveform_type (options.type) - fg.set_waveform_freq (options.waveform_freq) - fg.set_waveform_ampl (options.amplitude) - fg.set_waveform_offset (options.offset) + tb = my_top_block() + tb.set_interpolator (options.interp) + tb.set_waveform_type (options.type) + tb.set_waveform_freq (options.waveform_freq) + tb.set_waveform_ampl (options.amplitude) + tb.set_waveform_offset (options.offset) # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: - options.tx_subdev_spec = usrp.pick_tx_subdevice(fg.u) + options.tx_subdev_spec = usrp.pick_tx_subdevice(tb.u) - m = usrp.determine_tx_mux_value(fg.u, options.tx_subdev_spec) + m = usrp.determine_tx_mux_value(tb.u, options.tx_subdev_spec) #print "mux = %#04x" % (m,) - fg.u.set_mux(m) - fg.subdev = usrp.selected_subdev(fg.u, options.tx_subdev_spec) - print "Using TX d'board %s" % (fg.subdev.side_and_name(),) + tb.u.set_mux(m) + tb.subdev = usrp.selected_subdev(tb.u, options.tx_subdev_spec) + print "Using TX d'board %s" % (tb.subdev.side_and_name(),) if options.gain is None: - fg.subdev.set_gain(fg.subdev.gain_range()[1]) # set max Tx gain + tb.subdev.set_gain(fg.subdev.gain_range()[1]) # set max Tx gain else: - fg.subdev.set_gain(options.gain) # set max Tx gain + tb.subdev.set_gain(options.gain) # set max Tx gain - if not fg.set_freq(options.rf_freq): + if not tb.set_freq(options.rf_freq): sys.stderr.write('Failed to set RF frequency\n') raise SystemExit - fg.subdev.set_enable(True) # enable transmitter + tb.subdev.set_enable(True) # enable transmitter try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gr-utils/src/python/usrp_test_counting.py b/gr-utils/src/python/usrp_test_counting.py index ccfa948c..a8300afe 100755 --- a/gr-utils/src/python/usrp_test_counting.py +++ b/gr-utils/src/python/usrp_test_counting.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,20 +32,20 @@ from gnuradio import usrp def build_graph (): rx_decim = 32 - fg = gr.flow_graph () + tb = gr.top_block () usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_COUNTING) sink = gr.check_counting_s () - fg.connect (usrp_rx, sink) + tb.connect (usrp_rx, sink) # file_sink = gr.file_sink (gr.sizeof_short, 'counting.dat') - # fg.connect (usrp_rx, file_sink) + # tb.connect (usrp_rx, file_sink) - return fg + return tb def main (): - fg = build_graph () + tb = build_graph () try: - fg.run() + tb.run() except KeyboardInterrupt: pass diff --git a/gr-utils/src/python/usrp_test_loopback.py b/gr-utils/src/python/usrp_test_loopback.py index 51a705a0..b58ac06a 100755 --- a/gr-utils/src/python/usrp_test_loopback.py +++ b/gr-utils/src/python/usrp_test_loopback.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2004,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -29,7 +29,7 @@ from gnuradio import gr from gnuradio import usrp -def ramp_source (fg): +def ramp_source (tb): period = 2**16 src = gr.vector_source_s (range (-period/2, period/2, 1), True) return src @@ -38,26 +38,26 @@ def build_graph (): tx_interp = 32 # tx should be twice rx rx_decim = 16 - fg = gr.flow_graph () + tb = gr.top_block () - data_src = ramp_source (fg) + data_src = ramp_source (tb) # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98) usrp_tx = usrp.sink_s (0, tx_interp) - fg.connect (data_src, usrp_tx) + tb.connect (data_src, usrp_tx) usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) sink = gr.check_counting_s () - fg.connect (usrp_rx, sink) + tb.connect (usrp_rx, sink) # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat") - # fg.connect (usrp_rx, file_sink) + # tb.connect (usrp_rx, file_sink) - return fg + return tb def main (): - fg = build_graph () + tb = build_graph () try: - fg.run() + tb.run() except KeyboardInterrupt: pass -- 2.30.2