Merge branch 'dfsg-orig'
authorBdale Garbee <bdale@gag.com>
Fri, 8 Oct 2010 03:44:47 +0000 (21:44 -0600)
committerBdale Garbee <bdale@gag.com>
Fri, 8 Oct 2010 03:44:47 +0000 (21:44 -0600)
Conflicts:
gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT
grc/scripts/gnuradio-companion

1537 files changed:
.gitattributes [new file with mode: 0644]
.gitignore [new file with mode: 0644]
Makefile.am
Makefile.common
README
README-win32-mingw-short.txt [new file with mode: 0644]
README.building-boost [new file with mode: 0644]
README.ps3 [new file with mode: 0644]
config/.gitignore [new file with mode: 0644]
config/Makefile.am
config/gr_fortran.m4
config/gr_git.m4 [new file with mode: 0644]
config/gr_pwin32.m4
config/gr_python.m4
config/gr_set_md_cpu.m4
config/gr_version.m4 [new file with mode: 0644]
config/grc_gcell.m4
config/grc_gnuradio_core.m4
config/grc_gnuradio_examples.m4
config/grc_gr_atsc.m4
config/grc_gr_audio_alsa.m4
config/grc_gr_audio_jack.m4
config/grc_gr_audio_oss.m4
config/grc_gr_audio_osx.m4
config/grc_gr_audio_portaudio.m4
config/grc_gr_comedi.m4
config/grc_gr_cvsd_vocoder.m4
config/grc_gr_gsm_fr_vocoder.m4
config/grc_gr_msdd6000.m4
config/grc_gr_noaa.m4 [new file with mode: 0644]
config/grc_gr_pager.m4
config/grc_gr_qtgui.m4
config/grc_gr_trellis.m4
config/grc_gr_video_sdl.m4
config/grc_grc.m4
config/grc_gruel.m4
config/grc_usrp.m4
config/grc_usrp2.m4
config/usrp_fusb_tech.m4
config/usrp_libusb.m4 [changed mode: 0644->0755]
configure.ac
docs/.gitignore [new file with mode: 0644]
docs/doxygen/.gitignore [new file with mode: 0644]
docs/doxygen/Doxyfile.in
docs/doxygen/other/.gitignore [new file with mode: 0644]
docs/doxygen/other/Makefile.am
docs/doxygen/other/main_page.dox [new file with mode: 0644]
docs/doxygen/xml-swig/.gitignore [new file with mode: 0644]
docs/exploring-gnuradio/.gitignore [new file with mode: 0644]
docs/exploring-gnuradio/Makefile [new file with mode: 0644]
docs/exploring-gnuradio/ddc.eps [new file with mode: 0644]
docs/exploring-gnuradio/ddc.png [new file with mode: 0644]
docs/exploring-gnuradio/dial_tone.py [new file with mode: 0755]
docs/exploring-gnuradio/dial_tone_example.xml [new file with mode: 0644]
docs/exploring-gnuradio/exploring-gnuradio.xml [new file with mode: 0644]
docs/exploring-gnuradio/fm_demod.py [new file with mode: 0755]
docs/exploring-gnuradio/fm_demod_example.xml [new file with mode: 0644]
docs/exploring-gnuradio/swr-block-diagram.eps [new file with mode: 0644]
docs/exploring-gnuradio/swr-block-diagram.png [new file with mode: 0644]
docs/exploring-gnuradio/usrp-block-diagram.eps [new file with mode: 0644]
docs/exploring-gnuradio/usrp-block-diagram.png [new file with mode: 0644]
docs/howto-write-a-block/.gitignore [new file with mode: 0644]
docs/howto-write-a-block/Makefile.am [new file with mode: 0644]
docs/howto-write-a-block/README [new file with mode: 0644]
docs/howto-write-a-block/howto-write-a-block.xml [new file with mode: 0644]
docs/howto-write-a-block/howto_1.i [new file with mode: 0644]
docs/howto-write-a-block/make_numbered_listing.py [new file with mode: 0755]
docs/howto-write-a-block/qa_howto_1.py [new file with mode: 0755]
docs/howto-write-a-block/src_lib_Makefile_1.am [new file with mode: 0644]
docs/howto-write-a-block/src_lib_Makefile_2.am [new file with mode: 0644]
dtools/README [new file with mode: 0644]
dtools/bin/check-config-files [new file with mode: 0755]
dtools/bin/check-imports [new file with mode: 0755]
dtools/bin/check-tarball-h-files [new file with mode: 0755]
dtools/bin/get-config-files [new file with mode: 0755]
dtools/bin/install-tbb [new file with mode: 0755]
dtools/bin/make-upload [new file with mode: 0755]
dtools/bin/tweak-cell-for-cross-compiling [new file with mode: 0755]
dtools/bin/update_fsf_address [new file with mode: 0755]
dtools/microblaze/mb-gcc-4.1.1-gr-1.patch [new file with mode: 0644]
dtools/release-checklist [new file with mode: 0644]
gcell/.gitignore [new file with mode: 0644]
gcell/apps/.gitignore [new file with mode: 0644]
gcell/apps/Makefile.am
gcell/apps/benchmark_dma.cc
gcell/apps/benchmark_nop.cc
gcell/apps/benchmark_roundtrip.cc
gcell/apps/gen_script.py [new file with mode: 0755]
gcell/apps/plot_speedup.py [new file with mode: 0755]
gcell/apps/results-071223 [new file with mode: 0644]
gcell/apps/split_and_avg_results.py [new file with mode: 0755]
gcell/apps/spu/.gitignore [new file with mode: 0644]
gcell/gcell.pc.in
gcell/ibm/.gitignore [new file with mode: 0644]
gcell/include/.gitignore [new file with mode: 0644]
gcell/include/gcell/.gitignore [new file with mode: 0644]
gcell/include/gcell/spu/.gitignore [new file with mode: 0644]
gcell/lib/.gitignore [new file with mode: 0644]
gcell/lib/Makefile.am
gcell/lib/general/.gitignore [new file with mode: 0644]
gcell/lib/general/spu/.gitignore [new file with mode: 0644]
gcell/lib/runtime/.gitignore [new file with mode: 0644]
gcell/lib/runtime/Makefile.am
gcell/lib/runtime/gc_client_thread_info.h
gcell/lib/runtime/gc_job_manager_impl.cc
gcell/lib/runtime/gc_job_manager_impl.h
gcell/lib/runtime/spu/.gitignore [new file with mode: 0644]
gcell/lib/spu/.gitignore [new file with mode: 0644]
gcell/lib/wrapper/.gitignore [new file with mode: 0644]
gcell/lib/wrapper/qa_gcp_fft_1d_r2.cc [new file with mode: 0644]
gcell/lib/wrapper/spu/.gitignore [new file with mode: 0644]
gnuradio-core/.gitignore [new file with mode: 0644]
gnuradio-core/Makefile.am
gnuradio-core/gnuradio-core.pc.in
gnuradio-core/src/.gitignore [new file with mode: 0644]
gnuradio-core/src/Makefile.am
gnuradio-core/src/gen_interpolator_taps/.gitignore [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/Makefile.am
gnuradio-core/src/lib/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/Makefile.am
gnuradio-core/src/lib/filter/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/filter/Makefile.am
gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/filter.i
gnuradio-core/src/lib/filter/gr_cpu.h
gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc
gnuradio-core/src/lib/filter/gr_cpu_x86.cc
gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc [new file with mode: 0644]
gnuradio-core/src/lib/g72x/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/general/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/general/Makefile.am
gnuradio-core/src/lib/general/atsc_rrc1x.dat [new file with mode: 0644]
gnuradio-core/src/lib/general/atsc_rrc20.dat [new file with mode: 0644]
gnuradio-core/src/lib/general/atsc_rrc2x.dat [new file with mode: 0644]
gnuradio-core/src/lib/general/general.i
gnuradio-core/src/lib/general/general_generated.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constants.cc.in [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constants.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constants.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_copy.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_copy.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_copy.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fmdet_cf.cc
gnuradio-core/src/lib/general/gr_fmdet_cf.h
gnuradio-core/src/lib/general/gr_head.cc
gnuradio-core/src/lib/general/gr_head.h
gnuradio-core/src/lib/general/gr_head.i
gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.cc
gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
gnuradio-core/src/lib/general/gr_remez.cc
gnuradio-core/src/lib/general/gri_lfsr.h
gnuradio-core/src/lib/gengen/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/gengen/Makefile.am
gnuradio-core/src/lib/gengen/gr_vector_sink_X.h.t
gnuradio-core/src/lib/gengen/gr_vector_sink_X.i.t
gnuradio-core/src/lib/gnuradio-config-info.cc [new file with mode: 0644]
gnuradio-core/src/lib/hier/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/hier/Makefile.am
gnuradio-core/src/lib/io/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/io/Makefile.am
gnuradio-core/src/lib/io/gr_file_sink_base.cc
gnuradio-core/src/lib/io/gr_file_sink_base.h
gnuradio-core/src/lib/io/gr_histo_sink_f.cc
gnuradio-core/src/lib/io/gr_histo_sink_f.h
gnuradio-core/src/lib/io/gr_message_source.cc
gnuradio-core/src/lib/io/gr_message_source.h
gnuradio-core/src/lib/io/gr_message_source.i
gnuradio-core/src/lib/io/gr_udp_sink.cc
gnuradio-core/src/lib/io/gr_udp_sink.h
gnuradio-core/src/lib/io/gr_udp_sink.i
gnuradio-core/src/lib/io/gr_udp_source.cc
gnuradio-core/src/lib/io/gr_udp_source.h
gnuradio-core/src/lib/io/gr_udp_source.i
gnuradio-core/src/lib/io/gr_wavfile_sink.cc
gnuradio-core/src/lib/io/gr_wavfile_sink.h
gnuradio-core/src/lib/io/gri_wavfile.cc
gnuradio-core/src/lib/io/microtune_eval_board.i [new file with mode: 0644]
gnuradio-core/src/lib/missing/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/missing/Makefile.am
gnuradio-core/src/lib/reed-solomon/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/Makefile.in.karn [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/encode_rs_ccsds.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/gen_ccsds.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/gen_ccsds_tal.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/rs.3 [new file with mode: 0644]
gnuradio-core/src/lib/runtime/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/runtime/Makefile.am
gnuradio-core/src/lib/runtime/gr_basic_block.cc
gnuradio-core/src/lib/runtime/gr_basic_block.h
gnuradio-core/src/lib/runtime/gr_block.cc
gnuradio-core/src/lib/runtime/gr_block.h
gnuradio-core/src/lib/runtime/gr_block_detail.cc
gnuradio-core/src/lib/runtime/gr_block_detail.h
gnuradio-core/src/lib/runtime/gr_block_executor.cc
gnuradio-core/src/lib/runtime/gr_buffer.cc
gnuradio-core/src/lib/runtime/gr_buffer.h
gnuradio-core/src/lib/runtime/gr_msg_accepter.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_accepter.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_queue.cc
gnuradio-core/src/lib/runtime/gr_msg_queue.h
gnuradio-core/src/lib/runtime/gr_msg_queue.i
gnuradio-core/src/lib/runtime/gr_sptr_magic.cc
gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
gnuradio-core/src/lib/runtime/gr_top_block_impl.h
gnuradio-core/src/lib/runtime/gr_tpb_detail.cc
gnuradio-core/src/lib/runtime/gr_tpb_detail.h
gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc [new file with mode: 0644]
gnuradio-core/src/lib/swig/.gitignore [new file with mode: 0644]
gnuradio-core/src/lib/swig/Makefile.am
gnuradio-core/src/lib/viterbi/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/bin/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/Makefile.am
gnuradio-core/src/python/gnuradio/blks2/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py
gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py
gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py
gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks2impl/stream_to_vector_decimator.py
gnuradio-core/src/python/gnuradio/eng_option.py
gnuradio-core/src/python/gnuradio/gr/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/Makefile.am
gnuradio-core/src/python/gnuradio/gr/prefs.py
gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_copy.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_integrate.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_message.py
gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py
gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gru/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/hexint.py
gnuradio-core/src/python/gnuradio/modulation_utils2.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/optfir.py
gnuradio-core/src/python/gnuradio/packet_utils.py
gnuradio-core/src/python/gnuradio/usrp_options.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/vocoder/.gitignore [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/window.py
gnuradio-core/src/tests/.gitignore [new file with mode: 0644]
gnuradio-core/src/tests/nco_results [new file with mode: 0644]
gnuradio-core/src/tests/test_atsc.cc [new file with mode: 0644]
gnuradio-core/src/utils/.gitignore [new file with mode: 0644]
gnuradio-core/src/utils/cool.m [new file with mode: 0644]
gnuradio-core/src/utils/is_complex.m [new file with mode: 0644]
gnuradio-core/src/utils/lp_to_bp.m [new file with mode: 0644]
gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm [new file with mode: 0644]
gnuradio-core/src/utils/permute.scm [new file with mode: 0644]
gnuradio-core/src/utils/plot_cic_decimator_response.m [new file with mode: 0644]
gnuradio-core/src/utils/rainbow.m [new file with mode: 0644]
gnuradio-core/src/utils/read_xambi.m [new file with mode: 0644]
gnuradio-core/src/utils/runsum.m [new file with mode: 0644]
gnuradio-core/src/utils/split_vect.m [new file with mode: 0644]
gnuradio-examples/.gitignore [new file with mode: 0644]
gnuradio-examples/Makefile.am
gnuradio-examples/c++/.gitignore [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/.gitignore [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/Makefile.am [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/README [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/dial_tone.cc [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/dial_tone.h [new file with mode: 0644]
gnuradio-examples/c++/dial_tone/main.cc [new file with mode: 0644]
gnuradio-examples/grc/.gitignore [new file with mode: 0644]
gnuradio-examples/grc/Makefile.am [new file with mode: 0644]
gnuradio-examples/grc/audio/cvsd_sweep.grc [new file with mode: 0644]
gnuradio-examples/grc/audio/dial_tone.grc [new file with mode: 0644]
gnuradio-examples/grc/demod/digital_freq_lock.grc [new file with mode: 0644]
gnuradio-examples/grc/demod/mpsk_demod.grc [new file with mode: 0644]
gnuradio-examples/grc/demod/pam_sync.grc [new file with mode: 0644]
gnuradio-examples/grc/demod/pam_timing.grc [new file with mode: 0644]
gnuradio-examples/grc/simple/ber_simulation.grc [new file with mode: 0644]
gnuradio-examples/grc/simple/dpsk_loopback.grc [new file with mode: 0644]
gnuradio-examples/grc/simple/var_sink_taps.grc [new file with mode: 0644]
gnuradio-examples/grc/simple/variable_config.grc [new file with mode: 0644]
gnuradio-examples/grc/trellis/interference_cancellation.grc [new file with mode: 0644]
gnuradio-examples/grc/trellis/readme.txt [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp2_const_wave.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp2_dpsk_mod.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp2_fft.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp_rx_dpsk.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp_two_tone_loopback.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp_tx_dpsk.grc [new file with mode: 0644]
gnuradio-examples/grc/usrp/usrp_wbfm_receive.grc [new file with mode: 0644]
gnuradio-examples/grc/xmlrpc/readme.txt [new file with mode: 0644]
gnuradio-examples/grc/xmlrpc/xmlrpc_client.grc [new file with mode: 0644]
gnuradio-examples/grc/xmlrpc/xmlrpc_client_script.py [new file with mode: 0644]
gnuradio-examples/grc/xmlrpc/xmlrpc_server.grc [new file with mode: 0644]
gnuradio-examples/python/.gitignore [new file with mode: 0644]
gnuradio-examples/python/Makefile.am
gnuradio-examples/python/apps/.gitignore [new file with mode: 0644]
gnuradio-examples/python/apps/hf_explorer/.gitignore [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/.gitignore [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/input.py
gnuradio-examples/python/audio/.gitignore [new file with mode: 0644]
gnuradio-examples/python/digital-bert/.gitignore [new file with mode: 0644]
gnuradio-examples/python/digital/.gitignore [new file with mode: 0644]
gnuradio-examples/python/digital/Makefile.am
gnuradio-examples/python/digital/benchmark_loopback.py
gnuradio-examples/python/digital/benchmark_qt_loopback.py
gnuradio-examples/python/digital/benchmark_qt_loopback2.py [new file with mode: 0755]
gnuradio-examples/python/digital/benchmark_qt_rx.py
gnuradio-examples/python/digital/benchmark_qt_rx2.py [new file with mode: 0755]
gnuradio-examples/python/digital/benchmark_rx2.py [new file with mode: 0755]
gnuradio-examples/python/digital/benchmark_tx2.py [new file with mode: 0755]
gnuradio-examples/python/digital/pick_bitrate2.py [new file with mode: 0644]
gnuradio-examples/python/digital/qt_digital_window.py
gnuradio-examples/python/digital/qt_digital_window.ui
gnuradio-examples/python/digital/qt_digital_window2.py [new file with mode: 0644]
gnuradio-examples/python/digital/qt_digital_window2.ui [new file with mode: 0644]
gnuradio-examples/python/digital/qt_rx_window.py
gnuradio-examples/python/digital/qt_rx_window.ui
gnuradio-examples/python/digital/qt_rx_window2.py [new file with mode: 0644]
gnuradio-examples/python/digital/qt_rx_window2.ui [new file with mode: 0644]
gnuradio-examples/python/digital/receive_path.py
gnuradio-examples/python/digital/transmit_path.py
gnuradio-examples/python/digital/usrp_receive_path.py
gnuradio-examples/python/digital/usrp_receive_path2.py [new file with mode: 0644]
gnuradio-examples/python/digital/usrp_transmit_path.py
gnuradio-examples/python/digital/usrp_transmit_path2.py [new file with mode: 0644]
gnuradio-examples/python/digital_voice/.gitignore [new file with mode: 0644]
gnuradio-examples/python/mp-sched/.gitignore [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/core-duo.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/js21.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/ps3.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/qs21.dat [new file with mode: 0644]
gnuradio-examples/python/multi-antenna/.gitignore [new file with mode: 0644]
gnuradio-examples/python/multi_usrp/.gitignore [new file with mode: 0644]
gnuradio-examples/python/network/.gitignore [new file with mode: 0644]
gnuradio-examples/python/network/audio_sink.py
gnuradio-examples/python/network/audio_source.py
gnuradio-examples/python/network/dial_tone_sink.py
gnuradio-examples/python/network/dial_tone_source.py
gnuradio-examples/python/network/vector_sink.py
gnuradio-examples/python/network/vector_source.py
gnuradio-examples/python/ofdm/.gitignore [new file with mode: 0644]
gnuradio-examples/python/ofdm/gr_plot_ofdm.py [new file with mode: 0755]
gnuradio-examples/python/pfb/.gitignore [new file with mode: 0644]
gnuradio-examples/python/pfb/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/pfb/channelize.py [new file with mode: 0755]
gnuradio-examples/python/pfb/chirp_channelize.py [new file with mode: 0755]
gnuradio-examples/python/pfb/decimate.py [new file with mode: 0755]
gnuradio-examples/python/pfb/fmtest.py [new file with mode: 0755]
gnuradio-examples/python/pfb/interpolate.py [new file with mode: 0755]
gnuradio-examples/python/pfb/resampler_demo.grc [new file with mode: 0644]
gnuradio-examples/python/usrp/.gitignore [new file with mode: 0644]
gnuradio-examples/python/usrp/usrp_am_mw_rcv.py
gnuradio-examples/python/usrp/usrp_tv_rcv.py
gnuradio-examples/python/usrp/usrp_wfm_rcv.py
gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py
gnuradio-examples/python/usrp/usrp_wfm_rcv_fmdet.py
gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py
gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py
gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py
gnuradio-examples/python/usrp/usrp_wxapt_rcv.py
gnuradio-examples/python/usrp2/.gitignore [new file with mode: 0644]
gnuradio-examples/python/usrp2/usrp2_wfm_qt.py
gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py
gnuradio-pkg_chk.conf [new file with mode: 0644]
gr-atsc/.gitignore [new file with mode: 0644]
gr-atsc/Makefile.am [new file with mode: 0644]
gr-atsc/README [new file with mode: 0644]
gr-atsc/README.signal_flow [new file with mode: 0644]
gr-atsc/doc/.gitignore [new file with mode: 0644]
gr-atsc/doc/Makefile.am [new file with mode: 0644]
gr-atsc/gnuradio-atsc.pc.in [new file with mode: 0644]
gr-atsc/src/.gitignore [new file with mode: 0644]
gr-atsc/src/Makefile.am [new file with mode: 0644]
gr-atsc/src/lib/.gitignore [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop2.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop2.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop3.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscBitTimingLoop3.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscConvert2xTo20.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscConvert2xTo20.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDeinterleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDeinterleaver.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDerandomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscDerandomizer.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscEqualizer.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscEqualizer.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFPLL.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFPLL.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncChecker.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncChecker.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncDemux.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncDemux.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncMux.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscFieldSyncMux.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscInterleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscInterleaver.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRSDecoder.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRSDecoder.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRSEncoder.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRSEncoder.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRandomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscRandomizer.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSegSymSync.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSegSymSync.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSegSymSyncImpl.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscSymbolMapper.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscTrellisEncoder.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscTrellisEncoder.h [new file with mode: 0644]
gr-atsc/src/lib/GrAtscViterbiDecoder.cc [new file with mode: 0644]
gr-atsc/src/lib/GrAtscViterbiDecoder.h [new file with mode: 0644]
gr-atsc/src/lib/Makefile.am [new file with mode: 0644]
gr-atsc/src/lib/Makefile.swig.gen [new file with mode: 0644]
gr-atsc/src/lib/atsc.i [new file with mode: 0644]
gr-atsc/src/lib/atsc_bit_timing_loop.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_bit_timing_loop.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_consts.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_deinterleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_deinterleaver.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_depad.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_depad.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_derandomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_derandomizer.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_ds_to_softds.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_ds_to_softds.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_equalizer.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_equalizer.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_field_sync_demux.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_field_sync_demux.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_field_sync_mux.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_field_sync_mux.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_fpll.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_fpll.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_fs_checker.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_fs_checker.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_interleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_interleaver.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_pad.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_pad.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_randomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_randomizer.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_rs_decoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_rs_decoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_rs_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_rs_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_trellis_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_trellis_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_types.h [new file with mode: 0644]
gr-atsc/src/lib/atsc_viterbi_decoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsc_viterbi_decoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_basic_trellis_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_basic_trellis_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_data_interleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_data_interleaver.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_diag_output.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_lms.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_lms.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_lms2.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_lms2.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_nop.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_equalizer_nop.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_exp2_lp.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_exp2_lp.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_exp2_lp20.dat [new file with mode: 0644]
gr-atsc/src/lib/atsci_exp2_lp2x.dat [new file with mode: 0644]
gr-atsc/src/lib/atsci_fake_single_viterbi.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_fake_single_viterbi.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_checker.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_checker.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_checker_naive.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_checker_naive.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_correlator.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_correlator.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_correlator_naive.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_fs_correlator_naive.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_pnXXX.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_pnXXX.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_randomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_randomizer.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_reed_solomon.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_reed_solomon.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_root_raised_cosine.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_root_raised_cosine.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_single_viterbi.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_single_viterbi.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_slicer_agc.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_sliding_correlator.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_sliding_correlator.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_sssr.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_sssr.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_syminfo.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_sync_tag.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_trellis_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_trellis_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_viterbi_decoder.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_viterbi_decoder.h [new file with mode: 0644]
gr-atsc/src/lib/atsci_viterbi_gen.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_vsbtx_lp.cc [new file with mode: 0644]
gr-atsc/src/lib/atsci_vsbtx_lp.dat [new file with mode: 0644]
gr-atsc/src/lib/atsci_vsbtx_lp.h [new file with mode: 0644]
gr-atsc/src/lib/convolutional_interleaver.h [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_equalizer.cc [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_equalizer.h [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_fs_checker.cc [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_fs_checker.h [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_fs_correlator.cc [new file with mode: 0644]
gr-atsc/src/lib/create_atsci_fs_correlator.h [new file with mode: 0644]
gr-atsc/src/lib/fpll_btloop_coupling.h [new file with mode: 0644]
gr-atsc/src/lib/gen_encoder.py [new file with mode: 0755]
gr-atsc/src/lib/interleaver_fifo.h [new file with mode: 0644]
gr-atsc/src/lib/plinfo.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_data_interleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_data_interleaver.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_equalizer_nop.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_equalizer_nop.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_fs_correlator.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_fs_correlator.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_randomizer.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_randomizer.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_reed_solomon.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_reed_solomon.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_single_viterbi.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_single_viterbi.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_sliding_correlator.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_sliding_correlator.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_trellis_encoder.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_trellis_encoder.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_viterbi_decoder.h [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat [new file with mode: 0644]
gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat [new file with mode: 0644]
gr-atsc/src/lib/qa_convolutional_interleaver.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_convolutional_interleaver.h [new file with mode: 0644]
gr-atsc/src/lib/qa_interleaver_fifo.cc [new file with mode: 0644]
gr-atsc/src/lib/qa_interleaver_fifo.h [new file with mode: 0644]
gr-atsc/src/lib/test_atsci.cc [new file with mode: 0644]
gr-atsc/src/python/.gitignore [new file with mode: 0644]
gr-atsc/src/python/Makefile.am [new file with mode: 0644]
gr-atsc/src/python/README [new file with mode: 0644]
gr-atsc/src/python/atsc_utils.py [new file with mode: 0644]
gr-atsc/src/python/btl-fsd.py [new file with mode: 0755]
gr-atsc/src/python/fpll.py [new file with mode: 0755]
gr-atsc/src/python/interp.py [new file with mode: 0755]
gr-atsc/src/python/interp_short.py [new file with mode: 0755]
gr-atsc/src/python/qa_atsc.py [new file with mode: 0755]
gr-atsc/src/python/run_tests.in [new file with mode: 0644]
gr-atsc/src/python/viterbi-out.py [new file with mode: 0755]
gr-atsc/src/python/xlate.py [new file with mode: 0755]
gr-audio-alsa/.gitignore [new file with mode: 0644]
gr-audio-alsa/Makefile.am
gr-audio-alsa/build-stamp [new file with mode: 0644]
gr-audio-alsa/gnuradio-audio-alsa.pc.in [new file with mode: 0644]
gr-audio-alsa/src/.gitignore [new file with mode: 0644]
gr-audio-alsa/src/Makefile.am
gr-audio-jack/.gitignore [new file with mode: 0644]
gr-audio-jack/Makefile.am
gr-audio-jack/gnuradio-audio-jack.pc.in [new file with mode: 0644]
gr-audio-jack/src/.gitignore [new file with mode: 0644]
gr-audio-jack/src/Makefile.am
gr-audio-oss/.gitignore [new file with mode: 0644]
gr-audio-oss/Makefile.am
gr-audio-oss/gnuradio-audio-oss.pc.in [new file with mode: 0644]
gr-audio-oss/src/.gitignore [new file with mode: 0644]
gr-audio-oss/src/Makefile.am
gr-audio-osx/.gitignore [new file with mode: 0644]
gr-audio-osx/src/.gitignore [new file with mode: 0644]
gr-audio-osx/src/Makefile.am
gr-audio-osx/src/audio_osx.h
gr-audio-osx/src/audio_osx_sink.cc
gr-audio-osx/src/audio_osx_sink.h
gr-audio-osx/src/audio_osx_source.cc
gr-audio-osx/src/audio_osx_source.h
gr-audio-osx/src/circular_buffer.h
gr-audio-portaudio/.gitignore [new file with mode: 0644]
gr-audio-portaudio/Makefile.am
gr-audio-portaudio/autoconfiscate.patch [new file with mode: 0755]
gr-audio-portaudio/gnuradio-audio-portaudio.pc.in [new file with mode: 0644]
gr-audio-portaudio/src/.gitignore [new file with mode: 0644]
gr-audio-portaudio/src/Makefile.am
gr-audio-portaudio/src/audio_portaudio_sink.cc
gr-audio-portaudio/src/audio_portaudio_sink.h
gr-audio-portaudio/src/audio_portaudio_source.cc
gr-audio-portaudio/src/audio_portaudio_source.h
gr-audio-windows/.gitignore [new file with mode: 0644]
gr-audio-windows/src/.gitignore [new file with mode: 0644]
gr-audio-windows/src/Makefile.am
gr-comedi/.gitignore [new file with mode: 0644]
gr-comedi/Makefile.am [new file with mode: 0644]
gr-comedi/README [new file with mode: 0644]
gr-comedi/gnuradio-comedi.pc.in [new file with mode: 0644]
gr-comedi/src/.gitignore [new file with mode: 0644]
gr-comedi/src/Makefile.am [new file with mode: 0644]
gr-comedi/src/Makefile.swig.gen [new file with mode: 0644]
gr-comedi/src/comedi.i [new file with mode: 0644]
gr-comedi/src/comedi_sink_s.cc [new file with mode: 0644]
gr-comedi/src/comedi_sink_s.h [new file with mode: 0644]
gr-comedi/src/comedi_source_s.cc [new file with mode: 0644]
gr-comedi/src/comedi_source_s.h [new file with mode: 0644]
gr-comedi/src/gri_comedi.cc [new file with mode: 0644]
gr-comedi/src/gri_comedi.h [new file with mode: 0644]
gr-comedi/src/qa_comedi.py [new file with mode: 0755]
gr-comedi/src/run_tests.in [new file with mode: 0644]
gr-cvsd-vocoder/.gitignore [new file with mode: 0644]
gr-cvsd-vocoder/Makefile.am
gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc.in [new file with mode: 0644]
gr-cvsd-vocoder/src/.gitignore [new file with mode: 0644]
gr-cvsd-vocoder/src/Makefile.am
gr-cvsd-vocoder/src/lib/.gitignore [new file with mode: 0644]
gr-cvsd-vocoder/src/lib/Makefile.am
gr-cvsd-vocoder/src/python/.gitignore [new file with mode: 0644]
gr-gcell/.gitignore [new file with mode: 0644]
gr-gcell/src/.gitignore [new file with mode: 0644]
gr-gcell/src/Makefile.am
gr-gcell/src/examples/.gitignore [new file with mode: 0644]
gr-gpio/.gitignore [new file with mode: 0644]
gr-gpio/src/.gitignore [new file with mode: 0644]
gr-gpio/src/Makefile.am
gr-gpio/src/fpga/.gitignore [new file with mode: 0644]
gr-gpio/src/fpga/include/.gitignore [new file with mode: 0644]
gr-gpio/src/fpga/lib/.gitignore [new file with mode: 0644]
gr-gpio/src/fpga/rbf/.gitignore [new file with mode: 0644]
gr-gpio/src/fpga/top/.gitignore [new file with mode: 0644]
gr-gpio/src/python/.gitignore [new file with mode: 0644]
gr-gpio/src/python/gpio.py
gr-gpio/src/python/gpio_usrp_fft.py
gr-gsm-fr-vocoder/.gitignore [new file with mode: 0644]
gr-gsm-fr-vocoder/Makefile.am
gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in [new file with mode: 0644]
gr-gsm-fr-vocoder/src/.gitignore [new file with mode: 0644]
gr-gsm-fr-vocoder/src/Makefile.am
gr-gsm-fr-vocoder/src/lib/.gitignore [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/Makefile.am
gr-gsm-fr-vocoder/src/lib/gsm/.gitignore [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/README.gsm [new file with mode: 0644]
gr-gsm-fr-vocoder/src/python/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/AUTHORS [new file with mode: 0644]
gr-howto-write-a-block/COPYING [new file with mode: 0644]
gr-howto-write-a-block/ChangeLog [new file with mode: 0644]
gr-howto-write-a-block/INSTALL [new file with mode: 0644]
gr-howto-write-a-block/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/Makefile.common [new file with mode: 0644]
gr-howto-write-a-block/Makefile.swig [new file with mode: 0644]
gr-howto-write-a-block/Makefile.swig.gen.t [new file with mode: 0644]
gr-howto-write-a-block/NEWS [new file with mode: 0644]
gr-howto-write-a-block/README [new file with mode: 0644]
gr-howto-write-a-block/README.hacking [new file with mode: 0644]
gr-howto-write-a-block/apps/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/apps/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/apps/howto_square.grc [new file with mode: 0644]
gr-howto-write-a-block/apps/howto_square.py [new file with mode: 0755]
gr-howto-write-a-block/bootstrap [new file with mode: 0755]
gr-howto-write-a-block/config.guess [new file with mode: 0755]
gr-howto-write-a-block/config.sub [new file with mode: 0755]
gr-howto-write-a-block/config/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/config/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/config/acx_pthread.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_base.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_date_time.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_filesystem.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_iostreams.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_program_options.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_python.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_regex.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_serialization.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_signals.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_system.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_test_exec_monitor.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_thread.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_unit_test_framework.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/ax_boost_wserialization.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/bnv_have_qt.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/cppunit.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_check_createfilemapping.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_check_mc4020.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_check_shm_open.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_check_usrp.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_doxygen.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_fortran.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_git.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_gprof.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_lib64.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_libgnuradio_core_extra_ldflags.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_no_undefined.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_omnithread.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_pwin32.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_python.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_require_mc4020.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_scripting.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_set_md_cpu.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_standalone.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_subversion.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_swig.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_sysv_shm.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_version.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/lf_cc.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/lf_cxx.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/lf_warnings.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/lf_x11.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/mkstemp.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/onceonly.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/pkg.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/usrp_fusb_tech.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/usrp_libusb.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/usrp_sdcc.m4 [new file with mode: 0644]
gr-howto-write-a-block/configure.ac [new file with mode: 0644]
gr-howto-write-a-block/grc/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/grc/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/grc/howto_square2_ff.xml [new file with mode: 0644]
gr-howto-write-a-block/grc/howto_square_ff.xml [new file with mode: 0644]
gr-howto-write-a-block/lib/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/lib/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square2_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square2_ff.h [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square_ff.h [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto.h [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto_square2_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto_square2_ff.h [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto_square_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/qa_howto_square_ff.h [new file with mode: 0644]
gr-howto-write-a-block/lib/test_all.cc [new file with mode: 0644]
gr-howto-write-a-block/python/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/python/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/python/__init__.py [new file with mode: 0644]
gr-howto-write-a-block/python/qa_howto.py [new file with mode: 0755]
gr-howto-write-a-block/python/run_tests.in [new file with mode: 0644]
gr-howto-write-a-block/swig/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/swig/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/swig/Makefile.swig.gen [new file with mode: 0644]
gr-howto-write-a-block/swig/howto.i [new file with mode: 0644]
gr-howto-write-a-block/swig/howto_square2_ff.i [new file with mode: 0644]
gr-howto-write-a-block/swig/howto_square_ff.i [new file with mode: 0644]
gr-howto-write-a-block/version.sh [new file with mode: 0644]
gr-msdd6000/.gitignore [new file with mode: 0644]
gr-msdd6000/Makefile.am [new file with mode: 0644]
gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf [new file with mode: 0644]
gr-msdd6000/gnuradio-msdd6000.pc.in [new file with mode: 0644]
gr-msdd6000/src/.gitignore [new file with mode: 0644]
gr-msdd6000/src/Makefile.am [new file with mode: 0644]
gr-msdd6000/src/Makefile.swig.gen [new file with mode: 0644]
gr-msdd6000/src/README [new file with mode: 0644]
gr-msdd6000/src/msdd.i [new file with mode: 0644]
gr-msdd6000/src/msdd6000.cc [new file with mode: 0644]
gr-msdd6000/src/msdd6000.h [new file with mode: 0644]
gr-msdd6000/src/msdd6000_rs.cc [new file with mode: 0644]
gr-msdd6000/src/msdd6000_rs.h [new file with mode: 0644]
gr-msdd6000/src/msdd_buffer_copy_behaviors.h [new file with mode: 0644]
gr-msdd6000/src/msdd_rs.i [new file with mode: 0644]
gr-msdd6000/src/msdd_rs_source_simple.cc [new file with mode: 0644]
gr-msdd6000/src/msdd_rs_source_simple.h [new file with mode: 0644]
gr-msdd6000/src/msdd_source_simple.cc [new file with mode: 0644]
gr-msdd6000/src/msdd_source_simple.h [new file with mode: 0644]
gr-msdd6000/src/python-examples/msdd_dynamics.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/msdd_fft.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/msdd_rcv.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/msdd_rs_spec_an.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/msdd_spectrum_sense.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/new_msdd_fft.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/ofdm/benchmark_ofdm_rx.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/ofdm/gr_plot_ofdm.py [new file with mode: 0755]
gr-msdd6000/src/python-examples/ofdm/receive_path.py [new file with mode: 0644]
gr-msdd6000/src/python-examples/playback_samples.m [new file with mode: 0644]
gr-msdd6000/src/python-examples/read_complex_binary.m [new file with mode: 0644]
gr-msdd6000/src/python_test/capture_tcp_one_set.py [new file with mode: 0644]
gr-msdd6000/src/python_test/flood_udp.py [new file with mode: 0644]
gr-msdd6000/src/python_test/halt.py [new file with mode: 0644]
gr-msdd6000/src/python_test/newtest.py [new file with mode: 0644]
gr-msdd6000/src/python_test/spectrogram.py [new file with mode: 0644]
gr-msdd6000/src/python_test/test_tcp.py [new file with mode: 0755]
gr-msdd6000/src/python_test/test_tcp_fft.py [new file with mode: 0644]
gr-msdd6000/src/python_test/test_udp.py [new file with mode: 0755]
gr-msdd6000/src/python_test/udp_stream_cap.py [new file with mode: 0644]
gr-msdd6000/src/python_test/udp_stream_rate_test.py [new file with mode: 0644]
gr-msdd6000/src/python_test/udp_stream_rate_test_plot.py [new file with mode: 0644]
gr-msdd6000/src/python_test/udp_stream_rate_test_plot_loop.py [new file with mode: 0644]
gr-msdd6000/src/python_test/udp_stream_test.py [new file with mode: 0644]
gr-msdd6000/src/qa_msdd_source_simple.py [new file with mode: 0755]
gr-noaa/.gitignore [new file with mode: 0644]
gr-noaa/Makefile.am [new file with mode: 0644]
gr-noaa/README [new file with mode: 0644]
gr-noaa/apps/.gitignore [new file with mode: 0644]
gr-noaa/apps/Makefile.am [new file with mode: 0644]
gr-noaa/apps/file_rx_hrpt.grc [new file with mode: 0644]
gr-noaa/apps/file_rx_hrpt.py [new file with mode: 0755]
gr-noaa/apps/file_rx_lrit.grc [new file with mode: 0644]
gr-noaa/apps/file_rx_lrit.py [new file with mode: 0755]
gr-noaa/apps/hrpt_decode.grc [new file with mode: 0644]
gr-noaa/apps/hrpt_decode.py [new file with mode: 0755]
gr-noaa/apps/hrpt_demod.grc [new file with mode: 0644]
gr-noaa/apps/hrpt_demod.py [new file with mode: 0755]
gr-noaa/apps/usrp_rx_hrpt.grc [new file with mode: 0644]
gr-noaa/apps/usrp_rx_hrpt.py [new file with mode: 0755]
gr-noaa/apps/usrp_rx_hrpt_nogui.grc [new file with mode: 0644]
gr-noaa/apps/usrp_rx_hrpt_nogui.py [new file with mode: 0755]
gr-noaa/apps/usrp_rx_lrit.grc [new file with mode: 0644]
gr-noaa/apps/usrp_rx_lrit.py [new file with mode: 0755]
gr-noaa/grc/.gitignore [new file with mode: 0644]
gr-noaa/grc/Makefile.am [new file with mode: 0644]
gr-noaa/grc/noaa_hrpt_decoder.xml [new file with mode: 0644]
gr-noaa/grc/noaa_hrpt_deframer.xml [new file with mode: 0644]
gr-noaa/grc/noaa_hrpt_pll_cf.xml [new file with mode: 0644]
gr-noaa/lib/.gitignore [new file with mode: 0644]
gr-noaa/lib/Makefile.am [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt.h [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_decoder.cc [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_decoder.h [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_deframer.cc [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_deframer.h [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_pll_cf.cc [new file with mode: 0644]
gr-noaa/lib/noaa_hrpt_pll_cf.h [new file with mode: 0644]
gr-noaa/oct/.gitignore [new file with mode: 0644]
gr-noaa/oct/Makefile.am [new file with mode: 0644]
gr-noaa/oct/frames-to-png.sh [new file with mode: 0755]
gr-noaa/oct/frames_to_ppm.m [new file with mode: 0644]
gr-noaa/python/Makefile.am [new file with mode: 0644]
gr-noaa/swig/.gitignore [new file with mode: 0644]
gr-noaa/swig/Makefile.am [new file with mode: 0644]
gr-noaa/swig/Makefile.swig.gen [new file with mode: 0644]
gr-noaa/swig/__init__.py [new file with mode: 0644]
gr-noaa/swig/noaa_hrpt_decoder.i [new file with mode: 0644]
gr-noaa/swig/noaa_hrpt_deframer.i [new file with mode: 0644]
gr-noaa/swig/noaa_hrpt_pll_cf.i [new file with mode: 0644]
gr-noaa/swig/noaa_swig.i [new file with mode: 0644]
gr-pager/.gitignore [new file with mode: 0644]
gr-pager/Makefile.am
gr-pager/apps/.gitignore [new file with mode: 0644]
gr-pager/apps/Makefile.am [new file with mode: 0644]
gr-pager/apps/usrp_flex.py [new file with mode: 0755]
gr-pager/apps/usrp_flex_all.py [new file with mode: 0755]
gr-pager/apps/usrp_flex_band.py [new file with mode: 0755]
gr-pager/apps/usrp_rx_flex.grc [new file with mode: 0644]
gr-pager/apps/usrp_rx_flex.py [new file with mode: 0755]
gr-pager/gnuradio-pager.pc.in [new file with mode: 0644]
gr-pager/grc/.gitignore [new file with mode: 0644]
gr-pager/grc/Makefile.am [new file with mode: 0644]
gr-pager/grc/pager_flex_deinterleave.xml [new file with mode: 0644]
gr-pager/grc/pager_flex_sync.xml [new file with mode: 0644]
gr-pager/grc/pager_slicer_fb.xml [new file with mode: 0644]
gr-pager/lib/.gitignore [new file with mode: 0644]
gr-pager/lib/Makefile.am [new file with mode: 0644]
gr-pager/lib/Makefile.swig.gen [new file with mode: 0644]
gr-pager/lib/pager_flex_deinterleave.cc [new file with mode: 0644]
gr-pager/lib/pager_flex_deinterleave.h [new file with mode: 0644]
gr-pager/lib/pager_flex_frame.cc [new file with mode: 0644]
gr-pager/lib/pager_flex_frame.h [new file with mode: 0644]
gr-pager/lib/pager_flex_parse.cc [new file with mode: 0644]
gr-pager/lib/pager_flex_parse.h [new file with mode: 0644]
gr-pager/lib/pager_flex_sync.cc [new file with mode: 0644]
gr-pager/lib/pager_flex_sync.h [new file with mode: 0644]
gr-pager/lib/pager_slicer_fb.cc [new file with mode: 0644]
gr-pager/lib/pager_slicer_fb.h [new file with mode: 0644]
gr-pager/lib/pageri_bch3221.cc [new file with mode: 0644]
gr-pager/lib/pageri_bch3221.h [new file with mode: 0644]
gr-pager/lib/pageri_flex_modes.cc [new file with mode: 0644]
gr-pager/lib/pageri_flex_modes.h [new file with mode: 0644]
gr-pager/lib/pageri_util.cc [new file with mode: 0644]
gr-pager/lib/pageri_util.h [new file with mode: 0644]
gr-pager/python/.gitignore [new file with mode: 0644]
gr-pager/python/Makefile.am [new file with mode: 0644]
gr-pager/python/__init__.py [new file with mode: 0644]
gr-pager/python/flex_demod.py [new file with mode: 0644]
gr-pager/python/pager_utils.py [new file with mode: 0644]
gr-pager/python/qa_pager.py [new file with mode: 0755]
gr-pager/python/run_tests.in [new file with mode: 0644]
gr-pager/swig/.gitignore [new file with mode: 0644]
gr-pager/swig/Makefile.am [new file with mode: 0644]
gr-pager/swig/Makefile.swig.gen [new file with mode: 0644]
gr-pager/swig/pager_flex_deinterleave.i [new file with mode: 0644]
gr-pager/swig/pager_flex_frame.i [new file with mode: 0644]
gr-pager/swig/pager_flex_parse.i [new file with mode: 0644]
gr-pager/swig/pager_flex_sync.i [new file with mode: 0644]
gr-pager/swig/pager_slicer_fb.i [new file with mode: 0644]
gr-pager/swig/pager_swig.i [new file with mode: 0644]
gr-qtgui/.gitignore [new file with mode: 0644]
gr-qtgui/src/.gitignore [new file with mode: 0644]
gr-qtgui/src/Makefile.am
gr-qtgui/src/lib/.gitignore [new file with mode: 0644]
gr-qtgui/src/lib/ConstellationDisplayPlot.cc
gr-qtgui/src/lib/ConstellationDisplayPlot.h
gr-qtgui/src/lib/FrequencyDisplayPlot.cc
gr-qtgui/src/lib/FrequencyDisplayPlot.h
gr-qtgui/src/lib/Makefile.am
gr-qtgui/src/lib/SpectrumGUIClass.cc
gr-qtgui/src/lib/SpectrumGUIClass.h
gr-qtgui/src/lib/TimeDomainDisplayPlot.cc
gr-qtgui/src/lib/TimeDomainDisplayPlot.h
gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc
gr-qtgui/src/lib/Waterfall3DDisplayPlot.h
gr-qtgui/src/lib/WaterfallDisplayPlot.cc
gr-qtgui/src/lib/WaterfallDisplayPlot.h
gr-qtgui/src/lib/qtgui.i
gr-qtgui/src/lib/qtgui_sink_c.cc
gr-qtgui/src/lib/qtgui_sink_c.h
gr-qtgui/src/lib/qtgui_sink_f.cc
gr-qtgui/src/lib/qtgui_sink_f.h
gr-qtgui/src/lib/spectrumUpdateEvents.cc
gr-qtgui/src/lib/spectrumUpdateEvents.h
gr-qtgui/src/lib/spectrumdisplayform.cc
gr-qtgui/src/lib/spectrumdisplayform.h
gr-qtgui/src/lib/spectrumdisplayform.ui
gr-qtgui/src/lib/waterfallGlobalData.h
gr-qtgui/src/python/.gitignore [new file with mode: 0644]
gr-qtgui/src/python/pyqt_example.py
gr-qtgui/src/python/pyqt_example_f.py
gr-qtgui/src/python/qt_digital.py
gr-qtgui/src/python/qt_digital_window.py
gr-qtgui/src/python/qt_digital_window.ui
gr-qtgui/src/python/usrp2_display.py
gr-qtgui/src/python/usrp_display_qtgui.py [new file with mode: 0644]
gr-qtgui/src/python/usrp_display_qtgui.ui [new file with mode: 0644]
gr-radar-mono/.gitignore [new file with mode: 0644]
gr-radar-mono/doc/.gitignore [new file with mode: 0644]
gr-radar-mono/src/.gitignore [new file with mode: 0644]
gr-radar-mono/src/Makefile.am
gr-radar-mono/src/fpga/.gitignore [new file with mode: 0644]
gr-radar-mono/src/fpga/lib/.gitignore [new file with mode: 0644]
gr-radar-mono/src/fpga/models/.gitignore [new file with mode: 0644]
gr-radar-mono/src/fpga/tb/.gitignore [new file with mode: 0644]
gr-radar-mono/src/fpga/top/.gitignore [new file with mode: 0644]
gr-radar-mono/src/fpga/top/config.vh [new file with mode: 0644]
gr-radar-mono/src/fpga/top/dacpll.v [new file with mode: 0644]
gr-radar-mono/src/fpga/top/usrp_radar_mono.srf [new file with mode: 0644]
gr-radar-mono/src/lib/.gitignore [new file with mode: 0644]
gr-radar-mono/src/python/.gitignore [new file with mode: 0644]
gr-radar-mono/src/python/qa_nothing.py [new file with mode: 0644]
gr-radar-mono/src/utils/calc_avg.m [new file with mode: 0644]
gr-radar-mono/src/utils/czpad.m [new file with mode: 0644]
gr-radar-mono/src/utils/echo_image.m [new file with mode: 0644]
gr-radar-mono/src/utils/fftcorr.m [new file with mode: 0644]
gr-radar-mono/src/utils/pulse [new file with mode: 0644]
gr-radar-mono/src/utils/read_avg.m [new file with mode: 0644]
gr-radar-mono/src/utils/read_avg_sec.m [new file with mode: 0644]
gr-radar-mono/src/utils/read_echos.m [new file with mode: 0644]
gr-radio-astronomy/.gitignore [new file with mode: 0644]
gr-radio-astronomy/src/.gitignore [new file with mode: 0644]
gr-radio-astronomy/src/Makefile.am
gr-radio-astronomy/src/lib/.gitignore [new file with mode: 0644]
gr-radio-astronomy/src/lib/Makefile.am
gr-radio-astronomy/src/python/.gitignore [new file with mode: 0644]
gr-radio-astronomy/src/python/usrp_psr_receiver.help [new file with mode: 0644]
gr-radio-astronomy/src/python/usrp_psr_receiver.py
gr-radio-astronomy/src/python/usrp_ra_receiver.help [new file with mode: 0644]
gr-radio-astronomy/src/python/usrp_ra_receiver.py
gr-sounder/.gitignore [new file with mode: 0644]
gr-sounder/doc/.gitignore [new file with mode: 0644]
gr-sounder/src/.gitignore [new file with mode: 0644]
gr-sounder/src/Makefile.am
gr-sounder/src/fpga/.gitignore [new file with mode: 0644]
gr-sounder/src/fpga/lib/.gitignore [new file with mode: 0644]
gr-sounder/src/fpga/lib/lfsr.v [new file with mode: 0644]
gr-sounder/src/fpga/lib/lfsr_constants.v [new file with mode: 0644]
gr-sounder/src/fpga/tb/.gitignore [new file with mode: 0644]
gr-sounder/src/fpga/top/.gitignore [new file with mode: 0644]
gr-sounder/src/lib/.gitignore [new file with mode: 0644]
gr-sounder/src/python/.gitignore [new file with mode: 0644]
gr-trellis/.gitignore [new file with mode: 0644]
gr-trellis/Makefile.am
gr-trellis/doc/.gitignore [new file with mode: 0644]
gr-trellis/gnuradio-trellis.pc.in [new file with mode: 0644]
gr-trellis/src/.gitignore [new file with mode: 0644]
gr-trellis/src/Makefile.am
gr-trellis/src/examples/.gitignore [new file with mode: 0644]
gr-trellis/src/examples/fsm_files/.gitignore [new file with mode: 0644]
gr-trellis/src/examples/fsm_files/irregular.fsm [new file with mode: 0644]
gr-trellis/src/examples/fsm_files/joint_16_16.fsm [new file with mode: 0644]
gr-trellis/src/examples/fsm_files/joint_4_16.fsm [new file with mode: 0644]
gr-trellis/src/examples/test_cpm.py [new file with mode: 0755]
gr-trellis/src/lib/.gitignore [new file with mode: 0644]
gr-trellis/src/lib/Makefile.am
gr-trellis/src/python/.gitignore [new file with mode: 0644]
gr-usrp/.gitignore [new file with mode: 0644]
gr-usrp/apps/.gitignore [new file with mode: 0644]
gr-usrp/apps/Makefile.am
gr-usrp/gnuradio-usrp.pc.in
gr-usrp/src/.gitignore [new file with mode: 0644]
gr-usrp/src/Makefile.am
gr-usrp/src/flexrf_debug_gui.py [new file with mode: 0755]
gr-usrp/src/run_tests.in
gr-usrp/src/tx_debug_gui.py [new file with mode: 0755]
gr-usrp/src/usrp_base.cc
gr-usrp/src/usrp_base.h
gr-usrp/src/usrp_multi.py [new file with mode: 0644]
gr-usrp/src/usrp_sink_base.cc
gr-usrp/src/usrp_sink_base.h
gr-usrp/src/usrp_sink_c.cc
gr-usrp/src/usrp_sink_s.cc
gr-usrp/src/usrp_source_base.cc
gr-usrp/src/usrp_source_base.h
gr-usrp/src/usrp_source_c.cc
gr-usrp/src/usrp_source_s.cc
gr-usrp/src/usrp_standard.i
gr-usrp/src/usrp_swig.i
gr-usrp2/.gitignore [new file with mode: 0644]
gr-usrp2/gnuradio-usrp2.pc.in
gr-usrp2/src/.gitignore [new file with mode: 0644]
gr-usrp2/src/Makefile.am
gr-usrp2/src/run_tests.in
gr-usrp2/src/usrp2.i
gr-usrp2/src/usrp2_sink_16sc.cc
gr-usrp2/src/usrp2_sink_32fc.cc
gr-usrp2/src/usrp2_sink_base.cc
gr-usrp2/src/usrp2_sink_base.h
gr-usrp2/src/usrp2_source_base.cc
gr-usrp2/src/usrp2_source_base.h
gr-utils/.gitignore [new file with mode: 0644]
gr-utils/src/.gitignore [new file with mode: 0644]
gr-utils/src/Makefile.am
gr-utils/src/lib/.gitignore [new file with mode: 0644]
gr-utils/src/python/.gitignore [new file with mode: 0644]
gr-utils/src/python/Makefile.am
gr-utils/src/python/create-gnuradio-out-of-tree-project [new file with mode: 0755]
gr-utils/src/python/gr_filter_design.py [new file with mode: 0755]
gr-utils/src/python/gr_plot_const.py
gr-utils/src/python/gr_plot_fft.py
gr-utils/src/python/gr_plot_iq.py
gr-utils/src/python/gr_plot_psd.py
gr-utils/src/python/gr_plot_qt.py [new file with mode: 0755]
gr-utils/src/python/plot_data.py
gr-utils/src/python/pyqt_filter.py [new file with mode: 0644]
gr-utils/src/python/pyqt_filter.ui [new file with mode: 0644]
gr-utils/src/python/pyqt_plot.py [new file with mode: 0644]
gr-utils/src/python/pyqt_plot.ui [new file with mode: 0644]
gr-utils/src/python/usrp2_fft.py
gr-utils/src/python/usrp_fft.py
gr-utils/src/python/usrp_oscope.py
gr-utils/src/python/usrp_siggen.py
gr-utils/src/python/usrp_siggen_gui.py [new file with mode: 0755]
gr-video-sdl/.gitignore [new file with mode: 0644]
gr-video-sdl/Makefile.am
gr-video-sdl/gnuradio-video-sdl.pc.in [new file with mode: 0644]
gr-video-sdl/src/.gitignore [new file with mode: 0644]
gr-video-sdl/src/Makefile.am
gr-wxgui/.gitignore [new file with mode: 0644]
gr-wxgui/Makefile.am
gr-wxgui/gr-wxgui.pc.in
gr-wxgui/src/.gitignore [new file with mode: 0644]
gr-wxgui/src/python/.gitignore [new file with mode: 0644]
gr-wxgui/src/python/Makefile.am
gr-wxgui/src/python/common.py
gr-wxgui/src/python/const_window.py
gr-wxgui/src/python/constants.py
gr-wxgui/src/python/constsink_gl.py
gr-wxgui/src/python/fft_window.py
gr-wxgui/src/python/fftsink_gl.py
gr-wxgui/src/python/fftsink_nongl.py
gr-wxgui/src/python/forms/.gitignore [new file with mode: 0644]
gr-wxgui/src/python/forms/converters.py
gr-wxgui/src/python/forms/forms.py
gr-wxgui/src/python/histo_window.py
gr-wxgui/src/python/histosink_gl.py
gr-wxgui/src/python/number_window.py
gr-wxgui/src/python/numbersink2.py
gr-wxgui/src/python/plot.py
gr-wxgui/src/python/plotter/.gitignore [new file with mode: 0644]
gr-wxgui/src/python/plotter/channel_plotter.py
gr-wxgui/src/python/plotter/common.py
gr-wxgui/src/python/plotter/grid_plotter_base.py
gr-wxgui/src/python/plotter/plotter_base.py
gr-wxgui/src/python/plotter/waterfall_plotter.py
gr-wxgui/src/python/scope_window.py
gr-wxgui/src/python/scopesink_gl.py
gr-wxgui/src/python/termsink.py [new file with mode: 0644]
gr-wxgui/src/python/waterfall_window.py
gr-wxgui/src/python/waterfallsink_gl.py
gr-wxgui/src/python/waterfallsink_nongl.py
grc/.gitignore [new file with mode: 0644]
grc/Makefile.am
grc/__init__.py
grc/base/.gitignore [new file with mode: 0644]
grc/base/Block.py
grc/base/Element.py
grc/base/FlowGraph.py
grc/base/Makefile.am
grc/base/Param.py
grc/base/Platform.py
grc/base/Port.py
grc/blocks/.gitignore [new file with mode: 0644]
grc/blocks/Makefile.am
grc/blocks/band_pass_filter.xml
grc/blocks/band_reject_filter.xml
grc/blocks/blks2_cvsd_decode.xml [new file with mode: 0644]
grc/blocks/blks2_cvsd_encode.xml [new file with mode: 0644]
grc/blocks/blks2_dxpsk2_demod.xml [new file with mode: 0644]
grc/blocks/blks2_dxpsk2_mod.xml [new file with mode: 0644]
grc/blocks/blks2_dxpsk_demod.xml
grc/blocks/blks2_dxpsk_mod.xml
grc/blocks/blks2_pfb_arb_resampler.xml [new file with mode: 0644]
grc/blocks/block_tree.xml
grc/blocks/gr_additive_scrambler_bb.xml [new file with mode: 0644]
grc/blocks/gr_chunks_to_symbols.xml
grc/blocks/gr_copy.xml [new file with mode: 0644]
grc/blocks/gr_delay.xml
grc/blocks/gr_fll_band_edge_cc.xml [new file with mode: 0644]
grc/blocks/gr_kludge_copy.xml
grc/blocks/gr_message_sink.xml [new file with mode: 0644]
grc/blocks/gr_message_source.xml [new file with mode: 0644]
grc/blocks/gr_noise_source_x.xml
grc/blocks/gr_nop.xml
grc/blocks/gr_not_xx.xml
grc/blocks/gr_packed_to_unpacked_xx.xml
grc/blocks/gr_pfb_clock_sync.xml [new file with mode: 0644]
grc/blocks/gr_sample_and_hold_xx.xml
grc/blocks/gr_sig_source_x.xml
grc/blocks/gr_stream_mux.xml [new file with mode: 0644]
grc/blocks/gr_udp_sink.xml
grc/blocks/gr_udp_source.xml
grc/blocks/gr_unpacked_to_packed_xx.xml
grc/blocks/high_pass_filter.xml
grc/blocks/low_pass_filter.xml
grc/blocks/options.xml
grc/blocks/pad_sink.xml
grc/blocks/pad_source.xml
grc/blocks/parameter.xml
grc/blocks/usrp2_sink_xxxx.xml
grc/blocks/usrp2_source_xxxx.xml
grc/blocks/usrp_dual_sink_x.xml
grc/blocks/usrp_dual_source_x.xml
grc/blocks/usrp_simple_sink_x.xml
grc/blocks/usrp_simple_source_x.xml
grc/blocks/virtual_sink.xml [new file with mode: 0644]
grc/blocks/virtual_source.xml [new file with mode: 0644]
grc/blocks/wxgui_constellationsink2.xml
grc/blocks/wxgui_fftsink2.xml
grc/blocks/wxgui_histosink2.xml
grc/blocks/wxgui_numbersink2.xml
grc/blocks/wxgui_scopesink2.xml
grc/blocks/wxgui_termsink.xml [new file with mode: 0644]
grc/blocks/wxgui_waterfallsink2.xml
grc/cpp/README [new file with mode: 0644]
grc/freedesktop/.gitignore [new file with mode: 0644]
grc/freedesktop/Makefile.am
grc/freedesktop/grc-icon-256.svg [new file with mode: 0644]
grc/freedesktop/grc_setup_freedesktop.in
grc/grc_gnuradio/.gitignore [new file with mode: 0644]
grc/grc_gnuradio/usrp/dual_usrp.py
grc/grc_gnuradio/usrp/simple_usrp.py
grc/grc_gnuradio/wxgui/top_block_gui.py
grc/gui/.gitignore [new file with mode: 0644]
grc/gui/ActionHandler.py
grc/gui/Actions.py
grc/gui/Bars.py
grc/gui/Block.py
grc/gui/BlockTreeWindow.py
grc/gui/Connection.py
grc/gui/Dialogs.py
grc/gui/DrawingArea.py
grc/gui/Element.py
grc/gui/FlowGraph.py
grc/gui/MainWindow.py
grc/gui/Makefile.am
grc/gui/NotebookPage.py
grc/gui/Param.py
grc/gui/Platform.py
grc/gui/Port.py
grc/gui/PropsDialog.py [new file with mode: 0644]
grc/gui/StateCache.py
grc/gui/Utils.py
grc/python/.gitignore [new file with mode: 0644]
grc/python/Block.py
grc/python/Connection.py
grc/python/Constants.py
grc/python/FlowGraph.py
grc/python/Generator.py
grc/python/Makefile.am
grc/python/Param.py
grc/python/Platform.py
grc/python/Port.py
grc/python/convert_hier.py
grc/python/extract_docs.py
grc/python/flow_graph.tmpl
grc/scripts/.gitignore [new file with mode: 0644]
grc/scripts/Makefile.am
grc/scripts/usrp2_probe
grc/scripts/usrp_probe
grc/todo.txt [new file with mode: 0644]
gruel/.gitignore [new file with mode: 0644]
gruel/gruel.pc.in
gruel/src/.gitignore [new file with mode: 0644]
gruel/src/Makefile.am
gruel/src/include/.gitignore [new file with mode: 0644]
gruel/src/include/gruel/.gitignore [new file with mode: 0644]
gruel/src/include/gruel/Makefile.am
gruel/src/include/gruel/inet.h.in
gruel/src/include/gruel/msg_accepter.h [new file with mode: 0644]
gruel/src/include/gruel/msg_accepter_msgq.h [new file with mode: 0644]
gruel/src/include/gruel/msg_passing.h [new file with mode: 0644]
gruel/src/include/gruel/msg_queue.h [new file with mode: 0644]
gruel/src/include/gruel/pmt.h [new file with mode: 0644]
gruel/src/include/gruel/pmt_pool.h [new file with mode: 0644]
gruel/src/include/gruel/pmt_sugar.h [new file with mode: 0644]
gruel/src/include/gruel/thread.h [new file with mode: 0644]
gruel/src/include/gruel/thread_body_wrapper.h
gruel/src/include/gruel/thread_group.h
gruel/src/lib/.gitignore [new file with mode: 0644]
gruel/src/lib/Makefile.am
gruel/src/lib/msg/.gitignore [new file with mode: 0644]
gruel/src/lib/msg/Makefile.am [new file with mode: 0644]
gruel/src/lib/msg/msg_accepter.cc [new file with mode: 0644]
gruel/src/lib/msg/msg_accepter_msgq.cc [new file with mode: 0644]
gruel/src/lib/msg/msg_queue.cc [new file with mode: 0644]
gruel/src/lib/pmt/.gitignore [new file with mode: 0644]
gruel/src/lib/pmt/Makefile.am [new file with mode: 0644]
gruel/src/lib/pmt/generate_unv.py [new file with mode: 0755]
gruel/src/lib/pmt/pmt.cc [new file with mode: 0644]
gruel/src/lib/pmt/pmt_int.h [new file with mode: 0644]
gruel/src/lib/pmt/pmt_io.cc [new file with mode: 0644]
gruel/src/lib/pmt/pmt_pool.cc [new file with mode: 0644]
gruel/src/lib/pmt/pmt_serialize.cc [new file with mode: 0644]
gruel/src/lib/pmt/qa_pmt.cc [new file with mode: 0644]
gruel/src/lib/pmt/qa_pmt.h [new file with mode: 0644]
gruel/src/lib/pmt/qa_pmt_prims.cc [new file with mode: 0644]
gruel/src/lib/pmt/qa_pmt_prims.h [new file with mode: 0644]
gruel/src/lib/pmt/unv_qa_template.cc.t [new file with mode: 0644]
gruel/src/lib/pmt/unv_template.cc.t [new file with mode: 0644]
gruel/src/lib/pmt/unv_template.h.t [new file with mode: 0644]
gruel/src/lib/test_gruel.cc [new file with mode: 0644]
gruel/src/lib/thread.cc [new file with mode: 0644]
gruel/src/scheme/.gitignore [new file with mode: 0644]
gruel/src/scheme/Makefile.am [new file with mode: 0644]
gruel/src/scheme/gnuradio/.gitignore [new file with mode: 0644]
gruel/src/scheme/gnuradio/Makefile.am [new file with mode: 0644]
gruel/src/scheme/gnuradio/gen-serial-tags.scm [new file with mode: 0755]
gruel/src/scheme/gnuradio/macros-etc.scm [new file with mode: 0644]
gruel/src/scheme/gnuradio/pmt-serial-tags.scm [new file with mode: 0644]
gruel/src/scheme/gnuradio/pmt-serialize.scm [new file with mode: 0644]
run_tests.sh.in
usrp/.gitignore [new file with mode: 0644]
usrp/doc/.gitignore [new file with mode: 0644]
usrp/doc/Makefile.am
usrp/doc/inband-signaling-gigethernet [new file with mode: 0644]
usrp/doc/inband-signaling-usb [new file with mode: 0644]
usrp/doc/inband-signaling-usb-host [new file with mode: 0644]
usrp/doc/other/.gitignore [new file with mode: 0644]
usrp/doc/traffic-cop-dma [new file with mode: 0644]
usrp/doc/usrp_rfx_diagrams.odp [new file with mode: 0644]
usrp/firmware/.gitignore [new file with mode: 0644]
usrp/firmware/include/.gitignore [new file with mode: 0644]
usrp/firmware/include/Makefile.am
usrp/firmware/include/fx2regs.h
usrp/firmware/include/usrp_ids.h
usrp/firmware/lib/.gitignore [new file with mode: 0644]
usrp/firmware/lib/i2c-compiler-bug.c [new file with mode: 0644]
usrp/firmware/src/.gitignore [new file with mode: 0644]
usrp/firmware/src/common/.gitignore [new file with mode: 0644]
usrp/firmware/src/common/_startup.a51.brittle [new file with mode: 0644]
usrp/firmware/src/common/build_eeprom.py
usrp/firmware/src/usrp2/.gitignore [new file with mode: 0644]
usrp/firmware/src/usrp2/Makefile.am
usrp/firmware/src/usrp2/gpif.gpf [new file with mode: 0755]
usrp/fpga/.gitignore [new file with mode: 0644]
usrp/fpga/Makefile.am
usrp/fpga/README [new file with mode: 0644]
usrp/fpga/rbf/.gitignore [new file with mode: 0644]
usrp/fpga/rbf/rev2/.gitignore [new file with mode: 0644]
usrp/fpga/rbf/rev2/multi_4rx_0tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/.gitignore [new file with mode: 0644]
usrp/fpga/rbf/rev4/multi_4rx_0tx.rbf [new file with mode: 0755]
usrp/host/.gitignore [new file with mode: 0644]
usrp/host/Makefile.am
usrp/host/apps/.gitignore [new file with mode: 0644]
usrp/host/apps/Makefile.am
usrp/host/apps/burn-db-eeprom
usrp/host/apps/check_order [new file with mode: 0755]
usrp/host/apps/dump_12bit_shorts [new file with mode: 0755]
usrp/host/apps/dump_shorts [new file with mode: 0755]
usrp/host/apps/run [new file with mode: 0755]
usrp/host/apps/run2 [new file with mode: 0755]
usrp/host/apps/run_input [new file with mode: 0755]
usrp/host/apps/test_usrp_standard_rx.cc
usrp/host/apps/test_usrp_standard_tx.cc
usrp/host/apps/usrp_cal_dc_offset.cc
usrp/host/apps/usrper.cc
usrp/host/include/.gitignore [new file with mode: 0644]
usrp/host/include/Makefile.am [new file with mode: 0644]
usrp/host/include/usrp/.gitignore [new file with mode: 0644]
usrp/host/include/usrp/Makefile.am [new file with mode: 0644]
usrp/host/include/usrp/db_base.h [new file with mode: 0644]
usrp/host/include/usrp/db_base.i [new file with mode: 0644]
usrp/host/include/usrp/db_basic.h [new file with mode: 0644]
usrp/host/include/usrp/db_bitshark_rx.h [new file with mode: 0644]
usrp/host/include/usrp/db_dbs_rx.h [new file with mode: 0644]
usrp/host/include/usrp/db_dtt754.h [new file with mode: 0644]
usrp/host/include/usrp/db_dtt768.h [new file with mode: 0644]
usrp/host/include/usrp/db_flexrf.h [new file with mode: 0644]
usrp/host/include/usrp/db_flexrf_mimo.h [new file with mode: 0644]
usrp/host/include/usrp/db_tv_rx.h [new file with mode: 0644]
usrp/host/include/usrp/db_tv_rx_mimo.h [new file with mode: 0644]
usrp/host/include/usrp/db_wbxng.h [new file with mode: 0644]
usrp/host/include/usrp/db_xcvr2450.h [new file with mode: 0644]
usrp/host/include/usrp/libusb_types.h.in [new file with mode: 0644]
usrp/host/include/usrp/usrp_basic.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_bytesex.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_local_sighandler.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_prims.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_slots.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_standard.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_subdev_spec.h [new file with mode: 0644]
usrp/host/include/usrp/usrp_tune_result.h [new file with mode: 0644]
usrp/host/lib/.gitignore [new file with mode: 0644]
usrp/host/lib/Makefile.am
usrp/host/lib/README_OSX [new file with mode: 0644]
usrp/host/lib/ad9862.h [new file with mode: 0644]
usrp/host/lib/check_data.py [new file with mode: 0755]
usrp/host/lib/circular_buffer.h [new file with mode: 0644]
usrp/host/lib/circular_linked_list.h [new file with mode: 0644]
usrp/host/lib/darwin_libusb.h [new file with mode: 0644]
usrp/host/lib/db_base.cc [new file with mode: 0644]
usrp/host/lib/db_base_impl.h [new file with mode: 0644]
usrp/host/lib/db_basic.cc [new file with mode: 0644]
usrp/host/lib/db_bitshark_rx.cc [new file with mode: 0644]
usrp/host/lib/db_boards.cc [new file with mode: 0644]
usrp/host/lib/db_boards.h [new file with mode: 0644]
usrp/host/lib/db_dbs_rx.cc [new file with mode: 0644]
usrp/host/lib/db_dtt754.cc [new file with mode: 0644]
usrp/host/lib/db_dtt768.cc [new file with mode: 0644]
usrp/host/lib/db_flexrf.cc [new file with mode: 0644]
usrp/host/lib/db_flexrf_mimo.cc [new file with mode: 0644]
usrp/host/lib/db_tv_rx.cc [new file with mode: 0644]
usrp/host/lib/db_tv_rx_mimo.cc [new file with mode: 0644]
usrp/host/lib/db_util.cc [new file with mode: 0644]
usrp/host/lib/db_util.h [new file with mode: 0644]
usrp/host/lib/db_wbxng.cc [new file with mode: 0644]
usrp/host/lib/db_wbxng_adf4350.cc [new file with mode: 0644]
usrp/host/lib/db_wbxng_adf4350.h [new file with mode: 0644]
usrp/host/lib/db_wbxng_adf4350_regs.cc [new file with mode: 0644]
usrp/host/lib/db_wbxng_adf4350_regs.h [new file with mode: 0644]
usrp/host/lib/db_xcvr2450.cc [new file with mode: 0644]
usrp/host/lib/dump_data.py [new file with mode: 0755]
usrp/host/lib/fusb.cc [new file with mode: 0644]
usrp/host/lib/fusb.h [new file with mode: 0644]
usrp/host/lib/fusb_darwin.cc [new file with mode: 0644]
usrp/host/lib/fusb_darwin.h [new file with mode: 0644]
usrp/host/lib/fusb_generic.cc [new file with mode: 0644]
usrp/host/lib/fusb_generic.h [new file with mode: 0644]
usrp/host/lib/fusb_libusb1.cc [new file with mode: 0644]
usrp/host/lib/fusb_libusb1.h [new file with mode: 0644]
usrp/host/lib/fusb_linux.cc [new file with mode: 0644]
usrp/host/lib/fusb_linux.h [new file with mode: 0644]
usrp/host/lib/fusb_ra_wb.cc [new file with mode: 0644]
usrp/host/lib/fusb_ra_wb.h [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_darwin.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_generic.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_libusb1.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_linux.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_ra_wb.cc [new file with mode: 0644]
usrp/host/lib/fusb_sysconfig_win32.cc [new file with mode: 0644]
usrp/host/lib/fusb_win32.cc [new file with mode: 0644]
usrp/host/lib/fusb_win32.h [new file with mode: 0644]
usrp/host/lib/gen-ratios [new file with mode: 0755]
usrp/host/lib/gen_usrp_dbid.py [new file with mode: 0755]
usrp/host/lib/limbo/db_wbx.cc [new file with mode: 0644]
usrp/host/lib/limbo/db_wbx.h [new file with mode: 0644]
usrp/host/lib/md5.c [new file with mode: 0644]
usrp/host/lib/md5.h [new file with mode: 0644]
usrp/host/lib/rate_to_regval.h [new file with mode: 0644]
usrp/host/lib/std_paths.h.in [new file with mode: 0644]
usrp/host/lib/usrp_basic.cc [new file with mode: 0644]
usrp/host/lib/usrp_config.cc [new file with mode: 0644]
usrp/host/lib/usrp_config.h [new file with mode: 0644]
usrp/host/lib/usrp_dbid.dat [new file with mode: 0644]
usrp/host/lib/usrp_local_sighandler.cc [new file with mode: 0644]
usrp/host/lib/usrp_prims_common.cc [new file with mode: 0644]
usrp/host/lib/usrp_prims_libusb0.cc [new file with mode: 0644]
usrp/host/lib/usrp_prims_libusb1.cc [new file with mode: 0644]
usrp/host/lib/usrp_primsi.h [new file with mode: 0644]
usrp/host/lib/usrp_standard.cc [new file with mode: 0644]
usrp/host/misc/.gitignore [new file with mode: 0644]
usrp/host/swig/.gitignore [new file with mode: 0644]
usrp/host/swig/Makefile.am
usrp/host/swig/usrp_prims.i
usrp/host/swig/util.py [new file with mode: 0644]
usrp/usrp.pc.in
usrp2/.gitignore [new file with mode: 0644]
usrp2/doc/inband-signaling-eth [new file with mode: 0644]
usrp2/firmware/.gitignore [new file with mode: 0644]
usrp2/firmware/Makefile.am
usrp2/firmware/apps/.gitignore [new file with mode: 0644]
usrp2/firmware/apps/Makefile.am
usrp2/firmware/apps/app_common_v2.c
usrp2/firmware/apps/app_common_v2.h
usrp2/firmware/apps/app_passthru_v2.c
usrp2/firmware/apps/bitrot/tx_drop.c [new file with mode: 0644]
usrp2/firmware/apps/bitrot/tx_drop2.c [new file with mode: 0644]
usrp2/firmware/apps/bitrot/tx_drop_rate_limited.c [new file with mode: 0644]
usrp2/firmware/apps/double_buffer_fragment.c [new file with mode: 0644]
usrp2/firmware/apps/factory_test.c
usrp2/firmware/apps/gen_eth_packets.c
usrp2/firmware/apps/gen_pause_frames.c [new file with mode: 0644]
usrp2/firmware/apps/mimo_app_common_v2.c
usrp2/firmware/apps/mimo_tx.c
usrp2/firmware/apps/mimo_tx_slave.c
usrp2/firmware/apps/rcv_eth_packets.c
usrp2/firmware/apps/serdes_to_dsp.c [new file with mode: 0644]
usrp2/firmware/apps/serdes_txrx.c
usrp2/firmware/apps/tx_standalone.c
usrp2/firmware/apps/txrx.c
usrp2/firmware/config/.gitignore [new file with mode: 0644]
usrp2/firmware/config/grc_usrp2_firmware.m4
usrp2/firmware/configure.gnu
usrp2/firmware/divisors.py [new file with mode: 0755]
usrp2/firmware/include/.gitignore [new file with mode: 0644]
usrp2/firmware/include/usrp2_eth_packet.h
usrp2/firmware/include/usrp2_types.h
usrp2/firmware/lib/.gitignore [new file with mode: 0644]
usrp2/firmware/lib/Makefile.am
usrp2/firmware/lib/adf4350.c [new file with mode: 0644]
usrp2/firmware/lib/adf4350.h [new file with mode: 0644]
usrp2/firmware/lib/adf4350_regs.c [new file with mode: 0644]
usrp2/firmware/lib/adf4350_regs.h [new file with mode: 0644]
usrp2/firmware/lib/db.h
usrp2/firmware/lib/db_base.h
usrp2/firmware/lib/db_basic.c
usrp2/firmware/lib/db_bitshark_rx.c [new file with mode: 0644]
usrp2/firmware/lib/db_bitshark_rx.h [new file with mode: 0644]
usrp2/firmware/lib/db_dbsrx.c
usrp2/firmware/lib/db_init.c
usrp2/firmware/lib/db_init_wbx.c [new file with mode: 0644]
usrp2/firmware/lib/db_init_xcvr.c [new file with mode: 0644]
usrp2/firmware/lib/db_rfx.c
usrp2/firmware/lib/db_tvrx.c
usrp2/firmware/lib/db_wbxng.c [new file with mode: 0644]
usrp2/firmware/lib/db_wbxng.h [new file with mode: 0644]
usrp2/firmware/lib/db_xcvr2450.c
usrp2/firmware/lib/dbsm.c
usrp2/firmware/lib/eth_mac.c
usrp2/firmware/lib/eth_mac_regs.h
usrp2/firmware/lib/ethernet.c
usrp2/firmware/lib/memory_map.h
usrp2/firmware/lib/printf.c.smaller [new file with mode: 0644]
usrp2/firmware/u2_flash_tool [new file with mode: 0755]
usrp2/fpga/README [new file with mode: 0644]
usrp2/host/.gitignore [new file with mode: 0644]
usrp2/host/apps/.gitignore [new file with mode: 0644]
usrp2/host/apps/Makefile.am
usrp2/host/apps/bitrot/rx_samples.cc [new file with mode: 0644]
usrp2/host/apps/gen_2tone.py [new file with mode: 0755]
usrp2/host/apps/gen_sine.py [new file with mode: 0755]
usrp2/host/apps/stdin_int32_fft.py [new file with mode: 0755]
usrp2/host/apps/streaming_fft.py [new file with mode: 0755]
usrp2/host/apps/test.sh [new file with mode: 0755]
usrp2/host/apps/tx_samples.cc
usrp2/host/include/.gitignore [new file with mode: 0644]
usrp2/host/include/usrp2/.gitignore [new file with mode: 0644]
usrp2/host/include/usrp2/usrp2.h
usrp2/host/lib/.gitignore [new file with mode: 0644]
usrp2/host/lib/Makefile.am
usrp2/host/lib/control.cc
usrp2/host/lib/control.h
usrp2/host/lib/ring.cc
usrp2/host/lib/ring.h
usrp2/host/lib/usrp2.cc
usrp2/host/lib/usrp2_impl.cc
usrp2/host/lib/usrp2_impl.h
usrp2/host/usrp2.pc.in
version.sh [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..49a0e14
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# The following turn off LF->CRLF conversion for some files on Windows.
+# these conversions cause syntax errors on MinGW/MSYS.  They should not
+# have any effect on non-Windows systems or on Cygwin.  Any files that
+# required svn:eof-style=lf under subversion should be included here.
+#
+*.m4   -crlf
+*.ac   -crlf
+*.scm  -crlf
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..dba263a
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+.*
+*.o
+*.a
+*.ko
+*.so
+*.la
+*.lo
+*.py[oc]
+*.gz
+*.exe
+*.patch
+*~
+\#*#
+.deps
+.libs
+TAGS
+*-stamp
+!.gitattributes
+!.gitignore
+make.log
+/configure
+/Makefile.in
+/config.log
+/config.h
+/ltmain.sh
+/Makefile
+/config.status
+/stamp-h1
+/config.h.in
+/autom4te.cache
+/libtool
+/missing
+/aclocal.m4
+/install-sh
+/depcomp
+/py-compile
+/compile
+/build
+/run_tests.sh
index 1711f707dc4fcd36496889f0d109d578f3772e85..084fb5dc16312c88c7efa134495fbe787b562676 100644 (file)
@@ -32,7 +32,22 @@ EXTRA_DIST = \
        Makefile.swig \
        Makefile.swig.gen.t \
        Makefile.par.gen \
-       Makefile.gen.gen
+       Makefile.gen.gen \
+       version.sh
 
 SUBDIRS = @build_dirs@
 DIST_SUBDIRS = @build_dirs@ @skipped_dirs@ @with_dirs@
+DISTCLEANFILES = gnuradio*.tar.gz
+
+if PYTHON
+
+export pythondir
+
+install-data-hook:
+       @if ! python -c "import gnuradio" > /dev/null 2>&1; then\
+               printf "\n*** Post-Install Message ***\
+               \nWarning: python could not find the gnuradio module.\
+               \nMake sure that $${pythondir} is in your PYTHONPATH\n\n";\
+       fi
+
+endif
index b3955ac33b5da53650720140fa00dee3e0c07ab5..fb83b9470d3640ed5793c2a5c378708d6448f6ba 100644 (file)
@@ -1,6 +1,6 @@
 # -*- Makefile -*-
 #
-# Copyright 2004,2006,2007,2008,2009 Free Software Foundation, Inc.
+# Copyright 2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
 AM_CFLAGS = @autoconf_default_CFLAGS@ @lf_CFLAGS@
 AM_CXXFLAGS = @autoconf_default_CXXFLAGS@ @lf_CXXFLAGS@
 
+# Sets ABI version in SONAME and appends -LIBVER to filename
+LTVERSIONFLAGS = -version-info 0:0:0 -release $(LIBVER)
+
 # includes
 grincludedir = $(includedir)/gnuradio
 
+if PYTHON
 # swig includes
 swigincludedir = $(grincludedir)/swig
 
@@ -42,6 +46,7 @@ grpyexecdir = $(pyexecdir)/gnuradio
 
 usrppythondir = $(pythondir)/usrpm
 usrppyexecdir = $(pyexecdir)/usrpm
+endif
 
 # gcell includes
 gcellincludedir = $(includedir)/gcell
@@ -53,17 +58,13 @@ libspudir = $(libdir)spu
 # This used to be set in configure.ac but is now defined here for all 
 # Makefiles when this fragment is included.
 STD_DEFINES_AND_INCLUDES = $(DEFINES) $(BOOST_CPPFLAGS) \
-       $(OMNITHREAD_INCLUDES) $(GNURADIO_INCLUDES) $(GRUEL_INCLUDES)
+       $(GNURADIO_INCLUDES) $(GRUEL_INCLUDES)
 
 # when including for compilation from pre-installed libraries and such,
 # need to make sure those are put last on the compile command
 WITH_INCLUDES = @with_INCLUDES@
 WITH_SWIG_INCLUDES = @with_SWIG_INCLUDES@
 
-# How to link in the top-level omnithreads library from inside the tree
-OMNITHREAD_INCLUDES = @omnithread_INCLUDES@
-OMNITHREAD_LA = @omnithread_LA@
-
 # Where to find gnuradio include files in the current build tree
 # top_srcdir for original stuff, top_builddir for generated files
 GNURADIO_INCLUDES = @gnuradio_core_INCLUDES@
@@ -79,18 +80,6 @@ GRUEL_LA = @gruel_LA@
 USRP_INCLUDES = @usrp_INCLUDES@
 USRP_LA = @usrp_LA@
 
-# How to link in usrp-inband library from inside the tree
-USRP_INBAND_INCLUDES = @usrp_inband_INCLUDES@
-USRP_INBAND_LA = @usrp_inband_LA@
-
-# How to link the PMT library from inside the tree
-PMT_INCLUDES = @pmt_INCLUDES@
-PMT_LA = @pmt_LA@
-
-# How to link the mblock library from inside the tree
-MBLOCK_INCLUDES = @mblock_INCLUDES@
-MBLOCK_LA = @mblock_LA@
-
 # How to link the gcell library from inside the tree (the PPU part)
 GCELL_INCLUDES = @gcell_INCLUDES@
 GCELL_LA = @gcell_LA@
@@ -106,18 +95,20 @@ GCELL_EMBEDSPU_LIBTOOL = @abs_top_srcdir@/gcell/lib/runtime/gcell-embedspu-libto
 # using AM_PATH_PROG, but now here have to add a -f to be like GNU make
 RM=$(RM_PROG) -f
 
-RUN_GUILE = GUILE_LOAD_PATH="@abs_top_srcdir@/pmt/src/scheme:@abs_top_srcdir@/mblock/src/scheme" @GUILE@ -e main -s
-COMPILE_MBH = $(RUN_GUILE) $(top_srcdir)/mblock/src/scheme/gnuradio/compile-mbh.scm
+RUN_GUILE = GUILE_LOAD_PATH="@abs_top_srcdir@/gruel/src/scheme" @GUILE@ -e main -s
 
 # Base directory for example applications
 exampledir = $(datadir)/gnuradio/examples
 
 # Base directory for documentation (docdir undefined in autoconf < 1.60)
 docdir ?= $(datadir)/doc/$(PACKAGE)
-gr_docdir = $(docdir)-$(VERSION)
+gr_docdir = $(docdir)-$(DOCVER)
 
 # System configuration files
-gr_sysconfdir = $(sysconfdir)/$(PACKAGE)/conf.d
+gr_prefsdir = $(GR_PREFSDIR)
+
+# Data directory for grc block wrappers
+grc_blocksdir = $(pkgdatadir)/grc/blocks
 
 # Other common defines; use "+=" to add to these
 STAMPS =
diff --git a/README b/README
index 6eeb0fe8ae68be216bda4dbe7d64e3f88f561db9..4656af2c974427c8373da96b5ae045d1e5c1bfad 100644 (file)
--- a/README
+++ b/README
@@ -177,7 +177,7 @@ http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=175103
 
 We use Smart Pointers, the thread library and a bunch of other boost stuff.
 If your system doesn't have boost 1.35 or later, see README.building-boost
-for additional info.
+for additional info.  (Note: Mac OSX systems require 1.37 or later.)
 
 
 (7) cppunit 1.9.14 or later.   http://cppunit.sourceforge.net
diff --git a/README-win32-mingw-short.txt b/README-win32-mingw-short.txt
new file mode 100644 (file)
index 0000000..88338e3
--- /dev/null
@@ -0,0 +1,92 @@
+Building and using gnuradio on windows (win32) using mingw
+
+Required tools and libraries
+
+MingW and Msys 
+Download the latest stable version from the mingw site oand follow their installation instructions)
+
+Python for windows version 2.4 (or higher)
+You do not need to build this yourself.
+You can just install the windows executable which you can find on the python site.
+I am not sure if it will work if you have speces in your python pathname.
+I recommend installing it in C:\Python24 or D:\Python24
+
+Libtool
+If you are building from cvs you need a recent libtool
+msys comes with libtool, but the version distributed with current mingw doesn't work with gnuradio.
+download, build and install a recent libtool
+
+cppunit
+Build and install cppunit
+
+boost
+build and install boost (maybe you can get away with only unpacking the source, we only use the boost header files)
+If you build boost, you first have to download jam (boost jam) for win32. (Do not use build and use the cygwin version)
+
+build environment:
+You need to have the following files on your PATH:
+python.exe python24.dll libcppunit-1-10-2.dll libfftw3f-3.dll fftwf-wisdom.exe cppunit-config
+If you have cygwin installed Make sure that NO cygwin executables are on your path.
+
+needed on PATH:
+/usr/local/bin
+/mingw/bin
+/bin
+/c/Python24/           python.exe
+/c/Python24/libs       python24.dll
+/c/Python24/DLLs
+/usr/local/bin or /mingw/bin or /my/special/installed/lib/folder/bin
+                       libcppunit-1-10-2.dll
+                       libfftw3f-3.dll
+                       fftw-wisdom-to-conf
+                       fftwf-wisdom.exe
+                       cppunit-config
+/c/WINNT/system32
+/c/WINNT
+
+
+I made a little script set_clean_path.sh to set my path for building gnuradio where I just discard the original PATH (to get rid of the cygwin executables on my default path)  and just include what is needed:
+
+#!/bin/sh
+export PATH=".:/usr/local/bin:/mingw/bin:/bin:/c/Python24:/c/Python24/DLLs:/c/Python24/libs:/my/special/installed/lib/folder/bin:/c/WINNT/system32:/c/WINNT:/c/WINNT/System32/Wbem:.
+
+You need to source this script to set the PATH.
+. ./set_clean_path.sh
+(notice the extra dot and space in the beginning of the line, this means source this file. Sourcing means execute it and remember all environment variables set in this script)
+
+If you are building from cvs it is recommended that you edit bootstrap to your needs and use it
+If you built a recent libtool and didn't overwrite the original libtool
+(because you installed the new version in /usr/local) then you have to tell aclocal to use the more recent libtool m4 macros.
+You can do this by appending -I /usr/local/share/aclocal to the aclocal commandline
+I also changed the aclocal and automake invocations to use the most recent version in my bootstrap script
+Here follows the bootstrap script I use
+
+#!/bin/sh
+rm -fr config.cache autom4te*.cache
+
+aclocal-1.8 -I config -I /usr/local/share/aclocal
+autoconf
+autoheader
+libtoolize --automake
+automake-1.8 --add-missing
+
+If you run this script it will convert a clean cvs checkout to a version which you can configure, build and install
+
+So now you can configure gnuradio.
+On win32 /mingw you need to give it a few parameters
+You need to tell it where cppunit is installed
+where boost include files are to be found
+where the pkg-config of libfftw is to be found
+to use a generic cpu (no 3Dnow,SSE,MMX) (This option will not be needed anymore soon)
+If you have boost installed in C:\boost_1_32_0 and cppunit and fftw in /usr/local then you would need the following configur commandline
+$ ./configure --with-md-cpu=generic --with-cppunit-prefix=/usr/local --with-boost-include-dir=/c/boost_1_32_0/include/boost-1_32 PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
+
+If everything went well you cannow do
+make
+make install
+
+Now you have a working gnuradio-core
+Now you can go on building and installing gr-audio-windows and windows usrp and wxgui
+remember that all gnuradio and python dlls need to be on your path to use gnuradio
+The gnuradio dlls are installed at
+/c/Python24/Lib/site-packages:/c/Python24/Lib/site-packages/gnuradio:/c/Python24/Lib/site-packages/gnuradio/gr
diff --git a/README.building-boost b/README.building-boost
new file mode 100644 (file)
index 0000000..511adb5
--- /dev/null
@@ -0,0 +1,35 @@
+Until boost 1.35 (or later) ships with the distributions, you'll need
+to download and build it yourself.  It's not hard, and it can
+peacefully coexist with earlier versions of boost.
+
+Download the latest version of boost from boost.sourceforge.net.
+(boost_1_36_0.tar.bz2 was the latest when this was written)
+
+unpack it somewhere
+cd into the resulting directory
+
+$ cd boost_1_36_0
+
+# Pick a prefix to install it into.  I used /opt/boost_1_36_0
+
+$ BOOST_PREFIX=/opt/boost_1_36_0
+
+$ ./configure --prefix=$BOOST_PREFIX --with-libraries=thread,date_time,program_options
+$ make
+$ make install
+
+# Done!  That was easy!
+
+----------------------------------------------------------------
+
+Now, tell gnuradio where to find it:
+
+$ export LD_LIBRARY_PATH=$BOOST_PREFIX/lib
+
+$ cd <path-to-top-of-gnuradio-tree>
+$ ./bootstrap
+$ ./configure --with-boost=$BOOST_PREFIX  # plus whatever config args you usually use
+
+$ make && make check
+$ sudo make install
+
diff --git a/README.ps3 b/README.ps3
new file mode 100644 (file)
index 0000000..3d41fe3
--- /dev/null
@@ -0,0 +1,9 @@
+GNU Radio may be compiled natively on the Sony PlayStation 3 if you're
+extremely patient.  It takes a _long_ time because there's only 256MB
+of RAM on board and you'll be doing a lot of paging.
+
+However, it is possible to cross compile GNU Radio -- from say a big
+x86_64 box running Fedora 7 -- and generate code for the PS3.
+
+Detailed instructions may be found at
+http://gnuradio.org/trac/wiki/CrossCompilingForCell
diff --git a/config/.gitignore b/config/.gitignore
new file mode 100644 (file)
index 0000000..16f775e
--- /dev/null
@@ -0,0 +1,15 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/libtool.m4
+/lt~obsolete.m4
+/ltsugar.m4
+/ltversion.m4
+/ltoptions.m4
index 881a64d8a62082273362848a6c66d5fb0e02226d..4dc7216f1424491c2ef4883ccd456f07dc10c4f4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2006,2008 Free Software Foundation, Inc.
+# Copyright 2001,2006,2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -61,6 +61,7 @@ m4macros = \
        grc_gr_gcell.m4 \
        grc_gr_gpio.m4 \
        grc_gr_gsm_fr_vocoder.m4 \
+       grc_gr_noaa.m4 \
        grc_gr_radar_mono.m4 \
        grc_gr_radio_astronomy.m4 \
        grc_gr_sounder.m4 \
@@ -68,24 +69,22 @@ m4macros = \
        grc_gr_usrp.m4 \
        grc_gr_video_sdl.m4 \
        grc_gr_wxgui.m4 \
-       grc_mblock.m4 \
        grc_gruel.m4 \
        gr_check_createfilemapping.m4 \
        gr_check_mc4020.m4 \
        gr_check_shm_open.m4 \
        gr_check_usrp.m4 \
-       grc_pmt.m4 \
        grc_usrp.m4 \
        grc_usrp2.m4 \
        grc_gr_msdd6000.m4 \
        gr_doxygen.m4 \
        gr_fortran.m4 \
        gr_gcell.m4 \
+       gr_git.m4 \
        gr_gprof.m4 \
        gr_lib64.m4 \
        gr_libgnuradio_core_extra_ldflags.m4 \
        gr_no_undefined.m4 \
-       gr_omnithread.m4 \
        gr_pwin32.m4 \
        gr_python.m4 \
        gr_require_mc4020.m4 \
@@ -95,6 +94,7 @@ m4macros = \
        gr_subversion.m4 \
        gr_swig.m4 \
        gr_sysv_shm.m4 \
+       gr_version.m4 \
        lf_cc.m4 \
        lf_cxx.m4 \
        lf_warnings.m4 \
index b5b0470f45c2ce78cb525490bf56d32b0548f140..03105204304b5e1f0e28c3eec121aa54b1ef1702 100644 (file)
@@ -29,4 +29,5 @@ AC_DEFUN([GR_FORTRAN],[
         AC_PROG_F77
         AC_F77_LIBRARY_LDFLAGS
     fi
+    AC_PROG_CC dnl bux fix to restore $ac_ext
 ])
diff --git a/config/gr_git.m4 b/config/gr_git.m4
new file mode 100644 (file)
index 0000000..c4f1ea0
--- /dev/null
@@ -0,0 +1,63 @@
+dnl Copyright 2009,2010 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+
+AC_DEFUN([GR_GIT],[
+  dnl Identify git binary
+  AC_PATH_PROG([GIT],[git])
+  
+  dnl If it exists, get either 'git describe' or fallback to current commit
+  if test x$GIT != x ; then
+    AC_MSG_CHECKING([existence of git version control directory])
+    if test -d $srcdir/.git ; then
+      AC_MSG_RESULT([ok])
+      AC_MSG_CHECKING([git description of current commit])
+      if (cd $srcdir && $GIT describe >/dev/null 2>&1); then
+        GIT_DESCRIBE=`cd $srcdir && $GIT describe --abbrev=8 --long`
+        # Release candidate tags create an extra -rcX field
+       case $GIT_DESCRIBE in
+         *-*-*-*)
+           GIT_TAG=`echo $GIT_DESCRIBE | cut -f -2 -d '-'`
+           GIT_SEQNO=`echo $GIT_DESCRIBE | cut -f 3 -d '-'`
+           GIT_COMMIT=`echo $GIT_DESCRIBE | cut -f 4 -d '-' | cut -f 2- -d 'g'`
+           ;;
+         *-*-*)
+           GIT_TAG=`echo $GIT_DESCRIBE | cut -f 1 -d '-'`
+           GIT_SEQNO=`echo $GIT_DESCRIBE | cut -f 2 -d '-'`
+           GIT_COMMIT=`echo $GIT_DESCRIBE | cut -f 3 -d '-' | cut -f 2- -d 'g'`
+           ;;
+       esac
+
+       AC_MSG_RESULT([$GIT_DESCRIBE])
+      else
+        AC_MSG_RESULT([no tag in history, using current commit])
+       GIT_TAG=''
+       GIT_SEQNO=''
+       GIT_COMMIT=`cd $srcdir && $GIT describe --always --abbrev=8`
+      fi
+    else
+      AC_MSG_RESULT([not found])
+    fi
+
+    AC_SUBST([GIT_DESCRIBE])
+    AC_SUBST([GIT_TAG])
+    AC_SUBST([GIT_SEQNO])
+    AC_SUBST([GIT_COMMIT])
+  fi
+])
index 7b99cba6b7301de4f0c2720ab8d096cfd6e85b91..495e9dd4d39dba2246bbe9a48ef9fbd6715c2ec6 100644 (file)
@@ -99,6 +99,9 @@ struct timespec {
        long    tv_nsec;
 };
 #endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); }
 #endif
 
index 7479f0533dc921853d8e5bf6057344d007bdc855..43ccfc01575f5e0c53cab03a12f603e92c10c64b 100644 (file)
@@ -123,6 +123,12 @@ print path
              ;;
            esac
 
+           case $host_os in
+                *mingw* )
+             # Python 2.5 requires ".pyd" instead of ".dll" for extensions
+             PYTHON_LDFLAGS="-shrext .pyd ${PYTHON_LDFLAGS}"
+           esac
+
            AC_SUBST(PYTHON_LDFLAGS)
        fi
 ])
index 56fd83bacd84ef4acdf2de7060bb2b585ebb4e2b..cb5fb5aac193d4d0acb030425a3f0781ea93fae8 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -25,17 +25,67 @@ AC_DEFUN([_TRY_ADD_ALTIVEC],
   LF_CHECK_CXX_FLAG([-mabi=altivec -maltivec])
 ])
 
+AC_DEFUN([_FIND_ARM_ISA],
+[
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_5__
+    #error "Not armv5"
+    #endif
+  ]])],
+    [is_armv5=yes],
+    [is_armv5=no])
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_7A__
+    #error "Not armv7-a"
+    #endif
+  ]])],
+    [is_armv7_a=yes],
+    [is_armv7_a=no])
+
+])
+
 AC_DEFUN([GR_SET_MD_CPU],[
   AC_REQUIRE([AC_CANONICAL_HOST])
   AC_ARG_WITH(md-cpu,
        AC_HELP_STRING([--with-md-cpu=ARCH],[set machine dependent speedups (auto)]),
                [cf_with_md_cpu="$withval"],
-               [cf_with_md_cpu="$host_cpu"])
-
+               [
+  dnl see if the user has specified --host or --build, via 'cross_compiling'
+  if test "$cross_compiling" != no; then
+    dnl when cross-compiling, because the user specified it either via
+    dnl --target or --build, just keep the user's specs & hope for the best.
+    cf_with_md_cpu="$host_cpu"
+  else
+    dnl when the user didn't specify --target or --build, on Darwin 10
+    dnl (OSX 10.6.0 and .1) and GNU libtoool 2.2.6, 'configure' doesn't
+    dnl figure out the CPU type correctly, so do it by hand here using
+    dnl the sizeof (void*): if 4 then use i386, and otherwise use x86_64.
+    case "$host_os" in
+     *darwin*10*)
+      AC_CHECK_SIZEOF(void*)
+      if test "$ac_cv_sizeof_voidp" = 4; then
+       cf_with_md_cpu="i386"
+      else
+       cf_with_md_cpu="x86_64"
+      fi
+      ;;
+     *)
+      cf_with_md_cpu="$host_cpu"
+      ;;
+    esac
+  fi
+  ])
   case "$cf_with_md_cpu" in
    x86 | i[[3-7]]86)   MD_CPU=x86      MD_SUBCPU=x86 ;;
    x86_64)             MD_CPU=x86      MD_SUBCPU=x86_64 ;;
    powerpc*)            MD_CPU=powerpc ;;
+   arm*)
+       _FIND_ARM_ISA
+       if test $is_armv5 = yes; then MD_CPU=armv5;
+       elif test $is_armv7_a = yes; then MD_CPU=armv7_a;
+       else MD_CPU=generic; fi
+       ;;
    *)                  MD_CPU=generic ;;
   esac
 
@@ -59,5 +109,7 @@ AC_DEFUN([GR_SET_MD_CPU],[
   AM_CONDITIONAL(MD_CPU_x86,     test "$MD_CPU" = "x86")
   AM_CONDITIONAL(MD_SUBCPU_x86_64,  test "$MD_SUBCPU" = "x86_64")
   AM_CONDITIONAL(MD_CPU_powerpc, test "$MD_CPU" = "powerpc")
+  AM_CONDITIONAL(MD_CPU_armv5, test "$MD_CPU" = "armv5")
+  AM_CONDITIONAL(MD_CPU_armv7_a, test "$MD_CPU" = "armv7_a")
   AM_CONDITIONAL(MD_CPU_generic, test "$MD_CPU" = "generic")
 ])
diff --git a/config/gr_version.m4 b/config/gr_version.m4
new file mode 100644 (file)
index 0000000..a7a2022
--- /dev/null
@@ -0,0 +1,73 @@
+dnl Copyright 2009,2010 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GR_VERSION],[
+  dnl Computed version based on version.sh
+  dnl Does not force recompile on rev change
+  dnl
+  dnl Source the variables describing the release version
+  dnl 
+  dnl MAJOR_VERSION          Major release generation (2.x, 3.x, etc.)
+  dnl API_COMPAT             API compatibility version (3.2.x, 3.3.x, etc.)
+  dnl MINOR_VERSION          Minor release version (3.3.0, 3.3.1, etc.)
+  dnl MAINT_VERSION          Pure bugfix additions to make maintenance release
+  dnl
+  dnl The last two fields can have 'git' instead of a number to indicate
+  dnl that this branch is between versions.
+  . $srcdir/version.sh
+  
+  dnl Get git version if available
+  GR_GIT
+
+  dnl Test if we should use git version
+  if test "$MINOR_VERSION" == "git"; then
+    dnl RELEASE: 3.3git-xxx-gxxxxxxxx
+    dnl DOCVER:  3.3git
+    dnl LIBVER:  3.3git
+    RELEASE=$GIT_DESCRIBE
+    DOCVER=$MAJOR_VERSION.$API_COMPAT$MINOR_VERSION
+    LIBVER=$MAJOR_VERSION.$API_COMPAT$MINOR_VERSION
+  else
+    if test "$MAINT_VERSION" == "git" ; then
+      dnl RELEASE: 3.3.1git-xxx-gxxxxxxxx
+      dnl DOCVER:  3.3.1git
+      dnl LIBVER:  3.3.1git
+      RELEASE=$GIT_DESCRIBE
+      DOCVER=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION$MAINT_VERSION
+      LIBVER=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION$MAINT_VERSION
+    else
+      dnl This is a numbered release.
+      dnl RELEASE: 3.3.1{.x}
+      dnl DOCVER:  3.3.1{.x}
+      dnl LIBVER:  3.3.1{.x}
+      RELEASE=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION
+      if test "$MAINT_VERSION" != "0"; then
+        RELEASE=$RELEASE.$MAINT_VERSION
+      fi
+
+      DOCVER=$RELEASE
+      LIBVER=$RELEASE
+    fi
+  fi
+
+  AC_MSG_NOTICE([GNU Radio Release $RELEASE])
+  AC_SUBST(RELEASE)
+  AC_SUBST(DOCVER)
+  AC_SUBST(LIBVER)
+])
index ff289d1aeccfc14b400cd2527824053e58846ae5..b94deb4db465ea1a10cf6388d5ae813360ea9b45 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2010 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -21,9 +21,6 @@ AC_DEFUN([GRC_GCELL],[
     GRC_ENABLE(gcell)
     dnl GRC_WITH(gcell)
 
-    dnl Don't do gcell if omnithread skipped
-    GRC_CHECK_DEPENDENCY(gcell, omnithread)
-
     dnl If execution gets to here, $passed will be:
     dnl   with : if the --with code didn't error out
     dnl   yes  : if the --enable code passed muster and all dependencies are met
index a1724aea9de5ce53ec76d0ea2a248d78abd1af80..269634324ffe002f100dfdb05e73fec63ac15da1 100644 (file)
@@ -28,9 +28,8 @@ AC_DEFUN([GRC_GNURADIO_CORE],[
        gnuradio_core_PYDIRPATH=$pythondir
     ])
 
-    dnl Don't do gnuradio-core if gruel or omnithread skipped
+    dnl Don't do gnuradio-core if gruel skipped
     GRC_CHECK_DEPENDENCY(gnuradio-core, gruel)
-    GRC_CHECK_DEPENDENCY(gnuradio-core, omnithread)
 
     dnl If execution gets to here, $passed will be:
     dnl   with : if the --with code didn't error out
@@ -86,7 +85,7 @@ AC_DEFUN([GRC_GNURADIO_CORE],[
         gnuradio-core/src/lib/filter/Makefile \
         gnuradio-core/src/lib/g72x/Makefile \
         gnuradio-core/src/lib/general/Makefile \
-        gnuradio-core/src/lib/general/gr_prefix.cc \
+        gnuradio-core/src/lib/general/gr_constants.cc \
         gnuradio-core/src/lib/gengen/Makefile \
         gnuradio-core/src/lib/io/Makefile \
         gnuradio-core/src/lib/missing/Makefile \
index 7de55666d18cab9f2257051f6c3fa3a13ae9c763..4d6116c70f1b142b2d7174545ae6c29ac5a38a2e 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -27,18 +27,20 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[
         gnuradio-examples/Makefile \
        gnuradio-examples/c++/Makefile \
        gnuradio-examples/python/Makefile \
+       gnuradio-examples/grc/Makefile \
        gnuradio-examples/python/apps/hf_explorer/Makefile \
        gnuradio-examples/python/apps/hf_radio/Makefile \
        gnuradio-examples/python/apps/Makefile \
        gnuradio-examples/python/audio/Makefile \
        gnuradio-examples/python/digital/Makefile \
        gnuradio-examples/python/digital_voice/Makefile \
-        gnuradio-examples/python/digital-bert/Makefile \
+       gnuradio-examples/python/digital-bert/Makefile \
        gnuradio-examples/python/mp-sched/Makefile \
        gnuradio-examples/python/multi-antenna/Makefile \
        gnuradio-examples/python/multi_usrp/Makefile \
        gnuradio-examples/python/network/Makefile \
        gnuradio-examples/python/ofdm/Makefile \
+       gnuradio-examples/python/pfb/Makefile \
        gnuradio-examples/python/usrp/Makefile \
        gnuradio-examples/python/usrp2/Makefile \
     ])
index 003d1b7c7f587029d0825b9862bbe16a99f043d6..6dfb40132e549a6cdb0f3d4681eaf4b559caeab0 100644 (file)
@@ -25,6 +25,7 @@ AC_DEFUN([GRC_GR_ATSC],[
 
     AC_CONFIG_FILES([\
         gr-atsc/Makefile \
+       gr-atsc/gnuradio-atsc.pc \
         gr-atsc/doc/Makefile \
         gr-atsc/src/Makefile \
         gr-atsc/src/lib/Makefile \
index 9c653c1c255da8b8b302ea841efb826ceb18eaad..d6955980d2868094828fd9cf195be26eac193f61 100644 (file)
@@ -35,7 +35,7 @@ AC_DEFUN([GRC_GR_AUDIO_ALSA],[
 
     AC_CONFIG_FILES([ \
         gr-audio-alsa/Makefile \
-       gr-audio-alsa/gr-audio-alsa.pc \
+       gr-audio-alsa/gnuradio-audio-alsa.pc \
         gr-audio-alsa/src/Makefile \
         gr-audio-alsa/src/run_tests \
     ])
index cb7bf2990fc1ebf573ecc7b4a56388080925dafc..d1853588bbabbb64e568ea5066a265654126e02b 100644 (file)
@@ -35,6 +35,7 @@ AC_DEFUN([GRC_GR_AUDIO_JACK],[
 
     AC_CONFIG_FILES([ \
         gr-audio-jack/Makefile \
+       gr-audio-jack/gnuradio-audio-jack.pc \
         gr-audio-jack/src/Makefile \
         gr-audio-jack/src/run_tests \
     ])
index 6fd4577a8bad0ffa378fec1c7d6d592896162e44..13c83bba9b229cb30c13c291c69a8de35d838f46 100644 (file)
@@ -51,6 +51,7 @@ AC_DEFUN([GRC_GR_AUDIO_OSS],[
 
     AC_CONFIG_FILES([ \
         gr-audio-oss/Makefile \
+       gr-audio-oss/gnuradio-audio-oss.pc \
         gr-audio-oss/src/Makefile \
         gr-audio-oss/src/run_tests \
     ])
index 95fbc17d55895213c6c180677169a49d9621b7f5..df8634ff6fa352ce4b1b122e89bffec1fcfeb679 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2010 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -20,8 +20,7 @@ dnl Boston, MA 02110-1301, USA.
 AC_DEFUN([GRC_GR_AUDIO_OSX],[
     GRC_ENABLE(gr-audio-osx)
 
-    dnl Don't do gr-audio-osx if omnithread or gnuradio-core skipped
-    GRC_CHECK_DEPENDENCY(gr-audio-osx, omnithread)
+    dnl Don't do gr-audio-osx if gnuradio-core skipped
     GRC_CHECK_DEPENDENCY(gr-audio-osx, gnuradio-core)
 
     dnl If execution gets to here, $passed will be:
index b2f27f2c80f54f4d2ffb9107988138e1886ca148..ff551b38a77df1f07928e72d96daf9a617cff8c3 100644 (file)
@@ -35,6 +35,7 @@ AC_DEFUN([GRC_GR_AUDIO_PORTAUDIO],[
 
     AC_CONFIG_FILES([ \
         gr-audio-portaudio/Makefile \
+       gr-audio-portaudio/gnuradio-audio-portaudio.pc \
         gr-audio-portaudio/src/Makefile \
         gr-audio-portaudio/src/run_tests \
     ])
index 2bdfacbc05542a1a0aa1692a9e0b3fd7aec84548..5e30894174b46c697e416dec7c2ae2b1d8e8ab66 100644 (file)
@@ -35,6 +35,7 @@ AC_DEFUN([GRC_GR_COMEDI],[
 
     AC_CONFIG_FILES([ \
         gr-comedi/Makefile \
+       gr-comedi/gnuradio-comedi.pc \
         gr-comedi/src/Makefile \
         gr-comedi/src/run_tests \
     ])
index c73a3052b95739769a291fb94acc2de67267e251..ddf6f9b2f2b72fd6d8ebc8c636e79a84ac1274f4 100644 (file)
@@ -25,6 +25,7 @@ AC_DEFUN([GRC_GR_CVSD_VOCODER],[
 
     AC_CONFIG_FILES([\
         gr-cvsd-vocoder/Makefile \
+       gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc \
         gr-cvsd-vocoder/src/Makefile \
         gr-cvsd-vocoder/src/lib/Makefile \
         gr-cvsd-vocoder/src/python/Makefile \
index 941cb25577f7de3f34bbe3ed8896b84a5502e31e..a93d4edb7e13be4c80bd5b3d15a3bf6d105d7614 100644 (file)
@@ -25,6 +25,7 @@ AC_DEFUN([GRC_GR_GSM_FR_VOCODER],[
 
     AC_CONFIG_FILES([\
         gr-gsm-fr-vocoder/Makefile \
+       gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc \
         gr-gsm-fr-vocoder/src/Makefile \
         gr-gsm-fr-vocoder/src/lib/Makefile \
         gr-gsm-fr-vocoder/src/lib/gsm/Makefile \
index 3f2e17a2a5ab3d6fd8a7df18762283e9dd972297..0c6fc320ed5998c4eda3fe63509803285fc2b52f 100644 (file)
@@ -22,13 +22,14 @@ AC_DEFUN([GRC_GR_MSDD6000],[
 
     AC_CONFIG_FILES([\
        gr-msdd6000/Makefile \
+       gr-msdd6000/gnuradio-msdd6000.pc \
        gr-msdd6000/src/Makefile
     ])
 
     dnl Don't do gr-msdd6000 if gnuradio-core skipped
     GRC_CHECK_DEPENDENCY(gr-msdd6000, gnuradio-core)
 
-    AC_CHECK_HEADERS(netinet/in.h arpa/inet.h sys/socket.h netdb.h)
+    AC_CHECK_HEADERS(netinet/in.h arpa/inet.h sys/socket.h netdb.h, [], [passed=no])
 
     GRC_BUILD_CONDITIONAL([gr-msdd6000],[
         dnl run_tests is created from run_tests.in.  Make it executable.
diff --git a/config/grc_gr_noaa.m4 b/config/grc_gr_noaa.m4
new file mode 100644 (file)
index 0000000..69d0aad
--- /dev/null
@@ -0,0 +1,42 @@
+dnl Copyright 2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GRC_GR_NOAA],[
+    GRC_ENABLE(gr-noaa)
+
+    dnl Don't do gr-noaa if gnuradio-core skipped
+    GRC_CHECK_DEPENDENCY(gr-noaa, gnuradio-core)
+    GRC_CHECK_DEPENDENCY(gr-noaa, gr-wxgui)
+    GRC_CHECK_DEPENDENCY(gr-noaa, grc)
+
+    AC_CONFIG_FILES([\
+        gr-noaa/Makefile \
+       gr-noaa/apps/Makefile \
+       gr-noaa/grc/Makefile \
+       gr-noaa/lib/Makefile \
+       gr-noaa/oct/Makefile \
+       gr-noaa/python/Makefile \
+       gr-noaa/swig/Makefile \
+    ])
+
+    GRC_BUILD_CONDITIONAL(gr-noaa,[
+        dnl run_tests is created from run_tests.in.  Make it executable.
+        #AC_CONFIG_COMMANDS([run_tests_noaa], [chmod +x gr-pager/lib/run_tests])
+    ])
+])
index cb417ae25c2d14cd516a61eb66488d96c2ea7ffc..cdd6177af1f17fee05e21ca9ecd6698afa9fb4f9 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2006,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -25,12 +25,17 @@ AC_DEFUN([GRC_GR_PAGER],[
 
     AC_CONFIG_FILES([\
         gr-pager/Makefile \
-        gr-pager/src/Makefile \
-        gr-pager/src/run_tests
+       gr-pager/gnuradio-pager.pc \
+       gr-pager/apps/Makefile \
+       gr-pager/grc/Makefile \
+        gr-pager/lib/Makefile \
+       gr-pager/python/Makefile \
+       gr-pager/python/run_tests \
+       gr-pager/swig/Makefile \
     ])
 
     GRC_BUILD_CONDITIONAL(gr-pager,[
         dnl run_tests is created from run_tests.in.  Make it executable.
-        AC_CONFIG_COMMANDS([run_tests_pager], [chmod +x gr-pager/src/run_tests])
+        AC_CONFIG_COMMANDS([run_tests_pager], [chmod +x gr-pager/python/run_tests])
     ])
 ])
index d9700776cae2fc994f2e954ff06093fafdc632e9..84514d7ce9ad9f18091cc8f66201a336489737f1 100644 (file)
@@ -86,12 +86,6 @@ AC_DEFUN([GRC_GR_QTGUI],[
        AC_SUBST(QT_UIC_EXEC)
     fi
 
-    if test "$passed" = "no"; then
-        AM_CONDITIONAL(BUILD_QT, false)
-    else
-       AM_CONDITIONAL(BUILD_QT, true)
-    fi
-
     AC_CONFIG_FILES([ \
         gr-qtgui/Makefile \
         gr-qtgui/src/Makefile \
index f6ed4a488c1f0cd7db6592880f0ba271338a861d..cb51325d65433fba24ea6757d7aa11cc3d4d0314 100644 (file)
@@ -25,6 +25,7 @@ AC_DEFUN([GRC_GR_TRELLIS],[
 
     AC_CONFIG_FILES([\
         gr-trellis/Makefile \
+       gr-trellis/gnuradio-trellis.pc \
         gr-trellis/doc/Makefile \
         gr-trellis/src/Makefile \
         gr-trellis/src/lib/Makefile \
index 774f7250c8b0d69dae57c9af69363b24283174d3..c890bc31c452a4483055791714f6249498bc7b57 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -37,6 +37,7 @@ AC_DEFUN([GRC_GR_VIDEO_SDL],[
 
     AC_CONFIG_FILES([ \
         gr-video-sdl/Makefile \
+       gr-video-sdl/gnuradio-video-sdl.pc \
         gr-video-sdl/src/Makefile \
         gr-video-sdl/src/run_tests \
     ])
index ce23e3c25aee7b175eba890c1074df18a372a02c..16720b8fed4cf5f5396f906fdae0a7695bfc380d 100644 (file)
@@ -31,7 +31,7 @@ AC_DEFUN([GRC_GRC],[
     if test $passed = yes; then
         PYTHON_CHECK_MODULE([sys],[Python >= 2.5],[],[passed=no],[sys.version.split()[[0]] >= "2.5"])
         PYTHON_CHECK_MODULE([Cheetah],[Python Cheetah templates >= 2.0.0],[],[passed=no],[Cheetah.Version >= "2.0.0"])
-        PYTHON_CHECK_MODULE([lxml.etree],[Python lxml wrappers >= 2.0.0],[],[passed=no],[lxml.etree.LXML_VERSION >= (2, 0, 0, 0)])
+        PYTHON_CHECK_MODULE([lxml.etree],[Python lxml wrappers >= 1.3.6],[],[passed=no],[lxml.etree.LXML_VERSION >= (1, 3, 6, 0)])
         PYTHON_CHECK_MODULE([gtk],[Python gtk wrappers >= 2.10.0],[],[passed=no],[gtk.pygtk_version >= (2, 10, 0)])
     fi
 
@@ -50,7 +50,6 @@ AC_DEFUN([GRC_GRC],[
         grc/Makefile \
         grc/base/Makefile \
         grc/blocks/Makefile \
-        grc/examples/Makefile \
         grc/freedesktop/Makefile \
         grc/grc_gnuradio/Makefile \
         grc/gui/Makefile \
index 73e41be5f54ca76ba764c2b38ff1f8fd25e56f85..d8ac95fed63265dd3fa7a11b3e0f49a0cb14f615 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -25,6 +25,10 @@ AC_DEFUN([GRC_GRUEL],[
     dnl   with : if the --with code didn't error out
     dnl   yes  : if the --enable code passed muster and all dependencies are met
     dnl   no   : otherwise
+    if test $passed = yes; then
+       dnl Don't do gruel if guile not available
+       GRC_CHECK_GUILE(gruel)
+    fi
     if test $passed != with; then
        dnl how and where to find INCLUDES and LA and such
        gruel_INCLUDES="\
@@ -42,6 +46,10 @@ AC_DEFUN([GRC_GRUEL],[
         gruel/src/include/gruel/Makefile \
        gruel/src/include/gruel/inet.h \
         gruel/src/lib/Makefile \
+       gruel/src/lib/pmt/Makefile \
+       gruel/src/lib/msg/Makefile \
+       gruel/src/scheme/Makefile \
+       gruel/src/scheme/gnuradio/Makefile \
     ])
 
     dnl Allow creating autoconf independent header files for bytesex routines
index e1ca92bbc96b5b273effd8fee127d0920e3cdf6c..999b9c5c331b7db74b87e217bc6d5859685b0aba 100644 (file)
@@ -22,8 +22,8 @@ AC_DEFUN([GRC_USRP],[
 
     GRC_WITH(usrp)
 
-    dnl Don't do usrp if omnithread skipped
-    GRC_CHECK_DEPENDENCY(usrp, omnithread)
+    dnl Don't do usrp if gruel is skipped
+    GRC_CHECK_DEPENDENCY(usrp, gruel)
 
     dnl Make sure the fast usb technique is set, OS dependent.
     dnl This is always performed, since it puts out CLI flags.
@@ -44,33 +44,21 @@ AC_DEFUN([GRC_USRP],[
         AC_CHECK_FUNCS([getrusage sched_setscheduler pthread_setschedparam])
         AC_CHECK_FUNCS([sigaction snprintf])
 
-       dnl Make sure libusb is installed; required for legacy USB
-        USRP_LIBUSB([],[passed=no;AC_MSG_RESULT([Unable to find dependency libusb.])])
+       dnl Make sure libusb version is installed; required for legacy USB
+        USRP_LIBUSB([$req_libusb1],[],[passed=no;AC_MSG_RESULT([Unable to find dependency libusb.])])
 
        dnl Make sure SDCC >= 2.4.0 is available.
         USRP_SDCC([2.4.0],[],[passed=no;AC_MSG_RESULT([Unable to find firmware compiler SDCC.])])
     fi
     if test $passed != with; then
        dnl how and where to find INCLUDES and LA
-       usrp_INCLUDES="-I\${abs_top_srcdir}/usrp/host/lib/legacy \
-               -I\${abs_top_srcdir}/usrp/firmware/include \
-               -I\${abs_top_builddir}/usrp/host/lib/legacy"
-        usrp_LA="\${abs_top_builddir}/usrp/host/lib/legacy/libusrp.la"
+       usrp_INCLUDES=" \
+               -I\${abs_top_srcdir}/usrp/host/include \
+               -I\${abs_top_builddir}/usrp/host/include \
+               -I\${abs_top_srcdir}/usrp/firmware/include"
+        usrp_LA="\${abs_top_builddir}/usrp/host/lib/libusrp.la"
     fi
 
-    dnl There are 2 pkg-config files (usrp, and usrp-inband); the one
-    dnl for usrp requires omnithread for Darwin only.  Create a variable
-    dnl for just the usrp.pc.in case.
-    case "$host_os" in
-      darwin*)
-        usrp_darwin_omnithread_pc_requires="gnuradio-omnithread"
-        ;;
-      *) dnl (blanks)
-        usrp_darwin_omnithread_pc_requires=""
-        ;;
-    esac
-    AC_SUBST(usrp_darwin_omnithread_pc_requires)
-
     AC_CONFIG_FILES([ \
        usrp/Makefile \
        usrp/usrp.pc \
@@ -79,10 +67,11 @@ AC_DEFUN([GRC_USRP],[
         usrp/doc/Makefile \
         usrp/doc/other/Makefile \
         usrp/host/Makefile \
+       usrp/host/include/Makefile \
+       usrp/host/include/usrp/Makefile \
         usrp/host/misc/Makefile \
         usrp/host/lib/Makefile \
-        usrp/host/lib/legacy/Makefile \
-        usrp/host/lib/legacy/std_paths.h \
+        usrp/host/lib/std_paths.h \
         usrp/host/swig/Makefile \
         usrp/host/apps/Makefile \
         usrp/firmware/Makefile \
index f7064c9168ff6964b55b5aa4724dc9157606632c..701b100ad98a3c7e5f91c2eb8870644ed146aa33 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2008 Free Software Foundation, Inc.
+dnl Copyright 2008,2010 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -23,9 +23,8 @@ AC_DEFUN([GRC_USRP2],[
     dnl firmware uses a subsidiary configure.ac
     AC_CONFIG_SUBDIRS([usrp2/firmware])
 
-    dnl Don't do usrp if omnithread or gruel is skipped
+    dnl Don't do usrp if gruel is skipped
     GRC_CHECK_DEPENDENCY(usrp2, gruel)
-    GRC_CHECK_DEPENDENCY(usrp2, omnithread)
 
     dnl USRP2 host code only works on Linux at the moment
     AC_MSG_CHECKING([whether host_os is linux*])
index db857249b0d0f126b74f367afb795551bd0631e5..b99cf243207c43ba9210732e7346172d0c994a93 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -25,6 +25,8 @@ dnl
 #   ""  : do these tests
 
 AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
+  req_libusb1=no
+  USE_LIBUSB1=0
   AC_ARG_WITH([fusb-tech],
               AC_HELP_STRING([--with-fusb-tech=OS],
                             [Set fast USB technique (default=auto)]),
@@ -32,6 +34,11 @@ AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
              [cf_with_fusb_tech="$host_os"])
   if test [x]$1 != xno; then
       case "$cf_with_fusb_tech" in
+        libusb1*)
+          FUSB_TECH=libusb1
+          req_libusb1=yes
+         USE_LIBUSB1=1
+          ;;
         linux*)
           AC_CHECK_HEADER([linux/usbdevice_fs.h],
                          [x_have_usbdevice_fs_h=yes],
@@ -70,5 +77,11 @@ AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
   AM_CONDITIONAL(FUSB_TECH_win32,    test x$FUSB_TECH = xwin32)
   AM_CONDITIONAL(FUSB_TECH_generic,  test x$FUSB_TECH = xgeneric)
   AM_CONDITIONAL(FUSB_TECH_linux,    test x$FUSB_TECH = xlinux)
+  AM_CONDITIONAL(FUSB_TECH_libusb1,  test x$FUSB_TECH = xlibusb1)
   AM_CONDITIONAL(FUSB_TECH_ra_wb,    test x$FUSB_TECH = xra_wb)
+
+  AC_SUBST(USE_LIBUSB1)
+  AC_CONFIG_FILES([\
+       usrp/host/include/usrp/libusb_types.h \
+  ])
 ])
old mode 100644 (file)
new mode 100755 (executable)
index cb3130c..251f7df
@@ -1,4 +1,4 @@
-dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -17,32 +17,116 @@ dnl along with GNU Radio; see the file COPYING.  If not, write to
 dnl the Free Software Foundation, Inc., 51 Franklin Street,
 dnl Boston, MA 02110-1301, USA.
 
+# $1 is $req_libusb1:
+#   yes : check libusb-1.0
+#   no  : check libusb-0.12
+#   ""  : check libusb-0.12
+
+
 AC_DEFUN([USRP_LIBUSB], [
-    libusbok=yes
-    PKG_CHECK_MODULES(USB, libusb, [], [
-        AC_LANG_PUSH(C)
+  dnl Use PKGCONFIG to check for packages first, then check to
+  dnl make sure the USB_* variables work (whether from PKGCONFIG
+  dnl or overridden by the user)
 
-       AC_CHECK_HEADERS([usb.h], [], [libusbok=no; AC_MSG_RESULT([USRP requires libusb. usb.h not found. See http://libusb.sf.net])])
+  libusbok=no
+  have_libusb1=no
+  LIBUSB_PKG_CONFIG_NAME=''
+  if test x$1 = xyes; then
+    PKG_CHECK_MODULES(USB, libusb-1.0, [
+      libusbok=yes
+      have_libusb1=yes
+      usb_header='libusb-1.0/libusb.h'
+      usb_lib_func='libusb_bulk_transfer'
+      usb_lib_name='usb-1.0'
+      LIBUSB_PKG_CONFIG_NAME='libusb-1.0'
+    ])
+  else
+    dnl not using libusb1 (for now); see if legacy version is found.
+    dnl it might be installed under the name either 'libusb' or
+    dnl 'libusb-legacy', or just available via the
+    dnl user's shell environment
 
-       save_LIBS="$LIBS"
-       case "$host_os" in
-         darwin*)
-           LIBS="$LIBS -lIOKit"
-            ;;
-         *) ;;
-        esac
+    dnl see if the pkgconfig module 'libusb' is available
+    PKG_CHECK_MODULES(USB, libusb, [
+      libusbok=yes
+      LIBUSB_PKG_CONFIG_NAME='libusb'
+      ], [libusbok=no])
+    dnl PKG_CHECK_MODULES does not work correctly when embedded
+    if test $libusbok = no; then
+      dnl if not, see if the pkgconfig module 'libusb-legacy' is available
+      PKG_CHECK_MODULES(USB, [libusb-legacy], [
+        libusbok=yes
+        LIBUSB_PKG_CONFIG_NAME='libusb-legacy'
+        ], [libusbok=no])
+    fi
+    dnl set variables for further testing
+    usb_header='usb.h'
+    usb_lib_func='usb_bulk_write'
+    usb_lib_name='usb'
+  fi
+  AC_SUBST(LIBUSB_PKG_CONFIG_NAME)
+  if test x$1 != xyes || test $have_libusb1 = yes; then
+    dnl Either (1) libusb1 was specified and found; or
+    dnl (2) libusb1 was not specified. Restart checking.
+    libusbok=yes
 
-       AC_SEARCH_LIBS(usb_bulk_write, [usb], [USB_LIBS="$LIBS"], [libusbok=no; AC_MSG_RESULT([USRP requires libusb. usb_bulk_write not found. See http://libusb.sf.net])])
+    dnl Verify that $usb_header is a valid header, and if so,
+    dnl then verify that $usb_lib_func can be found in the
+    dnl library $usb_lib_name.
 
-        LIBS="$save_LIBS"
+    dnl If PKGCONFIG found variable USB_INCLUDEDIR, and it is
+    dnl not empty, use it for checking for $usb_header.
+    dnl Otherwise, maybe the user's shell environment is already
+    dnl configured to find this header.
 
-        AC_LANG_POP
-    ])
+    AC_LANG_PUSH(C)
+    save_CPPFLAGS="$CPPFLAGS"
+    if test x$USB_INCLUDEDIR != x; then
+      USB_INCLUDES="-I$USB_INCLUDEDIR"
+      CPPFLAGS="$CPPFLAGS $USB_INCLUDES"
+      AC_SUBST(USB_INCLUDES)
+    fi
+    AC_CHECK_HEADERS([$usb_header], [], [libusbok=no])
+    CPPFLAGS="$save_CPPFLAGS"
+    AC_LANG_POP(C)
 
-    if test x$libusbok = xyes; then
-        AC_SUBST(USB_LIBS)
-       ifelse([$1], , :, [$1])
+    if test $libusbok = no; then
+      AC_MSG_RESULT([USRP requires libusb header '$usb_header' which was not found or was not usable. See http://www.libusb.org])
     else
-        ifelse([$2], , :, [$2])
+
+      dnl found the header; now make sure the library is OK
+      dnl On Darwin, need to include the IOKit library.     
+
+      AC_LANG_PUSH(C)
+      save_LIBS="$LIBS"
+      LIBS=""
+      case "$host_os" in
+        darwin*)
+          USB_LIBS="$USB_LIBS -lIOKit"
+          LIBS="$USB_LIBS"
+          ;;
+        *) ;;
+      esac
+      AC_CHECK_LIB([$usb_lib_name], [$usb_lib_func], [], [
+        libusbok=no
+        AC_MSG_RESULT([USRP requires library '$usb_lib_name' with function '$usb_lib_func', which was either not found or was not usable. See http://www.libusb.org])
+      ])
+      case "$host_os" in
+        cygwin* | mingw*)
+          USB_LIBS="$LIBS"
+          ;;
+        *) ;;
+      esac
+      LIBS="$save_LIBS"
+      AC_LANG_POP(C)
     fi
+  fi
+  if test $libusbok = yes; then
+    AC_SUBST(USB_LIBS)
+    ifelse([$2], , :, [$2])
+  else
+    USB_INCLUDES=
+    USB_LIBS=
+    ifelse([$3], , :, [$3])
+  fi
 ])
index 6ea0a57020890ff28b9e0c0e4e1560af53436493..19d19317218c7366865758538fba9805448d3e43 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -26,7 +26,10 @@ AC_CANONICAL_BUILD
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
 
-AM_INIT_AUTOMAKE(gnuradio,3.2.2)
+GR_VERSION
+dnl ustar required to have pathnames > 99 chars
+_AM_SET_OPTION([tar-ustar])
+AM_INIT_AUTOMAKE(gnuradio,$RELEASE)
 
 DEFINES=""
 AC_SUBST(DEFINES)
@@ -121,20 +124,31 @@ dnl AC_DISABLE_SHARED     dnl don't build shared libraries
 AC_ENABLE_SHARED       dnl do build shared libraries
 AC_DISABLE_STATIC      dnl don't build static libraries
 m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL])
-GR_FORTRAN
+dnl GR_FORTRAN
 
 GR_NO_UNDEFINED                dnl do we need the -no-undefined linker flag
 GR_SCRIPTING
 
+# Allow user to choose whether to generate SWIG/Python 
+# Default is enabled
+AC_ARG_ENABLE([python],
+  [AS_HELP_STRING([--enable-python],
+    [generate SWIG/Python components (default is yes)])],
+  [case "${enableval}" in
+     yes) enable_python=yes ;;
+     no) enable_python=no ;;
+     *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
+   esac],
+  [enable_python=yes]
+)
+AM_CONDITIONAL([PYTHON], [test x$enable_python = xyes])
+
 AC_CHECK_PROG([XMLTO],[xmlto],[yes],[])
 AM_CONDITIONAL([HAS_XMLTO], [test x$XMLTO = xyes])
 
 dnl Checks for libraries.
 AC_CHECK_LIB(socket,socket)
 
-dnl check for omnithreads (will soon be removed)
-GR_OMNITHREAD
-
 dnl Set the c++ compiler that we use for the build system when cross compiling
 if test x$CXX_FOR_BUILD = x
 then
@@ -156,9 +170,9 @@ AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS(fcntl.h limits.h strings.h time.h sys/ioctl.h sys/time.h unistd.h)
 AC_CHECK_HEADERS(linux/ppdev.h dev/ppbus/ppi.h sys/mman.h sys/select.h sys/types.h)
 AC_CHECK_HEADERS(sys/resource.h stdint.h sched.h signal.h sys/syscall.h malloc.h)
-AC_CHECK_HEADERS(netinet/in.h)
 AC_CHECK_HEADERS(windows.h)
 AC_CHECK_HEADERS(vec_types.h)
+AC_CHECK_HEADERS(netdb.h netinet/in.h arpa/inet.h sys/types.h sys/socket.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -247,7 +261,17 @@ dnl We require the boost headers, thread lib and date_time lib.
 dnl AX_BOOST_BASE finds the headers and the lib dir (-L<foo>)
 dnl
 dnl calls AC_SUBST(BOOST_CPPFLAGS), AC_SUBST(BOOST_LDFLAGS) and defines HAVE_BOOST
-AX_BOOST_BASE([1.35])
+dnl
+dnl Current Boost version requirement is >=1.35 for all platforms except Darwin,
+dnl which requires >=1.37 for code in usrp host library.
+case "$host_os" in
+     darwin*)
+        AX_BOOST_BASE([1.37])
+        ;;
+      *)
+        AX_BOOST_BASE([1.35])
+        ;;
+esac
 
 dnl calls AC_SUBST(BOOST_THREAD_LIB), AC_SUBST(BOOST_CXXFLAGS) and defines HAVE_BOOST_THREAD
 AX_BOOST_THREAD
@@ -269,9 +293,24 @@ dnl AX_BOOST_TEST_EXEC_MONITOR
 dnl AX_BOOST_UNIT_TEST_FRAMEWORK
 dnl AX_BOOST_WSERIALIZATION
 
+BUILD_DATE=`date -u +"%a, %d %b %Y %R:%S"`
+AC_SUBST(BUILD_DATE)
 
-dnl If this is being done from a subversion tree, create variables
-GR_SUBVERSION
+dnl SYSCONFDIR substitution
+if test "${sysconfdir}" == "\${prefix}/etc" ; then
+   if test "${prefix}" == "NONE" ; then
+      SYSCONFDIR=["$ac_default_prefix/etc"]
+   else
+      SYSCONFDIR=["${prefix}/etc"]
+   fi
+else
+   SYSCONFDIR=[${sysconfdir}]
+fi
+AC_SUBST(SYSCONFDIR)
+
+dnl System configuration files
+GR_PREFSDIR=[$SYSCONFDIR/${PACKAGE}/conf.d]
+AC_SUBST(GR_PREFSDIR)
 
 dnl Component specific configuration
 dnl The order of the GR_ macros determines the order of compilation
@@ -297,25 +336,26 @@ AC_ARG_ENABLE(
 
 build_dirs="config"
 GRC_GRUEL                       dnl must come first
-GRC_OMNITHREAD                 dnl must come before gnuradio-core and mblock
 GRC_GCELL
 GRC_GNURADIO_CORE
-GRC_PMT
-GRC_MBLOCK                     dnl this must come after GRC_PMT
 GRC_USRP
 GRC_USRP2
 GRC_GR_USRP                    dnl this must come after GRC_USRP
 GRC_GR_USRP2
 GRC_GR_GCELL                   dnl this must come after GRC_GCELL and GRC_GNURADIO_CORE
+GRC_GR_MSDD6000        
 GRC_GR_AUDIO_ALSA
 GRC_GR_AUDIO_JACK
 GRC_GR_AUDIO_OSS
 GRC_GR_AUDIO_OSX
 GRC_GR_AUDIO_PORTAUDIO
 GRC_GR_AUDIO_WINDOWS
+GRC_GR_ATSC
+GRC_GR_COMEDI
 GRC_GR_CVSD_VOCODER
 GRC_GR_GPIO
 GRC_GR_GSM_FR_VOCODER
+GRC_GR_NOAA
 GRC_GR_PAGER
 GRC_GR_RADAR_MONO
 GRC_GR_RADIO_ASTRONOMY
@@ -324,7 +364,7 @@ GRC_GR_VIDEO_SDL
 GRC_GR_WXGUI
 GRC_GR_QTGUI
 GRC_GR_SOUNDER                 dnl this must come after GRC_USRP
-GRC_GR_UTILS                    dnl this must come after GRC_GR_WXGUI
+GRC_GR_UTILS                   dnl this must come after GRC_GR_WXGUI
 GRC_GNURADIO_EXAMPLES          dnl must come after all GRC_GR_*
 GRC_GRC
 GRC_DOCS                       dnl must be last
@@ -399,3 +439,5 @@ if test "$with_dirs" != ""; then
     echo These components will not be built.
     echo
 fi
+
+echo Configured GNU Radio release $RELEASE for build.
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644 (file)
index 0000000..9ee6454
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile.in
+/Makefile
diff --git a/docs/doxygen/.gitignore b/docs/doxygen/.gitignore
new file mode 100644 (file)
index 0000000..f44627c
--- /dev/null
@@ -0,0 +1,13 @@
+/Makefile
+/Makefile.in
+/html
+/latex
+/xml
+/man
+/Doxyfile
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index bf9b0ef478e9a5031c974cbb7381638249e99c52..243fa00bfd29aa329583e67deb6da5b171a6fa8e 100644 (file)
@@ -648,8 +648,6 @@ EXCLUDE                = @abs_top_builddir@/docs/doxygen/html \
                          @abs_top_builddir@/gr-video-sdl/src/video_sdl.py \
                          @abs_top_builddir@/gr-wxgui/src/python \
                          @abs_top_builddir@/grc \
-                         @abs_top_builddir@/omnithread/mach.cc \
-                         @abs_top_builddir@/omnithread/nt.cc \
                          @abs_top_builddir@/usrp/doc \
                          @abs_top_builddir@/usrp/firmware \
                          @abs_top_builddir@/usrp/fpga \
@@ -689,7 +687,6 @@ EXCLUDE_PATTERNS       = */.deps/* \
                          */__init__.py \
                          */gr-atsc/src/lib/Gr* \
                          */moc_*.cc \
-                         */omnithread/ot_* \
                          */qa_*.cc \
                          */qa_*.h \
                          */qa_*.py
diff --git a/docs/doxygen/other/.gitignore b/docs/doxygen/other/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index 5e05d5d363d5ef5397e2e9befc5b324923bb8e9d..eb5f170af3080c84bbe063f28a28ef4e0feef15f 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2004 Free Software Foundation, Inc.
+# Copyright 2001,2004,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -24,9 +24,6 @@ include $(top_srcdir)/Makefile.common
 EXTRA_DIST = \
        doxypy.py \
        group_defs.dox \
-       omnithread.html \
-       omnithread.pdf \
-       omnithread.ps \
        shared_ptr_docstub.h \
        tv-channel-frequencies \
        vector_docstub.h
diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox
new file mode 100644 (file)
index 0000000..43fcbf6
--- /dev/null
@@ -0,0 +1,12 @@
+/*! \mainpage
+
+Welcome to GNU Radio!
+
+For a list of all GNU Radio C++ blocks, please see <a href="modules.html">C++ Blocks</a>.
+
+Please note that at this time, we haven't found an acceptable way to
+provide unified documentation for the C++ parts of the system and the
+parts written in Python (mostly hierarchical blocks).  Until this gets
+worked out, please bear with us, or better yet, solve it for us!
+
+*/
diff --git a/docs/doxygen/xml-swig/.gitignore b/docs/doxygen/xml-swig/.gitignore
new file mode 100644 (file)
index 0000000..4671390
--- /dev/null
@@ -0,0 +1,16 @@
+/Makefile
+/Makefile.in
+/html
+/latex
+/man
+/Doxyfile
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.xml
+/combine.xslt
+/compound.xsd
+/index.xsd
diff --git a/docs/exploring-gnuradio/.gitignore b/docs/exploring-gnuradio/.gitignore
new file mode 100644 (file)
index 0000000..b6e6030
--- /dev/null
@@ -0,0 +1 @@
+/exploring-gnuradio.html
diff --git a/docs/exploring-gnuradio/Makefile b/docs/exploring-gnuradio/Makefile
new file mode 100644 (file)
index 0000000..b36ce1f
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# 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.
+# 
+
+TARGETS = exploring-gnuradio.html
+
+all: $(TARGETS)
+
+clean:
+       -rm -f $(TARGETS)
+
+%.html : %.xml
+       xmlto html-nochunks $<
diff --git a/docs/exploring-gnuradio/ddc.eps b/docs/exploring-gnuradio/ddc.eps
new file mode 100644 (file)
index 0000000..8931a16
--- /dev/null
@@ -0,0 +1,3105 @@
+%!PS-Adobe-3.0 EPSF-3.0 
+%%BoundingBox: 0 0 755 575
+%%Pages: 0
+%%Creator: Sun Microsystems, Inc.
+%%Title: none
+%%CreationDate: none
+%%LanguageLevel: 2
+%%EndComments
+%%BeginPreview: 760 575 1 1725 
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000010008000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000300FE001800C100000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000701CF001800C300000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000F03830018000300000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000003F03000018000300000000000
+%00000000000000001F800000000000031800000000000000000000000000780000000000000000
+%000000000000000000000000000000000000000000F00019C03000000000000000000000000000
+%0000000007303000019E0CFC0000000000
+%00000000000000007FE00000000000031800000000000000C00000000000F80000000000000000
+%000000000000000000000000000000000000000001E00019C03000000000000000000000000000
+%000000000030638001FF0C7C0000000000
+%000000000000000060700000000000030000000000000000C00000000000C00000000000000000
+%000000000000000000000000000000000000000003000019E03000000000000000000000000000
+%0000000000307FE001C38C300000000000
+%0000000000000000E0380000000000030000000000000000C00000000000C00000000000000000
+%000000000000000000000000000000000000000003000031F03000000000000000000000000000
+%000000000030787001C18C300000000000
+%0000000000000000E0000C04202002030842002100110181F01000000001F02000000000000000
+%000000000000000000000000000000000000000007C08031B03000000000000000000000000000
+%000000000030703001818C300000000000
+%0000000000000000E0007F86FDF87FC3187FC0FF803F8FF1F8FE001FFC03F9FC00000000000000
+%00000000000000000000000000000000000000000FE7F031B83000000000000000000000000000
+%0000000000307033F181CC300000000000
+%00000000000000007C00E3879FBC78C31879C1CF803F9C70E1C7001FFC00C38E00000000000000
+%0000000000000000000000000000000000000000030E38219C3000000000000000000000000000
+%0000000000307033F981CC300000000000
+%00000000000000003FC0C1C70E0C70631860E30780381838C38300000000C30600000000000000
+%0000000000000000000000000000000000000000030C18618C3000000000000000000000000000
+%00000000003070300181CC300000000000
+%000000000000000007E000C60E0C60631860630380380038C30180000000C30000000000000000
+%0000000000000000000000000000000000000000030C00618E3000000000000000000000000000
+%000000000030303001818C300000000000
+%000000000000000000F001C60E0C60731860670380380038C30380000000C3C000000000000000
+%0000000000000000000000000000000000000000030F804187300001B6DBFFFB6DB00000000000
+%000000000030303001C18C300000000000
+%000000000000000000383FC60E0C60331860670380380FF8C3FF801FFC00C1FC00000000000000
+%00000000000000000000000000000000000000000307F041833000000000000000000000000000
+%0000000000301C6001E30C300000000000
+%0000000000000001C018F8C60E0C60731860670380381E38C300001FFC00C03E00000000000000
+%00000000000000000000000000000000000000000300F8C183B000000000000000000000000000
+%0000000000300FC001FF0C3C0000000000
+%0000000000000001C019C0C60E0C60731860670380383838C30000000000C00700000000000000
+%000000000000000000000000000000000000000003001CC181F000000000000000000000000000
+%0000000000300780019C0C1C0000000000
+%0000000000000000E039C1C60E0C70631860630380383038C30180000000C30700000000000000
+%0000000000000000000000000000000000000000030C0C8180F000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000F071C1C60E0C70E31860638780383078E38380000000C30600000000000000
+%0000000000000000000000000000000000000000030C1D8180F000000000000000080000000000
+%0000000000000000000000000000000000
+%00000000000000007FE0E7C60E0C7FC3186061FF80381CF8F9FF00000000C3DE00000000000000
+%00000000000000000000000000000000000000000307F981807000000000000000040000000000
+%0000000000000000000000000000000000
+%00000000000000001FC07CC60E0C7F83186060FB80380F98787C00000000C0FC00000000000000
+%00000000000000000000000000000000000000000303F181803000000000000000020000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000060000000000300000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000060000000030300000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000060000000038700000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000006000000001FE00000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000060000000007800000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000008000000000
+%0008000000000000000018000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000004000000000
+%000C000180000060000018000000001000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000C000380000060000018000000003000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000004000000000
+%000C000380000060000018000000003000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000C000380000060000018000000003000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%03DC1F87E1F001F87E0019E01F00F87E00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000001000000000
+%0FFC7FC7C7FC00F0FF001FF83FC3FC7C00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%1C3C60C38E0C0061C3801C1870E30E3000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000001000000000
+%181C60E38C0C006181801C1CE063043000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000800000000
+%181C00E3800C006300C0181CC033803000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%381C0FE381FC006300C0181CC033F03000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000400000000
+%380C7FE387FC006300C0181CC030FC3000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%181C60E38E0C006300C0181CC0300E3000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%181CC0E38C0C006381C0181CC072063000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%1C1CC0E38C1C00618180181C6067063800
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0E3CE1E38E3C0071C380181C70E38E3800
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000100000000
+%07FC7F61E7EC0078FF00181C3FC1FC1E00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000100000000
+%01881C60E3C600383C0018080F00F00E00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000080000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000080000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000040000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000040000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000020000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000020000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000003000000C01803C03FC00000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000003000000C0180FF03FF00000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000003000000C0181E7C38F80000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000C018301C301C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000008000000
+%000000000000000C018300C301C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000004000000
+%00000603307E000C0183000301C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000070330FF800C0183C0030180000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000002000000
+%0000030631C1800C0181FC030380000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000002000000
+%000003063181800C01807F03FF00000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000001863001800C018007C3FF80000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000001000000
+%0000018C303F800C018001C301C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000018C30FD800C018000E300C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000800000
+%000000DC31C1800C018600E300E0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000800000
+%000000D83181800E038700E300E0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000F83183800E038380C300C0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000400000
+%0000007031C78007FF03FF83FFC0000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000007030FD8003FE00FF03FF80000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000203070800070003C03FC00000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000200000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000100000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000040000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000020000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000010000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000010000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000004000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000004000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000002600
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000003E00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000000003FE00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000001FE00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%00000000000000000000020000000000000000000000000000000000000000000010000000FE00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000007E00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000003E00
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000001E00
+%0000000000000000000000000000000000
+%000007000000000004003C00000000000000000000000000000000000F00000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000001E00
+%0000000000000000000000000000000000
+%00000700000000000C007C00000000000000000000000000000000007FE0000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000E00
+%0000000000000000000000000000000000
+%00000700000000000C00600000000000000000000000000000000007FFFE000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000600
+%0000000000000000000000000000000000
+%00000700000000000C0060000000000000000000000000000000001F801F800000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000200
+%0000000000000000000000000000000000
+%00000719E06F03033F01FCDC1E06787800000000000000000000007C0003E00000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071FF87FC3031F01F8FC7F87FDFC0000000000000000000000F80001F00000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071E1870E3030C0060E0E1C78F0C0000000000000000000001C00000380000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071C1C6063030C0060C0C0E7060E00000000000000000000038000001C0000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071C0C6063030C0060C18067060E00000000000000000000078000000E0000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E000000000000000000000CC000001B0000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E0000000000000000000018600000318000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E0000000000000000000018300000618000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063070C0060C1C067060E0000000000000000000030180000C0C000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%000007180C60E3070C0060C0C0C7060E00000000000000000000300C000180C000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%000007180C71C38F0C0060C0E1C7060E0000000000000000000060060003006000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%000007180C7F81FB0F0060C07F87060E0000000000000000000040030006002000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%000006180C6700F3070060C01E07060600000000000000000000C001800C003000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%0000000000600000000000000000000000000000000000000000C000C01C003000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%0000000000600000000000000000000000000000000000000001C0006038003800000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000001800000000000000000
+%0000000000600000000000000000000000000000000000000601C0003070003800000000000000
+%000000000000000000700200000000000000000000000000000000000000000000100000000000
+%0000000060000001800000000000000000
+%00000000006000000000000000000000000000000000000007E1800018E0001800000000000000
+%0000000000000000007F0200000000000000000000000000000000000000000000100000000000
+%000000007E000001800000000000000000
+%00000000000000000000000000000000000000000000000007FD80000DC0001800000000000000
+%0000000000000000007FC200000000000000000000000000000000000000000000100000000000
+%000000007FC00001800000000000000000
+%00000000000000000000000000000000000000000000000007FF80000780001800000000000000
+%0000000000000000007FFA00000003FF0000000060000000000300000000000000100000000000
+%000000007FF00001800000000000000000
+%0000000000000000000000000000000000000000000000000FFF80000700001C00000000000000
+%0000000000000000007FFA00000003FF800000006000000000C300000000000000100000000000
+%00000000FFF00001800000000000000000
+%00000000000000000000000000000000000000000000000007FD80000780001800000000000000
+%0000000000000000007FC20000000301C00000000000000000C000000000000000100000000000
+%000000007FC00001800000000000000000
+%00000000000000000000000000000000000000000000000007F180000DC0001800000000000000
+%0000000000000000007F020000000300E00000000000000000C000000000000000100000000000
+%000000007E000001800000000000000000
+%00000000000001007F0000200000000000000000000000000601800018E0001800000000000000
+%00000000000000000070020000000300601800404210100301E200400420000000100000000000
+%0000000060000001800000000000000000
+%00000000000003807FF003FC0000000000000000000000000001C0003070003800000000000000
+%00000000000000000000020000000300707F03F8637EFC1FE3F31BF03F60000000100000000000
+%0000000000000001800000000000000000
+%00000000000007807FF807FF0000000000000000000000000001C0006038003800000000000000
+%0000000000000000000002000000030030E7871C63CFDE1CF0C31F3879E0000000100000000000
+%0000000000000001800000000000000000
+%00000000000006C0601C0E070000000000000000000000000000C000C018003000000000000000
+%000000000000000000000200000003003181860C6387063030C31C1C60E0000000100000000000
+%0000000000000000000000000000000000
+%00000000000006C0600C1C038000000000000000000000000000C001800C003000000000000000
+%000000000000000000000200000003003181CC006307060030C31C1CE060000000100000000000
+%0000000000000000000000000000000000
+%0000000000000C60600E18018000000000000000000000000000C0030006003000000000000000
+%000000000000000000000200000003003381CC006303060070C3181CC060000000100000000000
+%0000000000000000000000000000000000
+%0000000000000C6060063800000000000000000000000000000040060003002000000000000000
+%0000000000000000000002000000030033FFCC006303060FF0C3181CC060000000100000000000
+%0000000000000000000000000000000000
+%0000000000001C70600638000000000000000000000000000000600C0001806000000000000000
+%0000000000000000000002000000030073800C006303063E30C3181CC060000000100000000000
+%0000000000000000000000000000000000
+%000000000000183060063800000000000000000000000000000020180000C04000000000000000
+%0000000000000000000002000000030063800C006303063030C3181CC060000000100000000000
+%0000000000000000000000000000000000
+%00000000000018306006380000000000000000000000000000003070000060C000000000000000
+%00000000000000000000020000000300E1818E0E6303063030C3181C60E0000000100000000000
+%0000000000000000000000000000000000
+%000000000000383860063800000000000000000000000000000038E0000031C000000000000000
+%00000000000000000000020000000301C1C1860C6303063070C3181C60E0000000100000000000
+%0000000000000000000000000000000000
+%0000000000003FF86006180000000000000000000000000000001CC000001B8000000000000000
+%000000000000000000000200000003FFC0FF87BC63030639F0F3181C3FE0000000100000000000
+%0000000000000000000000000000000000
+%000000000000301C600E180180000000000000000000000000000F8000000F0000000000000000
+%000000000000000000000200000003FF007E01F06303061FB873181C1F60000000100000000000
+%0000000000000000000000000000000000
+%000000000000600C600C1C038000000000000000000000000000070000000E0000000000000000
+%000000000000000000000200000000000000000000000000000000000060000000100000000000
+%0000000000000000000000000000000000
+%000000000000600C601C0E038000000000000000000000000000038000001C0000000000000000
+%000000000000000000000200000000000000000000000000000000004060000000100000000000
+%0000000000000000000000000000000000
+%000000000000E00E6078078F000000000000000000000000000001E00000780000000000000000
+%0000000000000000000002000000000000000000000000000000000061C0000000100000000000
+%0000000000000000000000000000000000
+%000000000000C0067FF003FE000000000000000000000000000000F80001F00000000000000000
+%000000000000000000000200000000000000000000000000000000003F80000000100000000000
+%0000000000000000000000000000000000
+%000000000000C0067FC000F00000000000000000000000000000003E0007C00000000000000000
+%000000000000000000000200000000000000000000000000000000000F00000000100000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000007F07E000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000003FFFC000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000007FE0000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000600000000000000000000
+%00000000000000000000020000000000C000000000007FE0000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000600000000000000000000
+%00000000000000000000020000000000C000000000007FF8000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000600000000000000000000
+%00000000000000000000020000000000C00000000000701C000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000F00000000000000000000
+%00000000000000000000020000000000C00000000000701C000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000F00000000000000000000
+%00000000000000000000020000000000C000E040C080700C0700E00C0000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000F00000000000000000000
+%00000000000000000000020000000000C003F860C180700C3FC3F83F8000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000001F00000000000000000000
+%00000000000000000000020000000000C0071C61E180700C71E31C738000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000001F80000000000000000000
+%00000000000000000000020000000000C00E0E61E180701C60660C61C000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000003F80000000000000000000
+%00000000000000000000020000000000C00C0631E3007FF8006700600000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000003FC0000000000000000000
+%00000000000000000000020000000000C00C0731B3007FF000E3C0780000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000C00C0733330070003FE1F83F8000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000C00C071B360070007C607C07C000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000C00C061B3600700060600E01C000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000C00C061E1E007000E0E606C0C000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000C00E0E1E1E007000E0E70E60C000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000FFC7FC0E1C00700077E3FC7F8000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000020000000000FFC1F00E1C0070003E61F83F0000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000003
+%C00000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000007000000000000003C0000000000000000000000000000000000040000000000000000001F
+%FC0000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000700000000000C007C000000000000000000000000000000000004000000000000000001FC
+%7FC000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000700000000000C0060000000000000000000000000000000000004000000000000000007E0
+%07E000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000700000000000C006000000000000000000000000000000000000400000000000000001F00
+%00F80000000000000000020000000000000000FFE3180000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000718E04703021F01F89C1E0238700000000000000000000000000400000000000000007800
+%001C0000000000000000020000000000000000FFE3186000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071BF07F83033F01FCFC7F87FCFC000000000000000000000000040000000000000000E000
+%000E0000000000000000020000000000000000C000186000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071F3879C3030C0060FCF1C7CF9C000000000000000000000000040000000000000000E000
+%00070000000000000000020000000000000000C000186000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071C1C70E3030C0060C0C0C7070E000000000000000000000000040000000000000001E000
+%00038000000000000000020000000000000000C00318F81C046000000000000000100000000000
+%0000000000000000000000000000000000
+%0000071C0C6063030C0060C1C067060E0000000000000000000000000400000000000000033000
+%0007C000000000000000020000000000000000C00318FC7F07F000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E0000000000000000000000000400000000000000061800
+%000CE000000000000000020000000000000000C0031870E387E000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E0000000000000000000000000400000000000000061C00
+%00187000000000000000020000000000000000FFC3186181870000000000000000100000000000
+%0000000000000000000000000000000000
+%000007180C6063030C0060C18067060E0000000000000000000000000400000000000000040E00
+%00307000000000000000020000000000000000FFC3186180C60000000000000000100000000000
+%0000000000000007C00000000000000000
+%000007180C6063030C0060C18067060E00000000000000000000000004000000000000000C0700
+%00603800000000000000020000000000000000C0031861FFC60000000000000000100000000000
+%000000000000001FF00000000000000000
+%000007180C6063070C0060C0C0E7060E0000000000000000000000000400000000000000180380
+%00C03800000000000000020000000000000000C0031861FFC60000000000000000100000000000
+%00000000000000383C0000000000000000
+%000007180C70C3070C0060C0E1C7060E00000000000000000000000004000000000000001801C0
+%01801800000000000000020000000000000000C003186180060000000000000000100000000000
+%00000000000000701C0000000000000000
+%000007180C7FC3FF0F0060C07F87060E00000000000000000000000004000000000000003000E0
+%03001C00000000000000020000000000000000C003186180060000000000000000100000000000
+%00000000000000E00E0000000000000000
+%000007180C6F00F3070060C03F07060E0000000000000000000000000400000000000000300060
+%06000C00000000000000020000000000000000C003186180C60000000000000000100000000000
+%00000000000000C0060000000000000000
+%000000000060000000000000000000000000000000000000000000000400000000000000300030
+%0C000C00000000000000020000000000000000C0031871C1860000000000000000100000000000
+%00000000000001C0070000000000000000
+%000000000060000000000000000000000000000000000000000000000400000000000C00300018
+%18000400000000000070020000000000000000C003187CFF860000000000000000100000000000
+%00000000600001C0070000000000000000
+%000000000060000000000000000000000000000000000000000000000400000000000FE060000E
+%3000060000000000007F020000000000000000C003183C3E060000000000000000100000000000
+%000000007E0001C0070000000000000000
+%000000000060000000000000000000000000000000000000000000000400000000000FF8600006
+%6000060000000000007FC200000000000000000000000000000000000000000000100000000000
+%000000007FC001C0070000000000000000
+%000000000060000000000000000000000000000000000000000000000400000000000FFF600003
+%C000060000000000007FFA00000000000000000000000000000000000000000000100000000000
+%00000000FFF001C0070000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000FFE600001
+%C000060000000000007FFA00000000000000000000000000000000000000000000100000000000
+%00000000FFF000C0060000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000FF8600003
+%C000060000000000007FC200000000000000000000000000000000000000000000100000000000
+%000000007FC000C0060000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000FE0600006
+%6000060000000000007F0200000000000000000000000000000000000000000000100000000000
+%000000007E000060EC0000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000C0060000C
+%380006000000000000700200000000000000000000000000000000000000000000100000000000
+%00000000600000707C0000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000700018
+%180006000000000000000200000000000000000000000000000000000000000000100000000000
+%000000000000003FFC0000000000000000
+%00000000000003807FE001FC000000000000000000000000000000000400000000000000300030
+%0C000C000000000000000200000000000000000000000000000000000000000000100000000000
+%000000000000000FEE0000000000000000
+%00000000000003807FF807FE000000000000000000000000000000000400000000000000300070
+%07000C000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000030000000000000000
+%00000000000006C0603C0E070000000000000000000000000000000004000000000000003000E0
+%03000C000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000000000006C0600C0C038000000000000000000000000000000004000000000000003001C0
+%01801C000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000000EE0600E1801800000000000000000000000000000000400000000000000180380
+%00E018000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000000C60600E1800000000000000000000000000000000000400000000000000180700
+%007038000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000000C60600638000000000000000000000000000000000004000000000000000C0E00
+%003838000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000001C70600638000000000000000000000000000000000004000000000000000C1C00
+%001C70000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000183060063800000000000000000000000000000000000400000000000000061800
+%000E70000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000183860063800000000000000000000000000000000000400000000000000033000
+%0007E0000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000003FF86006380000000000000000000000000000000000040000000000000001A000
+%000380000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000003FF8600E180180000000000000000000000000000000040000000000000000C000
+%000300000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000701C600E1C0180000000000000000000000000000000040000000000000000E000
+%000700000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000600C601C0C03800000000000000000000000000000000400000000000000007C00
+%003E00000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000E00E603C0F07000000000000000000000000000000000400000000000000003E00
+%00FC00000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000E00E7FF807FE000000000000000000000000000000000400000000000000000F80
+%01F000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000C0067FE001F80000000000000000000000000000000004000000000000000003FC
+%3F8000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000004000000000000000000FF
+%FF0000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000001F
+%F80000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000001
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000200000000000000000000000000000000000000000000100000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000003
+%0000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000003
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000007
+%00000000000000000000000000000000000000000000C000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000007
+%80000000000000000000000000000000000000000000C000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000000F
+%80000000000000000000000000000000000000000001E000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000000F
+%80000000000000000000000000000000000000000001E000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000000F
+%C0000000000000000000000000000000000000000001E000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000000F
+%C0000000000000000000000000000000000000000003F000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000000F
+%C0000000000000000000000000000000000000000003F000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000040000000000000000001F
+%C0000000000000000000000000000000000000000003F000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000000000000000000000000003F000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000000000000000000000000007F800000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%00000000000000000000000000000000000000000000C000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000C00000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000C00000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000800000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000007E0C6FC00400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000E70C7FE00400000000000000000000
+%0007807807C0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000C38C70600400000000000000000000
+%001FC1FE0FE0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000C00C60600400000000000000000000
+%003863871870000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000F00C60600400000000000000000000
+%003033039830000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000007E0C60600400000000000000000000
+%007007019800000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000001F8C60600400000000000000000000
+%006007019F80000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000038C60600400000000000000000000
+%0060060187E0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000818C60600400000000000000000000
+%0060070180F0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000C18C60600400000000000000000000
+%007037018038000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000E38C60600400000000000000000000
+%003033039838000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000007F0C60600400000000000000000000
+%003863871830000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%001FE1FE0FF0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%0007807C07C0000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000400000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFC0000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001803003E000F800000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001C0300FF803FE00000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001E0303C1C070780000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001E030300C0E0380000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001F030700E1C01C0000
+%00000000000000004000000000000001FF00000000006000018006086000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000000000001B83060001800C0000
+%00000000000000004000000000000001FFC0000000006000018006186000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000000000019C30E0003800E0000
+%0000000000000000400000000000000180C0000000006000000006186000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000000000019C30E0003800E0000
+%0000000000000000400000000000000180E0000000006000000006186000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000000000018E30C0003800E0000
+%0000000000000000400000000000000180603C08E00E66060D80C67E6700000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000000000018630E0003800E0000
+%000000000000000040000000000000018060FF1FF83FE30E0D83F67E6FC0000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000000000018330E0003800E0000
+%0000000000000000400000000000000180C1C71F3871E30E0D871E1878E0000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000183B060061800C0000
+%00000000000000004000000000000001FF83831C1C60E30F198E0E187060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000181B060061800C0000
+%00000000000000004000000000000001FF80031C0CE0630B198C0E186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000181F0700E0C01C0000
+%0000000000000000400000000000000181E0071C0CE0619B198C06186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000180F0381C0E0380000
+%000000000000000040000000000000018060FF1C0CC0619B318C06186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000180701FF807FF00000
+%000000000000000040000000000000018071E31C0CC06199B18C06186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000180700FF001FC00000
+%000000000000000040000000000000018073831C0CE060F1B18C06186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000018073031C0C6060F1E18E0E186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%0000000000000000400000000000000180E3071C0C70E0F0E1861E186060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000001FFC1FF9C0C3FE070E187FE1E6060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000001FF80F99C0C0F6060E181E60E6060000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000003E0300000000006000FC00000003
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000FF830000000000C003FF00000003
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000001C1C00000000000C0070780000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000380E00000000000C00E0180000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000380400000000000800C01C0000000
+%000000000000000040000000000000000C000000180000000010C0000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000380031BF81F8001801C0001FC1FC3
+%1BF03F800000000040000000000000000C000000180000000030C0000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000001F0031F3839C001801800039E38E3
+%1F3879C00000000040000000000000000C00000000000000003000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000FE031C1C60600100180007073063
+%1C1860E00000000040000000000000000C00000000000000003000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000001FC31C0C60700300180006033003
+%1C1CC060000000004000000000000001CC07001C18CF0E01F07CC07819E0000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000003C31C0CE070030018000E033C03
+%181CE060000000004000000000000007EC1FC07F18FFBF83FC7CC0FE1BF0000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000E31C0CFFF0030018000E031FC3
+%181CFFE000000000400000000000000E3C38E0E398F1F3861C30C1C71E38000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000300631C0CE00006001C00CE0303E3
+%181CC00000000000400000000000000C1C6070C198E0C18E0C30C3839C18000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000300631C0CE00006000C01CE030073
+%181CC0000000000040000000000000180C60318018E0C1800C30C3019818000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000380631C0C606006000E0186073073
+%181CE0600000000040000000000000180C7FF18018C0C1803C30C301981C000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000003C0C31C0C70600400070387063073
+%181C70E00000000040000000000000180C7FF18018C0C183FC30C701981C000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000001FFC31C0C3DE00C0003FF03DE3DE3
+%181C3BC00000000040000000000000180C60018018C0C1878C30C701981C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000007F031C0C1F800C0001FC01F80FC3
+%181C1F800000000040000000000000180C60018098C0C18C0C30C301981C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%0000000000000000400000000000000C1C7031C1D8C0C18C0C30C301981C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%0000000000000000400000000000000E1C7060C198C0C18C1C30C383981C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000007FC3FE07F18C0C187FE3EC1FF181C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000003CC0F803E18C0C183E61EC07C181C000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000007E000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000001FF800000000000000006000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000381C00000000000000006000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000700E00000000000000006000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000060060300860030110180F818
+%088000000000000040000000000000001E00000010000000000000380700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000E0001FC0DF81FC3F8FF0F8FE
+%0FE000000000000040000000000000003E000000300000000000003C0700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000C0003CE0F9C38E3F9C7061C7
+%0FC0000000000000400000000000000030000000300000000000003C0700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000C0003030E0C3073818386383
+%8E00000000000000400000000000000030000000300000000000003E0700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000C0FE6030C0E6033800386301
+%8C000000000000004000000000000000FE1F00F07E1F037007FF00360700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000C0FF7030C0E7033800386301
+%CC000000000000004000000000000000FE7FC1FC7C3F83F007FF00330700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000C0077FF0C0E7FF380FF86301
+%CC0000000000000040000000000000003061C38E3071C3D0000000338700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000E0076000C0E600381E386301
+%CC00000000000000400000000000000030E0C70630C0E38000000031C700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000E0076000C0E6003838386301
+%CC0000000000000040000000000000003000C60030C0630000000030C700000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000070077030C0E7033830386301
+%8C0000000000000040000000000000003007C60030C0630000000030E700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000381E3870C0E3073830786383
+%8C000000000000004000000000000000303FC60031C0730007FF00307700000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000800000000000001FFC1FE0C0E3FE381CF879FF
+%0C0000000000000040000000000000003070C60030C0630007FF00303700000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000008000000000000007F00FC0C0E0FC380F983C7C
+%0C00000000000000400000000000000030C0C60230C06300000000303F00000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%0000000000000000400000000000000030C0C60630C06300000000301F00000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%0000000000000000400000000000000030E1C30E38E0E300000000300F00000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000000307FE3FC3E7FC300000000300F00000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%00000000000000004000000000000000303C60F01E1F0300000000300700000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000080000000000000000000000000000000000000
+%000000000000000040000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFC0000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000018000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000018000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000003C000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000003C000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000003C000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000007C000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000007C000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000FE000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000FE000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000FF000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000FF000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000010000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000001F800000000000000000F000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000007FE00000000C00000001F000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000E0F00000000C000000018000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000001C0300000000C000000018000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000180380000000E000000038000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000380003F837E3F0FC0FC07F7F1FC07EC606
+%0FE0DF81FC60700000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000003800073C3CF0C1CE0FC0187F3CE0E7C606
+%1C70FBC38E70600000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000030000C0C3870C3030E0018703071C1C606
+%3830E0C30630600000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000030000C0E3030C3038C001870603181C606
+%3018C0C60030E00000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000030001C0E3030C7038C001870703181C606
+%3038C0C60038C00000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000030001FFE3030C7FF8C0018707FF180C606
+%3FF8C0C60018C00000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000038019C003030C7000C001870600180C606
+%3000C0C60019800000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000018019C003030C7000C001870600181C606
+%3000C0C6000D800000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000001C030C0C3030C3030C001870703181C606
+%3018C0C6060D000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000E070E0C3030C3830C0018703871C3C70E
+%3838C0C3060F000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000007FE07BC3030F1EF0C0018703FE0F7C3FE
+%1EF0C0C3DE07000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000003F803F0303070FC0C0018700FC07DC1F6
+%07E0C0C0F806000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000000001C000
+%000000000006000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000000001C000
+%000000000006000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000000001C000
+%00000000001C000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000000001C000
+%000000000038000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000008000
+%000000000030000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001E000187C00000000000003C0
+%0060F8000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000003E00011FF000C0000000007C0
+%0063FC000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000300003183001C000000000E00
+%00670E000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000300003303801C000000380C00
+%004606000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000FC1802301803E030000381F03
+%00C607000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000FC7F06001803F1FC000381F9F
+%C0C006000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000070E706003801C38E000380C18
+%E08006000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000031C386007001C707003FF8C30
+%60800E000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000031C00C00E001C603003FF8C38
+%01801C000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000030F00C01C001C603800380C1E
+%018038000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000FE307E0C038001C603800380C0F
+%C10070000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000FE300F88070001C603800380C03
+%E300E0000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000003003980E0001C603800380C00
+%7303C0000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000003181981C0001C703000380C30
+%330300000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000031C190380001C307000000C38
+%760600000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000030FF103FF800F3FE000000C1F
+%E60FFE000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000307E303FF800F0FC000000C0F
+%C60FFF000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%%EndPreview
+%%BeginProlog
+%%BeginResource: SDRes
+/b4_inc_state save def
+/dict_count countdictstack def
+/op_count count 1 sub def
+userdict begin
+0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath
+/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if
+/bdef {bind def} bind def
+/c {setgray} bdef
+/l {neg lineto} bdef
+/rl {neg rlineto} bdef
+/lc {setlinecap} bdef
+/lj {setlinejoin} bdef
+/lw {setlinewidth} bdef
+/ml {setmiterlimit} bdef
+/ld {setdash} bdef
+/m {neg moveto} bdef
+/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef
+/r {rotate} bdef
+/t {neg translate} bdef
+/s {scale} bdef
+/sw {show} bdef
+/gs {gsave} bdef
+/gr {grestore} bdef
+/f {findfont dup length dict begin
+{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def
+currentdict end /NFont exch definefont pop /NFont findfont} bdef
+/p {closepath} bdef
+/sf {scalefont setfont} bdef
+/ef {eofill}bdef
+/pc {closepath stroke}bdef
+/ps {stroke}bdef
+/pum {matrix currentmatrix}bdef
+/pom {setmatrix}bdef
+/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%EndPageSetup
+pum
+0.02834 0.02833 s 
+0 -20290 t
+/tm matrix currentmatrix def
+gs
+tm setmatrix
+-635 -635 t 
+1 1 s 
+635 635 m 27274 635 l 27274 20924 l 635 20924 l 635 635 l eoclip newpath
+0 lw 1 lj 0.000 c 17781 10461 m  14606 10461 l  14606 6016 l  20956 6016 l 
+20956 10461 l  17781 10461 l  pc
+gs
+pum
+15663 7567 t
+65 0 m  65 -606 l  274 -606 l  321 -606 357 -603 382 -597 ct 416 -589 446 -575 471 -554 ct 
+503 -527 526 -492 542 -450 ct 558 -408 566 -360 566 -306 ct 566 -260 561 -219 550 -184 ct 
+539 -148 525 -119 509 -95 ct 492 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+353 -3 320 0 284 0 ct p
+145 -71 m  275 -71 l  315 -71 346 -75 369 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 457 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -371 473 -419 452 -453 ct 
+431 -487 406 -510 376 -522 ct 355 -530 320 -534 272 -534 ct 145 -534 l  p ef
+965 -141 m  1042 -131 l  1030 -86 1007 -52 975 -27 ct 942 -2 900 9 849 9 ct 
+785 9 734 -9 696 -49 ct 658 -88 640 -144 640 -215 ct 640 -289 659 -347 697 -387 ct 
+735 -428 784 -449 845 -449 ct 903 -449 951 -429 989 -389 ct 1026 -349 1044 -292 1044 -220 ct 
+1044 -216 1044 -209 1044 -200 ct 716 -200 l  719 -152 733 -115 757 -89 ct 782 -64 813 -51 849 -51 ct 
+877 -51 900 -58 919 -72 ct 938 -87 l  954 -110 l  p
+721 -261 m  966 -261 l  963 -298 953 -326 938 -344 ct 914 -373 883 -387 845 -387 ct 
+811 -387 783 -376 759 -353 ct 736 -330 l  723 -300 l  p ef
+1427 -160 m  1500 -151 l  1492 -100 1472 -61 1439 -32 ct 1406 -4 1365 9 1317 9 ct 
+1257 9 1209 -9 1172 -49 ct 1136 -88 1118 -144 1118 -217 ct 1118 -265 1125 -306 1141 -342 ct 
+1157 -378 1181 -404 1213 -422 ct 1245 -440 1280 -449 1318 -449 ct 1365 -449 1404 -437 1435 -412 ct 
+1465 -388 1485 -354 1493 -310 ct 1421 -299 l  1414 -328 1402 -350 1384 -365 ct 
+1367 -380 1345 -387 1321 -387 ct 1283 -387 1253 -374 1229 -347 ct 1206 -320 1194 -278 1194 -220 ct 
+1194 -161 1205 -118 1228 -91 ct 1251 -64 1280 -51 1317 -51 ct 1346 -51 1370 -60 1390 -78 ct 
+1409 -96 l  1422 -123 l  p ef
+1564 -520 m  1564 -606 l  1638 -606 l  1638 -520 l  p
+1564 0 m  1564 -439 l  1638 -439 l  1638 0 l  p ef
+1748 0 m  1748 -439 l  1815 -439 l  1815 -377 l  1829 -399 1847 -416 1870 -429 ct 
+1893 -442 1919 -449 1948 -449 ct 1981 -449 2007 -442 2028 -428 ct 2049 -415 2064 -396 2072 -372 ct 
+2107 -423 2152 -449 2208 -449 ct 2251 -449 2285 -437 2308 -412 ct 2332 -388 2343 -351 2343 -301 ct 
+2343 0 l  2269 0 l  2269 -276 l  2269 -306 2267 -327 2262 -340 ct 2257 -354 2249 -364 2236 -372 ct 
+2223 -380 2208 -384 2191 -384 ct 2160 -384 2135 -374 2114 -353 ct 2094 -333 2084 -300 2084 -255 ct 
+2084 0 l  2009 0 l  2009 -285 l  2009 -318 2003 -343 1991 -359 ct 1979 -376 1959 -384 1932 -384 ct 
+1911 -384 1891 -379 1873 -368 ct 1856 -357 1843 -340 1835 -319 ct 1827 -298 1823 -267 1823 -227 ct 
+1823 0 l  p ef
+2750 -54 m  2722 -30 2696 -14 2670 -4 ct 2645 5 2617 9 2588 9 ct 2540 9 2503 -1 2477 -25 ct 
+2451 -49 2438 -79 2438 -115 ct 2438 -137 2443 -156 2453 -174 ct 2463 -192 2475 -206 2491 -217 ct 
+2507 -228 2525 -236 2545 -241 ct 2559 -245 2581 -249 2611 -253 ct 2671 -260 2715 -268 2744 -278 ct 
+2744 -288 2744 -295 2744 -298 ct 2744 -328 2737 -349 2723 -362 ct 2704 -379 2676 -387 2638 -387 ct 
+2603 -387 2577 -381 2561 -369 ct 2544 -356 2532 -335 2524 -303 ct 2451 -313 l 
+2458 -345 2468 -370 2484 -389 ct 2499 -408 2521 -423 2549 -433 ct 2578 -443 2611 -449 2649 -449 ct 
+2687 -449 2717 -444 2740 -435 ct 2764 -427 2781 -415 2792 -402 ct 2803 -389 2811 -372 2815 -351 ct 
+2818 -339 2819 -316 2819 -283 ct 2819 -184 l  2819 -114 2821 -71 2824 -52 ct 
+2827 -34 2833 -16 2843 0 ct 2765 0 l  2757 -15 l  2752 -33 l  p
+2744 -220 m  2717 -209 2676 -200 2622 -192 ct 2592 -187 2570 -182 2557 -177 ct 
+2545 -171 2535 -163 2528 -153 ct 2521 -142 2518 -130 2518 -117 ct 2518 -98 2525 -81 2540 -68 ct 
+2555 -55 2577 -48 2606 -48 ct 2635 -48 2660 -54 2683 -67 ct 2705 -79 2721 -96 2732 -118 ct 
+2740 -135 2744 -160 2744 -193 ct p ef
+3076 -66 m  3087 0 l  3066 3 3047 5 3030 5 ct 3003 5 2982 1 2968 -7 ct 2953 -15 2942 -26 2936 -40 ct 
+2930 -54 2927 -83 2927 -128 ct 2927 -381 l  2872 -381 l  2872 -439 l  2927 -439 l 
+2927 -547 l  3001 -592 l  3001 -439 l  3076 -439 l  3076 -381 l  3001 -381 l 
+3001 -124 l  3001 -103 3002 -89 3005 -83 ct 3008 -77 3012 -72 3018 -69 ct 3024 -65 3032 -63 3043 -63 ct 
+3051 -63 l  3062 -64 l  p ef
+3152 -520 m  3152 -606 l  3226 -606 l  3226 -520 l  p
+3152 0 m  3152 -439 l  3226 -439 l  3226 0 l  p ef
+3336 0 m  3336 -439 l  3403 -439 l  3403 -376 l  3436 -425 3482 -449 3543 -449 ct 
+3570 -449 3594 -444 3616 -434 ct 3638 -425 3655 -412 3666 -397 ct 3677 -382 3685 -363 3689 -342 ct 
+3692 -328 3693 -304 3693 -270 ct 3693 0 l  3619 0 l  3619 -267 l  3619 -297 3616 -320 3610 -335 ct 
+3604 -350 3594 -362 3579 -371 ct 3565 -380 3547 -384 3527 -384 ct 3496 -384 3468 -374 3445 -354 ct 
+3422 -334 3411 -296 3411 -239 ct 3411 0 l  p ef
+3799 36 m  3871 47 l  3874 69 3883 85 3896 95 ct 3915 109 3940 116 3972 116 ct 
+4006 116 4033 109 4052 95 ct 4071 82 4083 62 4090 38 ct 4094 22 4095 -8 4095 -57 ct 
+4063 -19 4022 0 3974 0 ct 3913 0 3867 -21 3833 -65 ct 3800 -108 3784 -161 3784 -222 ct 
+3784 -264 3791 -302 3807 -338 ct 3822 -373 3844 -400 3873 -420 ct 3901 -439 3935 -449 3974 -449 ct 
+4026 -449 4069 -428 4102 -386 ct 4102 -439 l  4171 -439 l  4171 -59 l  4171 8 4164 57 4150 85 ct 
+4136 114 4114 136 4084 153 ct 4054 169 4017 178 3972 178 ct 3920 178 3878 166 3845 142 ct 
+3813 119 l  3798 83 l  p
+3860 -227 m  3860 -169 3872 -127 3895 -101 ct 3918 -74 3946 -61 3981 -61 ct 
+4015 -61 4044 -74 4067 -101 ct 4090 -127 4101 -168 4101 -224 ct 4101 -278 4090 -319 4066 -346 ct 
+4042 -373 4013 -387 3979 -387 ct 3946 -387 3918 -374 3895 -347 ct 3872 -320 l 
+3860 -280 l  p ef
+pom
+pum
+16007 8520 t
+62 0 m  62 -606 l  142 -606 l  142 -71 l  440 -71 l  440 0 l  p ef
+478 -219 m  478 -300 500 -361 545 -400 ct 583 -432 629 -449 684 -449 ct 744 -449 793 -429 832 -389 ct 
+870 -350 889 -295 889 -225 ct 889 -169 881 -124 864 -92 ct 847 -60 822 -34 790 -16 ct 
+757 0 722 9 684 9 ct 622 9 572 -9 534 -49 ct 497 -88 l  478 -145 l  p
+554 -219 m  554 -163 566 -121 591 -93 ct 615 -65 646 -51 684 -51 ct 721 -51 751 -65 776 -93 ct 
+800 -121 813 -164 813 -222 ct 813 -276 800 -317 776 -345 ct 751 -373 720 -387 684 -387 ct 
+646 -387 615 -373 591 -345 ct 566 -317 l  554 -275 l  p ef
+1062 0 m  928 -439 l  1005 -439 l  1075 -185 l  1101 -91 l  1102 -96 1110 -126 1124 -181 ct 
+1194 -439 l  1270 -439 l  1336 -184 l  1358 -100 l  1383 -185 l  1458 -439 l 
+1531 -439 l  1393 0 l  1316 0 l  1246 -263 l  1229 -337 l  1140 0 l  p ef
+1811 0 m  1811 -606 l  2040 -606 l  2080 -606 2111 -604 2132 -600 ct 2162 -595 2187 -586 2207 -572 ct 
+2227 -558 2243 -538 2255 -513 ct 2268 -488 2274 -461 2274 -430 ct 2274 -379 2257 -335 2224 -300 ct 
+2192 -264 2132 -246 2047 -246 ct 1891 -246 l  1891 0 l  p
+1891 -318 m  2048 -318 l  2100 -318 2136 -327 2158 -346 ct 2180 -366 2191 -393 2191 -428 ct 
+2191 -453 2185 -475 2172 -493 ct 2159 -511 2142 -523 2121 -529 ct 2108 -532 2083 -534 2046 -534 ct 
+1891 -534 l  p ef
+2644 -54 m  2616 -30 2590 -14 2564 -4 ct 2539 5 2511 9 2482 9 ct 2434 9 2397 -1 2371 -25 ct 
+2345 -49 2332 -79 2332 -115 ct 2332 -137 2337 -156 2347 -174 ct 2357 -192 2369 -206 2385 -217 ct 
+2401 -228 2419 -236 2439 -241 ct 2453 -245 2475 -249 2505 -253 ct 2565 -260 2609 -268 2638 -278 ct 
+2638 -288 2638 -295 2638 -298 ct 2638 -328 2631 -349 2617 -362 ct 2598 -379 2570 -387 2532 -387 ct 
+2497 -387 2471 -381 2455 -369 ct 2438 -356 2426 -335 2418 -303 ct 2345 -313 l 
+2352 -345 2362 -370 2378 -389 ct 2393 -408 2415 -423 2443 -433 ct 2472 -443 2505 -449 2543 -449 ct 
+2581 -449 2611 -444 2634 -435 ct 2658 -427 2675 -415 2686 -402 ct 2697 -389 2705 -372 2709 -351 ct 
+2712 -339 2713 -316 2713 -283 ct 2713 -184 l  2713 -114 2715 -71 2718 -52 ct 
+2721 -34 2727 -16 2737 0 ct 2659 0 l  2651 -15 l  2646 -33 l  p
+2638 -220 m  2611 -209 2570 -200 2516 -192 ct 2486 -187 2464 -182 2451 -177 ct 
+2439 -171 2429 -163 2422 -153 ct 2415 -142 2412 -130 2412 -117 ct 2412 -98 2419 -81 2434 -68 ct 
+2449 -55 2471 -48 2500 -48 ct 2529 -48 2554 -54 2577 -67 ct 2599 -79 2615 -96 2626 -118 ct 
+2634 -135 2638 -160 2638 -193 ct p ef
+2778 -131 m  2851 -142 l  2855 -113 2867 -90 2886 -74 ct 2905 -59 2931 -51 2965 -51 ct 
+2999 -51 3024 -58 3041 -72 ct 3058 -86 3066 -102 3066 -121 ct 3066 -138 3059 -151 3044 -160 ct 
+3034 -167 3008 -175 2968 -186 ct 2913 -199 2875 -211 2854 -221 ct 2833 -231 2817 -245 2806 -263 ct 
+2795 -281 2790 -301 2790 -322 ct 2790 -342 2794 -360 2803 -376 ct 2812 -393 2825 -407 2840 -418 ct 
+2852 -427 2867 -434 2887 -440 ct 2907 -446 2929 -449 2952 -449 ct 2986 -449 3016 -444 3042 -434 ct 
+3069 -424 3088 -410 3100 -393 ct 3113 -376 3121 -354 3126 -325 ct 3053 -315 l 
+3050 -338 3040 -356 3024 -368 ct 3008 -381 2986 -387 2957 -387 ct 2923 -387 2898 -382 2884 -370 ct 
+2869 -359 2862 -346 2862 -331 ct 2862 -321 2865 -312 2871 -305 ct 2877 -297 2887 -290 2900 -285 ct 
+2907 -282 2929 -276 2965 -266 ct 3018 -252 3055 -240 3076 -231 ct 3096 -222 3113 -209 3125 -192 ct 
+3136 -175 3142 -154 3142 -129 ct 3142 -104 3135 -80 3121 -58 ct 3106 -37 3085 -20 3058 -8 ct 
+3031 3 3000 9 2965 9 ct 2908 9 2865 -1 2835 -25 ct 2805 -49 l  2786 -84 l  p ef
+3175 -131 m  3248 -142 l  3252 -113 3264 -90 3283 -74 ct 3302 -59 3328 -51 3362 -51 ct 
+3396 -51 3421 -58 3438 -72 ct 3455 -86 3463 -102 3463 -121 ct 3463 -138 3456 -151 3441 -160 ct 
+3431 -167 3405 -175 3365 -186 ct 3310 -199 3272 -211 3251 -221 ct 3230 -231 3214 -245 3203 -263 ct 
+3192 -281 3187 -301 3187 -322 ct 3187 -342 3191 -360 3200 -376 ct 3209 -393 3222 -407 3237 -418 ct 
+3249 -427 3264 -434 3284 -440 ct 3304 -446 3326 -449 3349 -449 ct 3383 -449 3413 -444 3439 -434 ct 
+3466 -424 3485 -410 3497 -393 ct 3510 -376 3518 -354 3523 -325 ct 3450 -315 l 
+3447 -338 3437 -356 3421 -368 ct 3405 -381 3383 -387 3354 -387 ct 3320 -387 3295 -382 3281 -370 ct 
+3266 -359 3259 -346 3259 -331 ct 3259 -321 3262 -312 3268 -305 ct 3274 -297 3284 -290 3297 -285 ct 
+3304 -282 3326 -276 3362 -266 ct 3415 -252 3452 -240 3473 -231 ct 3493 -222 3510 -209 3522 -192 ct 
+3533 -175 3539 -154 3539 -129 ct 3539 -104 3532 -80 3518 -58 ct 3503 -37 3482 -20 3455 -8 ct 
+3428 3 3397 9 3362 9 ct 3305 9 3262 -1 3232 -25 ct 3202 -49 l  3183 -84 l  p ef
+pom
+pum
+16827 9473 t
+69 0 m  69 -606 l  478 -606 l  478 -534 l  149 -534 l  149 -346 l  434 -346 l 
+434 -275 l  149 -275 l  149 0 l  p ef
+585 -520 m  585 -606 l  659 -606 l  659 -520 l  p
+585 0 m  585 -439 l  659 -439 l  659 0 l  p ef
+768 0 m  768 -606 l  842 -606 l  842 0 l  p ef
+1118 -66 m  1129 0 l  1108 3 1089 5 1072 5 ct 1045 5 1024 1 1010 -7 ct 995 -15 984 -26 978 -40 ct 
+972 -54 969 -83 969 -128 ct 969 -381 l  914 -381 l  914 -439 l  969 -439 l 
+969 -547 l  1043 -592 l  1043 -439 l  1118 -439 l  1118 -381 l  1043 -381 l 
+1043 -124 l  1043 -103 1044 -89 1047 -83 ct 1050 -77 1054 -72 1060 -69 ct 1066 -65 1074 -63 1085 -63 ct 
+1093 -63 l  1104 -64 l  p ef
+1494 -141 m  1571 -131 l  1559 -86 1536 -52 1504 -27 ct 1471 -2 1429 9 1378 9 ct 
+1314 9 1263 -9 1225 -49 ct 1187 -88 1169 -144 1169 -215 ct 1169 -289 1188 -347 1226 -387 ct 
+1264 -428 1313 -449 1374 -449 ct 1432 -449 1480 -429 1518 -389 ct 1555 -349 1573 -292 1573 -220 ct 
+1573 -216 1573 -209 1573 -200 ct 1245 -200 l  1248 -152 1262 -115 1286 -89 ct 
+1311 -64 1342 -51 1378 -51 ct 1406 -51 1429 -58 1448 -72 ct 1467 -87 l  1483 -110 l 
+p
+1250 -261 m  1495 -261 l  1492 -298 1482 -326 1467 -344 ct 1443 -373 1412 -387 1374 -387 ct 
+1340 -387 1312 -376 1288 -353 ct 1265 -330 l  1252 -300 l  p ef
+1669 0 m  1669 -439 l  1736 -439 l  1736 -372 l  1753 -403 1768 -424 1783 -434 ct 
+1797 -444 1813 -449 1831 -449 ct 1856 -449 1881 -441 1907 -425 ct 1882 -356 l 
+1863 -366 1845 -372 1827 -372 ct 1811 -372 1796 -367 1783 -357 ct 1770 -347 1761 -334 1755 -316 ct 
+1747 -290 1743 -261 1743 -229 ct 1743 0 l  p ef
+pom
+gr
+11317 10321 m  11312 10318 l  11099 10206 l  11093 10203 l  10924 10032 l 
+10921 10026 l  10811 9811 l  10808 9805 l  10769 9556 l  10769 9549 l 
+10808 9299 l  10811 9293 l  10921 9078 l  10924 9072 l  11093 8901 l  11099 8898 l 
+11312 8786 l  11317 8784 l  11564 8744 l  11571 8744 l  11817 8784 l  11823 8786 l 
+12036 8898 l  12041 8901 l  12210 9072 l  12213 9078 l  12324 9293 l  12326 9299 l 
+12366 9549 l  12366 9556 l  12326 9805 l  12324 9811 l  12213 10026 l 
+12210 10032 l  12041 10203 l  12036 10206 l  11823 10318 l  11817 10321 l 
+11571 10361 l  11564 10361 l  11317 10321 l  p
+11567 10319 m  11806 10279 l  12013 10171 l  12178 10004 l  12285 9794 l 
+12324 9552 l  12285 9310 l  12178 9100 l  12013 8933 l  11806 8825 l  11567 8786 l 
+11328 8825 l  11121 8933 l  10956 9100 l  10849 9310 l  10811 9552 l  10849 9794 l 
+10956 10004 l  11121 10171 l  11328 10279 l  11567 10319 l  p
+11049 9029 m  11079 8998 l  11286 9208 l  11493 9417 l  11700 9627 l  11907 9837 l 
+12115 10048 l  12085 10078 l  11877 9868 l  11670 9658 l  11463 9448 l 
+11255 9238 l  11049 9029 l  p
+11079 10078 m  11049 10049 l  11255 9838 l  11463 9628 l  11670 9418 l 
+11878 9208 l  12086 8998 l  12115 9029 l  11907 9239 l  11700 9449 l  11493 9659 l 
+11286 9869 l  11079 10078 l  p ef
+1 lw 0 lj 11317 10321 m  11312 10318 l  11099 10206 l  11093 10203 l  10924 10032 l 
+10921 10026 l  10811 9811 l  10808 9805 l  10769 9556 l  10769 9549 l 
+10808 9299 l  10811 9293 l  10921 9078 l  10924 9072 l  11093 8901 l  11099 8898 l 
+11312 8786 l  11317 8784 l  11564 8744 l  11571 8744 l  11817 8784 l  11823 8786 l 
+12036 8898 l  12041 8901 l  12210 9072 l  12213 9078 l  12324 9293 l  12326 9299 l 
+12366 9549 l  12366 9556 l  12326 9805 l  12324 9811 l  12213 10026 l 
+12210 10032 l  12041 10203 l  12036 10206 l  11823 10318 l  11817 10321 l 
+11571 10361 l  11564 10361 l  11317 10321 l  pc
+11567 10319 m  11806 10279 l  12013 10171 l  12178 10004 l  12285 9794 l 
+12324 9552 l  12285 9310 l  12178 9100 l  12013 8933 l  11806 8825 l  11567 8786 l 
+11328 8825 l  11121 8933 l  10956 9100 l  10849 9310 l  10811 9552 l  10849 9794 l 
+10956 10004 l  11121 10171 l  11328 10279 l  11567 10319 l  pc
+11049 9029 m  11079 8998 l  11286 9208 l  11493 9417 l  11700 9627 l  11907 9837 l 
+12115 10048 l  12085 10078 l  11877 9868 l  11670 9658 l  11463 9448 l 
+11255 9238 l  11049 9029 l  pc
+11079 10078 m  11049 10049 l  11255 9838 l  11463 9628 l  11670 9418 l 
+11878 9208 l  12086 8998 l  12115 9029 l  11907 9239 l  11700 9449 l  11493 9659 l 
+11286 9869 l  11079 10078 l  pc
+7989 6986 m  7538 6836 l  7539 7136 l  7989 6986 l  p ef
+5716 6986 m  7629 6986 l  ps
+14606 6986 m  14155 6836 l  14156 7136 l  14606 6986 l  p ef
+9526 6986 m  14246 6986 l  ps
+10769 9526 m  10318 9376 l  10319 9676 l  10769 9526 l  p ef
+5716 9526 m  10409 9526 l  ps
+14606 9526 m  14155 9376 l  14156 9676 l  14606 9526 l  p ef
+12426 9526 m  14246 9526 l  ps
+0 lw 1 lj 10061 16546 m  6251 16546 l  6251 12736 l  13871 12736 l  13871 16546 l 
+10061 16546 l  pc
+gs
+pum
+9102 13970 t
+64 0 m  64 -606 l  146 -606 l  465 -130 l  465 -606 l  542 -606 l  542 0 l 
+459 0 l  141 -476 l  141 0 l  p ef
+1106 -212 m  1187 -192 l  1170 -126 1140 -76 1096 -41 ct 1052 -6 999 10 936 10 ct 
+870 10 817 -2 776 -29 ct 735 -56 704 -94 683 -145 ct 661 -195 651 -249 651 -307 ct 
+651 -370 663 -425 687 -472 ct 711 -519 745 -555 790 -580 ct 834 -604 883 -616 937 -616 ct 
+998 -616 1049 -601 1090 -570 ct 1131 -539 1160 -496 1176 -440 ct 1097 -421 l 
+1083 -465 1063 -497 1036 -517 ct 1009 -537 976 -547 935 -547 ct 889 -547 850 -536 818 -514 ct 
+787 -492 765 -462 752 -424 ct 740 -386 733 -348 733 -308 ct 733 -256 741 -211 756 -173 ct 
+771 -134 794 -105 826 -86 ct 858 -67 892 -58 929 -58 ct 974 -58 1012 -71 1043 -97 ct 
+1074 -123 l  1095 -161 l  p ef
+1284 -295 m  1284 -395 1311 -474 1366 -531 ct 1420 -588 1489 -617 1575 -617 ct 
+1631 -617 1681 -603 1726 -576 ct 1771 -550 1805 -512 1829 -465 ct 1852 -417 1864 -362 1864 -302 ct 
+1864 -240 1852 -185 1827 -137 ct 1802 -88 1767 -52 1722 -27 ct 1676 -2 1627 10 1574 10 ct 
+1517 10 1466 -3 1421 -31 ct 1376 -58 1342 -96 1319 -143 ct 1296 -191 l  1284 -242 l 
+p
+1367 -294 m  1367 -220 1387 -163 1426 -121 ct 1465 -79 1515 -58 1574 -58 ct 
+1634 -58 1684 -79 1723 -122 ct 1762 -164 1782 -224 1782 -302 ct 1782 -352 1773 -395 1757 -431 ct 
+1740 -468 1715 -497 1683 -517 ct 1651 -537 1615 -547 1575 -547 ct 1518 -547 1470 -528 1429 -489 ct 
+1388 -450 l  1367 -385 l  p ef
+pom
+pum
+7514 14923 t
+38 -194 m  113 -201 l  117 -171 125 -146 138 -126 ct 151 -107 172 -91 199 -79 ct 
+227 -67 258 -61 292 -61 ct 323 -61 350 -66 373 -75 ct 397 -84 414 -96 426 -112 ct 
+437 -128 443 -145 443 -164 ct 443 -183 437 -200 426 -214 ct 415 -228 397 -240 372 -250 ct 
+355 -256 319 -266 264 -279 ct 208 -293 169 -305 147 -317 ct 118 -332 96 -351 82 -374 ct 
+68 -396 61 -421 61 -449 ct 61 -480 69 -508 87 -535 ct 104 -561 130 -582 163 -595 ct 
+196 -609 233 -616 274 -616 ct 319 -616 359 -609 393 -594 ct 427 -580 454 -559 472 -531 ct 
+491 -502 501 -471 502 -435 ct 425 -429 l  421 -468 407 -496 383 -516 ct 359 -536 324 -545 277 -545 ct 
+229 -545 194 -537 171 -519 ct 149 -501 138 -480 138 -454 ct 138 -433 146 -415 162 -401 ct 
+177 -387 217 -372 283 -357 ct 348 -343 393 -330 417 -319 ct 452 -303 478 -282 495 -257 ct 
+512 -232 520 -203 520 -171 ct 520 -138 511 -108 492 -80 ct 474 -51 447 -29 413 -13 ct 
+378 2 339 10 296 10 ct 241 10 195 2 158 -13 ct 121 -29 92 -53 71 -85 ct 50 -117 l 
+39 -154 l  p ef
+638 -520 m  638 -606 l  712 -606 l  712 -520 l  p
+638 0 m  638 -439 l  712 -439 l  712 0 l  p ef
+822 0 m  822 -439 l  889 -439 l  889 -376 l  922 -425 968 -449 1029 -449 ct 
+1056 -449 1080 -444 1102 -434 ct 1124 -425 1141 -412 1152 -397 ct 1163 -382 1171 -363 1175 -342 ct 
+1178 -328 1179 -304 1179 -270 ct 1179 0 l  1105 0 l  1105 -267 l  1105 -297 1102 -320 1096 -335 ct 
+1090 -350 1080 -362 1065 -371 ct 1051 -380 1033 -384 1013 -384 ct 982 -384 954 -374 931 -354 ct 
+908 -334 897 -296 897 -239 ct 897 0 l  p ef
+1600 -141 m  1677 -131 l  1665 -86 1642 -52 1610 -27 ct 1577 -2 1535 9 1484 9 ct 
+1420 9 1369 -9 1331 -49 ct 1293 -88 1275 -144 1275 -215 ct 1275 -289 1294 -347 1332 -387 ct 
+1370 -428 1419 -449 1480 -449 ct 1538 -449 1586 -429 1624 -389 ct 1661 -349 1679 -292 1679 -220 ct 
+1679 -216 1679 -209 1679 -200 ct 1351 -200 l  1354 -152 1368 -115 1392 -89 ct 
+1417 -64 1448 -51 1484 -51 ct 1512 -51 1535 -58 1554 -72 ct 1573 -87 l  1589 -110 l 
+p
+1356 -261 m  1601 -261 l  1598 -298 1588 -326 1573 -344 ct 1549 -373 1518 -387 1480 -387 ct 
+1446 -387 1418 -376 1394 -353 ct 1371 -330 l  1358 -300 l  p ef
+1958 10 m  2133 -616 l  2193 -616 l  2017 10 l  p ef
+2931 -212 m  3012 -192 l  2995 -126 2965 -76 2921 -41 ct 2877 -6 2824 10 2761 10 ct 
+2695 10 2642 -2 2601 -29 ct 2560 -56 2529 -94 2508 -145 ct 2486 -195 2476 -249 2476 -307 ct 
+2476 -370 2488 -425 2512 -472 ct 2536 -519 2570 -555 2615 -580 ct 2659 -604 2708 -616 2762 -616 ct 
+2823 -616 2874 -601 2915 -570 ct 2956 -539 2985 -496 3001 -440 ct 2922 -421 l 
+2908 -465 2888 -497 2861 -517 ct 2834 -537 2801 -547 2760 -547 ct 2714 -547 2675 -536 2643 -514 ct 
+2612 -492 2590 -462 2577 -424 ct 2565 -386 2558 -348 2558 -308 ct 2558 -256 2566 -211 2581 -173 ct 
+2596 -134 2619 -105 2651 -86 ct 2683 -67 2717 -58 2754 -58 ct 2799 -58 2837 -71 2868 -97 ct 
+2899 -123 l  2920 -161 l  p ef
+3097 -219 m  3097 -300 3119 -361 3164 -400 ct 3202 -432 3248 -449 3303 -449 ct 
+3363 -449 3412 -429 3451 -389 ct 3489 -350 3508 -295 3508 -225 ct 3508 -169 3500 -124 3483 -92 ct 
+3466 -60 3441 -34 3409 -16 ct 3376 0 3341 9 3303 9 ct 3241 9 3191 -9 3153 -49 ct 
+3116 -88 l  3097 -145 l  p
+3173 -219 m  3173 -163 3185 -121 3210 -93 ct 3234 -65 3265 -51 3303 -51 ct 3340 -51 3370 -65 3395 -93 ct 
+3419 -121 3432 -164 3432 -222 ct 3432 -276 3419 -317 3395 -345 ct 3370 -373 3339 -387 3303 -387 ct 
+3265 -387 3234 -373 3210 -345 ct 3185 -317 l  3173 -275 l  p ef
+3571 -131 m  3644 -142 l  3648 -113 3660 -90 3679 -74 ct 3698 -59 3724 -51 3758 -51 ct 
+3792 -51 3817 -58 3834 -72 ct 3851 -86 3859 -102 3859 -121 ct 3859 -138 3852 -151 3837 -160 ct 
+3827 -167 3801 -175 3761 -186 ct 3706 -199 3668 -211 3647 -221 ct 3626 -231 3610 -245 3599 -263 ct 
+3588 -281 3583 -301 3583 -322 ct 3583 -342 3587 -360 3596 -376 ct 3605 -393 3618 -407 3633 -418 ct 
+3645 -427 3660 -434 3680 -440 ct 3700 -446 3722 -449 3745 -449 ct 3779 -449 3809 -444 3835 -434 ct 
+3862 -424 3881 -410 3893 -393 ct 3906 -376 3914 -354 3919 -325 ct 3846 -315 l 
+3843 -338 3833 -356 3817 -368 ct 3801 -381 3779 -387 3750 -387 ct 3716 -387 3691 -382 3677 -370 ct 
+3662 -359 3655 -346 3655 -331 ct 3655 -321 3658 -312 3664 -305 ct 3670 -297 3680 -290 3693 -285 ct 
+3700 -282 3722 -276 3758 -266 ct 3811 -252 3848 -240 3869 -231 ct 3889 -222 3906 -209 3918 -192 ct 
+3929 -175 3935 -154 3935 -129 ct 3935 -104 3928 -80 3914 -58 ct 3899 -37 3878 -20 3851 -8 ct 
+3824 3 3793 9 3758 9 ct 3701 9 3658 -1 3628 -25 ct 3598 -49 l  3579 -84 l  p ef
+3998 -520 m  3998 -606 l  4072 -606 l  4072 -520 l  p
+3998 0 m  3998 -439 l  4072 -439 l  4072 0 l  p ef
+4183 0 m  4183 -439 l  4250 -439 l  4250 -376 l  4283 -425 4329 -449 4390 -449 ct 
+4417 -449 4441 -444 4463 -434 ct 4485 -425 4502 -412 4513 -397 ct 4524 -382 4532 -363 4536 -342 ct 
+4539 -328 4540 -304 4540 -270 ct 4540 0 l  4466 0 l  4466 -267 l  4466 -297 4463 -320 4457 -335 ct 
+4451 -350 4441 -362 4426 -371 ct 4412 -380 4394 -384 4374 -384 ct 4343 -384 4315 -374 4292 -354 ct 
+4269 -334 4258 -296 4258 -239 ct 4258 0 l  p ef
+4960 -141 m  5037 -131 l  5025 -86 5002 -52 4970 -27 ct 4937 -2 4895 9 4844 9 ct 
+4780 9 4729 -9 4691 -49 ct 4653 -88 4635 -144 4635 -215 ct 4635 -289 4654 -347 4692 -387 ct 
+4730 -428 4779 -449 4840 -449 ct 4898 -449 4946 -429 4984 -389 ct 5021 -349 5039 -292 5039 -220 ct 
+5039 -216 5039 -209 5039 -200 ct 4711 -200 l  4714 -152 4728 -115 4752 -89 ct 
+4777 -64 4808 -51 4844 -51 ct 4872 -51 4895 -58 4914 -72 ct 4933 -87 l  4949 -110 l 
+p
+4716 -261 m  4961 -261 l  4958 -298 4948 -326 4933 -344 ct 4909 -373 4878 -387 4840 -387 ct 
+4806 -387 4778 -376 4754 -353 ct 4731 -330 l  4718 -300 l  p ef
+pom
+pum
+8136 15876 t
+349 -237 m  349 -308 l  605 -309 l  605 -84 l  566 -52 525 -29 483 -13 ct 
+441 2 398 10 354 10 ct 295 10 241 -2 192 -27 ct 143 -53 107 -90 82 -138 ct 57 -186 45 -240 45 -300 ct 
+45 -359 57 -414 82 -465 ct 106 -516 142 -554 188 -579 ct 234 -604 288 -616 348 -616 ct 
+392 -616 432 -609 467 -595 ct 502 -581 530 -561 550 -535 ct 571 -510 586 -477 596 -436 ct 
+524 -416 l  515 -447 504 -472 490 -489 ct 476 -507 457 -521 432 -532 ct 407 -542 379 -547 349 -547 ct 
+312 -547 280 -542 253 -531 ct 227 -520 205 -505 189 -487 ct 172 -468 160 -449 150 -427 ct 
+135 -389 127 -349 127 -305 ct 127 -251 137 -205 155 -169 ct 174 -133 201 -106 236 -88 ct 
+272 -70 310 -62 350 -62 ct 385 -62 418 -68 452 -82 ct 485 -95 510 -109 527 -124 ct 
+527 -237 l  p ef
+1017 -141 m  1094 -131 l  1082 -86 1059 -52 1027 -27 ct 994 -2 952 9 901 9 ct 
+837 9 786 -9 748 -49 ct 710 -88 692 -144 692 -215 ct 692 -289 711 -347 749 -387 ct 
+787 -428 836 -449 897 -449 ct 955 -449 1003 -429 1041 -389 ct 1078 -349 1096 -292 1096 -220 ct 
+1096 -216 1096 -209 1096 -200 ct 768 -200 l  771 -152 785 -115 809 -89 ct 834 -64 865 -51 901 -51 ct 
+929 -51 952 -58 971 -72 ct 990 -87 l  1006 -110 l  p
+773 -261 m  1018 -261 l  1015 -298 1005 -326 990 -344 ct 966 -373 935 -387 897 -387 ct 
+863 -387 835 -376 811 -353 ct 788 -330 l  775 -300 l  p ef
+1193 0 m  1193 -439 l  1260 -439 l  1260 -376 l  1293 -425 1339 -449 1400 -449 ct 
+1427 -449 1451 -444 1473 -434 ct 1495 -425 1512 -412 1523 -397 ct 1534 -382 1542 -363 1546 -342 ct 
+1549 -328 1550 -304 1550 -270 ct 1550 0 l  1476 0 l  1476 -267 l  1476 -297 1473 -320 1467 -335 ct 
+1461 -350 1451 -362 1436 -371 ct 1422 -380 1404 -384 1384 -384 ct 1353 -384 1325 -374 1302 -354 ct 
+1279 -334 1268 -296 1268 -239 ct 1268 0 l  p ef
+1970 -141 m  2047 -131 l  2035 -86 2012 -52 1980 -27 ct 1947 -2 1905 9 1854 9 ct 
+1790 9 1739 -9 1701 -49 ct 1663 -88 1645 -144 1645 -215 ct 1645 -289 1664 -347 1702 -387 ct 
+1740 -428 1789 -449 1850 -449 ct 1908 -449 1956 -429 1994 -389 ct 2031 -349 2049 -292 2049 -220 ct 
+2049 -216 2049 -209 2049 -200 ct 1721 -200 l  1724 -152 1738 -115 1762 -89 ct 
+1787 -64 1818 -51 1854 -51 ct 1882 -51 1905 -58 1924 -72 ct 1943 -87 l  1959 -110 l 
+p
+1726 -261 m  1971 -261 l  1968 -298 1958 -326 1943 -344 ct 1919 -373 1888 -387 1850 -387 ct 
+1816 -387 1788 -376 1764 -353 ct 1741 -330 l  1728 -300 l  p ef
+2145 0 m  2145 -439 l  2212 -439 l  2212 -372 l  2229 -403 2244 -424 2259 -434 ct 
+2273 -444 2289 -449 2307 -449 ct 2332 -449 2357 -441 2383 -425 ct 2358 -356 l 
+2339 -366 2321 -372 2303 -372 ct 2287 -372 2272 -367 2259 -357 ct 2246 -347 2237 -334 2231 -316 ct 
+2223 -290 2219 -261 2219 -229 ct 2219 0 l  p ef
+2723 -54 m  2695 -30 2669 -14 2643 -4 ct 2618 5 2590 9 2561 9 ct 2513 9 2476 -1 2450 -25 ct 
+2424 -49 2411 -79 2411 -115 ct 2411 -137 2416 -156 2426 -174 ct 2436 -192 2448 -206 2464 -217 ct 
+2480 -228 2498 -236 2518 -241 ct 2532 -245 2554 -249 2584 -253 ct 2644 -260 2688 -268 2717 -278 ct 
+2717 -288 2717 -295 2717 -298 ct 2717 -328 2710 -349 2696 -362 ct 2677 -379 2649 -387 2611 -387 ct 
+2576 -387 2550 -381 2534 -369 ct 2517 -356 2505 -335 2497 -303 ct 2424 -313 l 
+2431 -345 2441 -370 2457 -389 ct 2472 -408 2494 -423 2522 -433 ct 2551 -443 2584 -449 2622 -449 ct 
+2660 -449 2690 -444 2713 -435 ct 2737 -427 2754 -415 2765 -402 ct 2776 -389 2784 -372 2788 -351 ct 
+2791 -339 2792 -316 2792 -283 ct 2792 -184 l  2792 -114 2794 -71 2797 -52 ct 
+2800 -34 2806 -16 2816 0 ct 2738 0 l  2730 -15 l  2725 -33 l  p
+2717 -220 m  2690 -209 2649 -200 2595 -192 ct 2565 -187 2543 -182 2530 -177 ct 
+2518 -171 2508 -163 2501 -153 ct 2494 -142 2491 -130 2491 -117 ct 2491 -98 2498 -81 2513 -68 ct 
+2528 -55 2550 -48 2579 -48 ct 2608 -48 2633 -54 2656 -67 ct 2678 -79 2694 -96 2705 -118 ct 
+2713 -135 2717 -160 2717 -193 ct p ef
+3049 -66 m  3060 0 l  3039 3 3020 5 3003 5 ct 2976 5 2955 1 2941 -7 ct 2926 -15 2915 -26 2909 -40 ct 
+2903 -54 2900 -83 2900 -128 ct 2900 -381 l  2845 -381 l  2845 -439 l  2900 -439 l 
+2900 -547 l  2974 -592 l  2974 -439 l  3049 -439 l  3049 -381 l  2974 -381 l 
+2974 -124 l  2974 -103 2975 -89 2978 -83 ct 2981 -77 2985 -72 2991 -69 ct 2997 -65 3005 -63 3016 -63 ct 
+3024 -63 l  3035 -64 l  p ef
+3097 -219 m  3097 -300 3119 -361 3164 -400 ct 3202 -432 3248 -449 3303 -449 ct 
+3363 -449 3412 -429 3451 -389 ct 3489 -350 3508 -295 3508 -225 ct 3508 -169 3500 -124 3483 -92 ct 
+3466 -60 3441 -34 3409 -16 ct 3376 0 3341 9 3303 9 ct 3241 9 3191 -9 3153 -49 ct 
+3116 -88 l  3097 -145 l  p
+3173 -219 m  3173 -163 3185 -121 3210 -93 ct 3234 -65 3265 -51 3303 -51 ct 3340 -51 3370 -65 3395 -93 ct 
+3419 -121 3432 -164 3432 -222 ct 3432 -276 3419 -317 3395 -345 ct 3370 -373 3339 -387 3303 -387 ct 
+3265 -387 3234 -373 3210 -345 ct 3185 -317 l  3173 -275 l  p ef
+3600 0 m  3600 -439 l  3667 -439 l  3667 -372 l  3684 -403 3699 -424 3714 -434 ct 
+3728 -444 3744 -449 3762 -449 ct 3787 -449 3812 -441 3838 -425 ct 3813 -356 l 
+3794 -366 3776 -372 3758 -372 ct 3742 -372 3727 -367 3714 -357 ct 3701 -347 3692 -334 3686 -316 ct 
+3678 -290 3674 -261 3674 -229 ct 3674 0 l  p ef
+pom
+gr
+gs
+pum
+1284 9366 t
+79 0 m  79 -606 l  159 -606 l  159 0 l  p ef
+293 0 m  293 -439 l  360 -439 l  360 -376 l  393 -425 439 -449 500 -449 ct 
+527 -449 551 -444 573 -434 ct 595 -425 612 -412 623 -397 ct 634 -382 642 -363 646 -342 ct 
+649 -328 650 -304 650 -270 ct 650 0 l  576 0 l  576 -267 l  576 -297 573 -320 567 -335 ct 
+561 -350 551 -362 536 -371 ct 522 -380 504 -384 484 -384 ct 453 -384 425 -374 402 -354 ct 
+379 -334 368 -296 368 -239 ct 368 0 l  p ef
+769 168 m  769 -439 l  837 -439 l  837 -382 l  853 -404 871 -421 891 -432 ct 
+911 -443 936 -449 965 -449 ct 1002 -449 1035 -439 1064 -420 ct 1092 -400 1114 -373 1129 -338 ct 
+1143 -303 1151 -264 1151 -222 ct 1151 -177 1143 -137 1126 -101 ct 1110 -65 1087 -37 1056 -18 ct 
+1025 0 993 9 959 9 ct 934 9 912 4 892 -5 ct 873 -16 856 -29 844 -45 ct 844 168 l 
+p
+837 -217 m  837 -160 848 -118 871 -91 ct 894 -64 922 -51 954 -51 ct 987 -51 1016 -65 1039 -93 ct 
+1063 -121 1075 -164 1075 -223 ct 1075 -279 1063 -321 1040 -349 ct 1017 -376 990 -390 958 -390 ct 
+926 -390 898 -376 873 -346 ct 849 -316 l  837 -273 l  p ef
+1507 0 m  1507 -64 l  1473 -14 1427 9 1368 9 ct 1342 9 1318 4 1295 -4 ct 1273 -14 1256 -27 1245 -42 ct 
+1234 -57 1227 -75 1222 -97 ct 1219 -112 1218 -135 1218 -167 ct 1218 -439 l  1292 -439 l 
+1292 -195 l  1292 -156 1294 -130 1297 -117 ct 1301 -97 1311 -82 1326 -70 ct 
+1342 -59 1360 -54 1383 -54 ct 1405 -54 1426 -59 1446 -71 ct 1465 -82 1479 -98 1487 -118 ct 
+1495 -137 1499 -166 1499 -203 ct 1499 -439 l  1574 -439 l  1574 0 l  p ef
+1858 -66 m  1869 0 l  1848 3 1829 5 1812 5 ct 1785 5 1764 1 1750 -7 ct 1735 -15 1724 -26 1718 -40 ct 
+1712 -54 1709 -83 1709 -128 ct 1709 -381 l  1654 -381 l  1654 -439 l  1709 -439 l 
+1709 -547 l  1783 -592 l  1783 -439 l  1858 -439 l  1858 -381 l  1783 -381 l 
+1783 -124 l  1783 -103 1784 -89 1787 -83 ct 1790 -77 1794 -72 1800 -69 ct 1806 -65 1814 -63 1825 -63 ct 
+1833 -63 l  1844 -64 l  p ef
+2190 0 m  2190 -381 l  2124 -381 l  2124 -439 l  2190 -439 l  2190 -485 l 
+2190 -515 2193 -537 2198 -551 ct 2205 -571 2218 -586 2236 -598 ct 2254 -610 2279 -616 2312 -616 ct 
+2333 -616 2356 -614 2381 -609 ct 2370 -544 l  2355 -547 2340 -548 2326 -548 ct 
+2304 -548 2288 -543 2278 -533 ct 2269 -524 2264 -506 2264 -479 ct 2264 -439 l 
+2350 -439 l  2350 -381 l  2264 -381 l  2264 0 l  p ef
+2410 0 m  2410 -439 l  2477 -439 l  2477 -372 l  2494 -403 2509 -424 2524 -434 ct 
+2538 -444 2554 -449 2572 -449 ct 2597 -449 2622 -441 2648 -425 ct 2623 -356 l 
+2604 -366 2586 -372 2568 -372 ct 2552 -372 2537 -367 2524 -357 ct 2511 -347 2502 -334 2496 -316 ct 
+2488 -290 2484 -261 2484 -229 ct 2484 0 l  p ef
+2674 -219 m  2674 -300 2696 -361 2741 -400 ct 2779 -432 2825 -449 2880 -449 ct 
+2940 -449 2989 -429 3028 -389 ct 3066 -350 3085 -295 3085 -225 ct 3085 -169 3077 -124 3060 -92 ct 
+3043 -60 3018 -34 2986 -16 ct 2953 0 2918 9 2880 9 ct 2818 9 2768 -9 2730 -49 ct 
+2693 -88 l  2674 -145 l  p
+2750 -219 m  2750 -163 2762 -121 2787 -93 ct 2811 -65 2842 -51 2880 -51 ct 2917 -51 2947 -65 2972 -93 ct 
+2996 -121 3009 -164 3009 -222 ct 3009 -276 2996 -317 2972 -345 ct 2947 -373 2916 -387 2880 -387 ct 
+2842 -387 2811 -373 2787 -345 ct 2762 -317 l  2750 -275 l  p ef
+3177 0 m  3177 -439 l  3244 -439 l  3244 -377 l  3258 -399 3276 -416 3299 -429 ct 
+3322 -442 3348 -449 3377 -449 ct 3410 -449 3436 -442 3457 -428 ct 3478 -415 3493 -396 3501 -372 ct 
+3536 -423 3581 -449 3637 -449 ct 3680 -449 3714 -437 3737 -412 ct 3761 -388 3772 -351 3772 -301 ct 
+3772 0 l  3698 0 l  3698 -276 l  3698 -306 3696 -327 3691 -340 ct 3686 -354 3678 -364 3665 -372 ct 
+3652 -380 3637 -384 3620 -384 ct 3589 -384 3564 -374 3543 -353 ct 3523 -333 3513 -300 3513 -255 ct 
+3513 0 l  3438 0 l  3438 -285 l  3438 -318 3432 -343 3420 -359 ct 3408 -376 3388 -384 3361 -384 ct 
+3340 -384 3320 -379 3302 -368 ct 3285 -357 3272 -340 3264 -319 ct 3256 -298 3252 -267 3252 -227 ct 
+3252 0 l  p ef
+pom
+pum
+2302 10319 t
+-1 0 m  231 -606 l  318 -606 l  566 0 l  474 0 l  404 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  379 -248 l  315 -416 l  296 -467 282 -509 272 -542 ct 265 -503 254 -465 240 -426 ct 
+p ef
+621 0 m  621 -606 l  830 -606 l  877 -606 913 -603 938 -597 ct 972 -589 1002 -575 1027 -554 ct 
+1059 -527 1082 -492 1098 -450 ct 1114 -408 1122 -360 1122 -306 ct 1122 -260 1117 -219 1106 -184 ct 
+1095 -148 1081 -119 1065 -95 ct 1048 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+909 -3 876 0 840 0 ct p
+701 -71 m  831 -71 l  871 -71 902 -75 925 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1013 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -371 1029 -419 1008 -453 ct 
+987 -487 962 -510 932 -522 ct 911 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1742 -192 l  1725 -126 1695 -76 1651 -41 ct 1607 -6 1554 10 1491 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -555 1345 -580 ct 1389 -604 1438 -616 1492 -616 ct 
+1553 -616 1604 -601 1645 -570 ct 1686 -539 1715 -496 1731 -440 ct 1652 -421 l 
+1638 -465 1618 -497 1591 -517 ct 1564 -537 1531 -547 1490 -547 ct 1444 -547 1405 -536 1373 -514 ct 
+1342 -492 1320 -462 1307 -424 ct 1295 -386 1288 -348 1288 -308 ct 1288 -256 1296 -211 1311 -173 ct 
+1326 -134 1349 -105 1381 -86 ct 1413 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -123 l  1650 -161 l  p ef
+pom
+gr
+gs
+pum
+1284 6773 t
+79 0 m  79 -606 l  159 -606 l  159 0 l  p ef
+293 0 m  293 -439 l  360 -439 l  360 -376 l  393 -425 439 -449 500 -449 ct 
+527 -449 551 -444 573 -434 ct 595 -425 612 -412 623 -397 ct 634 -382 642 -363 646 -342 ct 
+649 -328 650 -304 650 -270 ct 650 0 l  576 0 l  576 -267 l  576 -297 573 -320 567 -335 ct 
+561 -350 551 -362 536 -371 ct 522 -380 504 -384 484 -384 ct 453 -384 425 -374 402 -354 ct 
+379 -334 368 -296 368 -239 ct 368 0 l  p ef
+769 168 m  769 -439 l  837 -439 l  837 -382 l  853 -404 871 -421 891 -432 ct 
+911 -443 936 -449 965 -449 ct 1002 -449 1035 -439 1064 -420 ct 1092 -400 1114 -373 1129 -338 ct 
+1143 -303 1151 -264 1151 -222 ct 1151 -177 1143 -137 1126 -101 ct 1110 -65 1087 -37 1056 -18 ct 
+1025 0 993 9 959 9 ct 934 9 912 4 892 -5 ct 873 -16 856 -29 844 -45 ct 844 168 l 
+p
+837 -217 m  837 -160 848 -118 871 -91 ct 894 -64 922 -51 954 -51 ct 987 -51 1016 -65 1039 -93 ct 
+1063 -121 1075 -164 1075 -223 ct 1075 -279 1063 -321 1040 -349 ct 1017 -376 990 -390 958 -390 ct 
+926 -390 898 -376 873 -346 ct 849 -316 l  837 -273 l  p ef
+1507 0 m  1507 -64 l  1473 -14 1427 9 1368 9 ct 1342 9 1318 4 1295 -4 ct 1273 -14 1256 -27 1245 -42 ct 
+1234 -57 1227 -75 1222 -97 ct 1219 -112 1218 -135 1218 -167 ct 1218 -439 l  1292 -439 l 
+1292 -195 l  1292 -156 1294 -130 1297 -117 ct 1301 -97 1311 -82 1326 -70 ct 
+1342 -59 1360 -54 1383 -54 ct 1405 -54 1426 -59 1446 -71 ct 1465 -82 1479 -98 1487 -118 ct 
+1495 -137 1499 -166 1499 -203 ct 1499 -439 l  1574 -439 l  1574 0 l  p ef
+1858 -66 m  1869 0 l  1848 3 1829 5 1812 5 ct 1785 5 1764 1 1750 -7 ct 1735 -15 1724 -26 1718 -40 ct 
+1712 -54 1709 -83 1709 -128 ct 1709 -381 l  1654 -381 l  1654 -439 l  1709 -439 l 
+1709 -547 l  1783 -592 l  1783 -439 l  1858 -439 l  1858 -381 l  1783 -381 l 
+1783 -124 l  1783 -103 1784 -89 1787 -83 ct 1790 -77 1794 -72 1800 -69 ct 1806 -65 1814 -63 1825 -63 ct 
+1833 -63 l  1844 -64 l  p ef
+2190 0 m  2190 -381 l  2124 -381 l  2124 -439 l  2190 -439 l  2190 -485 l 
+2190 -515 2193 -537 2198 -551 ct 2205 -571 2218 -586 2236 -598 ct 2254 -610 2279 -616 2312 -616 ct 
+2333 -616 2356 -614 2381 -609 ct 2370 -544 l  2355 -547 2340 -548 2326 -548 ct 
+2304 -548 2288 -543 2278 -533 ct 2269 -524 2264 -506 2264 -479 ct 2264 -439 l 
+2350 -439 l  2350 -381 l  2264 -381 l  2264 0 l  p ef
+2410 0 m  2410 -439 l  2477 -439 l  2477 -372 l  2494 -403 2509 -424 2524 -434 ct 
+2538 -444 2554 -449 2572 -449 ct 2597 -449 2622 -441 2648 -425 ct 2623 -356 l 
+2604 -366 2586 -372 2568 -372 ct 2552 -372 2537 -367 2524 -357 ct 2511 -347 2502 -334 2496 -316 ct 
+2488 -290 2484 -261 2484 -229 ct 2484 0 l  p ef
+2674 -219 m  2674 -300 2696 -361 2741 -400 ct 2779 -432 2825 -449 2880 -449 ct 
+2940 -449 2989 -429 3028 -389 ct 3066 -350 3085 -295 3085 -225 ct 3085 -169 3077 -124 3060 -92 ct 
+3043 -60 3018 -34 2986 -16 ct 2953 0 2918 9 2880 9 ct 2818 9 2768 -9 2730 -49 ct 
+2693 -88 l  2674 -145 l  p
+2750 -219 m  2750 -163 2762 -121 2787 -93 ct 2811 -65 2842 -51 2880 -51 ct 2917 -51 2947 -65 2972 -93 ct 
+2996 -121 3009 -164 3009 -222 ct 3009 -276 2996 -317 2972 -345 ct 2947 -373 2916 -387 2880 -387 ct 
+2842 -387 2811 -373 2787 -345 ct 2762 -317 l  2750 -275 l  p ef
+3177 0 m  3177 -439 l  3244 -439 l  3244 -377 l  3258 -399 3276 -416 3299 -429 ct 
+3322 -442 3348 -449 3377 -449 ct 3410 -449 3436 -442 3457 -428 ct 3478 -415 3493 -396 3501 -372 ct 
+3536 -423 3581 -449 3637 -449 ct 3680 -449 3714 -437 3737 -412 ct 3761 -388 3772 -351 3772 -301 ct 
+3772 0 l  3698 0 l  3698 -276 l  3698 -306 3696 -327 3691 -340 ct 3686 -354 3678 -364 3665 -372 ct 
+3652 -380 3637 -384 3620 -384 ct 3589 -384 3564 -374 3543 -353 ct 3523 -333 3513 -300 3513 -255 ct 
+3513 0 l  3438 0 l  3438 -285 l  3438 -318 3432 -343 3420 -359 ct 3408 -376 3388 -384 3361 -384 ct 
+3340 -384 3320 -379 3302 -368 ct 3285 -357 3272 -340 3264 -319 ct 3256 -298 3252 -267 3252 -227 ct 
+3252 0 l  p ef
+pom
+pum
+2302 7726 t
+-1 0 m  231 -606 l  318 -606 l  566 0 l  474 0 l  404 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  379 -248 l  315 -416 l  296 -467 282 -509 272 -542 ct 265 -503 254 -465 240 -426 ct 
+p ef
+621 0 m  621 -606 l  830 -606 l  877 -606 913 -603 938 -597 ct 972 -589 1002 -575 1027 -554 ct 
+1059 -527 1082 -492 1098 -450 ct 1114 -408 1122 -360 1122 -306 ct 1122 -260 1117 -219 1106 -184 ct 
+1095 -148 1081 -119 1065 -95 ct 1048 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+909 -3 876 0 840 0 ct p
+701 -71 m  831 -71 l  871 -71 902 -75 925 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1013 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -371 1029 -419 1008 -453 ct 
+987 -487 962 -510 932 -522 ct 911 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1742 -192 l  1725 -126 1695 -76 1651 -41 ct 1607 -6 1554 10 1491 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -555 1345 -580 ct 1389 -604 1438 -616 1492 -616 ct 
+1553 -616 1604 -601 1645 -570 ct 1686 -539 1715 -496 1731 -440 ct 1652 -421 l 
+1638 -465 1618 -497 1591 -517 ct 1564 -537 1531 -547 1490 -547 ct 1444 -547 1405 -536 1373 -514 ct 
+1342 -492 1320 -462 1307 -424 ct 1295 -386 1288 -348 1288 -308 ct 1288 -256 1296 -211 1311 -173 ct 
+1326 -134 1349 -105 1381 -86 ct 1413 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -123 l  1650 -161 l  p ef
+pom
+gr
+8442 7781 m  8437 7778 l  8224 7666 l  8218 7663 l  8049 7492 l  8046 7486 l 
+7936 7271 l  7933 7265 l  7894 7016 l  7894 7009 l  7933 6759 l  7936 6753 l 
+8046 6538 l  8049 6532 l  8218 6361 l  8224 6358 l  8437 6246 l  8442 6244 l 
+8689 6204 l  8696 6204 l  8942 6244 l  8948 6246 l  9161 6358 l  9166 6361 l 
+9335 6532 l  9338 6538 l  9449 6753 l  9451 6759 l  9491 7009 l  9491 7016 l 
+9451 7265 l  9449 7271 l  9338 7486 l  9335 7492 l  9166 7663 l  9161 7666 l 
+8948 7778 l  8942 7781 l  8696 7821 l  8689 7821 l  8442 7781 l  p
+8692 7779 m  8931 7739 l  9138 7631 l  9303 7464 l  9410 7254 l  9449 7012 l 
+9410 6770 l  9303 6560 l  9138 6393 l  8931 6285 l  8692 6246 l  8453 6285 l 
+8246 6393 l  8081 6560 l  7974 6770 l  7936 7012 l  7974 7254 l  8081 7464 l 
+8246 7631 l  8453 7739 l  8692 7779 l  p
+8174 6489 m  8204 6458 l  8411 6668 l  8618 6877 l  8825 7087 l  9032 7297 l 
+9240 7508 l  9210 7538 l  9002 7328 l  8795 7118 l  8588 6908 l  8380 6698 l 
+8174 6489 l  p
+8204 7538 m  8174 7509 l  8380 7298 l  8588 7088 l  8795 6878 l  9003 6668 l 
+9211 6458 l  9240 6489 l  9032 6699 l  8825 6909 l  8618 7119 l  8411 7329 l 
+8204 7538 l  p ef
+1 lw 0 lj 8442 7781 m  8437 7778 l  8224 7666 l  8218 7663 l  8049 7492 l 
+8046 7486 l  7936 7271 l  7933 7265 l  7894 7016 l  7894 7009 l  7933 6759 l 
+7936 6753 l  8046 6538 l  8049 6532 l  8218 6361 l  8224 6358 l  8437 6246 l 
+8442 6244 l  8689 6204 l  8696 6204 l  8942 6244 l  8948 6246 l  9161 6358 l 
+9166 6361 l  9335 6532 l  9338 6538 l  9449 6753 l  9451 6759 l  9491 7009 l 
+9491 7016 l  9451 7265 l  9449 7271 l  9338 7486 l  9335 7492 l  9166 7663 l 
+9161 7666 l  8948 7778 l  8942 7781 l  8696 7821 l  8689 7821 l  8442 7781 l 
+pc
+8692 7779 m  8931 7739 l  9138 7631 l  9303 7464 l  9410 7254 l  9449 7012 l 
+9410 6770 l  9303 6560 l  9138 6393 l  8931 6285 l  8692 6246 l  8453 6285 l 
+8246 6393 l  8081 6560 l  7974 6770 l  7936 7012 l  7974 7254 l  8081 7464 l 
+8246 7631 l  8453 7739 l  8692 7779 l  pc
+8174 6489 m  8204 6458 l  8411 6668 l  8618 6877 l  8825 7087 l  9032 7297 l 
+9240 7508 l  9210 7538 l  9002 7328 l  8795 7118 l  8588 6908 l  8380 6698 l 
+8174 6489 l  pc
+8204 7538 m  8174 7509 l  8380 7298 l  8588 7088 l  8795 6878 l  9003 6668 l 
+9211 6458 l  9240 6489 l  9032 6699 l  8825 6909 l  8618 7119 l  8411 7329 l 
+8204 7538 l  pc
+8691 7821 m  8541 8271 l  8841 8270 l  8691 7821 l  p ef
+8691 8181 m  8691 12701 l  ps
+11531 10361 m  11381 10811 l  11681 10810 l  11531 10361 l  p ef
+11531 10721 m  11531 12701 l  ps
+gs
+pum
+7329 12171 t
+26 -131 m  99 -142 l  103 -113 115 -90 134 -74 ct 153 -59 179 -51 213 -51 ct 
+247 -51 272 -58 289 -72 ct 306 -86 314 -102 314 -121 ct 314 -138 307 -151 292 -160 ct 
+282 -167 256 -175 216 -186 ct 161 -199 123 -211 102 -221 ct 81 -231 65 -245 54 -263 ct 
+43 -281 38 -301 38 -322 ct 38 -342 42 -360 51 -376 ct 60 -393 73 -407 88 -418 ct 
+100 -427 115 -434 135 -440 ct 155 -446 177 -449 200 -449 ct 234 -449 264 -444 290 -434 ct 
+317 -424 336 -410 348 -393 ct 361 -376 369 -354 374 -325 ct 301 -315 l  298 -338 288 -356 272 -368 ct 
+256 -381 234 -387 205 -387 ct 171 -387 146 -382 132 -370 ct 117 -359 110 -346 110 -331 ct 
+110 -321 113 -312 119 -305 ct 125 -297 135 -290 148 -285 ct 155 -282 177 -276 213 -266 ct 
+266 -252 303 -240 324 -231 ct 344 -222 361 -209 373 -192 ct 384 -175 390 -154 390 -129 ct 
+390 -104 383 -80 369 -58 ct 354 -37 333 -20 306 -8 ct 279 3 248 9 213 9 ct 156 9 113 -1 83 -25 ct 
+53 -49 l  34 -84 l  p ef
+453 -520 m  453 -606 l  527 -606 l  527 -520 l  p
+453 0 m  453 -439 l  527 -439 l  527 0 l  p ef
+637 0 m  637 -439 l  704 -439 l  704 -376 l  737 -425 783 -449 844 -449 ct 
+871 -449 895 -444 917 -434 ct 939 -425 956 -412 967 -397 ct 978 -382 986 -363 990 -342 ct 
+993 -328 994 -304 994 -270 ct 994 0 l  920 0 l  920 -267 l  920 -297 917 -320 911 -335 ct 
+905 -350 895 -362 880 -371 ct 866 -380 848 -384 828 -384 ct 797 -384 769 -374 746 -354 ct 
+723 -334 712 -296 712 -239 ct 712 0 l  p ef
+pom
+gr
+gs
+pum
+11880 12223 t
+342 -160 m  415 -151 l  407 -100 387 -61 354 -32 ct 321 -4 280 9 232 9 ct 172 9 124 -9 87 -49 ct 
+51 -88 33 -144 33 -217 ct 33 -265 40 -306 56 -342 ct 72 -378 96 -404 128 -422 ct 
+160 -440 195 -449 233 -449 ct 280 -449 319 -437 350 -412 ct 380 -388 400 -354 408 -310 ct 
+336 -299 l  329 -328 317 -350 299 -365 ct 282 -380 260 -387 236 -387 ct 198 -387 168 -374 144 -347 ct 
+121 -320 109 -278 109 -220 ct 109 -161 120 -118 143 -91 ct 166 -64 195 -51 232 -51 ct 
+261 -51 285 -60 305 -78 ct 324 -96 l  337 -123 l  p ef
+451 -219 m  451 -300 473 -361 518 -400 ct 556 -432 602 -449 657 -449 ct 717 -449 766 -429 805 -389 ct 
+843 -350 862 -295 862 -225 ct 862 -169 854 -124 837 -92 ct 820 -60 795 -34 763 -16 ct 
+730 0 695 9 657 9 ct 595 9 545 -9 507 -49 ct 470 -88 l  451 -145 l  p
+527 -219 m  527 -163 539 -121 564 -93 ct 588 -65 619 -51 657 -51 ct 694 -51 724 -65 749 -93 ct 
+773 -121 786 -164 786 -222 ct 786 -276 773 -317 749 -345 ct 724 -373 693 -387 657 -387 ct 
+619 -387 588 -373 564 -345 ct 539 -317 l  527 -275 l  p ef
+926 -131 m  999 -142 l  1003 -113 1015 -90 1034 -74 ct 1053 -59 1079 -51 1113 -51 ct 
+1147 -51 1172 -58 1189 -72 ct 1206 -86 1214 -102 1214 -121 ct 1214 -138 1207 -151 1192 -160 ct 
+1182 -167 1156 -175 1116 -186 ct 1061 -199 1023 -211 1002 -221 ct 981 -231 965 -245 954 -263 ct 
+943 -281 938 -301 938 -322 ct 938 -342 942 -360 951 -376 ct 960 -393 973 -407 988 -418 ct 
+1000 -427 1015 -434 1035 -440 ct 1055 -446 1077 -449 1100 -449 ct 1134 -449 1164 -444 1190 -434 ct 
+1217 -424 1236 -410 1248 -393 ct 1261 -376 1269 -354 1274 -325 ct 1201 -315 l 
+1198 -338 1188 -356 1172 -368 ct 1156 -381 1134 -387 1105 -387 ct 1071 -387 1046 -382 1032 -370 ct 
+1017 -359 1010 -346 1010 -331 ct 1010 -321 1013 -312 1019 -305 ct 1025 -297 1035 -290 1048 -285 ct 
+1055 -282 1077 -276 1113 -266 ct 1166 -252 1203 -240 1224 -231 ct 1244 -222 1261 -209 1273 -192 ct 
+1284 -175 1290 -154 1290 -129 ct 1290 -104 1283 -80 1269 -58 ct 1254 -37 1233 -20 1206 -8 ct 
+1179 3 1148 9 1113 9 ct 1056 9 1013 -1 983 -25 ct 953 -49 l  934 -84 l  p ef
+pom
+gr
+24131 6986 m  23680 6836 l  23681 7136 l  24131 6986 l  p ef
+20956 6986 m  23771 6986 l  ps
+24131 9526 m  23680 9376 l  23681 9676 l  24131 9526 l  p ef
+20956 9526 m  23771 9526 l  ps
+gs
+pum
+24646 7223 t
+79 0 m  79 -606 l  159 -606 l  159 0 l  p ef
+pom
+gr
+gs
+pum
+24435 9763 t
+524 -64 m  562 -39 596 -20 627 -8 ct 604 47 l  560 31 517 6 473 -27 ct 429 -2 379 10 325 10 ct 
+270 10 220 -2 175 -29 ct 131 -55 96 -93 72 -141 ct 48 -189 36 -243 36 -303 ct 36 -362 48 -417 72 -466 ct 
+97 -515 131 -552 176 -578 ct 221 -604 271 -617 326 -617 ct 382 -617 433 -603 478 -577 ct 
+523 -550 557 -513 580 -465 ct 604 -417 616 -363 616 -303 ct 616 -253 608 -208 593 -168 ct 
+578 -129 l  555 -94 l  p
+348 -167 m  394 -154 432 -135 462 -109 ct 509 -152 533 -217 533 -303 ct 533 -352 525 -395 508 -432 ct 
+491 -468 467 -497 435 -517 ct 403 -537 367 -547 327 -547 ct 267 -547 217 -527 178 -486 ct 
+138 -445 119 -384 119 -303 ct 119 -224 138 -163 177 -121 ct 216 -79 266 -58 327 -58 ct 
+355 -58 382 -63 408 -74 ct 383 -90 356 -102 328 -109 ct p ef
+pom
+gr
+gs
+pum
+23747 3307 t
+315 0 m  241 0 l  241 -474 l  223 -457 199 -440 170 -423 ct 141 -405 115 -393 92 -384 ct 
+92 -456 l  133 -476 170 -499 201 -527 ct 232 -555 254 -582 267 -608 ct 315 -608 l 
+p ef
+897 -457 m  823 -452 l  816 -481 807 -502 795 -515 ct 775 -536 750 -547 720 -547 ct 
+697 -547 676 -540 658 -527 ct 634 -510 616 -485 602 -452 ct 589 -420 582 -373 581 -312 ct 
+599 -339 621 -360 647 -373 ct 673 -386 700 -393 729 -393 ct 778 -393 820 -375 855 -338 ct 
+890 -301 908 -254 908 -196 ct 908 -158 899 -123 883 -90 ct 867 -58 844 -33 815 -15 ct 
+787 1 754 10 718 10 ct 656 10 605 -12 566 -58 ct 527 -103 507 -178 507 -283 ct 
+507 -400 529 -486 572 -539 ct 610 -585 661 -608 725 -608 ct 773 -608 812 -595 842 -568 ct 
+873 -541 l  891 -504 l  p
+593 -196 m  593 -170 598 -146 609 -122 ct 620 -99 635 -81 655 -69 ct 675 -57 695 -50 717 -50 ct 
+748 -50 775 -63 798 -88 ct 820 -114 832 -148 832 -192 ct 832 -234 820 -267 798 -291 ct 
+776 -315 748 -327 714 -327 ct 680 -327 652 -315 628 -291 ct 605 -267 l  593 -235 l 
+p ef
+952 -181 m  952 -256 l  1181 -256 l  1181 -181 l  p ef
+1341 0 m  1272 0 l  1272 -606 l  1346 -606 l  1346 -390 l  1378 -429 1418 -449 1467 -449 ct 
+1494 -449 1519 -443 1543 -432 ct 1568 -421 1587 -406 1603 -386 ct 1619 -367 1631 -343 1640 -315 ct 
+1648 -287 1653 -257 1653 -226 ct 1653 -150 1634 -92 1597 -51 ct 1560 -10 1515 9 1463 9 ct 
+1411 9 1370 -11 1341 -55 ct p
+1340 -222 m  1340 -170 1347 -132 1362 -108 ct 1385 -70 1417 -51 1457 -51 ct 
+1489 -51 1517 -65 1541 -93 ct 1565 -121 1577 -164 1577 -220 ct 1577 -277 1565 -319 1543 -346 ct 
+1520 -374 1492 -387 1460 -387 ct 1428 -387 1399 -373 1376 -345 ct 1352 -317 l 
+1340 -276 l  p ef
+1723 -520 m  1723 -606 l  1797 -606 l  1797 -520 l  p
+1723 0 m  1723 -439 l  1797 -439 l  1797 0 l  p ef
+2070 -66 m  2081 0 l  2060 3 2041 5 2024 5 ct 1997 5 1976 1 1962 -7 ct 1947 -15 1936 -26 1930 -40 ct 
+1924 -54 1921 -83 1921 -128 ct 1921 -381 l  1866 -381 l  1866 -439 l  1921 -439 l 
+1921 -547 l  1995 -592 l  1995 -439 l  2070 -439 l  2070 -381 l  1995 -381 l 
+1995 -124 l  1995 -103 1996 -89 1999 -83 ct 2002 -77 2006 -72 2012 -69 ct 2018 -65 2026 -63 2037 -63 ct 
+2045 -63 l  2056 -64 l  p ef
+pom
+pum
+22596 4260 t
+340 0 m  340 -55 l  312 -11 272 9 217 9 ct 182 9 150 0 121 -19 ct 92 -38 69 -65 53 -99 ct 
+37 -134 28 -174 28 -219 ct 28 -263 36 -302 50 -338 ct 65 -374 87 -401 116 -420 ct 
+145 -439 178 -449 214 -449 ct 241 -449 264 -443 285 -432 ct 306 -421 322 -406 335 -388 ct 
+335 -606 l  409 -606 l  409 0 l  p
+105 -219 m  105 -162 117 -120 141 -93 ct 164 -65 192 -51 224 -51 ct 257 -51 285 -64 307 -91 ct 
+330 -117 342 -158 342 -212 ct 342 -273 330 -317 307 -345 ct 284 -373 255 -387 221 -387 ct 
+188 -387 160 -374 138 -346 ct 116 -319 l  105 -277 l  p ef
+818 -54 m  790 -30 764 -14 738 -4 ct 713 5 685 9 656 9 ct 608 9 571 -1 545 -25 ct 
+519 -49 506 -79 506 -115 ct 506 -137 511 -156 521 -174 ct 531 -192 543 -206 559 -217 ct 
+575 -228 593 -236 613 -241 ct 627 -245 649 -249 679 -253 ct 739 -260 783 -268 812 -278 ct 
+812 -288 812 -295 812 -298 ct 812 -328 805 -349 791 -362 ct 772 -379 744 -387 706 -387 ct 
+671 -387 645 -381 629 -369 ct 612 -356 600 -335 592 -303 ct 519 -313 l  526 -345 536 -370 552 -389 ct 
+567 -408 589 -423 617 -433 ct 646 -443 679 -449 717 -449 ct 755 -449 785 -444 808 -435 ct 
+832 -427 849 -415 860 -402 ct 871 -389 879 -372 883 -351 ct 886 -339 887 -316 887 -283 ct 
+887 -184 l  887 -114 889 -71 892 -52 ct 895 -34 901 -16 911 0 ct 833 0 l  825 -15 l 
+820 -33 l  p
+812 -220 m  785 -209 744 -200 690 -192 ct 660 -187 638 -182 625 -177 ct 613 -171 603 -163 596 -153 ct 
+589 -142 586 -130 586 -117 ct 586 -98 593 -81 608 -68 ct 623 -55 645 -48 674 -48 ct 
+703 -48 728 -54 751 -67 ct 773 -79 789 -96 800 -118 ct 808 -135 812 -160 812 -193 ct 
+p ef
+1144 -66 m  1155 0 l  1134 3 1115 5 1098 5 ct 1071 5 1050 1 1036 -7 ct 1021 -15 1010 -26 1004 -40 ct 
+998 -54 995 -83 995 -128 ct 995 -381 l  940 -381 l  940 -439 l  995 -439 l 
+995 -547 l  1069 -592 l  1069 -439 l  1144 -439 l  1144 -381 l  1069 -381 l 
+1069 -124 l  1069 -103 1070 -89 1073 -83 ct 1076 -77 1080 -72 1086 -69 ct 1092 -65 1100 -63 1111 -63 ct 
+1119 -63 l  1130 -64 l  p ef
+1506 -54 m  1478 -30 1452 -14 1426 -4 ct 1401 5 1373 9 1344 9 ct 1296 9 1259 -1 1233 -25 ct 
+1207 -49 1194 -79 1194 -115 ct 1194 -137 1199 -156 1209 -174 ct 1219 -192 1231 -206 1247 -217 ct 
+1263 -228 1281 -236 1301 -241 ct 1315 -245 1337 -249 1367 -253 ct 1427 -260 1471 -268 1500 -278 ct 
+1500 -288 1500 -295 1500 -298 ct 1500 -328 1493 -349 1479 -362 ct 1460 -379 1432 -387 1394 -387 ct 
+1359 -387 1333 -381 1317 -369 ct 1300 -356 1288 -335 1280 -303 ct 1207 -313 l 
+1214 -345 1224 -370 1240 -389 ct 1255 -408 1277 -423 1305 -433 ct 1334 -443 1367 -449 1405 -449 ct 
+1443 -449 1473 -444 1496 -435 ct 1520 -427 1537 -415 1548 -402 ct 1559 -389 1567 -372 1571 -351 ct 
+1574 -339 1575 -316 1575 -283 ct 1575 -184 l  1575 -114 1577 -71 1580 -52 ct 
+1583 -34 1589 -16 1599 0 ct 1521 0 l  1513 -15 l  1508 -33 l  p
+1500 -220 m  1473 -209 1432 -200 1378 -192 ct 1348 -187 1326 -182 1313 -177 ct 
+1301 -171 1291 -163 1284 -153 ct 1277 -142 1274 -130 1274 -117 ct 1274 -98 1281 -81 1296 -68 ct 
+1311 -55 1333 -48 1362 -48 ct 1391 -48 1416 -54 1439 -67 ct 1461 -79 1477 -96 1488 -118 ct 
+1496 -135 1500 -160 1500 -193 ct p ef
+2070 -66 m  2081 0 l  2060 3 2041 5 2024 5 ct 1997 5 1976 1 1962 -7 ct 1947 -15 1936 -26 1930 -40 ct 
+1924 -54 1921 -83 1921 -128 ct 1921 -381 l  1866 -381 l  1866 -439 l  1921 -439 l 
+1921 -547 l  1995 -592 l  1995 -439 l  2070 -439 l  2070 -381 l  1995 -381 l 
+1995 -124 l  1995 -103 1996 -89 1999 -83 ct 2002 -77 2006 -72 2012 -69 ct 2018 -65 2026 -63 2037 -63 ct 
+2045 -63 l  2056 -64 l  p ef
+2118 -219 m  2118 -300 2140 -361 2185 -400 ct 2223 -432 2269 -449 2324 -449 ct 
+2384 -449 2433 -429 2472 -389 ct 2510 -350 2529 -295 2529 -225 ct 2529 -169 2521 -124 2504 -92 ct 
+2487 -60 2462 -34 2430 -16 ct 2397 0 2362 9 2324 9 ct 2262 9 2212 -9 2174 -49 ct 
+2137 -88 l  2118 -145 l  p
+2194 -219 m  2194 -163 2206 -121 2231 -93 ct 2255 -65 2286 -51 2324 -51 ct 2361 -51 2391 -65 2416 -93 ct 
+2440 -121 2453 -164 2453 -222 ct 2453 -276 2440 -317 2416 -345 ct 2391 -373 2360 -387 2324 -387 ct 
+2286 -387 2255 -373 2231 -345 ct 2206 -317 l  2194 -275 l  p ef
+2860 0 m  2860 -606 l  2935 -606 l  2935 -388 l  2970 -429 3013 -449 3066 -449 ct 
+3099 -449 3127 -442 3151 -429 ct 3175 -417 3192 -399 3203 -376 ct 3213 -354 3218 -321 3218 -278 ct 
+3218 0 l  3144 0 l  3144 -278 l  3144 -315 3136 -342 3119 -359 ct 3103 -376 3081 -385 3051 -385 ct 
+3029 -385 3008 -379 2989 -367 ct 2969 -356 2955 -340 2947 -321 ct 2939 -301 2935 -274 2935 -240 ct 
+2935 0 l  p ef
+3309 -219 m  3309 -300 3331 -361 3376 -400 ct 3414 -432 3460 -449 3515 -449 ct 
+3575 -449 3624 -429 3663 -389 ct 3701 -350 3720 -295 3720 -225 ct 3720 -169 3712 -124 3695 -92 ct 
+3678 -60 3653 -34 3621 -16 ct 3588 0 3553 9 3515 9 ct 3453 9 3403 -9 3365 -49 ct 
+3328 -88 l  3309 -145 l  p
+3385 -219 m  3385 -163 3397 -121 3422 -93 ct 3446 -65 3477 -51 3515 -51 ct 3552 -51 3582 -65 3607 -93 ct 
+3631 -121 3644 -164 3644 -222 ct 3644 -276 3631 -317 3607 -345 ct 3582 -373 3551 -387 3515 -387 ct 
+3477 -387 3446 -373 3422 -345 ct 3397 -317 l  3385 -275 l  p ef
+3783 -131 m  3856 -142 l  3860 -113 3872 -90 3891 -74 ct 3910 -59 3936 -51 3970 -51 ct 
+4004 -51 4029 -58 4046 -72 ct 4063 -86 4071 -102 4071 -121 ct 4071 -138 4064 -151 4049 -160 ct 
+4039 -167 4013 -175 3973 -186 ct 3918 -199 3880 -211 3859 -221 ct 3838 -231 3822 -245 3811 -263 ct 
+3800 -281 3795 -301 3795 -322 ct 3795 -342 3799 -360 3808 -376 ct 3817 -393 3830 -407 3845 -418 ct 
+3857 -427 3872 -434 3892 -440 ct 3912 -446 3934 -449 3957 -449 ct 3991 -449 4021 -444 4047 -434 ct 
+4074 -424 4093 -410 4105 -393 ct 4118 -376 4126 -354 4131 -325 ct 4058 -315 l 
+4055 -338 4045 -356 4029 -368 ct 4013 -381 3991 -387 3962 -387 ct 3928 -387 3903 -382 3889 -370 ct 
+3874 -359 3867 -346 3867 -331 ct 3867 -321 3870 -312 3876 -305 ct 3882 -297 3892 -290 3905 -285 ct 
+3912 -282 3934 -276 3970 -266 ct 4023 -252 4060 -240 4081 -231 ct 4101 -222 4118 -209 4130 -192 ct 
+4141 -175 4147 -154 4147 -129 ct 4147 -104 4140 -80 4126 -58 ct 4111 -37 4090 -20 4063 -8 ct 
+4036 3 4005 9 3970 9 ct 3913 9 3870 -1 3840 -25 ct 3810 -49 l  3791 -84 l  p ef
+4372 -66 m  4383 0 l  4362 3 4343 5 4326 5 ct 4299 5 4278 1 4264 -7 ct 4249 -15 4238 -26 4232 -40 ct 
+4226 -54 4223 -83 4223 -128 ct 4223 -381 l  4168 -381 l  4168 -439 l  4223 -439 l 
+4223 -547 l  4297 -592 l  4297 -439 l  4372 -439 l  4372 -381 l  4297 -381 l 
+4297 -124 l  4297 -103 4298 -89 4301 -83 ct 4304 -77 4308 -72 4314 -69 ct 4320 -65 4328 -63 4339 -63 ct 
+4347 -63 l  4358 -64 l  p ef
+pom
+pum
+23257 5213 t
+177 0 m  10 -439 l  89 -439 l  183 -176 l  193 -147 203 -118 211 -87 ct 218 -110 227 -138 239 -171 ct 
+337 -439 l  413 -439 l  247 0 l  p ef
+479 -520 m  479 -606 l  553 -606 l  553 -520 l  p
+479 0 m  479 -439 l  553 -439 l  553 0 l  p ef
+951 -54 m  923 -30 897 -14 871 -4 ct 846 5 818 9 789 9 ct 741 9 704 -1 678 -25 ct 
+652 -49 639 -79 639 -115 ct 639 -137 644 -156 654 -174 ct 664 -192 676 -206 692 -217 ct 
+708 -228 726 -236 746 -241 ct 760 -245 782 -249 812 -253 ct 872 -260 916 -268 945 -278 ct 
+945 -288 945 -295 945 -298 ct 945 -328 938 -349 924 -362 ct 905 -379 877 -387 839 -387 ct 
+804 -387 778 -381 762 -369 ct 745 -356 733 -335 725 -303 ct 652 -313 l  659 -345 669 -370 685 -389 ct 
+700 -408 722 -423 750 -433 ct 779 -443 812 -449 850 -449 ct 888 -449 918 -444 941 -435 ct 
+965 -427 982 -415 993 -402 ct 1004 -389 1012 -372 1016 -351 ct 1019 -339 1020 -316 1020 -283 ct 
+1020 -184 l  1020 -114 1022 -71 1025 -52 ct 1028 -34 1034 -16 1044 0 ct 966 0 l 
+958 -15 l  953 -33 l  p
+945 -220 m  918 -209 877 -200 823 -192 ct 793 -187 771 -182 758 -177 ct 746 -171 736 -163 729 -153 ct 
+722 -142 719 -130 719 -117 ct 719 -98 726 -81 741 -68 ct 756 -55 778 -48 807 -48 ct 
+836 -48 861 -54 884 -67 ct 906 -79 922 -96 933 -118 ct 941 -135 945 -160 945 -193 ct 
+p ef
+1759 -606 m  1839 -606 l  1839 -256 l  1839 -195 1832 -146 1818 -110 ct 1804 -75 1780 -45 1744 -23 ct 
+1708 0 1660 10 1602 10 ct 1545 10 1499 0 1463 -19 ct 1426 -38 1401 -66 1385 -104 ct 
+1370 -141 1362 -191 1362 -256 ct 1362 -606 l  1442 -606 l  1442 -256 l  1442 -203 1447 -164 1457 -139 ct 
+1467 -115 1484 -95 1507 -82 ct 1531 -68 1560 -62 1595 -62 ct 1654 -62 1696 -75 1721 -102 ct 
+1746 -128 1759 -180 1759 -256 ct p ef
+1969 -194 m  2044 -201 l  2048 -171 2056 -146 2069 -126 ct 2082 -107 2103 -91 2130 -79 ct 
+2158 -67 2189 -61 2223 -61 ct 2254 -61 2281 -66 2304 -75 ct 2328 -84 2345 -96 2357 -112 ct 
+2368 -128 2374 -145 2374 -164 ct 2374 -183 2368 -200 2357 -214 ct 2346 -228 2328 -240 2303 -250 ct 
+2286 -256 2250 -266 2195 -279 ct 2139 -293 2100 -305 2078 -317 ct 2049 -332 2027 -351 2013 -374 ct 
+1999 -396 1992 -421 1992 -449 ct 1992 -480 2000 -508 2018 -535 ct 2035 -561 2061 -582 2094 -595 ct 
+2127 -609 2164 -616 2205 -616 ct 2250 -616 2290 -609 2324 -594 ct 2358 -580 2385 -559 2403 -531 ct 
+2422 -502 2432 -471 2433 -435 ct 2356 -429 l  2352 -468 2338 -496 2314 -516 ct 
+2290 -536 2255 -545 2208 -545 ct 2160 -545 2125 -537 2102 -519 ct 2080 -501 2069 -480 2069 -454 ct 
+2069 -433 2077 -415 2093 -401 ct 2108 -387 2148 -372 2214 -357 ct 2279 -343 2324 -330 2348 -319 ct 
+2383 -303 2409 -282 2426 -257 ct 2443 -232 2451 -203 2451 -171 ct 2451 -138 2442 -108 2423 -80 ct 
+2405 -51 2378 -29 2344 -13 ct 2309 2 2270 10 2227 10 ct 2172 10 2126 2 2089 -13 ct 
+2052 -29 2023 -53 2002 -85 ct 1981 -117 l  1970 -154 l  p ef
+2576 0 m  2576 -606 l  2803 -606 l  2849 -606 2886 -600 2914 -587 ct 2942 -575 2964 -556 2980 -531 ct 
+2996 -505 3004 -479 3004 -451 ct 3004 -425 2997 -400 2983 -378 ct 2969 -355 2948 -336 2919 -322 ct 
+2956 -311 2984 -293 3004 -267 ct 3024 -241 3033 -211 3033 -175 ct 3033 -147 3027 -120 3015 -96 ct 
+3003 -72 2989 -53 2971 -40 ct 2953 -26 2931 -16 2905 -10 ct 2878 -3 2845 0 2807 0 ct 
+p
+2656 -351 m  2787 -351 l  2822 -351 2848 -353 2863 -358 ct 2884 -364 2899 -374 2909 -388 ct 
+2920 -402 2925 -420 2925 -441 ct 2925 -461 2920 -479 2911 -494 ct 2901 -510 2887 -520 2869 -526 ct 
+2851 -531 2821 -534 2777 -534 ct 2656 -534 l  p
+2656 -71 m  2807 -71 l  2833 -71 2851 -72 2861 -74 ct 2880 -77 2895 -83 2908 -90 ct 
+2920 -98 2930 -109 2938 -124 ct 2946 -139 2950 -156 2950 -175 ct 2950 -198 2944 -218 2933 -234 ct 
+2921 -251 2905 -263 2885 -269 ct 2864 -276 2835 -279 2796 -279 ct 2656 -279 l 
+p ef
+pom
+gr
+gs
+pum
+6825 19235 t
+497 -212 m  578 -192 l  561 -126 531 -76 487 -41 ct 443 -6 390 10 327 10 ct 
+261 10 208 -2 167 -29 ct 126 -56 95 -94 74 -145 ct 52 -195 42 -249 42 -307 ct 42 -370 54 -425 78 -472 ct 
+102 -519 136 -555 181 -580 ct 225 -604 274 -616 328 -616 ct 389 -616 440 -601 481 -570 ct 
+522 -539 551 -496 567 -440 ct 488 -421 l  474 -465 454 -497 427 -517 ct 400 -537 367 -547 326 -547 ct 
+280 -547 241 -536 209 -514 ct 178 -492 156 -462 143 -424 ct 131 -386 124 -348 124 -308 ct 
+124 -256 132 -211 147 -173 ct 162 -134 185 -105 217 -86 ct 249 -67 283 -58 320 -58 ct 
+365 -58 403 -71 434 -97 ct 465 -123 l  486 -161 l  p ef
+991 -141 m  1068 -131 l  1056 -86 1033 -52 1001 -27 ct 968 -2 926 9 875 9 ct 
+811 9 760 -9 722 -49 ct 684 -88 666 -144 666 -215 ct 666 -289 685 -347 723 -387 ct 
+761 -428 810 -449 871 -449 ct 929 -449 977 -429 1015 -389 ct 1052 -349 1070 -292 1070 -220 ct 
+1070 -216 1070 -209 1070 -200 ct 742 -200 l  745 -152 759 -115 783 -89 ct 808 -64 839 -51 875 -51 ct 
+903 -51 926 -58 945 -72 ct 964 -87 l  980 -110 l  p
+747 -261 m  992 -261 l  989 -298 979 -326 964 -344 ct 940 -373 909 -387 871 -387 ct 
+837 -387 809 -376 785 -353 ct 762 -330 l  749 -300 l  p ef
+1166 0 m  1166 -439 l  1233 -439 l  1233 -376 l  1266 -425 1312 -449 1373 -449 ct 
+1400 -449 1424 -444 1446 -434 ct 1468 -425 1485 -412 1496 -397 ct 1507 -382 1515 -363 1519 -342 ct 
+1522 -328 1523 -304 1523 -270 ct 1523 0 l  1449 0 l  1449 -267 l  1449 -297 1446 -320 1440 -335 ct 
+1434 -350 1424 -362 1409 -371 ct 1395 -380 1377 -384 1357 -384 ct 1326 -384 1298 -374 1275 -354 ct 
+1252 -334 1241 -296 1241 -239 ct 1241 0 l  p ef
+1806 -66 m  1817 0 l  1796 3 1777 5 1760 5 ct 1733 5 1712 1 1698 -7 ct 1683 -15 1672 -26 1666 -40 ct 
+1660 -54 1657 -83 1657 -128 ct 1657 -381 l  1602 -381 l  1602 -439 l  1657 -439 l 
+1657 -547 l  1731 -592 l  1731 -439 l  1806 -439 l  1806 -381 l  1731 -381 l 
+1731 -124 l  1731 -103 1732 -89 1735 -83 ct 1738 -77 1742 -72 1748 -69 ct 1754 -65 1762 -63 1773 -63 ct 
+1781 -63 l  1792 -64 l  p ef
+2182 -141 m  2259 -131 l  2247 -86 2224 -52 2192 -27 ct 2159 -2 2117 9 2066 9 ct 
+2002 9 1951 -9 1913 -49 ct 1875 -88 1857 -144 1857 -215 ct 1857 -289 1876 -347 1914 -387 ct 
+1952 -428 2001 -449 2062 -449 ct 2120 -449 2168 -429 2206 -389 ct 2243 -349 2261 -292 2261 -220 ct 
+2261 -216 2261 -209 2261 -200 ct 1933 -200 l  1936 -152 1950 -115 1974 -89 ct 
+1999 -64 2030 -51 2066 -51 ct 2094 -51 2117 -58 2136 -72 ct 2155 -87 l  2171 -110 l 
+p
+1938 -261 m  2183 -261 l  2180 -298 2170 -326 2155 -344 ct 2131 -373 2100 -387 2062 -387 ct 
+2028 -387 2000 -376 1976 -353 ct 1953 -330 l  1940 -300 l  p ef
+2357 0 m  2357 -439 l  2424 -439 l  2424 -372 l  2441 -403 2456 -424 2471 -434 ct 
+2485 -444 2501 -449 2519 -449 ct 2544 -449 2569 -441 2595 -425 ct 2570 -356 l 
+2551 -366 2533 -372 2515 -372 ct 2499 -372 2484 -367 2471 -357 ct 2458 -347 2449 -334 2443 -316 ct 
+2435 -290 2431 -261 2431 -229 ct 2431 0 l  p ef
+2904 0 m  2904 -381 l  2838 -381 l  2838 -439 l  2904 -439 l  2904 -485 l 
+2904 -515 2907 -537 2912 -551 ct 2919 -571 2932 -586 2950 -598 ct 2968 -610 2993 -616 3026 -616 ct 
+3047 -616 3070 -614 3095 -609 ct 3084 -544 l  3069 -547 3054 -548 3040 -548 ct 
+3018 -548 3002 -543 2992 -533 ct 2983 -524 2978 -506 2978 -479 ct 2978 -439 l 
+3064 -439 l  3064 -381 l  2978 -381 l  2978 0 l  p ef
+3124 0 m  3124 -439 l  3191 -439 l  3191 -372 l  3208 -403 3223 -424 3238 -434 ct 
+3252 -444 3268 -449 3286 -449 ct 3311 -449 3336 -441 3362 -425 ct 3337 -356 l 
+3318 -366 3300 -372 3282 -372 ct 3266 -372 3251 -367 3238 -357 ct 3225 -347 3216 -334 3210 -316 ct 
+3202 -290 3198 -261 3198 -229 ct 3198 0 l  p ef
+3716 -141 m  3793 -131 l  3781 -86 3758 -52 3726 -27 ct 3693 -2 3651 9 3600 9 ct 
+3536 9 3485 -9 3447 -49 ct 3409 -88 3391 -144 3391 -215 ct 3391 -289 3410 -347 3448 -387 ct 
+3486 -428 3535 -449 3596 -449 ct 3654 -449 3702 -429 3740 -389 ct 3777 -349 3795 -292 3795 -220 ct 
+3795 -216 3795 -209 3795 -200 ct 3467 -200 l  3470 -152 3484 -115 3508 -89 ct 
+3533 -64 3564 -51 3600 -51 ct 3628 -51 3651 -58 3670 -72 ct 3689 -87 l  3705 -110 l 
+p
+3472 -261 m  3717 -261 l  3714 -298 3704 -326 3689 -344 ct 3665 -373 3634 -387 3596 -387 ct 
+3562 -387 3534 -376 3510 -353 ct 3487 -330 l  3474 -300 l  p ef
+4171 168 m  4171 -46 l  4160 -30 4144 -16 4123 -6 ct 4102 4 4080 9 4056 9 ct 
+4004 9 3959 -10 3922 -52 ct 3884 -94 3865 -151 3865 -223 ct 3865 -267 3873 -307 3888 -342 ct 
+3904 -377 3926 -404 3955 -422 ct 3984 -440 4016 -449 4051 -449 ct 4105 -449 4148 -426 4179 -380 ct 
+4179 -439 l  4246 -439 l  4246 168 l  p
+3942 -220 m  3942 -164 3954 -121 3977 -93 ct 4001 -65 4029 -51 4063 -51 ct 4094 -51 4122 -64 4144 -91 ct 
+4167 -118 4179 -159 4179 -214 ct 4179 -272 4167 -316 4143 -346 ct 4118 -375 4090 -390 4058 -390 ct 
+4025 -390 3998 -376 3975 -349 ct 3953 -321 l  3942 -279 l  p ef
+4656 0 m  4656 -64 l  4622 -14 4576 9 4517 9 ct 4491 9 4467 4 4444 -4 ct 4422 -14 4405 -27 4394 -42 ct 
+4383 -57 4376 -75 4371 -97 ct 4368 -112 4367 -135 4367 -167 ct 4367 -439 l  4441 -439 l 
+4441 -195 l  4441 -156 4443 -130 4446 -117 ct 4450 -97 4460 -82 4475 -70 ct 
+4491 -59 4509 -54 4532 -54 ct 4554 -54 4575 -59 4595 -71 ct 4614 -82 4628 -98 4636 -118 ct 
+4644 -137 4648 -166 4648 -203 ct 4648 -439 l  4723 -439 l  4723 0 l  p ef
+5145 -141 m  5222 -131 l  5210 -86 5187 -52 5155 -27 ct 5122 -2 5080 9 5029 9 ct 
+4965 9 4914 -9 4876 -49 ct 4838 -88 4820 -144 4820 -215 ct 4820 -289 4839 -347 4877 -387 ct 
+4915 -428 4964 -449 5025 -449 ct 5083 -449 5131 -429 5169 -389 ct 5206 -349 5224 -292 5224 -220 ct 
+5224 -216 5224 -209 5224 -200 ct 4896 -200 l  4899 -152 4913 -115 4937 -89 ct 
+4962 -64 4993 -51 5029 -51 ct 5057 -51 5080 -58 5099 -72 ct 5118 -87 l  5134 -110 l 
+p
+4901 -261 m  5146 -261 l  5143 -298 5133 -326 5118 -344 ct 5094 -373 5063 -387 5025 -387 ct 
+4991 -387 4963 -376 4939 -353 ct 4916 -330 l  4903 -300 l  p ef
+5320 0 m  5320 -439 l  5387 -439 l  5387 -376 l  5420 -425 5466 -449 5527 -449 ct 
+5554 -449 5578 -444 5600 -434 ct 5622 -425 5639 -412 5650 -397 ct 5661 -382 5669 -363 5673 -342 ct 
+5676 -328 5677 -304 5677 -270 ct 5677 0 l  5603 0 l  5603 -267 l  5603 -297 5600 -320 5594 -335 ct 
+5588 -350 5578 -362 5563 -371 ct 5549 -380 5531 -384 5511 -384 ct 5480 -384 5452 -374 5429 -354 ct 
+5406 -334 5395 -296 5395 -239 ct 5395 0 l  p ef
+6083 -160 m  6156 -151 l  6148 -100 6128 -61 6095 -32 ct 6062 -4 6021 9 5973 9 ct 
+5913 9 5865 -9 5828 -49 ct 5792 -88 5774 -144 5774 -217 ct 5774 -265 5781 -306 5797 -342 ct 
+5813 -378 5837 -404 5869 -422 ct 5901 -440 5936 -449 5974 -449 ct 6021 -449 6060 -437 6091 -412 ct 
+6121 -388 6141 -354 6149 -310 ct 6077 -299 l  6070 -328 6058 -350 6040 -365 ct 
+6023 -380 6001 -387 5977 -387 ct 5939 -387 5909 -374 5885 -347 ct 5862 -320 5850 -278 5850 -220 ct 
+5850 -161 5861 -118 5884 -91 ct 5907 -64 5936 -51 5973 -51 ct 6002 -51 6026 -60 6046 -78 ct 
+6065 -96 l  6078 -123 l  p ef
+6217 169 m  6209 99 l  6225 103 6239 105 6251 105 ct 6268 105 6281 103 6291 97 ct 
+6301 92 6309 84 6315 74 ct 6320 66 6328 48 6338 19 ct 6340 14 6342 8 6345 0 ct 
+6178 -439 l  6258 -439 l  6350 -184 l  6362 -152 6372 -118 6382 -83 ct 6390 -117 6400 -150 6412 -183 ct 
+6506 -439 l  6581 -439 l  6413 7 l  6396 55 6382 88 6372 107 ct 6358 131 6343 149 6326 161 ct 
+6309 172 6289 178 6265 178 ct 6251 178 l  6235 175 l  p ef
+pom
+pum
+7778 20188 t
+26 -181 m  26 -256 l  255 -256 l  255 -181 l  p ef
+364 0 m  364 -381 l  298 -381 l  298 -439 l  364 -439 l  364 -485 l  364 -515 367 -537 372 -551 ct 
+379 -571 392 -586 410 -598 ct 428 -610 453 -616 486 -616 ct 507 -616 530 -614 555 -609 ct 
+544 -544 l  529 -547 514 -548 500 -548 ct 478 -548 462 -543 452 -533 ct 443 -524 438 -506 438 -479 ct 
+438 -439 l  524 -439 l  524 -381 l  438 -381 l  438 0 l  p ef
+555 -131 m  628 -142 l  632 -113 644 -90 663 -74 ct 682 -59 708 -51 742 -51 ct 
+776 -51 801 -58 818 -72 ct 835 -86 843 -102 843 -121 ct 843 -138 836 -151 821 -160 ct 
+811 -167 785 -175 745 -186 ct 690 -199 652 -211 631 -221 ct 610 -231 594 -245 583 -263 ct 
+572 -281 567 -301 567 -322 ct 567 -342 571 -360 580 -376 ct 589 -393 602 -407 617 -418 ct 
+629 -427 644 -434 664 -440 ct 684 -446 706 -449 729 -449 ct 763 -449 793 -444 819 -434 ct 
+846 -424 865 -410 877 -393 ct 890 -376 898 -354 903 -325 ct 830 -315 l  827 -338 817 -356 801 -368 ct 
+785 -381 763 -387 734 -387 ct 700 -387 675 -382 661 -370 ct 646 -359 639 -346 639 -331 ct 
+639 -321 642 -312 648 -305 ct 654 -297 664 -290 677 -285 ct 684 -282 706 -276 742 -266 ct 
+795 -252 832 -240 853 -231 ct 873 -222 890 -209 902 -192 ct 913 -175 919 -154 919 -129 ct 
+919 -104 912 -80 898 -58 ct 883 -37 862 -20 835 -8 ct 808 3 777 9 742 9 ct 685 9 642 -1 612 -25 ct 
+582 -49 l  563 -84 l  p ef
+926 10 m  1101 -616 l  1161 -616 l  985 10 l  p ef
+1590 -71 m  1590 0 l  1189 0 l  1189 -17 1191 -35 1198 -51 ct 1208 -79 1224 -105 1247 -132 ct 
+1269 -158 1302 -189 1344 -224 ct 1410 -278 1455 -321 1478 -352 ct 1501 -384 1513 -413 1513 -442 ct 
+1513 -471 1502 -496 1481 -516 ct 1460 -537 1432 -547 1398 -547 ct 1363 -547 1334 -536 1312 -514 ct 
+1291 -493 1280 -463 1280 -425 ct 1203 -433 l  1208 -490 1228 -533 1262 -563 ct 
+1297 -593 1342 -608 1400 -608 ct 1458 -608 1504 -592 1538 -560 ct 1572 -528 1589 -488 1589 -440 ct 
+1589 -416 1584 -392 1574 -368 ct 1564 -345 1548 -320 1525 -294 ct 1502 -268 1463 -233 1410 -188 ct 
+1365 -150 1337 -125 1324 -111 ct 1311 -98 1301 -85 1293 -71 ct p ef
+2097 -66 m  2108 0 l  2087 3 2068 5 2051 5 ct 2024 5 2003 1 1989 -7 ct 1974 -15 1963 -26 1957 -40 ct 
+1951 -54 1948 -83 1948 -128 ct 1948 -381 l  1893 -381 l  1893 -439 l  1948 -439 l 
+1948 -547 l  2022 -592 l  2022 -439 l  2097 -439 l  2097 -381 l  2022 -381 l 
+2022 -124 l  2022 -103 2023 -89 2026 -83 ct 2029 -77 2033 -72 2039 -69 ct 2045 -65 2053 -63 2064 -63 ct 
+2072 -63 l  2083 -64 l  p ef
+2145 -219 m  2145 -300 2167 -361 2212 -400 ct 2250 -432 2296 -449 2351 -449 ct 
+2411 -449 2460 -429 2499 -389 ct 2537 -350 2556 -295 2556 -225 ct 2556 -169 2548 -124 2531 -92 ct 
+2514 -60 2489 -34 2457 -16 ct 2424 0 2389 9 2351 9 ct 2289 9 2239 -9 2201 -49 ct 
+2164 -88 l  2145 -145 l  p
+2221 -219 m  2221 -163 2233 -121 2258 -93 ct 2282 -65 2313 -51 2351 -51 ct 2388 -51 2418 -65 2443 -93 ct 
+2467 -121 2480 -164 2480 -222 ct 2480 -276 2467 -317 2443 -345 ct 2418 -373 2387 -387 2351 -387 ct 
+2313 -387 2282 -373 2258 -345 ct 2233 -317 l  2221 -275 l  p ef
+3043 -98 m  3043 -264 l  2878 -264 l  2878 -333 l  3043 -333 l  3043 -498 l 
+3113 -498 l  3113 -333 l  3278 -333 l  3278 -264 l  3113 -264 l  3113 -98 l 
+p ef
+3407 0 m  3407 -381 l  3341 -381 l  3341 -439 l  3407 -439 l  3407 -485 l 
+3407 -515 3410 -537 3415 -551 ct 3422 -571 3435 -586 3453 -598 ct 3471 -610 3496 -616 3529 -616 ct 
+3550 -616 3573 -614 3598 -609 ct 3587 -544 l  3572 -547 3557 -548 3543 -548 ct 
+3521 -548 3505 -543 3495 -533 ct 3486 -524 3481 -506 3481 -479 ct 3481 -439 l 
+3567 -439 l  3567 -381 l  3481 -381 l  3481 0 l  p ef
+3598 -131 m  3671 -142 l  3675 -113 3687 -90 3706 -74 ct 3725 -59 3751 -51 3785 -51 ct 
+3819 -51 3844 -58 3861 -72 ct 3878 -86 3886 -102 3886 -121 ct 3886 -138 3879 -151 3864 -160 ct 
+3854 -167 3828 -175 3788 -186 ct 3733 -199 3695 -211 3674 -221 ct 3653 -231 3637 -245 3626 -263 ct 
+3615 -281 3610 -301 3610 -322 ct 3610 -342 3614 -360 3623 -376 ct 3632 -393 3645 -407 3660 -418 ct 
+3672 -427 3687 -434 3707 -440 ct 3727 -446 3749 -449 3772 -449 ct 3806 -449 3836 -444 3862 -434 ct 
+3889 -424 3908 -410 3920 -393 ct 3933 -376 3941 -354 3946 -325 ct 3873 -315 l 
+3870 -338 3860 -356 3844 -368 ct 3828 -381 3806 -387 3777 -387 ct 3743 -387 3718 -382 3704 -370 ct 
+3689 -359 3682 -346 3682 -331 ct 3682 -321 3685 -312 3691 -305 ct 3697 -297 3707 -290 3720 -285 ct 
+3727 -282 3749 -276 3785 -266 ct 3838 -252 3875 -240 3896 -231 ct 3916 -222 3933 -209 3945 -192 ct 
+3956 -175 3962 -154 3962 -129 ct 3962 -104 3955 -80 3941 -58 ct 3926 -37 3905 -20 3878 -8 ct 
+3851 3 3820 9 3785 9 ct 3728 9 3685 -1 3655 -25 ct 3625 -49 l  3606 -84 l  p ef
+3969 10 m  4144 -616 l  4204 -616 l  4028 10 l  p ef
+4633 -71 m  4633 0 l  4232 0 l  4232 -17 4234 -35 4241 -51 ct 4251 -79 4267 -105 4290 -132 ct 
+4312 -158 4345 -189 4387 -224 ct 4453 -278 4498 -321 4521 -352 ct 4544 -384 4556 -413 4556 -442 ct 
+4556 -471 4545 -496 4524 -516 ct 4503 -537 4475 -547 4441 -547 ct 4406 -547 4377 -536 4355 -514 ct 
+4334 -493 4323 -463 4323 -425 ct 4246 -433 l  4251 -490 4271 -533 4305 -563 ct 
+4340 -593 4385 -608 4443 -608 ct 4501 -608 4547 -592 4581 -560 ct 4615 -528 4632 -488 4632 -440 ct 
+4632 -416 4627 -392 4617 -368 ct 4607 -345 4591 -320 4568 -294 ct 4545 -268 4506 -233 4453 -188 ct 
+4408 -150 4380 -125 4367 -111 ct 4354 -98 4344 -85 4336 -71 ct p ef
+pom
+gr
+10161 16546 m  10011 16996 l  10311 16995 l  10161 16546 l  p ef
+10161 18381 m  10161 16906 l  ps
+gs
+pum
+2805 3466 t
+38 -194 m  113 -201 l  117 -171 125 -146 138 -126 ct 151 -107 172 -91 199 -79 ct 
+227 -67 258 -61 292 -61 ct 323 -61 350 -66 373 -75 ct 397 -84 414 -96 426 -112 ct 
+437 -128 443 -145 443 -164 ct 443 -183 437 -200 426 -214 ct 415 -228 397 -240 372 -250 ct 
+355 -256 319 -266 264 -279 ct 208 -293 169 -305 147 -317 ct 118 -332 96 -351 82 -374 ct 
+68 -396 61 -421 61 -449 ct 61 -480 69 -508 87 -535 ct 104 -561 130 -582 163 -595 ct 
+196 -609 233 -616 274 -616 ct 319 -616 359 -609 393 -594 ct 427 -580 454 -559 472 -531 ct 
+491 -502 501 -471 502 -435 ct 425 -429 l  421 -468 407 -496 383 -516 ct 359 -536 324 -545 277 -545 ct 
+229 -545 194 -537 171 -519 ct 149 -501 138 -480 138 -454 ct 138 -433 146 -415 162 -401 ct 
+177 -387 217 -372 283 -357 ct 348 -343 393 -330 417 -319 ct 452 -303 478 -282 495 -257 ct 
+512 -232 520 -203 520 -171 ct 520 -138 511 -108 492 -80 ct 474 -51 447 -29 413 -13 ct 
+378 2 339 10 296 10 ct 241 10 195 2 158 -13 ct 121 -29 92 -53 71 -85 ct 50 -117 l 
+39 -154 l  p ef
+924 -54 m  896 -30 870 -14 844 -4 ct 819 5 791 9 762 9 ct 714 9 677 -1 651 -25 ct 
+625 -49 612 -79 612 -115 ct 612 -137 617 -156 627 -174 ct 637 -192 649 -206 665 -217 ct 
+681 -228 699 -236 719 -241 ct 733 -245 755 -249 785 -253 ct 845 -260 889 -268 918 -278 ct 
+918 -288 918 -295 918 -298 ct 918 -328 911 -349 897 -362 ct 878 -379 850 -387 812 -387 ct 
+777 -387 751 -381 735 -369 ct 718 -356 706 -335 698 -303 ct 625 -313 l  632 -345 642 -370 658 -389 ct 
+673 -408 695 -423 723 -433 ct 752 -443 785 -449 823 -449 ct 861 -449 891 -444 914 -435 ct 
+938 -427 955 -415 966 -402 ct 977 -389 985 -372 989 -351 ct 992 -339 993 -316 993 -283 ct 
+993 -184 l  993 -114 995 -71 998 -52 ct 1001 -34 1007 -16 1017 0 ct 939 0 l 
+931 -15 l  926 -33 l  p
+918 -220 m  891 -209 850 -200 796 -192 ct 766 -187 744 -182 731 -177 ct 719 -171 709 -163 702 -153 ct 
+695 -142 692 -130 692 -117 ct 692 -98 699 -81 714 -68 ct 729 -55 751 -48 780 -48 ct 
+809 -48 834 -54 857 -67 ct 879 -79 895 -96 906 -118 ct 914 -135 918 -160 918 -193 ct 
+p ef
+1087 0 m  1087 -439 l  1154 -439 l  1154 -377 l  1168 -399 1186 -416 1209 -429 ct 
+1232 -442 1258 -449 1287 -449 ct 1320 -449 1346 -442 1367 -428 ct 1388 -415 1403 -396 1411 -372 ct 
+1446 -423 1491 -449 1547 -449 ct 1590 -449 1624 -437 1647 -412 ct 1671 -388 1682 -351 1682 -301 ct 
+1682 0 l  1608 0 l  1608 -276 l  1608 -306 1606 -327 1601 -340 ct 1596 -354 1588 -364 1575 -372 ct 
+1562 -380 1547 -384 1530 -384 ct 1499 -384 1474 -374 1453 -353 ct 1433 -333 1423 -300 1423 -255 ct 
+1423 0 l  1348 0 l  1348 -285 l  1348 -318 1342 -343 1330 -359 ct 1318 -376 1298 -384 1271 -384 ct 
+1250 -384 1230 -379 1212 -368 ct 1195 -357 1182 -340 1174 -319 ct 1166 -298 1162 -267 1162 -227 ct 
+1162 0 l  p ef
+1801 168 m  1801 -439 l  1869 -439 l  1869 -382 l  1885 -404 1903 -421 1923 -432 ct 
+1943 -443 1968 -449 1997 -449 ct 2034 -449 2067 -439 2096 -420 ct 2124 -400 2146 -373 2161 -338 ct 
+2175 -303 2183 -264 2183 -222 ct 2183 -177 2175 -137 2158 -101 ct 2142 -65 2119 -37 2088 -18 ct 
+2057 0 2025 9 1991 9 ct 1966 9 1944 4 1924 -5 ct 1905 -16 1888 -29 1876 -45 ct 
+1876 168 l  p
+1869 -217 m  1869 -160 1880 -118 1903 -91 ct 1926 -64 1954 -51 1986 -51 ct 2019 -51 2048 -65 2071 -93 ct 
+2095 -121 2107 -164 2107 -223 ct 2107 -279 2095 -321 2072 -349 ct 2049 -376 2022 -390 1990 -390 ct 
+1958 -390 1930 -376 1905 -346 ct 1881 -316 l  1869 -273 l  p ef
+2250 0 m  2250 -606 l  2324 -606 l  2324 0 l  p ef
+2437 -520 m  2437 -606 l  2511 -606 l  2511 -520 l  p
+2437 0 m  2437 -439 l  2511 -439 l  2511 0 l  p ef
+2621 0 m  2621 -439 l  2688 -439 l  2688 -376 l  2721 -425 2767 -449 2828 -449 ct 
+2855 -449 2879 -444 2901 -434 ct 2923 -425 2940 -412 2951 -397 ct 2962 -382 2970 -363 2974 -342 ct 
+2977 -328 2978 -304 2978 -270 ct 2978 0 l  2904 0 l  2904 -267 l  2904 -297 2901 -320 2895 -335 ct 
+2889 -350 2879 -362 2864 -371 ct 2850 -380 2832 -384 2812 -384 ct 2781 -384 2753 -374 2730 -354 ct 
+2707 -334 2696 -296 2696 -239 ct 2696 0 l  p ef
+3085 36 m  3157 47 l  3160 69 3169 85 3182 95 ct 3201 109 3226 116 3258 116 ct 
+3292 116 3319 109 3338 95 ct 3357 82 3369 62 3376 38 ct 3380 22 3381 -8 3381 -57 ct 
+3349 -19 3308 0 3260 0 ct 3199 0 3153 -21 3119 -65 ct 3086 -108 3070 -161 3070 -222 ct 
+3070 -264 3077 -302 3093 -338 ct 3108 -373 3130 -400 3159 -420 ct 3187 -439 3221 -449 3260 -449 ct 
+3312 -449 3355 -428 3388 -386 ct 3388 -439 l  3457 -439 l  3457 -59 l  3457 8 3450 57 3436 85 ct 
+3422 114 3400 136 3370 153 ct 3340 169 3303 178 3258 178 ct 3206 178 3164 166 3131 142 ct 
+3099 119 l  3084 83 l  p
+3146 -227 m  3146 -169 3158 -127 3181 -101 ct 3204 -74 3232 -61 3267 -61 ct 
+3301 -61 3330 -74 3353 -101 ct 3376 -127 3387 -168 3387 -224 ct 3387 -278 3376 -319 3352 -346 ct 
+3328 -373 3299 -387 3265 -387 ct 3232 -387 3204 -374 3181 -347 ct 3158 -320 l 
+3146 -280 l  p ef
+3812 0 m  3812 -439 l  3879 -439 l  3879 -372 l  3896 -403 3911 -424 3926 -434 ct 
+3940 -444 3956 -449 3974 -449 ct 3999 -449 4024 -441 4050 -425 ct 4025 -356 l 
+4006 -366 3988 -372 3970 -372 ct 3954 -372 3939 -367 3926 -357 ct 3913 -347 3904 -334 3898 -316 ct 
+3890 -290 3886 -261 3886 -229 ct 3886 0 l  p ef
+4390 -54 m  4362 -30 4336 -14 4310 -4 ct 4285 5 4257 9 4228 9 ct 4180 9 4143 -1 4117 -25 ct 
+4091 -49 4078 -79 4078 -115 ct 4078 -137 4083 -156 4093 -174 ct 4103 -192 4115 -206 4131 -217 ct 
+4147 -228 4165 -236 4185 -241 ct 4199 -245 4221 -249 4251 -253 ct 4311 -260 4355 -268 4384 -278 ct 
+4384 -288 4384 -295 4384 -298 ct 4384 -328 4377 -349 4363 -362 ct 4344 -379 4316 -387 4278 -387 ct 
+4243 -387 4217 -381 4201 -369 ct 4184 -356 4172 -335 4164 -303 ct 4091 -313 l 
+4098 -345 4108 -370 4124 -389 ct 4139 -408 4161 -423 4189 -433 ct 4218 -443 4251 -449 4289 -449 ct 
+4327 -449 4357 -444 4380 -435 ct 4404 -427 4421 -415 4432 -402 ct 4443 -389 4451 -372 4455 -351 ct 
+4458 -339 4459 -316 4459 -283 ct 4459 -184 l  4459 -114 4461 -71 4464 -52 ct 
+4467 -34 4473 -16 4483 0 ct 4405 0 l  4397 -15 l  4392 -33 l  p
+4384 -220 m  4357 -209 4316 -200 4262 -192 ct 4232 -187 4210 -182 4197 -177 ct 
+4185 -171 4175 -163 4168 -153 ct 4161 -142 4158 -130 4158 -117 ct 4158 -98 4165 -81 4180 -68 ct 
+4195 -55 4217 -48 4246 -48 ct 4275 -48 4300 -54 4323 -67 ct 4345 -79 4361 -96 4372 -118 ct 
+4380 -135 4384 -160 4384 -193 ct p ef
+4716 -66 m  4727 0 l  4706 3 4687 5 4670 5 ct 4643 5 4622 1 4608 -7 ct 4593 -15 4582 -26 4576 -40 ct 
+4570 -54 4567 -83 4567 -128 ct 4567 -381 l  4512 -381 l  4512 -439 l  4567 -439 l 
+4567 -547 l  4641 -592 l  4641 -439 l  4716 -439 l  4716 -381 l  4641 -381 l 
+4641 -124 l  4641 -103 4642 -89 4645 -83 ct 4648 -77 4652 -72 4658 -69 ct 4664 -65 4672 -63 4683 -63 ct 
+4691 -63 l  4702 -64 l  p ef
+5092 -141 m  5169 -131 l  5157 -86 5134 -52 5102 -27 ct 5069 -2 5027 9 4976 9 ct 
+4912 9 4861 -9 4823 -49 ct 4785 -88 4767 -144 4767 -215 ct 4767 -289 4786 -347 4824 -387 ct 
+4862 -428 4911 -449 4972 -449 ct 5030 -449 5078 -429 5116 -389 ct 5153 -349 5171 -292 5171 -220 ct 
+5171 -216 5171 -209 5171 -200 ct 4843 -200 l  4846 -152 4860 -115 4884 -89 ct 
+4909 -64 4940 -51 4976 -51 ct 5004 -51 5027 -58 5046 -72 ct 5065 -87 l  5081 -110 l 
+p
+4848 -261 m  5093 -261 l  5090 -298 5080 -326 5065 -344 ct 5041 -373 5010 -387 4972 -387 ct 
+4938 -387 4910 -376 4886 -353 ct 4863 -330 l  4850 -300 l  p ef
+5897 -356 m  5497 -356 l  5497 -425 l  5897 -425 l  p
+5897 -172 m  5497 -172 l  5497 -241 l  5897 -241 l  p ef
+6264 0 m  6264 -381 l  6198 -381 l  6198 -439 l  6264 -439 l  6264 -485 l 
+6264 -515 6267 -537 6272 -551 ct 6279 -571 6292 -586 6310 -598 ct 6328 -610 6353 -616 6386 -616 ct 
+6407 -616 6430 -614 6455 -609 ct 6444 -544 l  6429 -547 6414 -548 6400 -548 ct 
+6378 -548 6362 -543 6352 -533 ct 6343 -524 6338 -506 6338 -479 ct 6338 -439 l 
+6424 -439 l  6424 -381 l  6338 -381 l  6338 0 l  p ef
+6455 -131 m  6528 -142 l  6532 -113 6544 -90 6563 -74 ct 6582 -59 6608 -51 6642 -51 ct 
+6676 -51 6701 -58 6718 -72 ct 6735 -86 6743 -102 6743 -121 ct 6743 -138 6736 -151 6721 -160 ct 
+6711 -167 6685 -175 6645 -186 ct 6590 -199 6552 -211 6531 -221 ct 6510 -231 6494 -245 6483 -263 ct 
+6472 -281 6467 -301 6467 -322 ct 6467 -342 6471 -360 6480 -376 ct 6489 -393 6502 -407 6517 -418 ct 
+6529 -427 6544 -434 6564 -440 ct 6584 -446 6606 -449 6629 -449 ct 6663 -449 6693 -444 6719 -434 ct 
+6746 -424 6765 -410 6777 -393 ct 6790 -376 6798 -354 6803 -325 ct 6730 -315 l 
+6727 -338 6717 -356 6701 -368 ct 6685 -381 6663 -387 6634 -387 ct 6600 -387 6575 -382 6561 -370 ct 
+6546 -359 6539 -346 6539 -331 ct 6539 -321 6542 -312 6548 -305 ct 6554 -297 6564 -290 6577 -285 ct 
+6584 -282 6606 -276 6642 -266 ct 6695 -252 6732 -240 6753 -231 ct 6773 -222 6790 -209 6802 -192 ct 
+6813 -175 6819 -154 6819 -129 ct 6819 -104 6812 -80 6798 -58 ct 6783 -37 6762 -20 6735 -8 ct 
+6708 3 6677 9 6642 9 ct 6585 9 6542 -1 6512 -25 ct 6482 -49 l  6463 -84 l  p ef
+pom
+gr
+gs
+pum
+15981 14102 t
+62 0 m  62 -606 l  289 -606 l  335 -606 372 -600 400 -587 ct 428 -575 450 -556 466 -531 ct 
+482 -505 490 -479 490 -451 ct 490 -425 483 -400 469 -378 ct 455 -355 434 -336 405 -322 ct 
+442 -311 470 -293 490 -267 ct 510 -241 519 -211 519 -175 ct 519 -147 513 -120 501 -96 ct 
+489 -72 475 -53 457 -40 ct 439 -26 417 -16 391 -10 ct 364 -3 331 0 293 0 ct p
+142 -351 m  273 -351 l  308 -351 334 -353 349 -358 ct 370 -364 385 -374 395 -388 ct 
+406 -402 411 -420 411 -441 ct 411 -461 406 -479 397 -494 ct 387 -510 373 -520 355 -526 ct 
+337 -531 307 -534 263 -534 ct 142 -534 l  p
+142 -71 m  293 -71 l  319 -71 337 -72 347 -74 ct 366 -77 381 -83 394 -90 ct 
+406 -98 416 -109 424 -124 ct 432 -139 436 -156 436 -175 ct 436 -198 430 -218 419 -234 ct 
+407 -251 391 -263 371 -269 ct 350 -276 321 -279 282 -279 ct 142 -279 l  p ef
+898 -54 m  870 -30 844 -14 818 -4 ct 793 5 765 9 736 9 ct 688 9 651 -1 625 -25 ct 
+599 -49 586 -79 586 -115 ct 586 -137 591 -156 601 -174 ct 611 -192 623 -206 639 -217 ct 
+655 -228 673 -236 693 -241 ct 707 -245 729 -249 759 -253 ct 819 -260 863 -268 892 -278 ct 
+892 -288 892 -295 892 -298 ct 892 -328 885 -349 871 -362 ct 852 -379 824 -387 786 -387 ct 
+751 -387 725 -381 709 -369 ct 692 -356 680 -335 672 -303 ct 599 -313 l  606 -345 616 -370 632 -389 ct 
+647 -408 669 -423 697 -433 ct 726 -443 759 -449 797 -449 ct 835 -449 865 -444 888 -435 ct 
+912 -427 929 -415 940 -402 ct 951 -389 959 -372 963 -351 ct 966 -339 967 -316 967 -283 ct 
+967 -184 l  967 -114 969 -71 972 -52 ct 975 -34 981 -16 991 0 ct 913 0 l  905 -15 l 
+900 -33 l  p
+892 -220 m  865 -209 824 -200 770 -192 ct 740 -187 718 -182 705 -177 ct 693 -171 683 -163 676 -153 ct 
+669 -142 666 -130 666 -117 ct 666 -98 673 -81 688 -68 ct 703 -55 725 -48 754 -48 ct 
+783 -48 808 -54 831 -67 ct 853 -79 869 -96 880 -118 ct 888 -135 892 -160 892 -193 ct 
+p ef
+1060 0 m  1060 -439 l  1127 -439 l  1127 -376 l  1160 -425 1206 -449 1267 -449 ct 
+1294 -449 1318 -444 1340 -434 ct 1362 -425 1379 -412 1390 -397 ct 1401 -382 1409 -363 1413 -342 ct 
+1416 -328 1417 -304 1417 -270 ct 1417 0 l  1343 0 l  1343 -267 l  1343 -297 1340 -320 1334 -335 ct 
+1328 -350 1318 -362 1303 -371 ct 1289 -380 1271 -384 1251 -384 ct 1220 -384 1192 -374 1169 -354 ct 
+1146 -334 1135 -296 1135 -239 ct 1135 0 l  p ef
+1822 0 m  1822 -55 l  1794 -11 1754 9 1699 9 ct 1664 9 1632 0 1603 -19 ct 1574 -38 1551 -65 1535 -99 ct 
+1519 -134 1510 -174 1510 -219 ct 1510 -263 1518 -302 1532 -338 ct 1547 -374 1569 -401 1598 -420 ct 
+1627 -439 1660 -449 1696 -449 ct 1723 -449 1746 -443 1767 -432 ct 1788 -421 1804 -406 1817 -388 ct 
+1817 -606 l  1891 -606 l  1891 0 l  p
+1587 -219 m  1587 -162 1599 -120 1623 -93 ct 1646 -65 1674 -51 1706 -51 ct 1739 -51 1767 -64 1789 -91 ct 
+1812 -117 1824 -158 1824 -212 ct 1824 -273 1812 -317 1789 -345 ct 1766 -373 1737 -387 1703 -387 ct 
+1670 -387 1642 -374 1620 -346 ct 1598 -319 l  1587 -277 l  p ef
+2094 0 m  1960 -439 l  2037 -439 l  2107 -185 l  2133 -91 l  2134 -96 2142 -126 2156 -181 ct 
+2226 -439 l  2302 -439 l  2368 -184 l  2390 -100 l  2415 -185 l  2490 -439 l 
+2563 -439 l  2425 0 l  2348 0 l  2278 -263 l  2261 -337 l  2172 0 l  p ef
+2596 -520 m  2596 -606 l  2670 -606 l  2670 -520 l  p
+2596 0 m  2596 -439 l  2670 -439 l  2670 0 l  p ef
+3065 0 m  3065 -55 l  3037 -11 2997 9 2942 9 ct 2907 9 2875 0 2846 -19 ct 2817 -38 2794 -65 2778 -99 ct 
+2762 -134 2753 -174 2753 -219 ct 2753 -263 2761 -302 2775 -338 ct 2790 -374 2812 -401 2841 -420 ct 
+2870 -439 2903 -449 2939 -449 ct 2966 -449 2989 -443 3010 -432 ct 3031 -421 3047 -406 3060 -388 ct 
+3060 -606 l  3134 -606 l  3134 0 l  p
+2830 -219 m  2830 -162 2842 -120 2866 -93 ct 2889 -65 2917 -51 2949 -51 ct 2982 -51 3010 -64 3032 -91 ct 
+3055 -117 3067 -158 3067 -212 ct 3067 -273 3055 -317 3032 -345 ct 3009 -373 2980 -387 2946 -387 ct 
+2913 -387 2885 -374 2863 -346 ct 2841 -319 l  2830 -277 l  p ef
+3419 -66 m  3430 0 l  3409 3 3390 5 3373 5 ct 3346 5 3325 1 3311 -7 ct 3296 -15 3285 -26 3279 -40 ct 
+3273 -54 3270 -83 3270 -128 ct 3270 -381 l  3215 -381 l  3215 -439 l  3270 -439 l 
+3270 -547 l  3344 -592 l  3344 -439 l  3419 -439 l  3419 -381 l  3344 -381 l 
+3344 -124 l  3344 -103 3345 -89 3348 -83 ct 3351 -77 3355 -72 3361 -69 ct 3367 -65 3375 -63 3386 -63 ct 
+3394 -63 l  3405 -64 l  p ef
+3495 0 m  3495 -606 l  3570 -606 l  3570 -388 l  3605 -429 3648 -449 3701 -449 ct 
+3734 -449 3762 -442 3786 -429 ct 3810 -417 3827 -399 3838 -376 ct 3848 -354 3853 -321 3853 -278 ct 
+3853 0 l  3779 0 l  3779 -278 l  3779 -315 3771 -342 3754 -359 ct 3738 -376 3716 -385 3686 -385 ct 
+3664 -385 3643 -379 3624 -367 ct 3604 -356 3590 -340 3582 -321 ct 3574 -301 3570 -274 3570 -240 ct 
+3570 0 l  p ef
+pom
+pum
+15888 15055 t
+340 0 m  340 -55 l  312 -11 272 9 217 9 ct 182 9 150 0 121 -19 ct 92 -38 69 -65 53 -99 ct 
+37 -134 28 -174 28 -219 ct 28 -263 36 -302 50 -338 ct 65 -374 87 -401 116 -420 ct 
+145 -439 178 -449 214 -449 ct 241 -449 264 -443 285 -432 ct 306 -421 322 -406 335 -388 ct 
+335 -606 l  409 -606 l  409 0 l  p
+105 -219 m  105 -162 117 -120 141 -93 ct 164 -65 192 -51 224 -51 ct 257 -51 285 -64 307 -91 ct 
+330 -117 342 -158 342 -212 ct 342 -273 330 -317 307 -345 ct 284 -373 255 -387 221 -387 ct 
+188 -387 160 -374 138 -346 ct 116 -319 l  105 -277 l  p ef
+832 -141 m  909 -131 l  897 -86 874 -52 842 -27 ct 809 -2 767 9 716 9 ct 652 9 601 -9 563 -49 ct 
+525 -88 507 -144 507 -215 ct 507 -289 526 -347 564 -387 ct 602 -428 651 -449 712 -449 ct 
+770 -449 818 -429 856 -389 ct 893 -349 911 -292 911 -220 ct 911 -216 911 -209 911 -200 ct 
+583 -200 l  586 -152 600 -115 624 -89 ct 649 -64 680 -51 716 -51 ct 744 -51 767 -58 786 -72 ct 
+805 -87 l  821 -110 l  p
+588 -261 m  833 -261 l  830 -298 820 -326 805 -344 ct 781 -373 750 -387 712 -387 ct 
+678 -387 650 -376 626 -353 ct 603 -330 l  590 -300 l  p ef
+1295 -160 m  1368 -151 l  1360 -100 1340 -61 1307 -32 ct 1274 -4 1233 9 1185 9 ct 
+1125 9 1077 -9 1040 -49 ct 1004 -88 986 -144 986 -217 ct 986 -265 993 -306 1009 -342 ct 
+1025 -378 1049 -404 1081 -422 ct 1113 -440 1148 -449 1186 -449 ct 1233 -449 1272 -437 1303 -412 ct 
+1333 -388 1353 -354 1361 -310 ct 1289 -299 l  1282 -328 1270 -350 1252 -365 ct 
+1235 -380 1213 -387 1189 -387 ct 1151 -387 1121 -374 1097 -347 ct 1074 -320 1062 -278 1062 -220 ct 
+1062 -161 1073 -118 1096 -91 ct 1119 -64 1148 -51 1185 -51 ct 1214 -51 1238 -60 1258 -78 ct 
+1277 -96 l  1290 -123 l  p ef
+1432 -520 m  1432 -606 l  1506 -606 l  1506 -520 l  p
+1432 0 m  1432 -439 l  1506 -439 l  1506 0 l  p ef
+1616 0 m  1616 -439 l  1683 -439 l  1683 -377 l  1697 -399 1715 -416 1738 -429 ct 
+1761 -442 1787 -449 1816 -449 ct 1849 -449 1875 -442 1896 -428 ct 1917 -415 1932 -396 1940 -372 ct 
+1975 -423 2020 -449 2076 -449 ct 2119 -449 2153 -437 2176 -412 ct 2200 -388 2211 -351 2211 -301 ct 
+2211 0 l  2137 0 l  2137 -276 l  2137 -306 2135 -327 2130 -340 ct 2125 -354 2117 -364 2104 -372 ct 
+2091 -380 2076 -384 2059 -384 ct 2028 -384 2003 -374 1982 -353 ct 1962 -333 1952 -300 1952 -255 ct 
+1952 0 l  1877 0 l  1877 -285 l  1877 -318 1871 -343 1859 -359 ct 1847 -376 1827 -384 1800 -384 ct 
+1779 -384 1759 -379 1741 -368 ct 1724 -357 1711 -340 1703 -319 ct 1695 -298 1691 -267 1691 -227 ct 
+1691 0 l  p ef
+2617 -54 m  2589 -30 2563 -14 2537 -4 ct 2512 5 2484 9 2455 9 ct 2407 9 2370 -1 2344 -25 ct 
+2318 -49 2305 -79 2305 -115 ct 2305 -137 2310 -156 2320 -174 ct 2330 -192 2342 -206 2358 -217 ct 
+2374 -228 2392 -236 2412 -241 ct 2426 -245 2448 -249 2478 -253 ct 2538 -260 2582 -268 2611 -278 ct 
+2611 -288 2611 -295 2611 -298 ct 2611 -328 2604 -349 2590 -362 ct 2571 -379 2543 -387 2505 -387 ct 
+2470 -387 2444 -381 2428 -369 ct 2411 -356 2399 -335 2391 -303 ct 2318 -313 l 
+2325 -345 2335 -370 2351 -389 ct 2366 -408 2388 -423 2416 -433 ct 2445 -443 2478 -449 2516 -449 ct 
+2554 -449 2584 -444 2607 -435 ct 2631 -427 2648 -415 2659 -402 ct 2670 -389 2678 -372 2682 -351 ct 
+2685 -339 2686 -316 2686 -283 ct 2686 -184 l  2686 -114 2688 -71 2691 -52 ct 
+2694 -34 2700 -16 2710 0 ct 2632 0 l  2624 -15 l  2619 -33 l  p
+2611 -220 m  2584 -209 2543 -200 2489 -192 ct 2459 -187 2437 -182 2424 -177 ct 
+2412 -171 2402 -163 2395 -153 ct 2388 -142 2385 -130 2385 -117 ct 2385 -98 2392 -81 2407 -68 ct 
+2422 -55 2444 -48 2473 -48 ct 2502 -48 2527 -54 2550 -67 ct 2572 -79 2588 -96 2599 -118 ct 
+2607 -135 2611 -160 2611 -193 ct p ef
+2943 -66 m  2954 0 l  2933 3 2914 5 2897 5 ct 2870 5 2849 1 2835 -7 ct 2820 -15 2809 -26 2803 -40 ct 
+2797 -54 2794 -83 2794 -128 ct 2794 -381 l  2739 -381 l  2739 -439 l  2794 -439 l 
+2794 -547 l  2868 -592 l  2868 -439 l  2943 -439 l  2943 -381 l  2868 -381 l 
+2868 -124 l  2868 -103 2869 -89 2872 -83 ct 2875 -77 2879 -72 2885 -69 ct 2891 -65 2899 -63 2910 -63 ct 
+2918 -63 l  2929 -64 l  p ef
+3019 -520 m  3019 -606 l  3093 -606 l  3093 -520 l  p
+3019 0 m  3019 -439 l  3093 -439 l  3093 0 l  p ef
+3177 -219 m  3177 -300 3199 -361 3244 -400 ct 3282 -432 3328 -449 3383 -449 ct 
+3443 -449 3492 -429 3531 -389 ct 3569 -350 3588 -295 3588 -225 ct 3588 -169 3580 -124 3563 -92 ct 
+3546 -60 3521 -34 3489 -16 ct 3456 0 3421 9 3383 9 ct 3321 9 3271 -9 3233 -49 ct 
+3196 -88 l  3177 -145 l  p
+3253 -219 m  3253 -163 3265 -121 3290 -93 ct 3314 -65 3345 -51 3383 -51 ct 3420 -51 3450 -65 3475 -93 ct 
+3499 -121 3512 -164 3512 -222 ct 3512 -276 3499 -317 3475 -345 ct 3450 -373 3419 -387 3383 -387 ct 
+3345 -387 3314 -373 3290 -345 ct 3265 -317 l  3253 -275 l  p ef
+3680 0 m  3680 -439 l  3747 -439 l  3747 -376 l  3780 -425 3826 -449 3887 -449 ct 
+3914 -449 3938 -444 3960 -434 ct 3982 -425 3999 -412 4010 -397 ct 4021 -382 4029 -363 4033 -342 ct 
+4036 -328 4037 -304 4037 -270 ct 4037 0 l  3963 0 l  3963 -267 l  3963 -297 3960 -320 3954 -335 ct 
+3948 -350 3938 -362 3923 -371 ct 3909 -380 3891 -384 3871 -384 ct 3840 -384 3812 -374 3789 -354 ct 
+3766 -334 3755 -296 3755 -239 ct 3755 0 l  p ef
+pom
+pum
+16087 16008 t
+73 0 m  73 -381 l  7 -381 l  7 -439 l  73 -439 l  73 -485 l  73 -515 76 -537 81 -551 ct 
+88 -571 101 -586 119 -598 ct 137 -610 162 -616 195 -616 ct 216 -616 239 -614 264 -609 ct 
+253 -544 l  238 -547 223 -548 209 -548 ct 187 -548 171 -543 161 -533 ct 152 -524 147 -506 147 -479 ct 
+147 -439 l  233 -439 l  233 -381 l  147 -381 l  147 0 l  p ef
+580 -54 m  552 -30 526 -14 500 -4 ct 475 5 447 9 418 9 ct 370 9 333 -1 307 -25 ct 
+281 -49 268 -79 268 -115 ct 268 -137 273 -156 283 -174 ct 293 -192 305 -206 321 -217 ct 
+337 -228 355 -236 375 -241 ct 389 -245 411 -249 441 -253 ct 501 -260 545 -268 574 -278 ct 
+574 -288 574 -295 574 -298 ct 574 -328 567 -349 553 -362 ct 534 -379 506 -387 468 -387 ct 
+433 -387 407 -381 391 -369 ct 374 -356 362 -335 354 -303 ct 281 -313 l  288 -345 298 -370 314 -389 ct 
+329 -408 351 -423 379 -433 ct 408 -443 441 -449 479 -449 ct 517 -449 547 -444 570 -435 ct 
+594 -427 611 -415 622 -402 ct 633 -389 641 -372 645 -351 ct 648 -339 649 -316 649 -283 ct 
+649 -184 l  649 -114 651 -71 654 -52 ct 657 -34 663 -16 673 0 ct 595 0 l  587 -15 l 
+582 -33 l  p
+574 -220 m  547 -209 506 -200 452 -192 ct 422 -187 400 -182 387 -177 ct 375 -171 365 -163 358 -153 ct 
+351 -142 348 -130 348 -117 ct 348 -98 355 -81 370 -68 ct 385 -55 407 -48 436 -48 ct 
+465 -48 490 -54 513 -67 ct 535 -79 551 -96 562 -118 ct 570 -135 574 -160 574 -193 ct 
+p ef
+1030 -160 m  1103 -151 l  1095 -100 1075 -61 1042 -32 ct 1009 -4 968 9 920 9 ct 
+860 9 812 -9 775 -49 ct 739 -88 721 -144 721 -217 ct 721 -265 728 -306 744 -342 ct 
+760 -378 784 -404 816 -422 ct 848 -440 883 -449 921 -449 ct 968 -449 1007 -437 1038 -412 ct 
+1068 -388 1088 -354 1096 -310 ct 1024 -299 l  1017 -328 1005 -350 987 -365 ct 
+970 -380 948 -387 924 -387 ct 886 -387 856 -374 832 -347 ct 809 -320 797 -278 797 -220 ct 
+797 -161 808 -118 831 -91 ct 854 -64 883 -51 920 -51 ct 949 -51 973 -60 993 -78 ct 
+1012 -96 l  1025 -123 l  p ef
+1329 -66 m  1340 0 l  1319 3 1300 5 1283 5 ct 1256 5 1235 1 1221 -7 ct 1206 -15 1195 -26 1189 -40 ct 
+1183 -54 1180 -83 1180 -128 ct 1180 -381 l  1125 -381 l  1125 -439 l  1180 -439 l 
+1180 -547 l  1254 -592 l  1254 -439 l  1329 -439 l  1329 -381 l  1254 -381 l 
+1254 -124 l  1254 -103 1255 -89 1258 -83 ct 1261 -77 1265 -72 1271 -69 ct 1277 -65 1285 -63 1296 -63 ct 
+1304 -63 l  1315 -64 l  p ef
+1377 -219 m  1377 -300 1399 -361 1444 -400 ct 1482 -432 1528 -449 1583 -449 ct 
+1643 -449 1692 -429 1731 -389 ct 1769 -350 1788 -295 1788 -225 ct 1788 -169 1780 -124 1763 -92 ct 
+1746 -60 1721 -34 1689 -16 ct 1656 0 1621 9 1583 9 ct 1521 9 1471 -9 1433 -49 ct 
+1396 -88 l  1377 -145 l  p
+1453 -219 m  1453 -163 1465 -121 1490 -93 ct 1514 -65 1545 -51 1583 -51 ct 1620 -51 1650 -65 1675 -93 ct 
+1699 -121 1712 -164 1712 -222 ct 1712 -276 1699 -317 1675 -345 ct 1650 -373 1619 -387 1583 -387 ct 
+1545 -387 1514 -373 1490 -345 ct 1465 -317 l  1453 -275 l  p ef
+1881 0 m  1881 -439 l  1948 -439 l  1948 -372 l  1965 -403 1980 -424 1995 -434 ct 
+2009 -444 2025 -449 2043 -449 ct 2068 -449 2093 -441 2119 -425 ct 2094 -356 l 
+2075 -366 2057 -372 2039 -372 ct 2023 -372 2008 -367 1995 -357 ct 1982 -347 1973 -334 1967 -316 ct 
+1959 -290 1955 -261 1955 -229 ct 1955 0 l  p ef
+2802 -356 m  2402 -356 l  2402 -425 l  2802 -425 l  p
+2802 -172 m  2402 -172 l  2402 -241 l  2802 -241 l  p ef
+3160 0 m  3160 -606 l  3242 -606 l  3561 -130 l  3561 -606 l  3638 -606 l 
+3638 0 l  3555 0 l  3237 -476 l  3237 0 l  p ef
+pom
+gr
+17781 10461 m  17631 10911 l  17931 10910 l  17781 10461 l  p ef
+17781 13336 m  17781 10821 l  ps
+gs
+pum
+17357 3466 t
+73 0 m  73 -381 l  7 -381 l  7 -439 l  73 -439 l  73 -485 l  73 -515 76 -537 81 -551 ct 
+88 -571 101 -586 119 -598 ct 137 -610 162 -616 195 -616 ct 216 -616 239 -614 264 -609 ct 
+253 -544 l  238 -547 223 -548 209 -548 ct 187 -548 171 -543 161 -533 ct 152 -524 147 -506 147 -479 ct 
+147 -439 l  233 -439 l  233 -381 l  147 -381 l  147 0 l  p ef
+264 -131 m  337 -142 l  341 -113 353 -90 372 -74 ct 391 -59 417 -51 451 -51 ct 
+485 -51 510 -58 527 -72 ct 544 -86 552 -102 552 -121 ct 552 -138 545 -151 530 -160 ct 
+520 -167 494 -175 454 -186 ct 399 -199 361 -211 340 -221 ct 319 -231 303 -245 292 -263 ct 
+281 -281 276 -301 276 -322 ct 276 -342 280 -360 289 -376 ct 298 -393 311 -407 326 -418 ct 
+338 -427 353 -434 373 -440 ct 393 -446 415 -449 438 -449 ct 472 -449 502 -444 528 -434 ct 
+555 -424 574 -410 586 -393 ct 599 -376 607 -354 612 -325 ct 539 -315 l  536 -338 526 -356 510 -368 ct 
+494 -381 472 -387 443 -387 ct 409 -387 384 -382 370 -370 ct 355 -359 348 -346 348 -331 ct 
+348 -321 351 -312 357 -305 ct 363 -297 373 -290 386 -285 ct 393 -282 415 -276 451 -266 ct 
+504 -252 541 -240 562 -231 ct 582 -222 599 -209 611 -192 ct 622 -175 628 -154 628 -129 ct 
+628 -104 621 -80 607 -58 ct 592 -37 571 -20 544 -8 ct 517 3 486 9 451 9 ct 394 9 351 -1 321 -25 ct 
+291 -49 l  272 -84 l  p ef
+635 10 m  810 -616 l  870 -616 l  694 10 l  p ef
+937 0 m  937 -606 l  1019 -606 l  1338 -130 l  1338 -606 l  1415 -606 l 
+1415 0 l  1332 0 l  1014 -476 l  1014 0 l  p ef
+pom
+gr
+22227 6350 m  22199 5876 l  21920 5987 l  22227 6350 l  p ef
+19422 3175 m  19475 3175 l  ps
+19528 3175 m  19581 3175 l  ps
+19634 3175 m  19687 3175 l  ps
+19740 3175 m  19793 3175 l  ps
+19846 3175 m  19899 3175 l  ps
+19952 3175 m  20006 3175 l  ps
+20059 3175 m  20112 3175 l  ps
+20165 3175 m  20218 3175 l  ps
+20271 3175 m  20324 3175 l  ps
+20377 3175 m  20430 3175 l  ps
+20483 3175 m  20536 3175 l  ps
+20590 3175 m  20643 3175 l  ps
+20696 3175 m  20749 3175 l  ps
+20802 3175 m  20855 3175 l  ps
+20908 3175 m  20956 3175 l  ps
+20956 3175 m  20958 3180 l  ps
+20977 3229 m  20997 3278 l  ps
+21017 3328 m  21037 3377 l  ps
+21056 3426 m  21076 3475 l  ps
+21096 3525 m  21115 3574 l  ps
+21135 3623 m  21155 3673 l  ps
+21175 3722 m  21194 3771 l  ps
+21214 3821 m  21234 3870 l  ps
+21254 3919 m  21273 3968 l  ps
+21293 4018 m  21313 4067 l  ps
+21332 4116 m  21352 4166 l  ps
+21372 4215 m  21392 4264 l  ps
+21411 4313 m  21431 4363 l  ps
+21451 4412 m  21471 4461 l  ps
+21490 4511 m  21510 4560 l  ps
+21530 4609 m  21550 4658 l  ps
+21569 4708 m  21589 4757 l  ps
+21609 4806 m  21628 4856 l  ps
+21648 4905 m  21668 4954 l  ps
+21688 5003 m  21707 5053 l  ps
+21727 5102 m  21747 5151 l  ps
+21767 5201 m  21786 5250 l  ps
+21806 5299 m  21826 5348 l  ps
+21845 5398 m  21865 5447 l  ps
+21885 5496 m  21905 5546 l  ps
+21924 5595 m  21944 5644 l  ps
+21964 5693 m  21984 5743 l  ps
+22003 5792 m  22023 5841 l  ps
+22043 5891 m  22063 5940 l  ps
+22082 5989 m  22093 6015 l  ps
+gr
+0 20290 t 
+pom
+count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore
+%%PageTrailer
+%%Trailer
+%%EOF
diff --git a/docs/exploring-gnuradio/ddc.png b/docs/exploring-gnuradio/ddc.png
new file mode 100644 (file)
index 0000000..ce35bc2
Binary files /dev/null and b/docs/exploring-gnuradio/ddc.png differ
diff --git a/docs/exploring-gnuradio/dial_tone.py b/docs/exploring-gnuradio/dial_tone.py
new file mode 100755 (executable)
index 0000000..9cc05ba
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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 import audio
+
+def build_graph ():
+    sampling_freq = 32000
+    ampl = 0.1
+
+    tb = gr.top_block ()
+    src0 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 350, ampl)
+    src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 440, ampl)
+    dst = audio.sink (sampling_freq)
+    tb.connect (src0, (dst, 0))
+    tb.connect (src1, (dst, 1))
+
+    return tb
+
+if __name__ == '__main__':
+    tb = build_graph ()
+    tb.start ()
+    raw_input ('Press Enter to quit: ')
+    tb.stop ()
diff --git a/docs/exploring-gnuradio/dial_tone_example.xml b/docs/exploring-gnuradio/dial_tone_example.xml
new file mode 100644 (file)
index 0000000..14ea680
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<example id="dial_tone_ex"><title>Dial Tone Output</title>
+<programlisting>
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+
+def build_graph ():
+    sampling_freq = 48000
+    ampl = 0.1
+
+    fg = gr.flow_graph ()
+    src0 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 350, ampl)
+    src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 440, ampl)
+    dst = audio.sink (sampling_freq)
+    fg.connect ((src0, 0), (dst, 0))
+    fg.connect ((src1, 0), (dst, 1))
+
+    return fg
+
+if __name__ == '__main__':
+    fg = build_graph ()
+    fg.start ()
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+</programlisting>
+</example>
diff --git a/docs/exploring-gnuradio/exploring-gnuradio.xml b/docs/exploring-gnuradio/exploring-gnuradio.xml
new file mode 100644 (file)
index 0000000..9d471f6
--- /dev/null
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "docbookx.dtd" [
+  <!ENTITY dial_tone_example SYSTEM "dial_tone_example.xml">
+  <!ENTITY fm_demod_example SYSTEM "fm_demod_example.xml">
+]>
+
+<article>
+<articleinfo>
+  <title>Exploring GNU Radio</title>
+  <author>
+     <firstname>Eric</firstname>
+     <surname>Blossom</surname>
+     <affiliation>
+        <address>
+           <email>eb@comsec.com</email>
+        </address>
+     </affiliation>
+  </author>
+
+<revhistory>
+  <revision>
+  <revnumber>v1.1</revnumber>
+  <date>2004-11-29</date>
+  <revremark>
+    Revised and expanded.  Examples now use 2.x code base.
+  </revremark>
+  </revision>
+
+  <revision>
+  <revnumber>v1.0</revnumber>
+  <date>2004-02-29</date>
+  <revremark>
+  Initial version published in Linux Journal, Issue 122, June 2004, as
+  <emphasis>GNU Radio: Tools for Exploring the RF Spectrum</emphasis>.
+  </revremark>
+  </revision>
+</revhistory>
+
+<abstract><para>This article provides an overview of the GNU Radio
+toolkit for building software radios.
+</para></abstract>
+
+</articleinfo>
+
+<sect1 id="intro"><title>Introduction</title>
+
+<para>Software radio is the technique of getting code as close to the
+antenna as possible. It turns radio hardware problems into software
+problems. The fundamental characteristic of software radio is that
+software defines the transmitted waveforms, and software demodulates
+the received waveforms. This is in contrast to most radios in which
+the processing is done with either analog circuitry or analog
+circuitry combined with digital chips. GNU Radio is a free software
+toolkit for building software radios.</para>
+
+<para>Software radio is a revolution in radio design due to its ability to
+create radios that change on the fly, creating new choices for
+users. At the baseline, software radios can do pretty much anything a
+traditional radio can do. The exciting part is the flexibility that
+software provides you. Instead of a bunch of fixed function gadgets,
+in the next few years we'll see a move to universal communication
+devices. Imagine a device that can morph into a cell phone and get you
+connectivity using GPRS, 802.11 Wi-Fi, 802.16 WiMax, a satellite
+hookup or the emerging standard of the day. You could determine your
+location using GPS, GLONASS or both.</para>
+
+<para>Perhaps most exciting of all is the potential to build decentralized
+communication systems. If you look at today's systems, the vast
+majority are infrastructure-based. Broadcast radio and TV provide a
+one-way channel, are tightly regulated and the content is controlled
+by a handful of organizations. Cell phones are a great convenience,
+but the features your phone supports are determined by the operator's
+interests, not yours.</para>
+
+<para>A centralized system limits the rate of innovation. We could take some
+lessons from the Internet and push the smarts out to the
+edges. Instead of cell phones being second-class citizens, usable only
+if infrastructure is in place and limited to the capabilities
+determined worthwhile by the operator, we could build smarter
+devices. These user-owned devices would generate the network. They'd
+create a mesh among themselves, negotiate for backhaul and be free to
+evolve new solutions, features and applications.</para>
+
+</sect1>
+
+<sect1 id="block-diagram"><title>The Block Diagram</title>
+
+<para><xref linkend="block-diagram-fig"/> shows a typical block
+diagram for a software radio. To understand the software part of the
+radio, we first need to understand a bit about the associated
+hardware. Examining the receive path in the figure,
+we see an antenna, a mysterious RF front end, an analog-to-digital
+converter (ADC) and a bunch of code. The analog-to-digital converter
+is the bridge between the physical world of continuous analog signals
+and the world of discrete digital samples manipulated by
+software.</para>
+
+<figure id="block-diagram-fig"><title>Typical software radio block diagram</title>
+<mediaobject>
+<imageobject><imagedata fileref="swr-block-diagram.eps" format="EPS"/></imageobject>
+<imageobject><imagedata fileref="swr-block-diagram.png" format="PNG"/></imageobject>
+<caption><para></para></caption>
+</mediaobject>
+</figure>
+
+<para>ADCs have two primary characteristics, sampling rate and dynamic
+range. Sampling rate is the number of times per second that the ADC
+measures the analog signal. Dynamic range refers to the difference
+between the smallest and largest signal that can be distinguished;
+it's a function of the number of bits in the ADC's digital output and
+the design of the converter. For example, an 8-bit converter at most
+can represent 256 (2<superscript>8</superscript>) signal levels, while
+a 16-bit converter represents up to 65,536 levels. Generally speaking,
+device physics and cost impose trade-offs between the sample rate and
+dynamic range.</para>
+
+<para>Before we dive into the software, we need to talk about a bit of
+theory. In 1927, a Swedish-born physicist and electrical engineer
+named Harry Nyquist determined that to avoid aliasing when converting
+from analog to digital, the ADC sampling frequency must be at least
+twice the bandwidth of the signal of interest. Aliasing is what makes
+the wagon wheels look like they're going backward in the old westerns:
+the sampling rate of the movie camera is not fast enough to represent
+the position of the spokes unambiguously.</para>
+
+<para>Assuming we're dealing with low pass signals - signals where the
+bandwidth of interest goes from 0 to f<subscript>MAX</subscript>, the
+Nyquist criterion states that our sampling frequency needs to be at
+least 2 * f<subscript>MAX</subscript>. But if our ADC runs at 20 MHz,
+how can we listen to broadcast FM radio at 92.1 MHz? The answer is the
+RF front end. The receive RF front end translates a range of
+frequencies appearing at its input to a lower range at its output. For
+example, we could imagine an RF front end that translated the signals
+occurring in the 90 - 100 MHz range down to the 0 - 10 MHz
+range.</para>
+
+<para>Mostly, we can treat the RF front end as a black box with a single
+control, the center of the input range that's to be translated. As a
+concrete example, a cable modem tuner module that we've employed
+successfully has the following characteristics. It translates a 6 MHz
+chunk of the spectrum centered between about 50 MHz and 800 MHz down to
+an output range centered at 5.75 MHz. The center frequency of the
+output range is called the intermediate frequency, or IF.</para>
+
+<para>In the simplest-thing-that-possibly-could-work category, the RF front
+end may be eliminated altogether. One GNU Radio experimenter has
+listened to AM and shortwave broadcasts by connecting a 100-foot piece
+of wire directly to his 20M sample/sec ADC.</para>
+
+</sect1> 
+
+<sect1 id="software"><title>On to the Software</title>
+
+<para>GNU Radio provides a library of signal processing blocks and the
+glue to tie it all together. The programmer builds a radio by creating
+a graph (as in graph theory) where the vertices are signal processing
+blocks and the edges represent the data flow between them. The
+signal processing blocks are implemented in C++. Conceptually,
+blocks process infinite streams of data flowing from their input
+ports to their output ports. Blocks' attributes include the number
+of input and output ports they have as well as the type of data that
+flows through each. The most frequently used types are short, float
+and complex.</para>
+
+<para>Some blocks have only output ports or input ports. These serve as
+data sources and sinks in the graph. There are sources that read from
+a file or ADC, and sinks that write to a file, digital-to-analog
+converter (DAC) or graphical display. About 100 blocks come with
+GNU Radio. Writing new blocks is not difficult.</para>
+
+<para>Graphs are constructed and run in Python.
+<!-- <xref linkend="dial_tone_ex"/> -->
+Example 1
+is the "Hello World" of GNU Radio. It generates two sine waves and outputs
+them to the sound card, one on the left channel, one on the
+right.</para>
+
+&dial_tone_example;
+
+<para>We start by creating a flow graph to hold the blocks and
+connections between them. The two sine waves are generated by the
+gr.sig_source_f calls. The f suffix indicates that the source produces
+floats. One sine wave is at 350 Hz, and the other is at
+440 Hz. Together, they sound like the US dial tone.</para>
+
+<para>audio.sink is a sink that writes its input to the sound card. It
+takes one or more streams of floats in the range -1 to +1 as its
+input. We connect the three blocks together using the 
+<methodname>connect</methodname> method of the flow graph.</para>
+
+<para><methodname>connect</methodname> takes two parameters, the
+source endpoint and the destination endpoint, and creates a connection
+from the source to the destination.  An endpoint has two components: a
+signal processing block and a port number.  The port number specifies
+which input or output port of the specified block is to be connected.
+In the most general form, an endpoint is represented as a python tuple
+like this: <literal>(block, port_number)</literal>.  When
+<literal>port_number</literal> is zero, the block may be used alone.
+</para>
+
+<para>These two expressions are equivalent:</para>
+<programlisting>
+fg.connect ((src1, 0), (dst, 1))
+fg.connect (src1, (dst, 1))
+</programlisting>
+
+<para>Once the graph is built, we start it. Calling
+<methodname>start</methodname> forks one or more threads to run the
+computation described by the graph and returns control immediately to
+the caller. In this case, we simply wait for any keystroke.</para>
+
+</sect1>
+
+<sect1 id="fm-receiver"><title>A Complete FM Receiver</title>
+
+<para>
+<!-- <xref linkend="fm_demod_ex"/> -->
+Example 2
+shows a somewhat simplified but
+complete broadcast FM receiver. It includes control of the RF front
+end and all required signal processing. This example uses an RF front
+end built from a cable modem tuner and a 20M sample/sec
+analog-to-digital converter.</para>
+
+&fm_demod_example;
+
+<para>Like the Hello World example, we build a graph, connect the
+blocks together and start it. In this case, our source, mc4020.source,
+is an interface to the Measurement Computing PCI-DAS 4020/12
+high-speed ADC.  We follow it with gr.freq_xlating_fir_filter_scf, a
+finite impulse response (FIR) filter that selects the FM station we're
+looking for and translates it to baseband (0Hz, DC). With the 20M
+sample/sec converter and cable modem tuner, we're really grabbing
+something in the neighborhood of a 6 MHz chunk of the spectrum. This
+single chunk may contain ten or more FM stations, and
+gr.freq_xlating_fir_filter_scf allows us to select the one we
+want.</para>
+
+<para>In this case, we select the one at the exact center of the IF of
+the RF front end (5.75 MHz). The output of
+gr.freq_xlating_fir_filter_scf is a stream of complex samples at
+160,000 samples/second. We feed the complex baseband signal into
+gr.quadrature_demod_cf, the block that does the actual FM
+demodulation.</para>
+
+<para>gr.quadrature_demod_cf works by subtracting the angle of
+each adjacent complex sample, effectively differentiating the
+frequency. The output of gr.quadrature_demod_cf contains the
+left-plus-right FM mono audio signal, the stereo pilot tone at 19kHz,
+the left-minus-right stereo information centered at 38kHz and any
+other sub-carriers above that. For this simplified receiver, we finish
+off by low pass filtering and decimating the stream, keeping only the
+left-plus-right audio information, and send that to the sound card at
+32,000 samples/sec.</para>
+
+<para>For a more indepth look at how the FM receiver
+works, please see "Listening to FM, Step by Step."</para>
+
+</sect1>
+
+<sect1 id="gui"><title>Graphical User Interfaces</title>
+
+<para>Graphical interfaces for GNU Radio applications are built in
+Python. Interfaces may be built using any toolkit you can access from
+Python; we recommend wxPython to maximize cross-platform
+portability. GNU Radio provides blocks that use interprocess
+communication to transfer chunks of data from the real-time C++ flow
+graph to Python-land. </para>
+
+<!-- please add more here, including example code and screen shots -->
+
+</sect1>
+
+<sect1 id="hardware-requirements"><title>Hardware Requirements</title>
+
+<para>GNU Radio is reasonably hardware-independent. Today's commodity
+multi-gigahertz, super-scalar CPUs with single-cycle floating-point
+units mean that serious digital signal processing is possible on the
+desktop. A 3 GHz Pentium or Athlon can evaluate 3 billion
+floating-point FIR taps/s. We now can build, virtually all in
+software, communication systems unthinkable only a few years ago.</para>
+
+<para>Your computational requirements depend on what you're trying to do,
+but generally speaking, a 1 or 2 GHz machine with at least 256 MB of RAM
+should suffice. You also need some way to connect the analog world to
+your computer. Low-cost options include built-in sound cards and
+audiophile quality 96 kHz, 24-bit, add-in cards. With either of these
+options, you are limited to processing relatively narrow band signals
+and need to use some kind of narrow-band RF front end.</para>
+
+<para>Another possible solution is an off-the-shelf, high-speed PCI
+analog-to-digital board. These are available in the 20M sample/sec
+range, but they are expensive, about the cost of a complete PC. For
+these high-speed boards, cable modem tuners make reasonable RF front
+ends.</para>
+
+<para>Finding none of these alternatives completely satisfactory, we
+designed the Universal Software Radio Peripheral, or USRP for short.
+</para>
+
+</sect1>
+
+<sect1 id="usrp"><title>The Universal Software Radio Peripheral</title>
+
+<para>Our preferred hardware solution is the Universal Software Radio
+Peripheral (USRP). <xref linkend="usrp-block-diagram-fig"/> shows the
+block diagram of the USRP. The brainchild of Matt Ettus, the USRP is
+an extremely flexible USB device that connects your PC to the RF
+world. The USRP consists of a small motherboard containing up to four
+12-bit 64M sample/sec ADCs, four 14-bit, 128M sample/sec DACs, a
+million gate-field programmable gate array (FPGA) and a programmable
+USB 2.0 controller. Each fully populated USRP motherboard supports
+four daughterboards, two for receive and two for transmit. RF front
+ends are implemented on the daughterboards. A variety of
+daughterboards is available to handle different frequency bands. For
+amateur radio use, low-power daughterboards are available that receive
+and transmit in the 440 MHz band and the 1.24 GHz band. A receive-only
+daughterboard based on a cable modem tuner is available that covers
+the range from 50 MHz to 800 MHz. Daughterboards are designed to be easy
+to prototype by hand in order to facilitate experimentation.</para>
+
+<figure id="usrp-block-diagram-fig"><title>Universal Software Radio Peripheral</title>
+<mediaobject>
+<imageobject><imagedata fileref="usrp-block-diagram.eps" format="EPS"/></imageobject>
+<imageobject><imagedata fileref="usrp-block-diagram.png" format="PNG"/></imageobject>
+<caption><para></para></caption>
+</mediaobject>
+</figure>
+
+<para>The flexibility of the USRP comes from the two programmable components
+on the board and their interaction with the host-side library. To get
+a feel for the USRP, let's look at its boot sequence. The USRP itself
+contains no ROM-based firmware, merely a few bytes that specify the
+vendor ID (VID), product ID (PID) and revision. When the USRP is
+plugged in to the USB for the first time, the host-side library sees
+an unconfigured USRP. It can tell it's unconfigured by reading the
+VID, PID and revision. The first thing the library code does is
+download the 8051 code that defines the behavior of the USB peripheral
+controller. When this code boots, the USRP simulates a USB disconnect
+and reconnect. When it reconnects, the host sees a different device:
+the VID, PID and revision are different. The firmware now running
+defines the USB endpoints, interfaces and command handlers. One of the
+commands the USB controller now understands is load the FPGA. The
+library code, after seeing the USRP reconnect as the new device, goes
+to the next stage of the boot process and downloads the FPGA
+configuration bitstream.</para>
+
+<para>FPGAs are generic hardware chips whose behavior is determined by the
+configuration bitstream that's loaded into them. You can think of the
+bitstream as object code. The bitstream is the output of compiling a
+high-level description of the design. In our case, the design is coded
+in the Verilog hardware description language. This is source code and,
+like the rest of the code in GNU Radio, is licensed under the GNU
+General Public License.</para>
+
+</sect1>
+
+<sect1 id="fpga"><title>What Goes in the FPGA?</title>
+
+<para>An FPGA is like a small, massively parallel computer that you design
+to do exactly what you want. Programming the FPGA takes a bit of
+skill, and mistakes can fry the board permanently. That said, we
+provide a standard configuration that is useful for a wide variety of
+applications.</para>
+
+<para>Using a good USB host controller, the USRP can sustain 32 MB/sec across
+the USB. The USB is half-duplex. Based on your needs, you partition
+the 32 MB/sec between the transmit and the receive directions. In the
+receive direction, the standard configuration allows you to select the
+part or parts of the digitized spectrum you're interested in,
+translate them to baseband and decimate as required. This is exactly
+equivalent to what's happening in the RF front end, only now we're
+doing it on digitized samples. The block of code that performs this
+function is called a digital down converter (<xref linkend="ddc-fig"/>).
+One advantage of performing this function in the digital domain is we can change the
+center frequency instantaneously, which is handy for frequency hopping
+spread spectrum systems.</para>
+
+<figure id="ddc-fig"><title>Digital Down Converter Block Diagram</title>
+<mediaobject>
+<imageobject><imagedata fileref="ddc.eps" format="EPS"/></imageobject>
+<imageobject><imagedata fileref="ddc.png" format="PNG"/></imageobject>
+<caption><para></para></caption>
+</mediaobject>
+</figure>
+
+
+<para>In the transmit direction, the exact inverse is performed. The FPGA
+contains multiple instances of the digital up and down
+converters. These instances can be connected to the same or different
+ADCs, depending on your needs. We don't have room here to cover all
+the theory behind them; see the GNU Radio Wiki for more information.</para>
+
+</sect1>
+
+<sect1 id="apps"><title>GNU Radio Applications</title>
+
+<para>In addition to the examples discussed above, GNU Radio comes with a
+complete HDTV transmitter and receiver, a spectrum analyzer, an
+oscilloscope, concurrent multichannel receiver and an ever-growing
+collection of modulators and demodulators.</para>
+
+<para>Projects under investigation or in progress include:</para>
+
+<itemizedlist>
+<listitem><para>A TiVo equivalent for radio, capable of recording multiple stations simultaneously.</para></listitem>
+<listitem><para>Time Division Multiple Access (TDMA) waveforms.</para></listitem>
+<listitem><para>A passive radar system that takes advantage of
+broadcast TV for its signal source. For those of you with old TVs
+hooked to antennas, think about the flutter you see when airplanes fly
+over.</para></listitem>
+<listitem><para>Radio astronomy.</para></listitem>
+<listitem><para>TETRA transceiver.</para></listitem>
+<listitem><para>Digital Radio Mundial (DRM).</para></listitem>
+<listitem><para>Software GPS.</para></listitem>
+<listitem><para>Distributed sensor networks.</para></listitem>
+<listitem><para>Distributed measurement of spectrum utilization.</para></listitem>
+<listitem><para>Amateur radio transceivers.</para></listitem>
+<listitem><para>Ad hoc mesh networks.</para></listitem>
+<listitem><para>RFID detector/reader.</para></listitem>
+<listitem><para>Multiple input multiple output (MIMO) processing. </para></listitem>
+</itemizedlist>
+
+</sect1>
+
+<sect1 id="politics"><title>Politics</title>
+
+<para>Every revolution has its political issues. Free software for building
+radios is troublesome to some people. In the US, we've run into
+opposition from the Motion Picture Association of America and its
+attempt with the Broadcast Flag to restrict the kinds of receivers
+that can be built for over-the-air digital TV.</para>
+
+<para>The US Federal Communications Commission has issued a Notice of
+Proposed Rule Making (NPRM) concerning Cognitive Radio
+Technologies and Software Defined Radios.  Several troublesome
+issues are raised in the NPRM, including restricting the sale of
+high-speed digital-to-analog converters, requirements for digital
+signatures or similar methods to keep unauthorized software out of
+software radio hardware and new restrictions on radios built for the
+amateur radio market.</para>
+
+</sect1>
+
+<sect1 id="summary"><title>Summary</title>
+
+<para>Software radio is an exciting field, and GNU Radio provides the tools
+to start exploring. A deep understanding of software radio requires
+knowledge from many domains. We're doing our best to lower the
+barriers to entry.</para>
+</sect1>
+
+<!-- FIXME
+<sect1 id="resource"><title>Resources</title>
+<para></para>
+</sect1>
+-->
+
+</article>
diff --git a/docs/exploring-gnuradio/fm_demod.py b/docs/exploring-gnuradio/fm_demod.py
new file mode 100755 (executable)
index 0000000..e58407f
--- /dev/null
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio import mc4020
+import sys
+
+def high_speed_adc (fg, input_rate):
+    # return gr.file_source (gr.sizeof_short, "dummy.dat", False)
+    return mc4020.source (input_rate, mc4020.MCC_CH3_EN | mc4020.MCC_ALL_1V)
+
+#
+# return a gr.flow_graph
+#
+def build_graph (freq1, freq2):
+    input_rate = 20e6
+    cfir_decimation = 125
+    audio_decimation = 5
+
+    quad_rate = input_rate / cfir_decimation
+    audio_rate = quad_rate / audio_decimation
+
+    fg = gr.flow_graph ()
+    
+    # use high speed ADC as input source
+    src = high_speed_adc (fg, input_rate)
+    
+    # compute FIR filter taps for channel selection
+    channel_coeffs = \
+      gr.firdes.low_pass (1.0,          # gain
+                          input_rate,   # sampling rate
+                          250e3,        # low pass cutoff freq
+                          8*100e3,      # width of trans. band
+                          gr.firdes.WIN_HAMMING)
+
+    # input: short; output: complex
+    chan_filter1 = \
+      gr.freq_xlating_fir_filter_scf (cfir_decimation,
+                                      channel_coeffs,
+                                      freq1,        # 1st station freq
+                                      input_rate)
+    
+    (head1, tail1) = build_pipeline (fg, quad_rate, audio_decimation)
+    
+    # sound card as final sink
+    audio_sink = audio.sink (int (audio_rate))
+
+    # now wire it all together
+    fg.connect (src, chan_filter1)
+    fg.connect (chan_filter1, head1)
+    fg.connect (tail1, (audio_sink, 0))
+
+    # two stations at once?
+    if freq2:
+        # Extract the second station and connect
+        # it to a second pipeline...
+
+        # input: short; output: complex
+        chan_filter2 = \
+          gr.freq_xlating_fir_filter_scf (cfir_decimation,
+                                          channel_coeffs,
+                                          freq2,        # 2nd station freq
+                                          input_rate)
+
+        (head2, tail2) = build_pipeline (fg, quad_rate, audio_decimation)
+
+        fg.connect (src, chan_filter2)
+        fg.connect (chan_filter2, head2)
+        fg.connect (tail2, (audio_sink, 1))
+    
+    return fg
+
+def build_pipeline (fg, quad_rate, audio_decimation):
+    '''Given a flow_graph, fg, construct a pipeline
+    for demodulating a broadcast FM signal.  The
+    input is the downconverteed complex baseband
+    signal. The output is the demodulated audio.
+
+    build_pipeline returns a two element tuple
+    containing the input and output endpoints.
+    '''
+    fm_demod_gain = 2200.0/32768.0
+    audio_rate = quad_rate / audio_decimation
+    volume = 1.0
+
+    # input: complex; output: float
+    fm_demod = gr.quadrature_demod_cf (volume*fm_demod_gain)
+
+    # 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
+    audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+    fg.connect (fm_demod, audio_filter)
+    return ((fm_demod, 0), (audio_filter, 0))
+    
+
+def main (args):
+    nargs = len (args)
+    if nargs == 1:
+        freq1 = float (args[0]) * 1e6
+        freq2 = None
+    elif nargs == 2:
+        freq1 = float (args[0]) * 1e6
+        freq2 = float (args[1]) * 1e6
+    else:
+        sys.stderr.write ('usage: fm_demod freq1 [freq2]\n')
+        sys.exit (1)
+
+    # connect to RF front end
+    rf_front_end = gr.microtune_4937_eval_board ()
+    if not rf_front_end.board_present_p ():
+        raise IOError, 'RF front end not found'
+
+    # set front end gain
+    rf_front_end.set_AGC (300)
+    IF_freq = rf_front_end.get_output_freq ()
+    IF_freq = 5.75e6
+
+    if not freq2:      # one station
+
+        rf_front_end.set_RF_freq (freq1)
+        fg = build_graph (IF_freq, None)
+
+    else:              # two stations
+
+        if abs (freq1 - freq2) > 5.5e6:
+            raise IOError, 'freqs too far apart'
+
+        target_freq = (freq1 + freq2) / 2
+        actual_freq = rf_front_end.set_RF_freq (target_freq)
+        #actual_freq = target_freq
+        
+        fg = build_graph (IF_freq + freq1 - actual_freq,
+                          IF_freq + freq2 - actual_freq)
+    
+    fg.start ()        # fork thread(s) and return
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
+if __name__ == '__main__':
+    main (sys.argv[1:])
+
+
diff --git a/docs/exploring-gnuradio/fm_demod_example.xml b/docs/exploring-gnuradio/fm_demod_example.xml
new file mode 100644 (file)
index 0000000..3036f88
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<example id="fm_demod_ex"><title>Broadcast FM Receiver</title>
+<programlisting>
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio import mc4020
+import sys
+
+def high_speed_adc (fg, input_rate):
+    # return gr.file_source (gr.sizeof_short, "dummy.dat", False)
+    return mc4020.source (input_rate, mc4020.MCC_CH3_EN | mc4020.MCC_ALL_1V)
+
+#
+# return a gr.flow_graph
+#
+def build_graph (freq1, freq2):
+    input_rate = 20e6
+    cfir_decimation = 125
+    audio_decimation = 5
+
+    quad_rate = input_rate / cfir_decimation
+    audio_rate = quad_rate / audio_decimation
+
+    fg = gr.flow_graph ()
+    
+    # use high speed ADC as input source
+    src = high_speed_adc (fg, input_rate)
+    
+    # compute FIR filter taps for channel selection
+    channel_coeffs = \
+      gr.firdes.low_pass (1.0,          # gain
+                          input_rate,   # sampling rate
+                          250e3,        # low pass cutoff freq
+                          8*100e3,      # width of trans. band
+                          gr.firdes.WIN_HAMMING)
+
+    # input: short; output: complex
+    chan_filter1 = \
+      gr.freq_xlating_fir_filter_scf (cfir_decimation,
+                                      channel_coeffs,
+                                      freq1,        # 1st station freq
+                                      input_rate)
+    
+    (head1, tail1) = build_pipeline (fg, quad_rate, audio_decimation)
+    
+    # sound card as final sink
+    audio_sink = audio.sink (int (audio_rate))
+
+    # now wire it all together
+    fg.connect (src, chan_filter1)
+    fg.connect (chan_filter1, head1)
+    fg.connect (tail1, (audio_sink, 0))
+
+    return fg
+
+def build_pipeline (fg, quad_rate, audio_decimation):
+    '''Given a flow_graph, fg, construct a pipeline
+    for demodulating a broadcast FM signal.  The
+    input is the downconverted complex baseband
+    signal. The output is the demodulated audio.
+
+    build_pipeline returns a two element tuple
+    containing the input and output endpoints.
+    '''
+    fm_demod_gain = 2200.0/32768.0
+    audio_rate = quad_rate / audio_decimation
+    volume = 1.0
+
+    # input: complex; output: float
+    fm_demod = gr.quadrature_demod_cf (volume*fm_demod_gain)
+
+    # 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
+    audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+    fg.connect (fm_demod, audio_filter)
+    return ((fm_demod, 0), (audio_filter, 0))
+    
+
+def main (args):
+    nargs = len (args)
+    if nargs == 1:
+        # get station frequency from command line
+        freq1 = float (args[0]) * 1e6
+    else:
+        sys.stderr.write ('usage: fm_demod freq\n')
+        sys.exit (1)
+
+    # connect to RF front end
+    rf_front_end = gr.microtune_4937_eval_board ()
+    if not rf_front_end.board_present_p ():
+        raise IOError, 'RF front end not found'
+
+    # set front end gain
+    rf_front_end.set_AGC (300)
+
+    # determine the front end's "Intermediate Frequency"
+    IF_freq = rf_front_end.get_output_freq () # 5.75e6
+
+    # Tell the front end to tune to freq1.  
+    # I.e., freq1 is translated down to the IF frequency
+    rf_front_end.set_RF_freq (freq1)
+
+    # build the flow graph
+    fg = build_graph (IF_freq, None)
+    
+    fg.start ()        # fork thread(s) and return
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
+if __name__ == '__main__':
+    main (sys.argv[1:])
+</programlisting>
+</example>
diff --git a/docs/exploring-gnuradio/swr-block-diagram.eps b/docs/exploring-gnuradio/swr-block-diagram.eps
new file mode 100644 (file)
index 0000000..dd029f3
--- /dev/null
@@ -0,0 +1,2399 @@
+%!PS-Adobe-3.0 EPSF-3.0 
+%%BoundingBox: 0 0 755 575
+%%Pages: 0
+%%Creator: Sun Microsystems, Inc.
+%%Title: none
+%%CreationDate: none
+%%LanguageLevel: 2
+%%EndComments
+%%BeginPreview: 760 575 1 1725 
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000800000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000400000000800000000800000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000001000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000002000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000002000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000080000000800000004000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000080000000800000004000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000040000000800000008000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000010000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000020000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000010000000800000020000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000008000000800000040000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000080000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000080000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000002000000800000100000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000002000000800000100000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000001000000800000200000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000400000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000800000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000007FFFFFFFFFFFFFFFFFFFFF
+%FFFF000000000000000000000000000000
+%000000000000400000800000800000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000030000000000000000000000
+%0000E00000000000000000000000000000
+%000000000000200000800001000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000080000000000000000000000
+%0000080000000000000000000000000000
+%000000000000000000800002000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000040000000000000000000000000000
+%000000000000100000800002000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000020000000000000000000000000000
+%000000000000080000800004000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000080000800004000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000040000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800010000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000002000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000020000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000002000000000000000000000000000
+%000000000000010000800020000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000008000800040000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800080000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000004000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000002000800100000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000002000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800400000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000400800800000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000200801000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000802000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000100800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000080804000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000080800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000810000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000010820000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000008840000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000880000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000004800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000002900000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000002800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000C00000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000C00000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000
+%0000000000000000FFFFFFFFFFFFFFFFFF80000000000000000000000000000380180000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000180380000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000002000000000000000000000000000000000000000000000001C0700000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000004000000000000000000000000000000000000000000000000C0E00000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000E1C07008184600
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%000000000000001000000000000000000000000000000000000000000000000061C1FC1818FE00
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%000000000000002000000000000000000000000000000000000000000000000073838E1818FC00
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000003707061838E000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000800000000000000000000000000000000000000000000000003E0E073030E000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000001000000000000000000000000000000000000000000000000001C0C033030C000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000001C0C073030C000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000400000000000000000000000000000000000000000000000000180C0630318000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000800000000000000000000000000000000000000000000000000180C0670718000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400FFC00000000000C000000001FF00FFE00000000
+%0000000000000000000000000000000000000000000000000000000000000000180C0E70618000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400FFF00000000000C000000003FFC0FFE00000000
+%0000000000002000000000000000000000000000000000000000000000000000180E1C70E18000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400E0780000000000C00000000381E0FFE00000000
+%00000000000040000000000000000000000000000000000000000000000000003807783F630000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C01C000000000000000000038070C0000000000
+%00000000000000000000000000000000000000000000000000000000000000003003F01E630000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C01C000000000000000000038030C0000000000
+%000000000001000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C01C1F007C07C0CE060F80038030C0000000000
+%000000000002000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C01C3FC1FE1FE0C6063FC0038070C0000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C03860E3873830C60C70600380E0C0000000000
+%000000000008000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400FFF06063033018C60C607003FFC0FFC00000000
+%000000000010000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400FFC0C063003018C30C603003FF00FFC00000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C1C0FFE3003FF8C3187FF0038300C0000000000
+%000000000040000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C0E0FFE3003FF8C1987FF0038180C0000000000
+%000000000080000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C070C003003000C19860000381C0C0000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C038C063033018C1B060200380E0C0000000000
+%000000000200000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C0386063833838C0F07070038060C0000000000
+%0000000004000001C03FF000FE00000000000000000000000000000000000001F8000000300000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C01C71E1C61C70C0E038E0038070C0000000000
+%0000000000000001C03FFC03FF00000000000000000000000000000000000007FE000000300000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C00E3FC0FE0FE0C0E01FC0038038C0000000000
+%0000000010000003E0301E07838000000000000000000000000000000000000E0E000000300000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400C00E0E00380380C0400700010018C0000000000
+%00000000200000036030060601C000000000000000000000000000000000001C07000000700000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000077030070E00C00000000000000000000000000000000000380301C00C603800
+%0000001000000000000000000000000000
+%000000000000000000800000000000000C00400000000000000000000000000000000000000000
+%0001C000800000063030030C00000000000000000000000000C00000000000300007F03F60FE00
+%0000001000000000000000000000000000
+%000000000000000000800000000000000F80400000000000000000000000000000000000000000
+%0001F001000000063830031C00000000000000000000000000F8000000000070000C3871E1C700
+%0000001000000000000000000000000000
+%000000000000000000800000000000000FF8400000000000000000000000000000000000000000
+%0001FF000000000E1830031C00000000000000000000000000FF800000000060001818E0E30300
+%0000001000000000000000000000000000
+%000000000000000000800000000000000FFE400000000000000000000000000000000000000000
+%0001FFE40000000C1830031C00000000000000000000000000FFE00000000060003018C0C70300
+%0000001000000000000000000000000000
+%0000000000000000007FFFFFFFFFFFFFFFFFC000000000000000000000000000000000003FFFFF
+%FFFFFFF80000000C1C30031C00000000007FFFFFFFFFFFFFFFFFF80000000060003019C0C70300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000FF8400000000000000000000000000000000000000000
+%0001FF000000001FFC30030C00000000000000000000000000FF80000000006000301980C7FF00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000FE0400000000000000000000000000000000000000000
+%0001FC020000001FFC30030C00C00000000000000000000000FE00000000006006701980C60000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000F00400000000000000000000000000000000000000000
+%0001F001000000380E30070E00C00000000000000000000000F00000000000700E701981C60000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003FF80000000000003FFC00000080000000000
+%00000000000000300630060601C00000000000000000000000000000000000300C303181860600
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003FFC0000000006003FFE000000C0000000000
+%000000004000003007301E0783800000000000000000000000000000000000381C3071C3870E00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003800000000000E003800000000C0000000000
+%0000000020000070033FFC03FF0000000000000000000000000000000000001FF81FE0FF83FC00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000000000000E003000000000C0000000000
+%000000000000006003BFF000FC00000000000000000000000000000000000007E00F807981F000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000000000000E003000000000C0000000000
+%000000000800000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000DE1F833E1F80300037C03CC0000000000
+%000000000400000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000FE7FC3FF0E0030003FF0FFC0000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000E060E3830E0030003871C3C0000000000
+%000000000100000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003FF0E0E063838E003FFC303181C0000000000
+%000000000080000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003FF0E0C073038E003FFC303180C0000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C0C033038E003000303180C0000000000
+%000000000020000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C0C033038E003000303180C0000000000
+%000000000010000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C0C033038E003000303180C0000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C0C063038E003000303181C0000000000
+%000000000004000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C06063038E0030003031C1C0000000000
+%0000000000020000000000000000000000000000000000000000000000000038030000000001C0
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C071C30387003FFE3030E7C0000000000
+%0000000000000000000000000000000000000000000000000000000000000038070000000001C0
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400003000C03F830387803FFE30307EC0000000000
+%000000000000800000000000000000000000000000000000000000000000003006000000000180
+%0000001000000000000000000000000000
+%0000000000000000000000000000000000004000030004006030103803FFE30301880000000000
+%000000000000400000000000000000000000000000000000000000000000003006000000000180
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000030060380CC0E0380
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%0000000000001000000000000000000000000000000000000000000000000070060FE0DE3F8380
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000008000000000000000000000000000000000000000000000000700E1C70F061C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000007FFC3030E0C0C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%000000000000020000000000000000000000000000000000000000000000007FFC7039C1C0C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000001000000000000000000000000000000000000000000000000E00C7FF981FFC200
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000C01C7FF181FFC200
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000400000000000000000000000000000000000000000000000C01C600181800200
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000C018600381800000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000C018606301818000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000001C01870E301C38000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000001C0183FC300FF0E00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000180380F03007C0C00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000400000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%0000000000000000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000
+%00000000000000007FFFFFFFFFFFFFFFFF80000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000002000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000002000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001000000000000000000000000
+%0000008000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000800000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000400000000000000000000000
+%0000010000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000300000000000000000000000
+%0000060000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000080000000000000000000000
+%0000180000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000020000000000000000000000
+%0000200000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000001C000000000000000000000
+%0001800000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000007FF00000
+%0000006000000001FF800000300000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000007FFC0000
+%0000006000000001FFC0000C300000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700C0000
+%000000000000000180E0000C300000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700E0000
+%00000000000000018060000C300000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000070060300
+%1C01C062010380018070381F318000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700E1FC0
+%7F07F063030FE0018070FE1F3FE000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700E38E0
+%E38E3863031C70018061C70C3E7000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000007FFC3031
+%C19C1C630638300180E3830C383000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000007FF06031
+%80180C6186301801FFC0030C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000071E07FF1
+%801FFC61863FF801FF80070C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000070707FF9
+%801FFC618C3FF8018000FF0C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000070386001
+%80180060CC3000018001E30C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000070386001
+%80180060CC3000018003830C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000701C3031
+%819C0C60783018018003030C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700E3871
+%C18C1C60783830018003070C303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000700E1FE0
+%FF0FF860701FF0018003DF0F303800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000070070FC0
+%3E03E0603007C0018001F987B03800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000400000000800000000800000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000400000000800000000800000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000200000000800000001000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000002000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000100000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000080000000800000004000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000008000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000010000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000010000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000010000000800000020000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000010000000800000020000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000008000000800000040000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000080000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000004000000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000002000000800000100000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000200000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000400000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800000400000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000400000800000800000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000038000000000000000000000
+%0000E00000000000000000000000000000
+%000000000000400000800000800000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000C0000000000000000000000
+%0000180000000000000000000000000000
+%000000000000200000800001000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000100000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800002000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000400000000000000000000000
+%0000000000000000000000000000000000
+%000000000000100000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000800000000000000000000000
+%0000000000000000000000000000000000
+%000000000000080000800004000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800008000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000800010000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000002000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000800010000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000002000000000000000000000000000
+%000000000000010000800020000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000002000000000000000000000000000
+%000000000000010000800020000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000008000800040000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000800080000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000004000800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000002000800100000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000001000800200000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800400000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800400000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000400800800000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000400800800000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000200801000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000802000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000100800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000080804000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000040808000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000810000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000810000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000010820000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000010800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000008840000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000880000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000004900000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000002800000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000001A00000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000C00000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000C00000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000400000
+%000000000000000000000000000000000080000000000000000000000000000380380000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000180700000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000C0700000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000C0E00000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000E1C0F818186E00
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000006383FC1818FE00
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000007307061818F000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000003706061838E000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000001E0E073030C000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000001C0C033030C000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000001C0C073030C000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000180C0630718000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000180C0670718000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000004000000180380000180001FFC0FFF0000000000000
+%0000000000000000000000000000000000000000000000000000000000000000180C0C70E18000
+%0000001000000000000000000000000000
+%00000000000000000080000000000000000040000001C0700000186001FFE0FFF0000000000000
+%0000000000000000000000000000000000000000000000000000000000000000380E1C71E18000
+%0000001000000000000000000000000000
+%00000000000000000080000000000000000040000000E06000000060018070C000000000000000
+%00000000000080000000000000000000000000000000000000000000000000003007F83F630000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000004000000070C000000060018030C000000000000000
+%00000000000000000000000000000000000000000000000000000000000000003001E01C630000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000004000000031C000000070018030C000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000003B81BE7E18FC018030C000000000000000
+%000000000004000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000001F01E7EF1860018070C000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000E01C383186001C3E0E000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000E018383186001FFC0FFE0000000000000
+%000000000020000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000001F018383186001FF00FFC0000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000001B8183831860018380C000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000003181838318600181C0C000000000000000
+%000000000100000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000004000000071C1838318600180E0C000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%00000000000000000080000000000000000040000000E0E183831860018070C000000000000000
+%000000000400001F80006000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%00000000000000000080000000000000000040000000C07183831860018070C000000000000000
+%000000000800003FF800F001FE00000000000000000000000000000000000003FC000000300000
+%0000001000000000000000000000000000
+%00000000000000000080000000000000000040000001C07183831878018038C000000000000000
+%000000000000003FFC00F003FF8000000000000000000000000000000000000F9E000000300000
+%0000001000000000000000000000000000
+%0000000000000000008000000000000000004000000380398383183C018018C000000000000000
+%00000000200000300E01F007018000000000000000000000000000000000001C07000000300000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000400000300701B80E01C000000000000000000000000000000000001803000000600000
+%0000001000000000000000000000000000
+%000000000000000000800000000000000000400000000000000000000000000000000000000000
+%00000000000000300301980C00C00000000000000000000000000000000000380303E01E607C00
+%0000001000000000000000000000000000
+%000000000000000000800800000000000000400000000000000000000000000000000000000400
+%00000001000000300303980C0000000000000080000000000000000000000030000FF03F61FE00
+%0000001000000000000000000000000000
+%000000000000000000803800000000000000400000000000000000000000000000000000001C00
+%000000020000003003030C1C0000000000000780000000000000000000000070001C3861E38300
+%0000001000000000000000000000000000
+%00000000000000000081F80000000000000040000000000000000000000000000000000000FC00
+%000000000000003003830C1C0000000000001F80000000000000000000000060003818C0E30300
+%0000001000000000000000000000000000
+%0000000000000000009FF8000000000000004000000000000000000000000000000000000FFC00
+%000000080000003003860E1C000000000001FF80000000000000000000000060003018C0C70300
+%0000001000000000000000000000000000
+%000000000000000000FFFFFFFFFFFFFFFFFFC000000000000000000000000000000000003FFFFF
+%FFFFFFFC0000003003070E1C00000000000FFFFFFFFFFFFFFFFFF8000000006000301980C7FF00
+%0000001000000000000000000000000000
+%0000000000000000001FF8000000000000004000000000000000000000000000000000000FFC00
+%0000000000000030030FFF0C000000000001FF8000000000000000000000006000301980C7FF00
+%0000001000000000000000000000000000
+%00000000000000000001F80000000000000040000000000000000000000000000000000000FC00
+%0000000100000030030E070C00C0000000001F8000000000000000000000006006701980C60000
+%0000001000000000000000000000000000
+%000000000000000000007800000000000000400000000000000000000000000000000000001C00
+%0000000080000030070C030E00C00000000007800000000000000000000000700E703981C60600
+%0000001000000000000000000000000000
+%000000000000000000000800000000000000400007FF80000000004007FFC00000180000000400
+%00000000000000300E1C038701C00000000000800000000000000000000000381C303181860600
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400007FF8000000000C007FFC00000180000000000
+%00000000200000383C180183C78000000000000000000000000000000000003C3838E0C7871C00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400007000000000000C00700000000180000000000
+%000000001000003FF83801C1FF0000000000000000000000000000000000000FF01FC0FF83F800
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000000000000C00700000000180000000000
+%000000000000003FE03000C07C00000000000000000000000000000000000003C007003980E000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000880C02303E00700043003180000000000
+%000000000400000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000FC7F86FE3F0070006FC0FD80000000000
+%000000000200000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000FCF3C7CE0C0070007CE1C780000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400007FE0C0C0C7070C007FF870618380000000000
+%000000000080000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400007FF0C1C0E7030C007FF860730180000000000
+%000000000040000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400007FE0C18067030C007FF060730180000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C18067030C00700060730180000000000
+%000000000010000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C18067030C00700060730180000000000
+%000000000008000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C18067030C00700060730180000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C1C0E7030C00700060738380000000000
+%000000000002000000000000000000000000000000000000000000000000001003000000000080
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C0E1C7030C00700060718380000000000
+%0000000000010000000000000000000000000000000000000000000000000038030000000001C0
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C07F87030F007FFC6071FF80000000000
+%000000000000000000000000000000000000000000000000000000000000003007000000000180
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400006000C03F070307007FFC60707D80000000000
+%000000000000400000000000000000000000000000000000000000000000003006000000000180
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%000000000000200000000000000000000000000000000000000000000000003006000000000180
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000300607C0CE1F0380
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000008000000000000000000000000000000000000000000000000700E1FE0FC7F8380
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%000000000000040000000000000000000000000000000000000000000000007FFE3830E0E0C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000007FFC3031C0C0C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000001000000000000000000000000000000000000000000000000601C7039C1C0C300
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000800000000000000000000000000000000000000000000000E00C7FF981FFC200
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000C01C7FF181FFC200
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000200000000000000000000000000000000000000000000000C01C600181800600
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000100000000000000000000000000000000000000000000000C018602381818000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000001C018606301818000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000040000000000000000000000000000000000000000000001C01831C301C70400
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%00000000000000020000000000000000000000000000000000000000000001C0383F8300FE0E00
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000400000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000180300E0300380C00
+%0000001000000000000000000000000000
+%0000000000000000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000
+%0000000000000000FFFFFFFFFFFFFFFFFF80000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000001000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000004000000000000000000000000
+%0000002000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000002000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000001000000000000000000000000
+%0000004000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000400000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000100000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000C0000000000000000000000
+%0000180000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000020000000000000000000000
+%0000200000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000003FFFFFFFFFFFFFFFFFFFFF
+%FFFE000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000007FFC00000
+%00000000000182003FF80000860000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000007FFC00000
+%00000000000186003FFC0001860000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000018000000
+%0000000000000600301C0001860000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000018000000
+%0000000000000600300E0001860000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001806E1F8
+%33C07813C3C19F80300E0F83E67800000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001807E3FC
+%3FE1FE1FFFE18F80300E3FE3E7FE00000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001807060E
+%3871871C78618600300C3061878600000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001806060E
+%3033821838318600303C6061870700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001806000E
+%30318018303186003FF80061860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000180600FE
+%3031F818303186003FE007E1860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000180603FE
+%30307E183031860030003FE1860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%00000000000000000000000000000000000000000000000000000000000000000000001806070E
+%30300F183031860030007861860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000018060E0E
+%303003183031860030006061860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000018060C0E
+%303383183031860030006061860700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000018060E1E
+%3031871830318600300070E1C60700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000180607FE
+%3031FE183031878030003FF1F60700000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%0000000000000000000000000000000000000000000000000000000000000000000000180603C6
+%303078183031838030001E30F60300000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%%EndPreview
+%%BeginProlog
+%%BeginResource: SDRes
+/b4_inc_state save def
+/dict_count countdictstack def
+/op_count count 1 sub def
+userdict begin
+0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath
+/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if
+/bdef {bind def} bind def
+/c {setgray} bdef
+/l {neg lineto} bdef
+/rl {neg rlineto} bdef
+/lc {setlinecap} bdef
+/lj {setlinejoin} bdef
+/lw {setlinewidth} bdef
+/ml {setmiterlimit} bdef
+/ld {setdash} bdef
+/m {neg moveto} bdef
+/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef
+/r {rotate} bdef
+/t {neg translate} bdef
+/s {scale} bdef
+/sw {show} bdef
+/gs {gsave} bdef
+/gr {grestore} bdef
+/f {findfont dup length dict begin
+{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def
+currentdict end /NFont exch definefont pop /NFont findfont} bdef
+/p {closepath} bdef
+/sf {scalefont setfont} bdef
+/ef {eofill}bdef
+/pc {closepath stroke}bdef
+/ps {stroke}bdef
+/pum {matrix currentmatrix}bdef
+/pom {setmatrix}bdef
+/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%EndPageSetup
+pum
+0.02834 0.02833 s 
+0 -20290 t
+/tm matrix currentmatrix def
+gs
+tm setmatrix
+-635 -635 t 
+1 1 s 
+635 635 m 27274 635 l 27274 20924 l 635 20924 l 635 635 l eoclip newpath
+0 lw 1 lj 0.000 c 1905 1905 m  3175 3810 l  ps
+3175 3810 m  4445 1905 l  ps
+3175 1905 m  3175 5080 l  ps
+0.996 c 12565 5080 m  13835 3810 l  16375 3810 l  16375 6350 l  13835 6350 l 
+12565 5080 l  p ef
+0.000 c 12565 5080 m  13835 3810 l  16375 3810 l  16375 6350 l  13835 6350 l 
+12565 5080 l  pc
+gs
+pum
+13573 5371 t
+-1 0 m  231 -606 l  318 -606 l  566 0 l  474 0 l  404 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  379 -248 l  315 -416 l  296 -467 282 -509 272 -542 ct 265 -503 254 -465 240 -426 ct 
+p ef
+621 0 m  621 -606 l  830 -606 l  877 -606 913 -603 938 -597 ct 972 -589 1002 -575 1027 -554 ct 
+1059 -527 1082 -492 1098 -450 ct 1114 -408 1122 -360 1122 -306 ct 1122 -260 1117 -219 1106 -184 ct 
+1095 -148 1081 -119 1065 -95 ct 1048 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+909 -3 876 0 840 0 ct p
+701 -71 m  831 -71 l  871 -71 902 -75 925 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1013 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -371 1029 -419 1008 -453 ct 
+987 -487 962 -510 932 -522 ct 911 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1742 -192 l  1725 -126 1695 -76 1651 -41 ct 1607 -6 1554 10 1491 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -555 1345 -580 ct 1389 -604 1438 -616 1492 -616 ct 
+1553 -616 1604 -601 1645 -570 ct 1686 -539 1715 -496 1731 -440 ct 1652 -421 l 
+1638 -465 1618 -497 1591 -517 ct 1564 -537 1531 -547 1490 -547 ct 1444 -547 1405 -536 1373 -514 ct 
+1342 -492 1320 -462 1307 -424 ct 1295 -386 1288 -348 1288 -308 ct 1288 -256 1296 -211 1311 -173 ct 
+1326 -134 1349 -105 1381 -86 ct 1413 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -123 l  1650 -161 l  p ef
+pom
+gr
+8255 6350 m  5715 6350 l  5715 3810 l  10795 3810 l  10795 6350 l  8255 6350 l 
+pc
+gs
+pum
+6033 4895 t
+66 0 m  66 -606 l  335 -606 l  389 -606 430 -600 458 -589 ct 486 -579 509 -559 526 -532 ct 
+542 -504 551 -474 551 -440 ct 551 -397 537 -361 509 -332 ct 481 -302 438 -283 380 -275 ct 
+401 -265 417 -255 428 -245 ct 452 -224 474 -197 495 -165 ct 600 0 l  500 0 l 
+419 -126 l  396 -162 377 -190 361 -209 ct 346 -228 333 -242 321 -250 ct 309 -257 296 -263 284 -266 ct 
+275 -268 260 -269 239 -269 ct 146 -269 l  146 0 l  p
+146 -338 m  319 -338 l  355 -338 384 -342 405 -350 ct 425 -357 441 -369 452 -386 ct 
+463 -403 468 -421 468 -440 ct 468 -469 458 -493 437 -511 ct 416 -530 383 -539 338 -539 ct 
+146 -539 l  p ef
+965 -141 m  1042 -131 l  1030 -86 1007 -52 975 -27 ct 942 -2 900 9 849 9 ct 
+785 9 734 -9 696 -49 ct 658 -88 640 -144 640 -215 ct 640 -289 659 -347 697 -387 ct 
+735 -428 784 -449 845 -449 ct 903 -449 951 -429 989 -389 ct 1026 -349 1044 -292 1044 -220 ct 
+1044 -216 1044 -209 1044 -200 ct 716 -200 l  719 -152 733 -115 757 -89 ct 782 -64 813 -51 849 -51 ct 
+877 -51 900 -58 919 -72 ct 938 -87 l  954 -110 l  p
+721 -261 m  966 -261 l  963 -298 953 -326 938 -344 ct 914 -373 883 -387 845 -387 ct 
+811 -387 783 -376 759 -353 ct 736 -330 l  723 -300 l  p ef
+1427 -160 m  1500 -151 l  1492 -100 1472 -61 1439 -32 ct 1406 -4 1365 9 1317 9 ct 
+1257 9 1209 -9 1172 -49 ct 1136 -88 1118 -144 1118 -217 ct 1118 -265 1125 -306 1141 -342 ct 
+1157 -378 1181 -404 1213 -422 ct 1245 -440 1280 -449 1318 -449 ct 1365 -449 1404 -437 1435 -412 ct 
+1465 -388 1485 -354 1493 -310 ct 1421 -299 l  1414 -328 1402 -350 1384 -365 ct 
+1367 -380 1345 -387 1321 -387 ct 1283 -387 1253 -374 1229 -347 ct 1206 -320 1194 -278 1194 -220 ct 
+1194 -161 1205 -118 1228 -91 ct 1251 -64 1280 -51 1317 -51 ct 1346 -51 1370 -60 1390 -78 ct 
+1409 -96 l  1422 -123 l  p ef
+1864 -141 m  1941 -131 l  1929 -86 1906 -52 1874 -27 ct 1841 -2 1799 9 1748 9 ct 
+1684 9 1633 -9 1595 -49 ct 1557 -88 1539 -144 1539 -215 ct 1539 -289 1558 -347 1596 -387 ct 
+1634 -428 1683 -449 1744 -449 ct 1802 -449 1850 -429 1888 -389 ct 1925 -349 1943 -292 1943 -220 ct 
+1943 -216 1943 -209 1943 -200 ct 1615 -200 l  1618 -152 1632 -115 1656 -89 ct 
+1681 -64 1712 -51 1748 -51 ct 1776 -51 1799 -58 1818 -72 ct 1837 -87 l  1853 -110 l 
+p
+1620 -261 m  1865 -261 l  1862 -298 1852 -326 1837 -344 ct 1813 -373 1782 -387 1744 -387 ct 
+1710 -387 1682 -376 1658 -353 ct 1635 -330 l  1622 -300 l  p ef
+2040 -520 m  2040 -606 l  2114 -606 l  2114 -520 l  p
+2040 0 m  2040 -439 l  2114 -439 l  2114 0 l  p ef
+2347 0 m  2180 -439 l  2259 -439 l  2353 -176 l  2363 -147 2373 -118 2381 -87 ct 
+2388 -110 2397 -138 2409 -171 ct 2507 -439 l  2583 -439 l  2417 0 l  p ef
+2949 -141 m  3026 -131 l  3014 -86 2991 -52 2959 -27 ct 2926 -2 2884 9 2833 9 ct 
+2769 9 2718 -9 2680 -49 ct 2642 -88 2624 -144 2624 -215 ct 2624 -289 2643 -347 2681 -387 ct 
+2719 -428 2768 -449 2829 -449 ct 2887 -449 2935 -429 2973 -389 ct 3010 -349 3028 -292 3028 -220 ct 
+3028 -216 3028 -209 3028 -200 ct 2700 -200 l  2703 -152 2717 -115 2741 -89 ct 
+2766 -64 2797 -51 2833 -51 ct 2861 -51 2884 -58 2903 -72 ct 2922 -87 l  2938 -110 l 
+p
+2705 -261 m  2950 -261 l  2947 -298 2937 -326 2922 -344 ct 2898 -373 2867 -387 2829 -387 ct 
+2795 -387 2767 -376 2743 -353 ct 2720 -330 l  2707 -300 l  p ef
+3373 0 m  3373 -606 l  3642 -606 l  3696 -606 3737 -600 3765 -589 ct 3793 -579 3816 -559 3833 -532 ct 
+3849 -504 3858 -474 3858 -440 ct 3858 -397 3844 -361 3816 -332 ct 3788 -302 3745 -283 3687 -275 ct 
+3708 -265 3724 -255 3735 -245 ct 3759 -224 3781 -197 3802 -165 ct 3907 0 l  3807 0 l 
+3726 -126 l  3703 -162 3684 -190 3668 -209 ct 3653 -228 3640 -242 3628 -250 ct 
+3616 -257 3603 -263 3591 -266 ct 3582 -268 3567 -269 3546 -269 ct 3453 -269 l 
+3453 0 l  p
+3453 -338 m  3626 -338 l  3662 -338 3691 -342 3712 -350 ct 3732 -357 3748 -369 3759 -386 ct 
+3770 -403 3775 -421 3775 -440 ct 3775 -469 3765 -493 3744 -511 ct 3723 -530 3690 -539 3645 -539 ct 
+3453 -539 l  p ef
+3985 0 m  3985 -606 l  4394 -606 l  4394 -534 l  4065 -534 l  4065 -346 l 
+4350 -346 l  4350 -275 l  4065 -275 l  4065 0 l  p ef
+pom
+pum
+6364 5848 t
+69 0 m  69 -606 l  478 -606 l  478 -534 l  149 -534 l  149 -346 l  434 -346 l 
+434 -275 l  149 -275 l  149 0 l  p ef
+584 0 m  584 -439 l  651 -439 l  651 -372 l  668 -403 683 -424 698 -434 ct 
+712 -444 728 -449 746 -449 ct 771 -449 796 -441 822 -425 ct 797 -356 l  778 -366 760 -372 742 -372 ct 
+726 -372 711 -367 698 -357 ct 685 -347 676 -334 670 -316 ct 662 -290 658 -261 658 -229 ct 
+658 0 l  p ef
+848 -219 m  848 -300 870 -361 915 -400 ct 953 -432 999 -449 1054 -449 ct 1114 -449 1163 -429 1202 -389 ct 
+1240 -350 1259 -295 1259 -225 ct 1259 -169 1251 -124 1234 -92 ct 1217 -60 1192 -34 1160 -16 ct 
+1127 0 1092 9 1054 9 ct 992 9 942 -9 904 -49 ct 867 -88 l  848 -145 l  p
+924 -219 m  924 -163 936 -121 961 -93 ct 985 -65 1016 -51 1054 -51 ct 1091 -51 1121 -65 1146 -93 ct 
+1170 -121 1183 -164 1183 -222 ct 1183 -276 1170 -317 1146 -345 ct 1121 -373 1090 -387 1054 -387 ct 
+1016 -387 985 -373 961 -345 ct 936 -317 l  924 -275 l  p ef
+1351 0 m  1351 -439 l  1418 -439 l  1418 -376 l  1451 -425 1497 -449 1558 -449 ct 
+1585 -449 1609 -444 1631 -434 ct 1653 -425 1670 -412 1681 -397 ct 1692 -382 1700 -363 1704 -342 ct 
+1707 -328 1708 -304 1708 -270 ct 1708 0 l  1634 0 l  1634 -267 l  1634 -297 1631 -320 1625 -335 ct 
+1619 -350 1609 -362 1594 -371 ct 1580 -380 1562 -384 1542 -384 ct 1511 -384 1483 -374 1460 -354 ct 
+1437 -334 1426 -296 1426 -239 ct 1426 0 l  p ef
+1991 -66 m  2002 0 l  1981 3 1962 5 1945 5 ct 1918 5 1897 1 1883 -7 ct 1868 -15 1857 -26 1851 -40 ct 
+1845 -54 1842 -83 1842 -128 ct 1842 -381 l  1787 -381 l  1787 -439 l  1842 -439 l 
+1842 -547 l  1916 -592 l  1916 -439 l  1991 -439 l  1991 -381 l  1916 -381 l 
+1916 -124 l  1916 -103 1917 -89 1920 -83 ct 1923 -77 1927 -72 1933 -69 ct 1939 -65 1947 -63 1958 -63 ct 
+1966 -63 l  1977 -64 l  p ef
+2316 0 m  2316 -606 l  2754 -606 l  2754 -534 l  2396 -534 l  2396 -349 l 
+2731 -349 l  2731 -277 l  2396 -277 l  2396 -71 l  2768 -71 l  2768 0 l 
+p ef
+2886 0 m  2886 -439 l  2953 -439 l  2953 -376 l  2986 -425 3032 -449 3093 -449 ct 
+3120 -449 3144 -444 3166 -434 ct 3188 -425 3205 -412 3216 -397 ct 3227 -382 3235 -363 3239 -342 ct 
+3242 -328 3243 -304 3243 -270 ct 3243 0 l  3169 0 l  3169 -267 l  3169 -297 3166 -320 3160 -335 ct 
+3154 -350 3144 -362 3129 -371 ct 3115 -380 3097 -384 3077 -384 ct 3046 -384 3018 -374 2995 -354 ct 
+2972 -334 2961 -296 2961 -239 ct 2961 0 l  p ef
+3647 0 m  3647 -55 l  3619 -11 3579 9 3524 9 ct 3489 9 3457 0 3428 -19 ct 3399 -38 3376 -65 3360 -99 ct 
+3344 -134 3335 -174 3335 -219 ct 3335 -263 3343 -302 3357 -338 ct 3372 -374 3394 -401 3423 -420 ct 
+3452 -439 3485 -449 3521 -449 ct 3548 -449 3571 -443 3592 -432 ct 3613 -421 3629 -406 3642 -388 ct 
+3642 -606 l  3716 -606 l  3716 0 l  p
+3412 -219 m  3412 -162 3424 -120 3448 -93 ct 3471 -65 3499 -51 3531 -51 ct 3564 -51 3592 -64 3614 -91 ct 
+3637 -117 3649 -158 3649 -212 ct 3649 -273 3637 -317 3614 -345 ct 3591 -373 3562 -387 3528 -387 ct 
+3495 -387 3467 -374 3445 -346 ct 3423 -319 l  3412 -277 l  p ef
+pom
+gr
+21272 7620 m  19550 7620 l  19274 7620 19050 7396 19050 7120 ct 19050 3040 l 
+19050 2764 19274 2540 19550 2540 ct 22995 2540 l  23271 2540 23495 2764 23495 3040 ct 
+23495 7120 l  23495 7396 23271 7620 22995 7620 ct 21272 7620 l  pc
+gs
+pum
+20360 4418 t
+236 0 m  285 -234 l  98 -606 l  185 -606 l  275 -429 l  294 -390 313 -349 332 -305 ct 
+352 -342 380 -383 415 -428 ct 557 -606 l  654 -606 l  365 -228 l  317 0 l 
+p ef
+597 -166 m  597 -252 622 -323 673 -379 ct 714 -425 769 -449 836 -449 ct 889 -449 932 -432 964 -399 ct 
+997 -366 1013 -321 1013 -265 ct 1013 -215 1003 -168 982 -124 ct 962 -81 933 -47 895 -24 ct 
+858 -1 818 9 776 9 ct 742 9 711 2 683 -11 ct 655 -26 634 -47 619 -74 ct 604 -100 l 
+597 -131 l  p
+672 -174 m  672 -132 682 -101 701 -80 ct 721 -58 747 -47 777 -47 ct 793 -47 809 -51 825 -57 ct 
+840 -64 855 -74 869 -87 ct 882 -100 894 -115 903 -132 ct 913 -149 920 -167 926 -187 ct 
+935 -214 939 -240 939 -265 ct 939 -305 929 -336 909 -358 ct 889 -380 864 -391 833 -391 ct 
+810 -391 789 -385 769 -374 ct 750 -363 733 -346 717 -325 ct 701 -303 690 -278 683 -250 ct 
+675 -221 l  672 -196 l  p ef
+1359 -79 m  1307 -19 1253 9 1198 9 ct 1164 9 1136 0 1116 -19 ct 1095 -38 1084 -62 1084 -90 ct 
+1084 -109 1089 -140 1099 -185 ct 1151 -439 l  1226 -439 l  1168 -158 l  1163 -134 1160 -116 1160 -103 ct 
+1160 -87 1165 -74 1175 -65 ct 1185 -55 1200 -51 1220 -51 ct 1241 -51 1261 -56 1281 -66 ct 
+1301 -76 1318 -90 1333 -107 ct 1347 -125 1359 -145 1368 -169 ct 1374 -184 1381 -211 1389 -249 ct 
+1429 -439 l  1504 -439 l  1412 0 l  1343 0 l  p ef
+1536 0 m  1627 -439 l  1694 -439 l  1675 -349 l  1698 -383 1720 -408 1741 -424 ct 
+1763 -441 1785 -449 1808 -449 ct 1823 -449 1841 -443 1863 -433 ct 1832 -363 l 
+1819 -372 1805 -377 1790 -377 ct 1763 -377 1736 -362 1709 -333 ct 1681 -304 1660 -252 1644 -176 ct 
+1607 0 l  p ef
+pom
+pum
+20241 5371 t
+510 -213 m  591 -202 l  565 -132 528 -79 480 -43 ct 431 -7 377 10 316 10 ct 
+243 10 184 -12 141 -57 ct 98 -102 76 -166 76 -250 ct 76 -359 109 -449 175 -521 ct 
+233 -584 306 -616 393 -616 ct 457 -616 509 -599 549 -564 ct 589 -530 612 -484 618 -425 ct 
+543 -418 l  535 -462 518 -495 493 -517 ct 468 -538 436 -549 397 -549 ct 322 -549 262 -516 217 -450 ct 
+177 -394 157 -326 157 -248 ct 157 -186 172 -138 203 -105 ct 234 -73 273 -56 323 -56 ct 
+364 -56 402 -70 436 -97 ct 470 -124 l  495 -163 l  p ef
+650 -166 m  650 -252 675 -323 726 -379 ct 767 -425 822 -449 889 -449 ct 942 -449 985 -432 1017 -399 ct 
+1050 -366 1066 -321 1066 -265 ct 1066 -215 1056 -168 1035 -124 ct 1015 -81 986 -47 948 -24 ct 
+911 -1 871 9 829 9 ct 795 9 764 2 736 -11 ct 708 -26 687 -47 672 -74 ct 657 -100 l 
+650 -131 l  p
+725 -174 m  725 -132 735 -101 754 -80 ct 774 -58 800 -47 830 -47 ct 846 -47 862 -51 878 -57 ct 
+893 -64 908 -74 922 -87 ct 935 -100 947 -115 956 -132 ct 966 -149 973 -167 979 -187 ct 
+988 -214 992 -240 992 -265 ct 992 -305 982 -336 962 -358 ct 942 -380 917 -391 886 -391 ct 
+863 -391 842 -385 822 -374 ct 803 -363 786 -346 770 -325 ct 754 -303 743 -278 736 -250 ct 
+728 -221 l  725 -196 l  p ef
+1409 -63 m  1366 -14 1321 9 1275 9 ct 1233 9 1198 -5 1171 -36 ct 1143 -66 1129 -111 1129 -169 ct 
+1129 -223 1140 -272 1162 -316 ct 1184 -360 1211 -394 1244 -416 ct 1277 -438 1310 -449 1343 -449 ct 
+1398 -449 1439 -422 1467 -370 ct 1517 -606 l  1591 -606 l  1465 0 l  1396 0 l 
+p
+1204 -184 m  1204 -153 1207 -129 1213 -111 ct 1219 -94 1229 -79 1244 -67 ct 
+1258 -55 1276 -50 1296 -50 ct 1330 -50 1361 -67 1388 -102 ct 1425 -149 1444 -207 1444 -276 ct 
+1444 -311 1435 -338 1417 -358 ct 1398 -377 1376 -387 1348 -387 ct 1330 -387 1314 -383 1299 -375 ct 
+1284 -367 1270 -353 1255 -334 ct 1241 -315 1228 -291 1219 -261 ct 1209 -232 l 
+1204 -206 l  p ef
+1911 -149 m  1984 -141 l  1974 -105 1949 -71 1912 -38 ct 1874 -6 1829 9 1777 9 ct 
+1745 9 1715 2 1688 -12 ct 1661 -27 1640 -49 1626 -78 ct 1611 -106 1604 -139 1604 -176 ct 
+1604 -224 1615 -270 1638 -315 ct 1660 -360 1689 -394 1724 -416 ct 1759 -438 1797 -449 1838 -449 ct 
+1891 -449 1933 -432 1964 -400 ct 1995 -367 2011 -323 2011 -267 ct 2011 -245 2009 -223 2005 -201 ct 
+1682 -201 l  1681 -192 1680 -184 1680 -177 ct 1680 -136 1689 -105 1708 -83 ct 
+1727 -62 1750 -51 1778 -51 ct 1803 -51 1829 -59 1853 -76 ct 1878 -93 l  1897 -117 l 
+p
+1694 -258 m  1940 -258 l  1940 -265 1941 -271 1941 -274 ct 1941 -312 1931 -340 1912 -360 ct 
+1894 -380 1870 -390 1840 -390 ct 1808 -390 1779 -379 1753 -357 ct 1726 -335 l 
+1707 -302 l  p ef
+pom
+pum
+20214 6324 t
+35 0 m  162 -606 l  243 -606 l  190 -354 l  504 -354 l  557 -606 l  638 -606 l 
+512 0 l  430 0 l  490 -285 l  176 -285 l  116 0 l  p ef
+959 -149 m  1032 -141 l  1022 -105 997 -71 960 -38 ct 922 -6 877 9 825 9 ct 
+793 9 763 2 736 -12 ct 709 -27 688 -49 674 -78 ct 659 -106 652 -139 652 -176 ct 
+652 -224 663 -270 686 -315 ct 708 -360 737 -394 772 -416 ct 807 -438 845 -449 886 -449 ct 
+939 -449 981 -432 1012 -400 ct 1043 -367 1059 -323 1059 -267 ct 1059 -245 1057 -223 1053 -201 ct 
+730 -201 l  729 -192 728 -184 728 -177 ct 728 -136 737 -105 756 -83 ct 775 -62 798 -51 826 -51 ct 
+851 -51 877 -59 901 -76 ct 926 -93 l  945 -117 l  p
+742 -258 m  988 -258 l  988 -265 989 -271 989 -274 ct 989 -312 979 -340 960 -360 ct 
+942 -380 918 -390 888 -390 ct 856 -390 827 -379 801 -357 ct 774 -335 l  755 -302 l 
+p ef
+1113 0 m  1204 -439 l  1271 -439 l  1252 -349 l  1275 -383 1297 -408 1318 -424 ct 
+1340 -441 1362 -449 1385 -449 ct 1400 -449 1418 -443 1440 -433 ct 1409 -363 l 
+1396 -372 1382 -377 1367 -377 ct 1340 -377 1313 -362 1286 -333 ct 1258 -304 1237 -252 1221 -176 ct 
+1184 0 l  p ef
+1726 -149 m  1799 -141 l  1789 -105 1764 -71 1727 -38 ct 1689 -6 1644 9 1592 9 ct 
+1560 9 1530 2 1503 -12 ct 1476 -27 1455 -49 1441 -78 ct 1426 -106 1419 -139 1419 -176 ct 
+1419 -224 1430 -270 1453 -315 ct 1475 -360 1504 -394 1539 -416 ct 1574 -438 1612 -449 1653 -449 ct 
+1706 -449 1748 -432 1779 -400 ct 1810 -367 1826 -323 1826 -267 ct 1826 -245 1824 -223 1820 -201 ct 
+1497 -201 l  1496 -192 1495 -184 1495 -177 ct 1495 -136 1504 -105 1523 -83 ct 
+1542 -62 1565 -51 1593 -51 ct 1618 -51 1644 -59 1668 -76 ct 1693 -93 l  1712 -117 l 
+p
+1509 -258 m  1755 -258 l  1755 -265 1756 -271 1756 -274 ct 1756 -312 1746 -340 1727 -360 ct 
+1709 -380 1685 -390 1655 -390 ct 1623 -390 1594 -379 1568 -357 ct 1541 -335 l 
+1522 -302 l  p ef
+1946 -153 m  1992 -482 l  2018 -606 l  2109 -606 l  2081 -471 l  1993 -153 l 
+p
+1899 0 m  1917 -84 l  2001 -84 l  1983 0 l  p ef
+pom
+gr
+5715 5080 m  5264 4930 l  5265 5230 l  5715 5080 l  p ef
+1 lw 0 lj 3175 5080 m  5355 5080 l  ps
+12565 5080 m  12114 4930 l  12115 5230 l  12565 5080 l  p ef
+10795 5080 m  12205 5080 l  ps
+19050 5080 m  18599 4930 l  18600 5230 l  19050 5080 l  p ef
+16375 5080 m  18690 5080 l  ps
+gs
+pum
+10425 8413 t
+66 0 m  66 -606 l  335 -606 l  389 -606 430 -600 458 -589 ct 486 -579 509 -559 526 -532 ct 
+542 -504 551 -474 551 -440 ct 551 -397 537 -361 509 -332 ct 481 -302 438 -283 380 -275 ct 
+401 -265 417 -255 428 -245 ct 452 -224 474 -197 495 -165 ct 600 0 l  500 0 l 
+419 -126 l  396 -162 377 -190 361 -209 ct 346 -228 333 -242 321 -250 ct 309 -257 296 -263 284 -266 ct 
+275 -268 260 -269 239 -269 ct 146 -269 l  146 0 l  p
+146 -338 m  319 -338 l  355 -338 384 -342 405 -350 ct 425 -357 441 -369 452 -386 ct 
+463 -403 468 -421 468 -440 ct 468 -469 458 -493 437 -511 ct 416 -530 383 -539 338 -539 ct 
+146 -539 l  p ef
+965 -141 m  1042 -131 l  1030 -86 1007 -52 975 -27 ct 942 -2 900 9 849 9 ct 
+785 9 734 -9 696 -49 ct 658 -88 640 -144 640 -215 ct 640 -289 659 -347 697 -387 ct 
+735 -428 784 -449 845 -449 ct 903 -449 951 -429 989 -389 ct 1026 -349 1044 -292 1044 -220 ct 
+1044 -216 1044 -209 1044 -200 ct 716 -200 l  719 -152 733 -115 757 -89 ct 782 -64 813 -51 849 -51 ct 
+877 -51 900 -58 919 -72 ct 938 -87 l  954 -110 l  p
+721 -261 m  966 -261 l  963 -298 953 -326 938 -344 ct 914 -373 883 -387 845 -387 ct 
+811 -387 783 -376 759 -353 ct 736 -330 l  723 -300 l  p ef
+1427 -160 m  1500 -151 l  1492 -100 1472 -61 1439 -32 ct 1406 -4 1365 9 1317 9 ct 
+1257 9 1209 -9 1172 -49 ct 1136 -88 1118 -144 1118 -217 ct 1118 -265 1125 -306 1141 -342 ct 
+1157 -378 1181 -404 1213 -422 ct 1245 -440 1280 -449 1318 -449 ct 1365 -449 1404 -437 1435 -412 ct 
+1465 -388 1485 -354 1493 -310 ct 1421 -299 l  1414 -328 1402 -350 1384 -365 ct 
+1367 -380 1345 -387 1321 -387 ct 1283 -387 1253 -374 1229 -347 ct 1206 -320 1194 -278 1194 -220 ct 
+1194 -161 1205 -118 1228 -91 ct 1251 -64 1280 -51 1317 -51 ct 1346 -51 1370 -60 1390 -78 ct 
+1409 -96 l  1422 -123 l  p ef
+1864 -141 m  1941 -131 l  1929 -86 1906 -52 1874 -27 ct 1841 -2 1799 9 1748 9 ct 
+1684 9 1633 -9 1595 -49 ct 1557 -88 1539 -144 1539 -215 ct 1539 -289 1558 -347 1596 -387 ct 
+1634 -428 1683 -449 1744 -449 ct 1802 -449 1850 -429 1888 -389 ct 1925 -349 1943 -292 1943 -220 ct 
+1943 -216 1943 -209 1943 -200 ct 1615 -200 l  1618 -152 1632 -115 1656 -89 ct 
+1681 -64 1712 -51 1748 -51 ct 1776 -51 1799 -58 1818 -72 ct 1837 -87 l  1853 -110 l 
+p
+1620 -261 m  1865 -261 l  1862 -298 1852 -326 1837 -344 ct 1813 -373 1782 -387 1744 -387 ct 
+1710 -387 1682 -376 1658 -353 ct 1635 -330 l  1622 -300 l  p ef
+2040 -520 m  2040 -606 l  2114 -606 l  2114 -520 l  p
+2040 0 m  2040 -439 l  2114 -439 l  2114 0 l  p ef
+2347 0 m  2180 -439 l  2259 -439 l  2353 -176 l  2363 -147 2373 -118 2381 -87 ct 
+2388 -110 2397 -138 2409 -171 ct 2507 -439 l  2583 -439 l  2417 0 l  p ef
+2949 -141 m  3026 -131 l  3014 -86 2991 -52 2959 -27 ct 2926 -2 2884 9 2833 9 ct 
+2769 9 2718 -9 2680 -49 ct 2642 -88 2624 -144 2624 -215 ct 2624 -289 2643 -347 2681 -387 ct 
+2719 -428 2768 -449 2829 -449 ct 2887 -449 2935 -429 2973 -389 ct 3010 -349 3028 -292 3028 -220 ct 
+3028 -216 3028 -209 3028 -200 ct 2700 -200 l  2703 -152 2717 -115 2741 -89 ct 
+2766 -64 2797 -51 2833 -51 ct 2861 -51 2884 -58 2903 -72 ct 2922 -87 l  2938 -110 l 
+p
+2705 -261 m  2950 -261 l  2947 -298 2937 -326 2922 -344 ct 2898 -373 2867 -387 2829 -387 ct 
+2795 -387 2767 -376 2743 -353 ct 2720 -330 l  2707 -300 l  p ef
+3372 0 m  3372 -606 l  3601 -606 l  3641 -606 3672 -604 3693 -600 ct 3723 -595 3748 -586 3768 -572 ct 
+3788 -558 3804 -538 3816 -513 ct 3829 -488 3835 -461 3835 -430 ct 3835 -379 3818 -335 3785 -300 ct 
+3753 -264 3693 -246 3608 -246 ct 3452 -246 l  3452 0 l  p
+3452 -318 m  3609 -318 l  3661 -318 3697 -327 3719 -346 ct 3741 -366 3752 -393 3752 -428 ct 
+3752 -453 3746 -475 3733 -493 ct 3720 -511 3703 -523 3682 -529 ct 3669 -532 3644 -534 3607 -534 ct 
+3452 -534 l  p ef
+4205 -54 m  4177 -30 4151 -14 4125 -4 ct 4100 5 4072 9 4043 9 ct 3995 9 3958 -1 3932 -25 ct 
+3906 -49 3893 -79 3893 -115 ct 3893 -137 3898 -156 3908 -174 ct 3918 -192 3930 -206 3946 -217 ct 
+3962 -228 3980 -236 4000 -241 ct 4014 -245 4036 -249 4066 -253 ct 4126 -260 4170 -268 4199 -278 ct 
+4199 -288 4199 -295 4199 -298 ct 4199 -328 4192 -349 4178 -362 ct 4159 -379 4131 -387 4093 -387 ct 
+4058 -387 4032 -381 4016 -369 ct 3999 -356 3987 -335 3979 -303 ct 3906 -313 l 
+3913 -345 3923 -370 3939 -389 ct 3954 -408 3976 -423 4004 -433 ct 4033 -443 4066 -449 4104 -449 ct 
+4142 -449 4172 -444 4195 -435 ct 4219 -427 4236 -415 4247 -402 ct 4258 -389 4266 -372 4270 -351 ct 
+4273 -339 4274 -316 4274 -283 ct 4274 -184 l  4274 -114 4276 -71 4279 -52 ct 
+4282 -34 4288 -16 4298 0 ct 4220 0 l  4212 -15 l  4207 -33 l  p
+4199 -220 m  4172 -209 4131 -200 4077 -192 ct 4047 -187 4025 -182 4012 -177 ct 
+4000 -171 3990 -163 3983 -153 ct 3976 -142 3973 -130 3973 -117 ct 3973 -98 3980 -81 3995 -68 ct 
+4010 -55 4032 -48 4061 -48 ct 4090 -48 4115 -54 4138 -67 ct 4160 -79 4176 -96 4187 -118 ct 
+4195 -135 4199 -160 4199 -193 ct p ef
+4531 -66 m  4542 0 l  4521 3 4502 5 4485 5 ct 4458 5 4437 1 4423 -7 ct 4408 -15 4397 -26 4391 -40 ct 
+4385 -54 4382 -83 4382 -128 ct 4382 -381 l  4327 -381 l  4327 -439 l  4382 -439 l 
+4382 -547 l  4456 -592 l  4456 -439 l  4531 -439 l  4531 -381 l  4456 -381 l 
+4456 -124 l  4456 -103 4457 -89 4460 -83 ct 4463 -77 4467 -72 4473 -69 ct 4479 -65 4487 -63 4498 -63 ct 
+4506 -63 l  4517 -64 l  p ef
+4606 0 m  4606 -606 l  4681 -606 l  4681 -388 l  4716 -429 4759 -449 4812 -449 ct 
+4845 -449 4873 -442 4897 -429 ct 4921 -417 4938 -399 4949 -376 ct 4959 -354 4964 -321 4964 -278 ct 
+4964 0 l  4890 0 l  4890 -278 l  4890 -315 4882 -342 4865 -359 ct 4849 -376 4827 -385 4797 -385 ct 
+4775 -385 4754 -379 4735 -367 ct 4715 -356 4701 -340 4693 -321 ct 4685 -301 4681 -274 4681 -240 ct 
+4681 0 l  p ef
+pom
+gr
+0 lw 1 lj 1905 12030 m  3175 13935 l  ps
+3175 13935 m  4445 12030 l  ps
+3175 12030 m  3175 15205 l  ps
+0.996 c 12565 15205 m  13835 13935 l  16375 13935 l  16375 16475 l  13835 16475 l 
+12565 15205 l  p ef
+0.000 c 12565 15205 m  13835 13935 l  16375 13935 l  16375 16475 l  13835 16475 l 
+12565 15205 l  pc
+gs
+pum
+13573 15504 t
+65 0 m  65 -606 l  274 -606 l  321 -606 357 -603 382 -597 ct 416 -589 446 -575 471 -554 ct 
+503 -527 526 -492 542 -450 ct 558 -408 566 -360 566 -306 ct 566 -260 561 -219 550 -184 ct 
+539 -148 525 -119 509 -95 ct 492 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+353 -3 320 0 284 0 ct p
+145 -71 m  275 -71 l  315 -71 346 -75 369 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 457 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -371 473 -419 452 -453 ct 
+431 -487 406 -510 376 -522 ct 355 -530 320 -534 272 -534 ct 145 -534 l  p ef
+608 0 m  840 -606 l  927 -606 l  1175 0 l  1083 0 l  1013 -183 l  759 -183 l 
+692 0 l  p
+782 -248 m  988 -248 l  924 -416 l  905 -467 891 -509 881 -542 ct 874 -503 863 -465 849 -426 ct 
+p ef
+1661 -212 m  1742 -192 l  1725 -126 1695 -76 1651 -41 ct 1607 -6 1554 10 1491 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -555 1345 -580 ct 1389 -604 1438 -616 1492 -616 ct 
+1553 -616 1604 -601 1645 -570 ct 1686 -539 1715 -496 1731 -440 ct 1652 -421 l 
+1638 -465 1618 -497 1591 -517 ct 1564 -537 1531 -547 1490 -547 ct 1444 -547 1405 -536 1373 -514 ct 
+1342 -492 1320 -462 1307 -424 ct 1295 -386 1288 -348 1288 -308 ct 1288 -256 1296 -211 1311 -173 ct 
+1326 -134 1349 -105 1381 -86 ct 1413 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -123 l  1650 -161 l  p ef
+pom
+gr
+8255 16475 m  5715 16475 l  5715 13935 l  10795 13935 l  10795 16475 l 
+8255 16475 l  pc
+gs
+pum
+6708 15028 t
+3 0 m  238 -315 l  31 -606 l  126 -606 l  236 -450 l  259 -418 276 -393 285 -376 ct 
+299 -398 315 -421 333 -445 ct 455 -606 l  543 -606 l  330 -320 l  559 0 l 
+460 0 l  307 -216 l  299 -228 290 -242 281 -256 ct 267 -234 258 -219 252 -211 ct 
+100 0 l  p ef
+611 0 m  611 -439 l  678 -439 l  678 -377 l  692 -399 710 -416 733 -429 ct 
+756 -442 782 -449 811 -449 ct 844 -449 870 -442 891 -428 ct 912 -415 927 -396 935 -372 ct 
+970 -423 1015 -449 1071 -449 ct 1114 -449 1148 -437 1171 -412 ct 1195 -388 1206 -351 1206 -301 ct 
+1206 0 l  1132 0 l  1132 -276 l  1132 -306 1130 -327 1125 -340 ct 1120 -354 1112 -364 1099 -372 ct 
+1086 -380 1071 -384 1054 -384 ct 1023 -384 998 -374 977 -353 ct 957 -333 947 -300 947 -255 ct 
+947 0 l  872 0 l  872 -285 l  872 -318 866 -343 854 -359 ct 842 -376 822 -384 795 -384 ct 
+774 -384 754 -379 736 -368 ct 719 -357 706 -340 698 -319 ct 690 -298 686 -267 686 -227 ct 
+686 0 l  p ef
+1326 -520 m  1326 -606 l  1400 -606 l  1400 -520 l  p
+1326 0 m  1326 -439 l  1400 -439 l  1400 0 l  p ef
+1673 -66 m  1684 0 l  1663 3 1644 5 1627 5 ct 1600 5 1579 1 1565 -7 ct 1550 -15 1539 -26 1533 -40 ct 
+1527 -54 1524 -83 1524 -128 ct 1524 -381 l  1469 -381 l  1469 -439 l  1524 -439 l 
+1524 -547 l  1598 -592 l  1598 -439 l  1673 -439 l  1673 -381 l  1598 -381 l 
+1598 -124 l  1598 -103 1599 -89 1602 -83 ct 1605 -77 1609 -72 1615 -69 ct 1621 -65 1629 -63 1640 -63 ct 
+1648 -63 l  1659 -64 l  p ef
+1997 0 m  1997 -606 l  2266 -606 l  2320 -606 2361 -600 2389 -589 ct 2417 -579 2440 -559 2457 -532 ct 
+2473 -504 2482 -474 2482 -440 ct 2482 -397 2468 -361 2440 -332 ct 2412 -302 2369 -283 2311 -275 ct 
+2332 -265 2348 -255 2359 -245 ct 2383 -224 2405 -197 2426 -165 ct 2531 0 l  2431 0 l 
+2350 -126 l  2327 -162 2308 -190 2292 -209 ct 2277 -228 2264 -242 2252 -250 ct 
+2240 -257 2227 -263 2215 -266 ct 2206 -268 2191 -269 2170 -269 ct 2077 -269 l 
+2077 0 l  p
+2077 -338 m  2250 -338 l  2286 -338 2315 -342 2336 -350 ct 2356 -357 2372 -369 2383 -386 ct 
+2394 -403 2399 -421 2399 -440 ct 2399 -469 2389 -493 2368 -511 ct 2347 -530 2314 -539 2269 -539 ct 
+2077 -539 l  p ef
+2609 0 m  2609 -606 l  3018 -606 l  3018 -534 l  2689 -534 l  2689 -346 l 
+2974 -346 l  2974 -275 l  2689 -275 l  2689 0 l  p ef
+pom
+pum
+6350 15981 t
+69 0 m  69 -606 l  478 -606 l  478 -534 l  149 -534 l  149 -346 l  434 -346 l 
+434 -275 l  149 -275 l  149 0 l  p ef
+584 0 m  584 -439 l  651 -439 l  651 -372 l  668 -403 683 -424 698 -434 ct 
+712 -444 728 -449 746 -449 ct 771 -449 796 -441 822 -425 ct 797 -356 l  778 -366 760 -372 742 -372 ct 
+726 -372 711 -367 698 -357 ct 685 -347 676 -334 670 -316 ct 662 -290 658 -261 658 -229 ct 
+658 0 l  p ef
+848 -219 m  848 -300 870 -361 915 -400 ct 953 -432 999 -449 1054 -449 ct 1114 -449 1163 -429 1202 -389 ct 
+1240 -350 1259 -295 1259 -225 ct 1259 -169 1251 -124 1234 -92 ct 1217 -60 1192 -34 1160 -16 ct 
+1127 0 1092 9 1054 9 ct 992 9 942 -9 904 -49 ct 867 -88 l  848 -145 l  p
+924 -219 m  924 -163 936 -121 961 -93 ct 985 -65 1016 -51 1054 -51 ct 1091 -51 1121 -65 1146 -93 ct 
+1170 -121 1183 -164 1183 -222 ct 1183 -276 1170 -317 1146 -345 ct 1121 -373 1090 -387 1054 -387 ct 
+1016 -387 985 -373 961 -345 ct 936 -317 l  924 -275 l  p ef
+1351 0 m  1351 -439 l  1418 -439 l  1418 -376 l  1451 -425 1497 -449 1558 -449 ct 
+1585 -449 1609 -444 1631 -434 ct 1653 -425 1670 -412 1681 -397 ct 1692 -382 1700 -363 1704 -342 ct 
+1707 -328 1708 -304 1708 -270 ct 1708 0 l  1634 0 l  1634 -267 l  1634 -297 1631 -320 1625 -335 ct 
+1619 -350 1609 -362 1594 -371 ct 1580 -380 1562 -384 1542 -384 ct 1511 -384 1483 -374 1460 -354 ct 
+1437 -334 1426 -296 1426 -239 ct 1426 0 l  p ef
+1991 -66 m  2002 0 l  1981 3 1962 5 1945 5 ct 1918 5 1897 1 1883 -7 ct 1868 -15 1857 -26 1851 -40 ct 
+1845 -54 1842 -83 1842 -128 ct 1842 -381 l  1787 -381 l  1787 -439 l  1842 -439 l 
+1842 -547 l  1916 -592 l  1916 -439 l  1991 -439 l  1991 -381 l  1916 -381 l 
+1916 -124 l  1916 -103 1917 -89 1920 -83 ct 1923 -77 1927 -72 1933 -69 ct 1939 -65 1947 -63 1958 -63 ct 
+1966 -63 l  1977 -64 l  p ef
+2316 0 m  2316 -606 l  2754 -606 l  2754 -534 l  2396 -534 l  2396 -349 l 
+2731 -349 l  2731 -277 l  2396 -277 l  2396 -71 l  2768 -71 l  2768 0 l 
+p ef
+2886 0 m  2886 -439 l  2953 -439 l  2953 -376 l  2986 -425 3032 -449 3093 -449 ct 
+3120 -449 3144 -444 3166 -434 ct 3188 -425 3205 -412 3216 -397 ct 3227 -382 3235 -363 3239 -342 ct 
+3242 -328 3243 -304 3243 -270 ct 3243 0 l  3169 0 l  3169 -267 l  3169 -297 3166 -320 3160 -335 ct 
+3154 -350 3144 -362 3129 -371 ct 3115 -380 3097 -384 3077 -384 ct 3046 -384 3018 -374 2995 -354 ct 
+2972 -334 2961 -296 2961 -239 ct 2961 0 l  p ef
+3647 0 m  3647 -55 l  3619 -11 3579 9 3524 9 ct 3489 9 3457 0 3428 -19 ct 3399 -38 3376 -65 3360 -99 ct 
+3344 -134 3335 -174 3335 -219 ct 3335 -263 3343 -302 3357 -338 ct 3372 -374 3394 -401 3423 -420 ct 
+3452 -439 3485 -449 3521 -449 ct 3548 -449 3571 -443 3592 -432 ct 3613 -421 3629 -406 3642 -388 ct 
+3642 -606 l  3716 -606 l  3716 0 l  p
+3412 -219 m  3412 -162 3424 -120 3448 -93 ct 3471 -65 3499 -51 3531 -51 ct 3564 -51 3592 -64 3614 -91 ct 
+3637 -117 3649 -158 3649 -212 ct 3649 -273 3637 -317 3614 -345 ct 3591 -373 3562 -387 3528 -387 ct 
+3495 -387 3467 -374 3445 -346 ct 3423 -319 l  3412 -277 l  p ef
+pom
+gr
+21272 17745 m  19550 17745 l  19274 17745 19050 17521 19050 17245 ct 19050 13165 l 
+19050 12889 19274 12665 19550 12665 ct 22995 12665 l  23271 12665 23495 12889 23495 13165 ct 
+23495 17245 l  23495 17521 23271 17745 22995 17745 ct 21272 17745 l  pc
+gs
+pum
+20360 14552 t
+236 0 m  285 -234 l  98 -606 l  185 -606 l  275 -429 l  294 -390 313 -349 332 -305 ct 
+352 -342 380 -383 415 -428 ct 557 -606 l  654 -606 l  365 -228 l  317 0 l 
+p ef
+597 -166 m  597 -252 622 -323 673 -379 ct 714 -425 769 -449 836 -449 ct 889 -449 932 -432 964 -399 ct 
+997 -366 1013 -321 1013 -265 ct 1013 -215 1003 -168 982 -124 ct 962 -81 933 -47 895 -24 ct 
+858 -1 818 9 776 9 ct 742 9 711 2 683 -11 ct 655 -26 634 -47 619 -74 ct 604 -100 l 
+597 -131 l  p
+672 -174 m  672 -132 682 -101 701 -80 ct 721 -58 747 -47 777 -47 ct 793 -47 809 -51 825 -57 ct 
+840 -64 855 -74 869 -87 ct 882 -100 894 -115 903 -132 ct 913 -149 920 -167 926 -187 ct 
+935 -214 939 -240 939 -265 ct 939 -305 929 -336 909 -358 ct 889 -380 864 -391 833 -391 ct 
+810 -391 789 -385 769 -374 ct 750 -363 733 -346 717 -325 ct 701 -303 690 -278 683 -250 ct 
+675 -221 l  672 -196 l  p ef
+1359 -79 m  1307 -19 1253 9 1198 9 ct 1164 9 1136 0 1116 -19 ct 1095 -38 1084 -62 1084 -90 ct 
+1084 -109 1089 -140 1099 -185 ct 1151 -439 l  1226 -439 l  1168 -158 l  1163 -134 1160 -116 1160 -103 ct 
+1160 -87 1165 -74 1175 -65 ct 1185 -55 1200 -51 1220 -51 ct 1241 -51 1261 -56 1281 -66 ct 
+1301 -76 1318 -90 1333 -107 ct 1347 -125 1359 -145 1368 -169 ct 1374 -184 1381 -211 1389 -249 ct 
+1429 -439 l  1504 -439 l  1412 0 l  1343 0 l  p ef
+1536 0 m  1627 -439 l  1694 -439 l  1675 -349 l  1698 -383 1720 -408 1741 -424 ct 
+1763 -441 1785 -449 1808 -449 ct 1823 -449 1841 -443 1863 -433 ct 1832 -363 l 
+1819 -372 1805 -377 1790 -377 ct 1763 -377 1736 -362 1709 -333 ct 1681 -304 1660 -252 1644 -176 ct 
+1607 0 l  p ef
+pom
+pum
+20241 15505 t
+510 -213 m  591 -202 l  565 -132 528 -79 480 -43 ct 431 -7 377 10 316 10 ct 
+243 10 184 -12 141 -57 ct 98 -102 76 -166 76 -250 ct 76 -359 109 -449 175 -521 ct 
+233 -584 306 -616 393 -616 ct 457 -616 509 -599 549 -564 ct 589 -530 612 -484 618 -425 ct 
+543 -418 l  535 -462 518 -495 493 -517 ct 468 -538 436 -549 397 -549 ct 322 -549 262 -516 217 -450 ct 
+177 -394 157 -326 157 -248 ct 157 -186 172 -138 203 -105 ct 234 -73 273 -56 323 -56 ct 
+364 -56 402 -70 436 -97 ct 470 -124 l  495 -163 l  p ef
+650 -166 m  650 -252 675 -323 726 -379 ct 767 -425 822 -449 889 -449 ct 942 -449 985 -432 1017 -399 ct 
+1050 -366 1066 -321 1066 -265 ct 1066 -215 1056 -168 1035 -124 ct 1015 -81 986 -47 948 -24 ct 
+911 -1 871 9 829 9 ct 795 9 764 2 736 -11 ct 708 -26 687 -47 672 -74 ct 657 -100 l 
+650 -131 l  p
+725 -174 m  725 -132 735 -101 754 -80 ct 774 -58 800 -47 830 -47 ct 846 -47 862 -51 878 -57 ct 
+893 -64 908 -74 922 -87 ct 935 -100 947 -115 956 -132 ct 966 -149 973 -167 979 -187 ct 
+988 -214 992 -240 992 -265 ct 992 -305 982 -336 962 -358 ct 942 -380 917 -391 886 -391 ct 
+863 -391 842 -385 822 -374 ct 803 -363 786 -346 770 -325 ct 754 -303 743 -278 736 -250 ct 
+728 -221 l  725 -196 l  p ef
+1409 -63 m  1366 -14 1321 9 1275 9 ct 1233 9 1198 -5 1171 -36 ct 1143 -66 1129 -111 1129 -169 ct 
+1129 -223 1140 -272 1162 -316 ct 1184 -360 1211 -394 1244 -416 ct 1277 -438 1310 -449 1343 -449 ct 
+1398 -449 1439 -422 1467 -370 ct 1517 -606 l  1591 -606 l  1465 0 l  1396 0 l 
+p
+1204 -184 m  1204 -153 1207 -129 1213 -111 ct 1219 -94 1229 -79 1244 -67 ct 
+1258 -55 1276 -50 1296 -50 ct 1330 -50 1361 -67 1388 -102 ct 1425 -149 1444 -207 1444 -276 ct 
+1444 -311 1435 -338 1417 -358 ct 1398 -377 1376 -387 1348 -387 ct 1330 -387 1314 -383 1299 -375 ct 
+1284 -367 1270 -353 1255 -334 ct 1241 -315 1228 -291 1219 -261 ct 1209 -232 l 
+1204 -206 l  p ef
+1911 -149 m  1984 -141 l  1974 -105 1949 -71 1912 -38 ct 1874 -6 1829 9 1777 9 ct 
+1745 9 1715 2 1688 -12 ct 1661 -27 1640 -49 1626 -78 ct 1611 -106 1604 -139 1604 -176 ct 
+1604 -224 1615 -270 1638 -315 ct 1660 -360 1689 -394 1724 -416 ct 1759 -438 1797 -449 1838 -449 ct 
+1891 -449 1933 -432 1964 -400 ct 1995 -367 2011 -323 2011 -267 ct 2011 -245 2009 -223 2005 -201 ct 
+1682 -201 l  1681 -192 1680 -184 1680 -177 ct 1680 -136 1689 -105 1708 -83 ct 
+1727 -62 1750 -51 1778 -51 ct 1803 -51 1829 -59 1853 -76 ct 1878 -93 l  1897 -117 l 
+p
+1694 -258 m  1940 -258 l  1940 -265 1941 -271 1941 -274 ct 1941 -312 1931 -340 1912 -360 ct 
+1894 -380 1870 -390 1840 -390 ct 1808 -390 1779 -379 1753 -357 ct 1726 -335 l 
+1707 -302 l  p ef
+pom
+pum
+20214 16458 t
+35 0 m  162 -606 l  243 -606 l  190 -354 l  504 -354 l  557 -606 l  638 -606 l 
+512 0 l  430 0 l  490 -285 l  176 -285 l  116 0 l  p ef
+959 -149 m  1032 -141 l  1022 -105 997 -71 960 -38 ct 922 -6 877 9 825 9 ct 
+793 9 763 2 736 -12 ct 709 -27 688 -49 674 -78 ct 659 -106 652 -139 652 -176 ct 
+652 -224 663 -270 686 -315 ct 708 -360 737 -394 772 -416 ct 807 -438 845 -449 886 -449 ct 
+939 -449 981 -432 1012 -400 ct 1043 -367 1059 -323 1059 -267 ct 1059 -245 1057 -223 1053 -201 ct 
+730 -201 l  729 -192 728 -184 728 -177 ct 728 -136 737 -105 756 -83 ct 775 -62 798 -51 826 -51 ct 
+851 -51 877 -59 901 -76 ct 926 -93 l  945 -117 l  p
+742 -258 m  988 -258 l  988 -265 989 -271 989 -274 ct 989 -312 979 -340 960 -360 ct 
+942 -380 918 -390 888 -390 ct 856 -390 827 -379 801 -357 ct 774 -335 l  755 -302 l 
+p ef
+1113 0 m  1204 -439 l  1271 -439 l  1252 -349 l  1275 -383 1297 -408 1318 -424 ct 
+1340 -441 1362 -449 1385 -449 ct 1400 -449 1418 -443 1440 -433 ct 1409 -363 l 
+1396 -372 1382 -377 1367 -377 ct 1340 -377 1313 -362 1286 -333 ct 1258 -304 1237 -252 1221 -176 ct 
+1184 0 l  p ef
+1726 -149 m  1799 -141 l  1789 -105 1764 -71 1727 -38 ct 1689 -6 1644 9 1592 9 ct 
+1560 9 1530 2 1503 -12 ct 1476 -27 1455 -49 1441 -78 ct 1426 -106 1419 -139 1419 -176 ct 
+1419 -224 1430 -270 1453 -315 ct 1475 -360 1504 -394 1539 -416 ct 1574 -438 1612 -449 1653 -449 ct 
+1706 -449 1748 -432 1779 -400 ct 1810 -367 1826 -323 1826 -267 ct 1826 -245 1824 -223 1820 -201 ct 
+1497 -201 l  1496 -192 1495 -184 1495 -177 ct 1495 -136 1504 -105 1523 -83 ct 
+1542 -62 1565 -51 1593 -51 ct 1618 -51 1644 -59 1668 -76 ct 1693 -93 l  1712 -117 l 
+p
+1509 -258 m  1755 -258 l  1755 -265 1756 -271 1756 -274 ct 1756 -312 1746 -340 1727 -360 ct 
+1709 -380 1685 -390 1655 -390 ct 1623 -390 1594 -379 1568 -357 ct 1541 -335 l 
+1522 -302 l  p ef
+1946 -153 m  1992 -482 l  2018 -606 l  2109 -606 l  2081 -471 l  1993 -153 l 
+p
+1899 0 m  1917 -84 l  2001 -84 l  1983 0 l  p ef
+pom
+gr
+3175 15240 m  3625 15389 l  3624 15089 l  3175 15240 l  p ef
+1 lw 0 lj 5715 15240 m  3535 15240 l  ps
+10795 15240 m  11245 15389 l  11244 15089 l  10795 15240 l  p ef
+12565 15240 m  11155 15240 l  ps
+16510 15240 m  16960 15389 l  16959 15089 l  16510 15240 l  p ef
+19050 15240 m  16870 15240 l  ps
+gs
+pum
+10319 18547 t
+219 0 m  219 -534 l  19 -534 l  19 -606 l  500 -606 l  500 -534 l  299 -534 l 
+299 0 l  p ef
+584 0 m  584 -439 l  651 -439 l  651 -372 l  668 -403 683 -424 698 -434 ct 
+712 -444 728 -449 746 -449 ct 771 -449 796 -441 822 -425 ct 797 -356 l  778 -366 760 -372 742 -372 ct 
+726 -372 711 -367 698 -357 ct 685 -347 676 -334 670 -316 ct 662 -290 658 -261 658 -229 ct 
+658 0 l  p ef
+1162 -54 m  1134 -30 1108 -14 1082 -4 ct 1057 5 1029 9 1000 9 ct 952 9 915 -1 889 -25 ct 
+863 -49 850 -79 850 -115 ct 850 -137 855 -156 865 -174 ct 875 -192 887 -206 903 -217 ct 
+919 -228 937 -236 957 -241 ct 971 -245 993 -249 1023 -253 ct 1083 -260 1127 -268 1156 -278 ct 
+1156 -288 1156 -295 1156 -298 ct 1156 -328 1149 -349 1135 -362 ct 1116 -379 1088 -387 1050 -387 ct 
+1015 -387 989 -381 973 -369 ct 956 -356 944 -335 936 -303 ct 863 -313 l  870 -345 880 -370 896 -389 ct 
+911 -408 933 -423 961 -433 ct 990 -443 1023 -449 1061 -449 ct 1099 -449 1129 -444 1152 -435 ct 
+1176 -427 1193 -415 1204 -402 ct 1215 -389 1223 -372 1227 -351 ct 1230 -339 1231 -316 1231 -283 ct 
+1231 -184 l  1231 -114 1233 -71 1236 -52 ct 1239 -34 1245 -16 1255 0 ct 1177 0 l 
+1169 -15 l  1164 -33 l  p
+1156 -220 m  1129 -209 1088 -200 1034 -192 ct 1004 -187 982 -182 969 -177 ct 
+957 -171 947 -163 940 -153 ct 933 -142 930 -130 930 -117 ct 930 -98 937 -81 952 -68 ct 
+967 -55 989 -48 1018 -48 ct 1047 -48 1072 -54 1095 -67 ct 1117 -79 1133 -96 1144 -118 ct 
+1152 -135 1156 -160 1156 -193 ct p ef
+1325 0 m  1325 -439 l  1392 -439 l  1392 -376 l  1425 -425 1471 -449 1532 -449 ct 
+1559 -449 1583 -444 1605 -434 ct 1627 -425 1644 -412 1655 -397 ct 1666 -382 1674 -363 1678 -342 ct 
+1681 -328 1682 -304 1682 -270 ct 1682 0 l  1608 0 l  1608 -267 l  1608 -297 1605 -320 1599 -335 ct 
+1593 -350 1583 -362 1568 -371 ct 1554 -380 1536 -384 1516 -384 ct 1485 -384 1457 -374 1434 -354 ct 
+1411 -334 1400 -296 1400 -239 ct 1400 0 l  p ef
+1772 -131 m  1845 -142 l  1849 -113 1861 -90 1880 -74 ct 1899 -59 1925 -51 1959 -51 ct 
+1993 -51 2018 -58 2035 -72 ct 2052 -86 2060 -102 2060 -121 ct 2060 -138 2053 -151 2038 -160 ct 
+2028 -167 2002 -175 1962 -186 ct 1907 -199 1869 -211 1848 -221 ct 1827 -231 1811 -245 1800 -263 ct 
+1789 -281 1784 -301 1784 -322 ct 1784 -342 1788 -360 1797 -376 ct 1806 -393 1819 -407 1834 -418 ct 
+1846 -427 1861 -434 1881 -440 ct 1901 -446 1923 -449 1946 -449 ct 1980 -449 2010 -444 2036 -434 ct 
+2063 -424 2082 -410 2094 -393 ct 2107 -376 2115 -354 2120 -325 ct 2047 -315 l 
+2044 -338 2034 -356 2018 -368 ct 2002 -381 1980 -387 1951 -387 ct 1917 -387 1892 -382 1878 -370 ct 
+1863 -359 1856 -346 1856 -331 ct 1856 -321 1859 -312 1865 -305 ct 1871 -297 1881 -290 1894 -285 ct 
+1901 -282 1923 -276 1959 -266 ct 2012 -252 2049 -240 2070 -231 ct 2090 -222 2107 -209 2119 -192 ct 
+2130 -175 2136 -154 2136 -129 ct 2136 -104 2129 -80 2115 -58 ct 2100 -37 2079 -20 2052 -8 ct 
+2025 3 1994 9 1959 9 ct 1902 9 1859 -1 1829 -25 ct 1799 -49 l  1780 -84 l  p ef
+2198 0 m  2198 -439 l  2265 -439 l  2265 -377 l  2279 -399 2297 -416 2320 -429 ct 
+2343 -442 2369 -449 2398 -449 ct 2431 -449 2457 -442 2478 -428 ct 2499 -415 2514 -396 2522 -372 ct 
+2557 -423 2602 -449 2658 -449 ct 2701 -449 2735 -437 2758 -412 ct 2782 -388 2793 -351 2793 -301 ct 
+2793 0 l  2719 0 l  2719 -276 l  2719 -306 2717 -327 2712 -340 ct 2707 -354 2699 -364 2686 -372 ct 
+2673 -380 2658 -384 2641 -384 ct 2610 -384 2585 -374 2564 -353 ct 2544 -333 2534 -300 2534 -255 ct 
+2534 0 l  2459 0 l  2459 -285 l  2459 -318 2453 -343 2441 -359 ct 2429 -376 2409 -384 2382 -384 ct 
+2361 -384 2341 -379 2323 -368 ct 2306 -357 2293 -340 2285 -319 ct 2277 -298 2273 -267 2273 -227 ct 
+2273 0 l  p ef
+2914 -520 m  2914 -606 l  2988 -606 l  2988 -520 l  p
+2914 0 m  2914 -439 l  2988 -439 l  2988 0 l  p ef
+3261 -66 m  3272 0 l  3251 3 3232 5 3215 5 ct 3188 5 3167 1 3153 -7 ct 3138 -15 3127 -26 3121 -40 ct 
+3115 -54 3112 -83 3112 -128 ct 3112 -381 l  3057 -381 l  3057 -439 l  3112 -439 l 
+3112 -547 l  3186 -592 l  3186 -439 l  3261 -439 l  3261 -381 l  3186 -381 l 
+3186 -124 l  3186 -103 3187 -89 3190 -83 ct 3193 -77 3197 -72 3203 -69 ct 3209 -65 3217 -63 3228 -63 ct 
+3236 -63 l  3247 -64 l  p ef
+3584 0 m  3584 -606 l  3813 -606 l  3853 -606 3884 -604 3905 -600 ct 3935 -595 3960 -586 3980 -572 ct 
+4000 -558 4016 -538 4028 -513 ct 4041 -488 4047 -461 4047 -430 ct 4047 -379 4030 -335 3997 -300 ct 
+3965 -264 3905 -246 3820 -246 ct 3664 -246 l  3664 0 l  p
+3664 -318 m  3821 -318 l  3873 -318 3909 -327 3931 -346 ct 3953 -366 3964 -393 3964 -428 ct 
+3964 -453 3958 -475 3945 -493 ct 3932 -511 3915 -523 3894 -529 ct 3881 -532 3856 -534 3819 -534 ct 
+3664 -534 l  p ef
+4417 -54 m  4389 -30 4363 -14 4337 -4 ct 4312 5 4284 9 4255 9 ct 4207 9 4170 -1 4144 -25 ct 
+4118 -49 4105 -79 4105 -115 ct 4105 -137 4110 -156 4120 -174 ct 4130 -192 4142 -206 4158 -217 ct 
+4174 -228 4192 -236 4212 -241 ct 4226 -245 4248 -249 4278 -253 ct 4338 -260 4382 -268 4411 -278 ct 
+4411 -288 4411 -295 4411 -298 ct 4411 -328 4404 -349 4390 -362 ct 4371 -379 4343 -387 4305 -387 ct 
+4270 -387 4244 -381 4228 -369 ct 4211 -356 4199 -335 4191 -303 ct 4118 -313 l 
+4125 -345 4135 -370 4151 -389 ct 4166 -408 4188 -423 4216 -433 ct 4245 -443 4278 -449 4316 -449 ct 
+4354 -449 4384 -444 4407 -435 ct 4431 -427 4448 -415 4459 -402 ct 4470 -389 4478 -372 4482 -351 ct 
+4485 -339 4486 -316 4486 -283 ct 4486 -184 l  4486 -114 4488 -71 4491 -52 ct 
+4494 -34 4500 -16 4510 0 ct 4432 0 l  4424 -15 l  4419 -33 l  p
+4411 -220 m  4384 -209 4343 -200 4289 -192 ct 4259 -187 4237 -182 4224 -177 ct 
+4212 -171 4202 -163 4195 -153 ct 4188 -142 4185 -130 4185 -117 ct 4185 -98 4192 -81 4207 -68 ct 
+4222 -55 4244 -48 4273 -48 ct 4302 -48 4327 -54 4350 -67 ct 4372 -79 4388 -96 4399 -118 ct 
+4407 -135 4411 -160 4411 -193 ct p ef
+4742 -66 m  4753 0 l  4732 3 4713 5 4696 5 ct 4669 5 4648 1 4634 -7 ct 4619 -15 4608 -26 4602 -40 ct 
+4596 -54 4593 -83 4593 -128 ct 4593 -381 l  4538 -381 l  4538 -439 l  4593 -439 l 
+4593 -547 l  4667 -592 l  4667 -439 l  4742 -439 l  4742 -381 l  4667 -381 l 
+4667 -124 l  4667 -103 4668 -89 4671 -83 ct 4674 -77 4678 -72 4684 -69 ct 4690 -65 4698 -63 4709 -63 ct 
+4717 -63 l  4728 -64 l  p ef
+4818 0 m  4818 -606 l  4893 -606 l  4893 -388 l  4928 -429 4971 -449 5024 -449 ct 
+5057 -449 5085 -442 5109 -429 ct 5133 -417 5150 -399 5161 -376 ct 5171 -354 5176 -321 5176 -278 ct 
+5176 0 l  5102 0 l  5102 -278 l  5102 -315 5094 -342 5077 -359 ct 5061 -376 5039 -385 5009 -385 ct 
+4987 -385 4966 -379 4947 -367 ct 4927 -356 4913 -340 4905 -321 ct 4897 -301 4893 -274 4893 -240 ct 
+4893 0 l  p ef
+pom
+gr
+gr
+0 20290 t 
+pom
+count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore
+%%PageTrailer
+%%Trailer
+%%EOF
diff --git a/docs/exploring-gnuradio/swr-block-diagram.png b/docs/exploring-gnuradio/swr-block-diagram.png
new file mode 100644 (file)
index 0000000..580aa68
Binary files /dev/null and b/docs/exploring-gnuradio/swr-block-diagram.png differ
diff --git a/docs/exploring-gnuradio/usrp-block-diagram.eps b/docs/exploring-gnuradio/usrp-block-diagram.eps
new file mode 100644 (file)
index 0000000..190b9de
--- /dev/null
@@ -0,0 +1,2785 @@
+%!PS-Adobe-3.0 EPSF-3.0 
+%%BoundingBox: 0 0 755 575
+%%Pages: 0
+%%Creator: Sun Microsystems, Inc.
+%%Title: none
+%%CreationDate: none
+%%LanguageLevel: 2
+%%EndComments
+%%BeginPreview: 760 575 1 1725 
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000FFE300707800000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000FFE380E1FE00000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C001C0C30700000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C000E1830300000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C000E3820300000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C00077000300000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C0003E000300000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C0001C000700000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000FFC01C000E00000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000FFC03E001C00000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C00037003800000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C0006700F000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C000E381C000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C001C1C18000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C00180C30000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C00380E7FF00000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000C0070077FF00000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300701F80FF80007C00000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300707FE0FFE000FF00000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300706070C060018380000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000030070E038C030010180000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000030070C000C030030180000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000030070E000C030000180000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300707C00C070000380000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300703FC0FFE0000300000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000003007007E0FFC0000700000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000003007000F0FFF0000E00000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08000000300700038C030003C00000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000030071C018C038007000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000038061C018C01800E000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000018060E038C03801C000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000001C0E0F070C070018000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000FFC07FE0FFF003FF80000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800000007F001FC0FFC003FF80000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080007E00000000000000031800000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08001FF80000000300000031800000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800381C0000000300000031800000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800700C0000000300000031800000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800600E03808E07C8C0E03180E023000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800E0000FE0FF8FCFE3F83183F83F800000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800E0001C70F3C30FC71C31871C3F000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800C0003038E0C30E0E0E318E0E38000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800C0003018C0C30C0C06318C0630000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800C0007018C0C30C0C06318FFE30000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800C0007018C0C30C0C07318FFE30000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800E0067018C0C30C0C07318C0030000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800600E7018C0C30C0C06318C0030000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800700C3038C0C30C0C06318C0630000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0800381C3830C0C30C0E0E318E0E30000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%08001FF81FF0C0C3CC07FC3187FC30000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080007E00FC0C0C1CC01F03181F030000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%080000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000018000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000000
+%007FFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000000FFFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000010000
+%004000000000000000000000000000020000040000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000020000000000000000000
+%004000000000000000000000000000020000000000000000000020000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000040000000000000000000
+%004000000000000000000000000000020000000000000000000010000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000100000000000000000000
+%004000000000000000000000000000020000000000000000000004000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000200000000000000000000
+%004000000000000000000000000000020000000000000000000002000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000400000000000000000000
+%004000000000000000000000000000020000000000000000000001000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000800000000000000000000
+%004000000000000000000000000000020000000000000000000000800000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001000000000000000000000
+%004000000000000000000000000000020000000000000000000000400000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000002000000000000000000000
+%004000000000000000000000000000020000000000000000000000200000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000C000000000000000000000
+%004000000000000000000000000000020000000000000000000000180000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000010000000000000000000000
+%004000000000000000000000000000020000000000000000000000040000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000020000000000000000000000
+%004000000000000000000000000000020000000000000000000000020000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000040000000000000000000000
+%004000000000000000000000000000020000000000000000000000010000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000080000000000000000000000
+%004000000000000000000000000000020000000000000000000000008000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000100000000000000000000000
+%004000000000000000000000000000020000000000000000000000004000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000C00000000000000000000000
+%004000000000000000000000000000020000000000000000000000001800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000020001C03FF800FE0000000000
+%00400000000000000000000000000002000000000003C03FF001FE000200000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000040001E03FFC03FF8000000000
+%00400000000000000000000000000002000000000003C03FFC03FF000100000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000360300E07038000000000
+%00400000000000000000000000000002000000000003C0301C0703800000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040001000036030060601C000000000
+%0040000000000000000000000000000200000000000760300E0E01800040000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040002000073030070C00C000000000
+%004000000000000000000000000000020000000000066030060C01C00020000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040004000063030030C000000000000
+%004000000000000000000000000000020000000000067030071C00000010000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000063830031C000000000000
+%0040000000000000000000000000000200000000000C3030071800000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000E1830031C00000000FFFF
+%FFC0000000000000000000000000000200000000000C3030031800000001FFFF80000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400200000C1830031C00000000FFFF
+%FFC0000000000000000000000000000200000000001C1830031800000003FFFF80000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FF800000C1C30031C000000000000
+%00400000000000000000000000000003FFFFF800001C1830031800000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001FFC30030C000000000000
+%0040000000000000000000000000000200000000001FFC30071800000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001FFE30070C00C000000000
+%0040000000000000000000000000000200000000003FFC30061C00C00000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000380630070E00C000000000
+%004000000000000000000000000000020000000000300E30060C01C00000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400020003006300E0701C000000000
+%004000000000000000000000000000020000000000300E300E0E03800020000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400010003007301E07838000000000
+%0040000000000000000000000000000200000000006006301C0707800040000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000000070033FF801FF0000000000
+%00400000000000000000000000000002000000000060073FF803FE000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400004006003BFE0007C0000000000
+%004000000000000000000000000000020000000000E0033FE000FC000100000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400002000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000200000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000800000000000000000000000
+%004000000000000000000000000000020000000000000000000000000800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000400000000000000000000000
+%004000000000000000000000000000020000000000000000000000001000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000100000000000000000000000
+%004000000000000000000000000000020000000000000000000000004000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000003FF800000000003000000000000000000400000080000000000000000000000
+%00400000000000000000000000000002000000000000000000000000800000008000000000003F
+%F800000000003000000000000000000400
+%0008000000000003FFC00000000003000000000000000000400000040000000000000000000000
+%00400000000000000000000000000002000000000000000000000001000000008000000000003F
+%FC00000000003000000000000000000400
+%000800000000000300E00000000002000000000000000000400000020000000000000000000000
+%004000000000000000000000000000020000000000000000000000020000000080000000000038
+%0E00000000002000000000000000000400
+%000800000000000300600000000000000000000000000000400000018000000000000000000000
+%0040000000000000000000000000000200000000000000000000000C0000000080000000000030
+%0700000000000000000000000000000400
+%000800000000000300700000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000100000000080000000000030
+%0700000000000000000000000000000400
+%00080000000000030070FE03F03F0330187E000000000000400000002000000000000000000000
+%004000000000000000000000000000020000000000000000000000200000000080000000000030
+%0707E03F03F8338187F000000000000400
+%00080000000000030061EF073873833838E7000000000000400000001000000000000000000000
+%004000000000000000000000000000020000000000000000000000400000000080000000000030
+%070E7073873C31818E7800000000000400
+%000800000000000301E1830E1CE0C3183181800000000000400000000800000000000000000000
+%004000000000000000000000000000020000000000000000000000800000000080000000000038
+%1E1838E0CE0C31831C1800000000000400
+%0008000000000003FF83018C0CC0E3183181C00000000000400000000400000000000000000000
+%00400000000000000000000000000002000000000000000000000100000000008000000000003F
+%FC3018C0CC0631C3180C00000000000400
+%0008000000000003FE03019C01C0E30C6381C00000000000400000000200000000000000000000
+%00400000000000000000000000000002000000000000000000000200000000008000000000003F
+%F03018C00C0630C3181C00000000000400
+%00080000000000030703FF9C01FFE30C63FFC00000000000400000000100000000000000000000
+%004000000000000000000000000000020000000000000000000004000000000080000000000030
+%383FF8C00FFE30C61FFC00000000000400
+%00080000000000030383001C01C0030C6380000000000000400000000040000000000000000000
+%004000000000000000000000000000020000000000000000000010000000000080000000000030
+%183000C00C003066180000000000000400
+%000800000000000301C3001C01C00306C380000000000000400000000020000000000000000000
+%004000000000000000000000000000020000000000000000000020000000000080000000000030
+%1C3000C00C003066180000000000000400
+%000800000000000300E3018C0CC04306C181800000000000400000000000000000000000010000
+%004000000000000000000000000000020000040000000000000000000000000080000000000030
+%0E3818C0CC06306C180C00000000000400
+%000800000000000300E1838E1CE0C307C1C1800000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000030
+%071838E0CE0E303C1C1C00000000000400
+%00080000000000030071E7073873C30380E7800000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000030
+%071E707387BC30380F7800000000000400
+%00080000000000030030FE03F03F8303807F000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000030
+%0387E03F03F8303807F000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800FFC0000000000030000000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFC00000000
+%00030000000000C0000000000000C00400
+%000800FFF000000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFF00000000
+%0003000C000000C0000000000000C00400
+%000800E07800000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E0780000000
+%0003000C000000C0000000000000C00400
+%000800E01800000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E01C0000000
+%0003000C000000C0000000000000C00400
+%000800E01C00000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E00C0000000
+%0003000E000000C0000000000000C00400
+%000800E00C1FC38183FC37E3F0FC1FCDF03F81FE1FC7FC00400000000000000000000000010000
+%0040000000000000000000000000000200000400000000000000000000000000800E00C1FE1818
+%3FE37E1F0FC0FCDF01FC0FE1FC7EC00400
+%000800E00C39E381873C3CE0C1CE1FCF3879C3CF1F8E7C00400000000020000000000000000000
+%0040000000000000000000000000000200000000000000000000200000000000800E00E38E1818
+%73E3EF0C1CF0FCFB879E1CF1F8E7C00400
+%000800E00E7063818C1C3870C3031C0E1C60E3031C1C3C00400000000040000000000000000000
+%0040000000000000000000000000000200000000000000000000100000000000800E00E3071818
+%E1E3830C3030E0E1C6063831C1C1C00400
+%000800E00E0063818C0C3030C7031C0C0CC0600318181C00400000000100000000000000000000
+%0040000000000000000000000000000200000000000000000000040000000000800E00E0071818
+%C0E3030C3038C0C0CE070031C181C00400
+%000800E00E006381980C3030C7039C0C0CC0700718181C00400000000200000000000000000000
+%0040000000000000000000000000000200000000000000000000020000000000800E00E0071818
+%C0E3030C7038C0C0CC0300718180C00400
+%000800E00C1FE381980C3030C7FF9C0C0CC030FF18381C00400000000400000000000000000000
+%0040000000000000000000000000000200000000000000000000010000000000800E00E0FF1819
+%C0E3030C7FF8C0C0EC030FF18180C00400
+%000800E00C3E6381980C3030C7001C0C0CC033E318381C00400000000800000000000000000000
+%0040000000000000000000000000000200000000000000000000008000000000800E00E3E71819
+%C0E3030C7000C0C0EC031E318180C00400
+%000800E00C7063839C0C3030C6001C0C0CC0730318181C00400000001000000000000000000000
+%0040000000000000000000000000000200000000000000000000004000000000800E00C7071818
+%C0E3030C7000C0C0CC0330318180C00400
+%000800E01C6063838C0C3030C7031C0C0CE0670318181C00400000002000000000000000000000
+%0040000000000000000000000000000200000000000000000000002000000000800E01C6071838
+%C0E3030C3030C0C0CE0730318181C00400
+%000800E03860E1878C1C3030C3871C0E1860E707181C3C00400000008000000000000000000000
+%0040000000000000000000000000000200000000000000000000001800000000800E0386071838
+%E1E3030C3830C0E1C706307180C1C00400
+%000800FFF071E1FF877C3030F1CE1C0F3879C39F180E7C00400000010000000000000000000000
+%0040000000000000000000000000000200000000000000000000000400000000800FFF039F1FF8
+%73E3030F1EF0C0FB839E39F180F7C00400
+%000800FFE03F30F983EC303070FC1C0DF01F81FB1807FC00400000020000000000000000000000
+%0040000000000000000000000000000200000000000000000000000200000000800FFE03F30FD8
+%3FE303078FE0C0DF01F81FB9807EC00400
+%0008000000000000000C0000000000000000000000000000400000040000000000000000000000
+%004000000000000000000000000000020000000000000000000000010000000080000000000000
+%00E0000000000000000000000000000400
+%0008000000000000080C0000000000000000000000000000400000080000000000000000000000
+%004000000000000000000000000000020000000000000000000000008000000080000000000000
+%C0C0000000000000000000000000000400
+%00080000000000000C1C0000000000000000000000000000400000100000000000000000000000
+%004000000000000000000000000000020000000000000000000000004000000080000000000000
+%E1C0000000000000000000000000000400
+%000800000000000007F80000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%7F80000000000000000000000000000400
+%000800000000000003E00000000000000000000000000000400000C00000000000000000000000
+%004000000000000000000000000000020000000000000000000000001800000080000000000000
+%1E00000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000020001C03FF801FE0000000000
+%00400000000000000000000000000002000000000003C03FF801FE000200000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000040001E03FFC03FF8000000000
+%00400000000000000000000000000002000000000003C03FFC03FF000100000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000360300E07018000000000
+%00400000000000000000000000000002000000000003E0301C0703800000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040001000036030070E01C000000000
+%0040000000000000000000000000000200000000000660300E0E01800040000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040002000073030070C00C000000000
+%004000000000000000000000000000020000000000066030060C00800020000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040004000063030030C000000000000
+%004000000000000000000000000000020000000000067030071C00000010000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040010000063830031C000000000000
+%0040000000000000000000000000000200000000000C3030031800000000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FF800000E1830031C00000000FFFF
+%FFC0000000000000000000000000000200000000000C3830031800000001FFFF80000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FF800000C1C30031C00000000FFFF
+%FFC0000000000000000000000000000200000800001C1830031800000001FFFF80000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400200000C1C30031C000000000000
+%00400000000000000000000000000003FFFFF800001C1830031800000002000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001FFC30030C000000000000
+%0040000000000000000000000000000200000000001FFC30071C00000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001FFE30070C00C000000000
+%0040000000000000000000000000000200000000003FFC30060C00C00000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000380630070E00C000000000
+%004000000000000000000000000000020000000000300E30060C01C00000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400020003007300E0701C000000000
+%004000000000000000000000000000020000000000300E300E0E03800020000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000003007383C03C78000000000
+%0040000000000000000000000000000200000000006006303C0787000000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000000070033FF801FF0000000000
+%00400000000000000000000000000002000000000060073FF803FE000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400004006003BFE0007C0000000000
+%004000000000000000000000000000020000000000E0033FE000F8000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000800000000000000000000000
+%004000000000000000000000000000020000000000000000000000000800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000400000000000000000000000
+%004000000000000000000000000000020000000000000000000000001000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000100000000000000000000000
+%004000000000000000000000000000020000000000000000000000004000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000080000000000000000000000
+%004000000000000000000000000000020000000000000000000000008000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000020000000000000000000000
+%004000000000000000000000000000020000000000000000000000020000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000018000000000000000000000
+%0040000000000000000000000000000200000000000000000000000C0000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000004000000000000000000000
+%004000000000000000000000000000020000000000000000000000100000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000002000000000000000000000
+%004000000000000000000000000000020000000000000000000000200000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000001000000000000000000000
+%004000000000000000000000000000020000000000000000000000400000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000800000000000000000000
+%004000000000000000000000000000020000000000000000000000800000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000400000000000000000000
+%004000000000000000000000000000020000000000000000000001000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000200000000000000000000
+%004000000000000000000000000000020000000000000000000002000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000080000000000000000000
+%004000000000000000000000000000020000000000000000000008000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000040000000000000000000
+%004000000000000000000000000000020000000000000000000010000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000020000000000000000000
+%004000000000000000000000000000020000000000000000000020000000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000001FFFFFFFFFFFFFFF0000
+%00400000000000000000000000000002000007FFFFFFFFFFFFFFC0000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000FFFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007FF9FF8007C001C000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007FF9FFE01FF801C000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007001C0F0383C03E000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C070700C036000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C030E00C036000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C030C000063000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C031C000063000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007001C071C0000E3800000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007FF1FFE1C0FE0C1800000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000007FE1FFC1C0FE0C1800000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C001C00E1FFC00000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C000C0061FFC00000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C000C006380E00000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C000E006300600000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C000781E300700000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C0003FFC700700000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0040000006001C0000FF0600300000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000007FFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000001FFFFFFFFFFFFFFF0000
+%00400000000000000000000000000002000007FFFFFFFFFFFFFFC0000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000080000000000000000000
+%004000000000000000000000000000020000000000000000000008000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000002000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000008000000000000000000000
+%004000000000000000000000000000020000000000000000000000080000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000010000000000000000000000
+%004000000000000000000000000000020000000000000000000000040000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000040000000000000000000000
+%004000000000000000000000000000020000000000000000000000010000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000080000000000000000000000
+%004000000000000000000000000000020000000000000000000000008000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000C00000000000000000000000
+%004000000000000000000000000000020000000000000000000000001800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400001003FE00060007C0000000000
+%0040000000000000000000000000000200000000003FE000E00078000400000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400002003FF800F001FF0000000000
+%0040000000000000000000000000000200000000003FF800E001FE000200000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000400383E00F003C78000000000
+%004000000000000000000000000000020000000000303C01E00787000100000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000800380E01F80701C000000000
+%004000000000000000000000000000020000000000300E01B00E03800080000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040001000380701980E00C000000000
+%004000000000000000000000000000020000000000300601B00C01C00040000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040002000380301980C008000000000
+%004000000000000000000000000000020000000000300703181C00800020000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400080003803039C0C000000000000
+%004000000000000000000000000000020000000000300303181C00000008000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400100003803830C1C000000000000
+%0040000000000000000000000000000200000000003003071C1800000004000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000003803830C1C000000008000
+%0040000000000000000000000000000200000800003003060C1800000000000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FFC0000380386061C00000000FFFF
+%FFC00000000000000000000000000003FFFFF800003003060C1800000001FFFF80000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040020000380387FE1C000000000000
+%00400000000000000000000000000002000000000030030FFE1800000002000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000000038030FFF0C000000000000
+%00400000000000000000000000000002000000000030070FFE1C00000004000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000C00038030C030C00C000000000
+%00400000000000000000000000000002000000000030061C070C00C00018000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000000038070C030E01C000000000
+%004000000000000000000000000000020000000000300618030E01C00000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000380E1C038701C000000000
+%004000000000000000000000000000020000000000300E18038703800000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400008003FFC180183FF8000000000
+%0040000000000000000000000000000200000000003FFC380387FF000080000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000003FF83801C1FE0000000000
+%0040000000000000000000000000000200000000003FF8300181FE000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400002000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000200000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400001000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000400000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000800000000000000000000000
+%004000000000000000000000000000020000000000000000000000000800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000007FFE00000000000000000C100000000000400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800000000003FF
+%E00000000000000000C100000000000400
+%000800000000003FFE00000000000000000C300000000000400000004000000000000000000000
+%0040000000000000000000000000000200000000000000000000001000000000800000000003FF
+%E00000000000000000C300000000000400
+%0008000000000001C0000000000000000000300000000000400000002000000000000000000000
+%00400000000000000000000000000002000000000000000000000020000000008000000000000C
+%0000000000000000000300000000000400
+%0008000000000001C0000000000000000000300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0000000000000000000300000000000400
+%0008000000000001C0670F833C03C19E1C0CFC0000000000400000000800000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0270F811C03C09E1C0CFC0000000000400
+%0008000000000001C07F3FE3FF0FE1FF7F0CFC0000000000400000000400000000000000000000
+%00400000000000000000000000000002000000000000000000000100000000008000000000000C
+%07F1FE1FF0FF1FF3F0CFC0000000000400
+%0008000000000001C07A30E3C31C31E3C70C300000000000400000000100000000000000000000
+%00400000000000000000000000000002000000000000000000000400000000008000000000000C
+%0783061C38C31E3E30C300000000000400
+%0008000000000001C0707063839831C1830C300000000000400000000080000000000000000000
+%00400000000000000000000000000002000000000000000000000800000000008000000000000C
+%0703071819C11C1C38C300000000000400
+%0008000000000001C0700063819C01C1830C300000000000400000000040000000000000000000
+%00400000000000000000000000000002000000000000000000001000000000008000000000000C
+%0700071819C01C1818C300000000000400
+%0008000000000001C06003E3818F8181830C300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%07001F1818F81C1818C300000000000400
+%0008000000000001C0603FE38187F181830C30000000000040000000001FFFFFFFFFFFFFFF0000
+%00400000000000000000000000000002000007FFFFFFFFFFFFFFC000000000008000000000000C
+%0701FF18187F1C1818C300000000000400
+%0008000000000001C06078638180F181830C300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0703C718180F9C1818C300000000000400
+%0008000000000001C060606381803981830C300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0707071818019C1818C300000000000400
+%0008000000000001C060606381981981830C300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0706071819819C1818C300000000000400
+%0008000000000001C06060E3819C3981830C300000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%07070F1819C39C1818C300000000000400
+%0008000000000001C0607FE3818FF181830C3C0000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0703FF1818FF1C1818C3C0000000000400
+%0008000000000001C0601E338187C181830C1C0000000000400000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000008000000000000C
+%0701F318183E1C1818C1C0000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800FFE0000000000030004000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFE00000000
+%00030004000000C0000000000000C00400
+%000800FFF000000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFF00000000
+%0003000C000000C0000000000000C00400
+%000800E03800000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E0380000000
+%0003000C000000C0000000000000C00400
+%000800E01C00000000003000C000000C0000000000000C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E01C0000000
+%0003000C000000C0000000000000C00400
+%000800E00C0F838181EC33C3F07819CCE00F007C1B83CC0040000000001FFFFFFFFFFFFFFF0000
+%00400000000000000000000000000002000007FFFFFFFFFFFFFFC00000000000800E00C0F81818
+%1E633C1F0780DCCE00F007C1BC3CC00400
+%000800E00C3FE38187FC3FE3F1FE1FCFF83FC1FE1F8FFC00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E00E1FE1818
+%7FE3FE1F1FE0FCFF83FC1FE1FC7FC00400
+%000800E00E30E3818E1C3870C3871E0E1870E3871E9C3C00400000000040000000000000000000
+%0040000000000000000000000000000200000000000000000000100000000000800E00E3061818
+%61E3870C3870E0F1C70E3871E0C3C00400
+%000800E00E7063818C0C3030C3031C0E1CE063031C181C00400000000080000000000000000000
+%0040000000000000000000000000000200000000000000000000080000000000800E00E3071818
+%C0E3030C3030C0E0C6063031C1C1C00400
+%000800E00E0063819C0C3030C6031C0C0CC0700318181C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E00E0071818
+%C0E3030C3038C0C0CC0300318181C00400
+%000800E00E03E381980C3030C7FF9C0C0CC0303F18381C00400000000400000000000000000000
+%0040000000000000000000000000000200000000000000000000010000000000800E00E03F1819
+%C0E3030C7FF8C0C0EC0301F18180C00400
+%000800E00C3FE381980C3030C7FF9C0C0CC031FF18381C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E00E1FF1819
+%C0E3030C7FF8C0C0EC031FF18180C00400
+%000800E00C786383980C3030C6001C0C0CC033C318381C00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E00C3871819
+%C0E3030C7000C0C0EC033C318180C00400
+%000800E01C6063839C0C3030C7001C0C0CC0770318181C00400000002000000000000000000000
+%0040000000000000000000000000000200000000000000000000002000000000800E00C7071818
+%C0E3030C7000C0C0CC0330318180C00400
+%000800E0186063838C0C3030C3031C0C1CE0670718181C00400000004000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800E01C6071838
+%C0E3030C3038C0E0C606303181C1C00400
+%000800E07870E1878E1C3030C3871C0E1870E70F180C3C00400000008000000000000000000000
+%0040000000000000000000000000000200000000000000000000000800000000800E07870F1C78
+%E1E3030C3870C0E1C70E307180C3C00400
+%000800FFF03FF1FD87FC3030F1FE1C0FF03FC3FF180FFC00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFF03FF0FD8
+%7FE3030F1FE0C0FF83FC3FF1807FC00400
+%000800FFC01E307981EC303070781C0DE01F01F39803CC00400000000000000000000000000000
+%0040000000000000000000000000000200000000000000000000000000000000800FFC01F30798
+%1EE3030787C0C0CE00F00F19803CC00400
+%0008000000000000000C0000000000000000000000000000400000040000000000000000000000
+%004000000000000000000000000000020000000000000000000000010000000080000000000000
+%00C0000000000000000000000000000400
+%00080000000000000C0C0000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%C0C0000000000000000000000000000400
+%00080000000000000E380000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%F3C0000000000000000000000000000400
+%000800000000000007F00000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%7F80000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400001003FF00060007C0000000000
+%0040000000000000000000000000000200000000003FE000E000FC000400000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400002003FFC00F001FF0000000000
+%0040000000000000000000000000000200000000003FF800E003FE000200000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000381E00F003838000000000
+%004000000000000000000000000000020000000000301C01F00787800000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000800380601F80701C000000000
+%004000000000000000000000000000020000000000300E01B00E03800080000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040001000380701980E00C000000000
+%004000000000000000000000000000020000000000300603B00C01C00040000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040004000380301980C000000000000
+%004000000000000000000000000000020000000000300703181C00000010000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400080003803031C0C000000000000
+%004000000000000000000000000000020000000000300303181800000008000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400100003803830C1C000000000000
+%0040000000000000000000000000000200000000003003071C1800000004000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FFA00003803870E1C00000000FFFF
+%FFC00000000000000000000000000003FFFFF800003003060C1800000003FFFF80000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000007FFC0000380386061C00000000FFFF
+%FFC00000000000000000000000000003FFFFF800003003060C1800000001FFFF80000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040020000380307FE0C000000000000
+%00400000000000000000000000000002000000000030030FFE1800000002000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004001000038030FFF0C00C000000000
+%00400000000000000000000000000002000000000030070FFE1C00800004000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000C00038030C030C00C000000000
+%00400000000000000000000000000002000000000030061C070C01C00018000080000000000000
+%0000000000000000000000000000000400
+%0008000000000000000000000000000000000000000000004000000038070C038601C000000000
+%004000000000000000000000000000020000000000300E18030E01800000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040001000380E1C0387038000000000
+%004000000000000000000000000000020000000000301E18038703800040000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400008003FFC180183FF8000000000
+%0040000000000000000000000000000200000000003FFC380387FF000080000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000003FF83801C1FE0000000000
+%0040000000000000000000000000000200000000003FF0300181FE000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400002000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000200000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400001000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000400000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000800000000000000000000000
+%004000000000000000000000000000020000000000000000000000000800000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000200000000000000000000000
+%004000000000000000000000000000020000000000000000000000002000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000040000000000000000000000
+%004000000000000000000000000000020000000000000000000000010000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000100000000000000000000
+%004000000000000000000000000000020000000000000000000004000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000080000000000000000000
+%004000000000000000000000000000020000000000000000000008000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000040000000000000000000
+%004000000000000000000000000000020000000000000000000010000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%00080000000000000000000000000000000000000000000040000000001FFFFFFFFFFFFFFF0000
+%00400000000000000000000000000002000007FFFFFFFFFFFFFFC0000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000800000000000000000000000000000000000000000000400000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000080000000000000
+%0000000000000000000000000000000400
+%000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000000
+%00400000000000000000000000000002000000000000000000000000000000007FFFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%004000000000000000000000000000020000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%007FFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%000000000000000000000000000000000000000000000000000000000000000000000000000000
+%0000000000000000000000000000000000
+%%EndPreview
+%%BeginProlog
+%%BeginResource: SDRes
+/b4_inc_state save def
+/dict_count countdictstack def
+/op_count count 1 sub def
+userdict begin
+0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath
+/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if
+/bdef {bind def} bind def
+/c {setgray} bdef
+/l {neg lineto} bdef
+/rl {neg rlineto} bdef
+/lc {setlinecap} bdef
+/lj {setlinejoin} bdef
+/lw {setlinewidth} bdef
+/ml {setmiterlimit} bdef
+/ld {setdash} bdef
+/m {neg moveto} bdef
+/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef
+/r {rotate} bdef
+/t {neg translate} bdef
+/s {scale} bdef
+/sw {show} bdef
+/gs {gsave} bdef
+/gr {grestore} bdef
+/f {findfont dup length dict begin
+{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def
+currentdict end /NFont exch definefont pop /NFont findfont} bdef
+/p {closepath} bdef
+/sf {scalefont setfont} bdef
+/ef {eofill}bdef
+/pc {closepath stroke}bdef
+/ps {stroke}bdef
+/pum {matrix currentmatrix}bdef
+/pom {setmatrix}bdef
+/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%EndPageSetup
+pum
+0.02834 0.02833 s 
+0 -20290 t
+/tm matrix currentmatrix def
+gs
+tm setmatrix
+-635 -635 t 
+1 1 s 
+635 635 m 27274 635 l 27274 20924 l 635 20924 l 635 635 l eoclip newpath
+0.996 c 7835 7938 m  8893 6985 l  11010 6985 l  11010 8890 l  8893 8890 l 
+7835 7938 l  p ef
+0 lw 1 lj 0.000 c 7835 7938 m  8893 6985 l  11010 6985 l  11010 8890 l  8893 8890 l 
+7835 7938 l  pc
+gs
+pum
+8520 8228 t
+-1 0 m  231 -605 l  317 -605 l  565 0 l  474 0 l  403 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  378 -248 l  315 -416 l  296 -467 282 -509 272 -541 ct 264 -503 254 -464 240 -426 ct 
+p ef
+621 0 m  621 -605 l  829 -605 l  876 -605 912 -602 937 -596 ct 972 -588 1001 -574 1026 -553 ct 
+1058 -526 1082 -492 1098 -450 ct 1114 -408 1121 -360 1121 -306 ct 1121 -260 1116 -219 1105 -183 ct 
+1095 -148 1081 -118 1064 -95 ct 1047 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+908 -3 876 0 839 0 ct p
+701 -71 m  830 -71 l  870 -71 901 -75 924 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1012 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -370 1028 -419 1008 -453 ct 
+987 -487 962 -510 932 -521 ct 910 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+13955 5080 m  11733 5080 l  11733 1270 l  16178 1270 l  16178 5080 l  13955 5080 l 
+pc
+gs
+pum
+13176 2513 t
+69 0 m  69 -605 l  477 -605 l  477 -534 l  149 -534 l  149 -346 l  433 -346 l 
+433 -275 l  149 -275 l  149 0 l  p ef
+532 0 m  766 -315 l  560 -605 l  655 -605 l  765 -450 l  788 -418 804 -393 814 -375 ct 
+827 -397 843 -420 862 -444 ct 984 -605 l  1071 -605 l  858 -320 l  1087 0 l 
+988 0 l  836 -216 l  827 -228 818 -241 809 -256 ct 796 -234 786 -219 780 -211 ct 
+628 0 l  p ef
+1510 -71 m  1510 0 l  1110 0 l  1110 -17 1112 -35 1119 -51 ct 1129 -78 1145 -105 1168 -132 ct 
+1190 -158 1223 -189 1265 -223 ct 1331 -277 1375 -320 1398 -352 ct 1422 -383 1433 -413 1433 -441 ct 
+1433 -471 1423 -495 1402 -516 ct 1380 -536 1353 -546 1319 -546 ct 1283 -546 1255 -535 1233 -514 ct 
+1212 -492 1201 -463 1201 -425 ct 1124 -432 l  1129 -489 1149 -533 1183 -563 ct 
+1217 -593 1263 -608 1321 -608 ct 1379 -608 1425 -591 1459 -559 ct 1493 -527 1510 -487 1510 -439 ct 
+1510 -415 1505 -391 1495 -368 ct 1485 -345 1468 -320 1445 -294 ct 1422 -268 1384 -233 1331 -187 ct 
+1286 -150 1257 -125 1245 -111 ct 1232 -98 1222 -84 1213 -71 ct p ef
+pom
+pum
+12713 3466 t
+462 -605 m  542 -605 l  542 -255 l  542 -194 535 -146 522 -110 ct 508 -74 483 -45 447 -23 ct 
+411 0 364 10 306 10 ct 249 10 202 0 166 -19 ct 130 -38 105 -66 89 -103 ct 74 -140 66 -191 66 -255 ct 
+66 -605 l  146 -605 l  146 -256 l  146 -203 151 -164 161 -139 ct 171 -114 187 -95 211 -82 ct 
+235 -68 264 -61 299 -61 ct 358 -61 400 -75 425 -102 ct 450 -128 462 -180 462 -256 ct 
+p ef
+673 -194 m  748 -201 l  752 -170 760 -146 773 -126 ct 786 -107 806 -91 834 -79 ct 
+862 -67 893 -61 927 -61 ct 958 -61 985 -66 1008 -75 ct 1031 -84 1049 -96 1060 -112 ct 
+1072 -128 1077 -145 1077 -164 ct 1077 -183 1072 -200 1061 -214 ct 1050 -228 1032 -240 1006 -249 ct 
+990 -256 954 -266 898 -279 ct 843 -292 804 -305 782 -317 ct 753 -332 731 -351 717 -373 ct 
+703 -396 696 -421 696 -449 ct 696 -479 704 -508 722 -534 ct 739 -561 764 -581 798 -595 ct 
+831 -609 868 -615 909 -615 ct 954 -615 993 -608 1028 -594 ct 1062 -579 1088 -558 1107 -530 ct 
+1125 -502 1135 -470 1136 -434 ct 1060 -429 l  1055 -467 1041 -496 1018 -515 ct 
+994 -535 959 -545 912 -545 ct 864 -545 828 -536 806 -518 ct 784 -500 773 -479 773 -454 ct 
+773 -432 781 -414 796 -400 ct 812 -386 852 -372 917 -357 ct 982 -342 1027 -329 1051 -318 ct 
+1087 -302 1113 -282 1129 -257 ct 1146 -232 1155 -203 1155 -171 ct 1155 -138 1145 -108 1127 -79 ct 
+1108 -51 1082 -29 1047 -13 ct 1013 2 974 10 931 10 ct 876 10 830 2 793 -13 ct 756 -29 727 -53 706 -85 ct 
+685 -117 l  674 -154 l  p ef
+1278 0 m  1278 -605 l  1506 -605 l  1552 -605 1589 -599 1617 -587 ct 1645 -574 1667 -556 1683 -530 ct 
+1699 -505 1706 -478 1706 -450 ct 1706 -424 1699 -400 1685 -377 ct 1671 -354 1650 -336 1622 -322 ct 
+1658 -311 1687 -293 1706 -267 ct 1726 -241 1736 -210 1736 -175 ct 1736 -147 1730 -120 1718 -96 ct 
+1706 -72 1691 -53 1673 -40 ct 1656 -26 1634 -16 1607 -10 ct 1580 -3 1548 0 1509 0 ct 
+p
+1359 -351 m  1490 -351 l  1525 -351 1551 -353 1566 -358 ct 1586 -364 1602 -374 1612 -388 ct 
+1622 -402 1628 -419 1628 -441 ct 1628 -461 1623 -478 1613 -494 ct 1603 -509 1590 -520 1572 -525 ct 
+1554 -531 1523 -534 1480 -534 ct 1359 -534 l  p
+1359 -71 m  1509 -71 l  1535 -71 1553 -72 1564 -74 ct 1582 -77 1598 -83 1610 -90 ct 
+1623 -98 1633 -109 1641 -124 ct 1649 -139 1653 -156 1653 -175 ct 1653 -198 1647 -217 1635 -234 ct 
+1624 -251 1608 -262 1587 -269 ct 1567 -276 1537 -279 1499 -279 ct 1359 -279 l 
+p ef
+2436 -71 m  2436 0 l  2036 0 l  2036 -17 2038 -35 2045 -51 ct 2055 -78 2071 -105 2094 -132 ct 
+2116 -158 2149 -189 2191 -223 ct 2257 -277 2301 -320 2324 -352 ct 2348 -383 2359 -413 2359 -441 ct 
+2359 -471 2349 -495 2328 -516 ct 2306 -536 2279 -546 2245 -546 ct 2209 -546 2181 -535 2159 -514 ct 
+2138 -492 2127 -463 2127 -425 ct 2050 -432 l  2055 -489 2075 -533 2109 -563 ct 
+2143 -593 2189 -608 2247 -608 ct 2305 -608 2351 -591 2385 -559 ct 2419 -527 2436 -487 2436 -439 ct 
+2436 -415 2431 -391 2421 -368 ct 2411 -345 2394 -320 2371 -294 ct 2348 -268 2310 -233 2257 -187 ct 
+2212 -150 2183 -125 2171 -111 ct 2158 -98 2148 -84 2139 -71 ct p ef
+pom
+pum
+12091 4419 t
+497 -212 m  577 -192 l  560 -126 530 -76 486 -41 ct 443 -6 389 10 326 10 ct 
+261 10 208 -2 167 -29 ct 126 -56 95 -94 74 -145 ct 52 -195 42 -249 42 -307 ct 42 -370 54 -425 78 -472 ct 
+102 -519 136 -554 181 -579 ct 225 -603 274 -615 327 -615 ct 388 -615 439 -600 480 -569 ct 
+522 -538 550 -495 567 -439 ct 488 -420 l  474 -465 453 -497 427 -517 ct 400 -537 366 -547 326 -547 ct 
+279 -547 240 -536 209 -513 ct 178 -491 156 -461 143 -424 ct 131 -386 124 -347 124 -307 ct 
+124 -256 132 -211 147 -172 ct 162 -134 185 -105 217 -86 ct 248 -67 283 -58 320 -58 ct 
+365 -58 403 -71 434 -97 ct 465 -122 l  486 -161 l  p ef
+663 -219 m  663 -300 685 -360 730 -399 ct 768 -432 814 -448 868 -448 ct 929 -448 978 -428 1016 -389 ct 
+1054 -349 1074 -295 1074 -225 ct 1074 -169 1065 -124 1048 -92 ct 1031 -59 1007 -34 974 -16 ct 
+942 0 907 9 868 9 ct 807 9 757 -9 719 -49 ct 682 -88 l  663 -145 l  p
+739 -219 m  739 -163 751 -121 776 -93 ct 800 -65 831 -51 868 -51 ct 905 -51 936 -65 960 -93 ct 
+985 -121 997 -164 997 -221 ct 997 -276 985 -317 960 -345 ct 936 -373 905 -387 868 -387 ct 
+831 -387 800 -373 776 -345 ct 751 -317 l  739 -275 l  p ef
+1166 0 m  1166 -438 l  1233 -438 l  1233 -376 l  1265 -424 1312 -448 1373 -448 ct 
+1399 -448 1424 -443 1446 -434 ct 1468 -424 1484 -412 1495 -396 ct 1507 -381 1514 -363 1519 -342 ct 
+1521 -328 1523 -304 1523 -269 ct 1523 0 l  1448 0 l  1448 -266 l  1448 -297 1446 -319 1440 -334 ct 
+1434 -349 1424 -361 1409 -370 ct 1394 -379 1377 -384 1357 -384 ct 1325 -384 1298 -374 1275 -354 ct 
+1252 -333 1241 -295 1241 -239 ct 1241 0 l  p ef
+1806 -66 m  1816 0 l  1795 3 1777 5 1760 5 ct 1733 5 1712 1 1697 -7 ct 1683 -15 1672 -26 1666 -40 ct 
+1660 -54 1657 -83 1657 -128 ct 1657 -380 l  1602 -380 l  1602 -438 l  1657 -438 l 
+1657 -547 l  1731 -591 l  1731 -438 l  1806 -438 l  1806 -380 l  1731 -380 l 
+1731 -124 l  1731 -103 1732 -89 1735 -83 ct 1737 -77 1742 -72 1748 -68 ct 1753 -65 1762 -63 1773 -63 ct 
+1781 -63 l  1792 -64 l  p ef
+1880 0 m  1880 -438 l  1947 -438 l  1947 -372 l  1964 -403 1980 -423 1995 -433 ct 
+2009 -443 2025 -448 2042 -448 ct 2067 -448 2093 -440 2119 -424 ct 2093 -355 l 
+2075 -366 2057 -371 2039 -371 ct 2022 -371 2008 -366 1995 -357 ct 1982 -347 1973 -333 1967 -316 ct 
+1959 -289 1955 -261 1955 -229 ct 1955 0 l  p ef
+2145 -219 m  2145 -300 2167 -360 2212 -399 ct 2250 -432 2296 -448 2350 -448 ct 
+2411 -448 2460 -428 2498 -389 ct 2536 -349 2556 -295 2556 -225 ct 2556 -169 2547 -124 2530 -92 ct 
+2513 -59 2489 -34 2456 -16 ct 2424 0 2389 9 2350 9 ct 2289 9 2239 -9 2201 -49 ct 
+2164 -88 l  2145 -145 l  p
+2221 -219 m  2221 -163 2233 -121 2258 -93 ct 2282 -65 2313 -51 2350 -51 ct 2387 -51 2418 -65 2442 -93 ct 
+2467 -121 2479 -164 2479 -221 ct 2479 -276 2467 -317 2442 -345 ct 2418 -373 2387 -387 2350 -387 ct 
+2313 -387 2282 -373 2258 -345 ct 2233 -317 l  2221 -275 l  p ef
+2647 0 m  2647 -605 l  2721 -605 l  2721 0 l  p ef
+2832 0 m  2832 -605 l  2906 -605 l  2906 0 l  p ef
+3319 -141 m  3395 -131 l  3383 -86 3361 -52 3328 -27 ct 3295 -2 3253 9 3203 9 ct 
+3138 9 3087 -9 3050 -49 ct 3012 -88 2993 -144 2993 -215 ct 2993 -289 3012 -346 3050 -387 ct 
+3089 -428 3138 -448 3198 -448 ct 3257 -448 3305 -428 3342 -388 ct 3379 -348 3398 -292 3398 -220 ct 
+3398 -215 3398 -209 3397 -200 ct 3070 -200 l  3073 -152 3087 -115 3111 -89 ct 
+3136 -64 3166 -51 3203 -51 ct 3230 -51 3253 -58 3273 -72 ct 3292 -87 l  3307 -109 l 
+p
+3074 -261 m  3319 -261 l  3316 -298 3307 -326 3291 -344 ct 3268 -373 3237 -387 3199 -387 ct 
+3165 -387 3136 -376 3113 -353 ct 3090 -330 l  3077 -299 l  p ef
+3494 0 m  3494 -438 l  3561 -438 l  3561 -372 l  3578 -403 3594 -423 3609 -433 ct 
+3623 -443 3639 -448 3656 -448 ct 3681 -448 3707 -440 3733 -424 ct 3707 -355 l 
+3689 -366 3671 -371 3653 -371 ct 3636 -371 3622 -366 3609 -357 ct 3596 -347 3587 -333 3581 -316 ct 
+3573 -289 3569 -261 3569 -229 ct 3569 0 l  p ef
+pom
+gr
+13956 19115 m  11900 19115 l  11900 6350 l  16013 6350 l  16013 19115 l 
+13956 19115 l  pc
+gs
+pum
+12806 13017 t
+69 0 m  69 -605 l  477 -605 l  477 -534 l  149 -534 l  149 -346 l  433 -346 l 
+433 -275 l  149 -275 l  149 0 l  p ef
+594 0 m  594 -605 l  822 -605 l  862 -605 893 -603 914 -599 ct 944 -594 969 -585 989 -571 ct 
+1009 -557 1025 -538 1038 -513 ct 1050 -488 1056 -460 1056 -430 ct 1056 -378 1040 -335 1007 -299 ct 
+974 -264 915 -246 829 -246 ct 674 -246 l  674 0 l  p
+674 -317 m  830 -317 l  882 -317 919 -327 941 -346 ct 963 -365 973 -392 973 -427 ct 
+973 -453 967 -474 954 -493 ct 941 -511 925 -522 904 -528 ct 890 -532 865 -534 829 -534 ct 
+674 -534 l  p ef
+1433 -237 m  1433 -308 l  1690 -308 l  1690 -84 l  1650 -52 1610 -29 1568 -13 ct 
+1526 2 1483 10 1439 10 ct 1379 10 1325 -2 1277 -27 ct 1228 -53 1191 -90 1167 -138 ct 
+1142 -186 1130 -240 1130 -299 ct 1130 -358 1142 -413 1167 -464 ct 1191 -516 1227 -553 1273 -578 ct 
+1319 -603 1372 -615 1433 -615 ct 1477 -615 1516 -608 1551 -594 ct 1587 -580 1615 -560 1635 -535 ct 
+1655 -510 1670 -476 1681 -436 ct 1608 -416 l  1599 -447 1588 -471 1574 -489 ct 
+1561 -506 1542 -520 1517 -531 ct 1492 -542 1464 -547 1433 -547 ct 1397 -547 1365 -541 1338 -530 ct 
+1311 -519 1290 -504 1273 -486 ct 1257 -468 1244 -448 1235 -426 ct 1220 -389 1212 -348 1212 -304 ct 
+1212 -250 1221 -205 1240 -169 ct 1259 -133 1286 -106 1321 -88 ct 1357 -70 1394 -61 1434 -61 ct 
+1469 -61 1503 -68 1536 -82 ct 1569 -95 1594 -109 1611 -124 ct 1611 -237 l  p ef
+1745 0 m  1977 -605 l  2063 -605 l  2311 0 l  2220 0 l  2149 -183 l  1896 -183 l 
+1829 0 l  p
+1919 -248 m  2124 -248 l  2061 -416 l  2042 -467 2028 -509 2018 -541 ct 2010 -503 2000 -464 1986 -426 ct 
+p ef
+pom
+gr
+0.996 c 7835 17258 m  8893 16305 l  11010 16305 l  11010 18210 l  8893 18210 l 
+7835 17258 l  p ef
+0.000 c 7835 17258 m  8893 16305 l  11010 16305 l  11010 18210 l  8893 18210 l 
+7835 17258 l  pc
+gs
+pum
+8520 17542 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+608 0 m  840 -605 l  926 -605 l  1174 0 l  1083 0 l  1012 -183 l  759 -183 l 
+692 0 l  p
+782 -248 m  987 -248 l  924 -416 l  905 -467 891 -509 881 -541 ct 873 -503 863 -464 849 -426 ct 
+p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 7835 10478 m  8893 9525 l  11010 9525 l  11010 11430 l  8893 11430 l 
+7835 10478 l  p ef
+0.000 c 7835 10478 m  8893 9525 l  11010 9525 l  11010 11430 l  8893 11430 l 
+7835 10478 l  pc
+gs
+pum
+8520 10768 t
+-1 0 m  231 -605 l  317 -605 l  565 0 l  474 0 l  403 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  378 -248 l  315 -416 l  296 -467 282 -509 272 -541 ct 264 -503 254 -464 240 -426 ct 
+p ef
+621 0 m  621 -605 l  829 -605 l  876 -605 912 -602 937 -596 ct 972 -588 1001 -574 1026 -553 ct 
+1058 -526 1082 -492 1098 -450 ct 1114 -408 1121 -360 1121 -306 ct 1121 -260 1116 -219 1105 -183 ct 
+1095 -148 1081 -118 1064 -95 ct 1047 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+908 -3 876 0 839 0 ct p
+701 -71 m  830 -71 l  870 -71 901 -75 924 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1012 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -370 1028 -419 1008 -453 ct 
+987 -487 962 -510 932 -521 ct 910 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 7835 14618 m  8893 13665 l  11010 13665 l  11010 15570 l  8893 15570 l 
+7835 14618 l  p ef
+0.000 c 7835 14618 m  8893 13665 l  11010 13665 l  11010 15570 l  8893 15570 l 
+7835 14618 l  pc
+gs
+pum
+8520 14896 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+608 0 m  840 -605 l  926 -605 l  1174 0 l  1083 0 l  1012 -183 l  759 -183 l 
+692 0 l  p
+782 -248 m  987 -248 l  924 -416 l  905 -467 891 -509 881 -541 ct 873 -503 863 -464 849 -426 ct 
+p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 19984 7938 m  18926 6985 l  16809 6985 l  16809 8890 l  18926 8890 l 
+19984 7938 l  p ef
+0.000 c 19984 7938 m  18926 6985 l  16809 6985 l  16809 8890 l  18926 8890 l 
+19984 7938 l  pc
+gs
+pum
+17489 8228 t
+-1 0 m  231 -605 l  317 -605 l  565 0 l  474 0 l  403 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  378 -248 l  315 -416 l  296 -467 282 -509 272 -541 ct 264 -503 254 -464 240 -426 ct 
+p ef
+621 0 m  621 -605 l  829 -605 l  876 -605 912 -602 937 -596 ct 972 -588 1001 -574 1026 -553 ct 
+1058 -526 1082 -492 1098 -450 ct 1114 -408 1121 -360 1121 -306 ct 1121 -260 1116 -219 1105 -183 ct 
+1095 -148 1081 -118 1064 -95 ct 1047 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+908 -3 876 0 839 0 ct p
+701 -71 m  830 -71 l  870 -71 901 -75 924 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1012 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -370 1028 -419 1008 -453 ct 
+987 -487 962 -510 932 -521 ct 910 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 19984 17258 m  18926 16305 l  16809 16305 l  16809 18210 l  18926 18210 l 
+19984 17258 l  p ef
+0.000 c 19984 17258 m  18926 16305 l  16809 16305 l  16809 18210 l  18926 18210 l 
+19984 17258 l  pc
+gs
+pum
+17489 17542 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+608 0 m  840 -605 l  926 -605 l  1174 0 l  1083 0 l  1012 -183 l  759 -183 l 
+692 0 l  p
+782 -248 m  987 -248 l  924 -416 l  905 -467 891 -509 881 -541 ct 873 -503 863 -464 849 -426 ct 
+p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 19984 10478 m  18926 9525 l  16809 9525 l  16809 11430 l  18926 11430 l 
+19984 10478 l  p ef
+0.000 c 19984 10478 m  18926 9525 l  16809 9525 l  16809 11430 l  18926 11430 l 
+19984 10478 l  pc
+gs
+pum
+17489 10768 t
+-1 0 m  231 -605 l  317 -605 l  565 0 l  474 0 l  403 -183 l  150 -183 l 
+83 0 l  p
+173 -248 m  378 -248 l  315 -416 l  296 -467 282 -509 272 -541 ct 264 -503 254 -464 240 -426 ct 
+p ef
+621 0 m  621 -605 l  829 -605 l  876 -605 912 -602 937 -596 ct 972 -588 1001 -574 1026 -553 ct 
+1058 -526 1082 -492 1098 -450 ct 1114 -408 1121 -360 1121 -306 ct 1121 -260 1116 -219 1105 -183 ct 
+1095 -148 1081 -118 1064 -95 ct 1047 -72 1029 -54 1009 -40 ct 989 -27 965 -17 937 -10 ct 
+908 -3 876 0 839 0 ct p
+701 -71 m  830 -71 l  870 -71 901 -75 924 -82 ct 947 -90 965 -100 979 -114 ct 
+998 -133 1012 -158 1023 -190 ct 1034 -222 1039 -261 1039 -307 ct 1039 -370 1028 -419 1008 -453 ct 
+987 -487 962 -510 932 -521 ct 910 -530 876 -534 828 -534 ct 701 -534 l  p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+0.996 c 19984 14618 m  18926 13665 l  16809 13665 l  16809 15570 l  18926 15570 l 
+19984 14618 l  p ef
+0.000 c 19984 14618 m  18926 13665 l  16809 13665 l  16809 15570 l  18926 15570 l 
+19984 14618 l  pc
+gs
+pum
+17489 14896 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+608 0 m  840 -605 l  926 -605 l  1174 0 l  1083 0 l  1012 -183 l  759 -183 l 
+692 0 l  p
+782 -248 m  987 -248 l  924 -416 l  905 -467 891 -509 881 -541 ct 873 -503 863 -464 849 -426 ct 
+p ef
+1661 -212 m  1741 -192 l  1724 -126 1694 -76 1650 -41 ct 1607 -6 1553 10 1490 10 ct 
+1425 10 1372 -2 1331 -29 ct 1290 -56 1259 -94 1238 -145 ct 1216 -195 1206 -249 1206 -307 ct 
+1206 -370 1218 -425 1242 -472 ct 1266 -519 1300 -554 1345 -579 ct 1389 -603 1438 -615 1491 -615 ct 
+1552 -615 1603 -600 1644 -569 ct 1686 -538 1714 -495 1731 -439 ct 1652 -420 l 
+1638 -465 1617 -497 1591 -517 ct 1564 -537 1530 -547 1490 -547 ct 1443 -547 1404 -536 1373 -513 ct 
+1342 -491 1320 -461 1307 -424 ct 1295 -386 1288 -347 1288 -307 ct 1288 -256 1296 -211 1311 -172 ct 
+1326 -134 1349 -105 1381 -86 ct 1412 -67 1447 -58 1484 -58 ct 1529 -58 1567 -71 1598 -97 ct 
+1629 -122 l  1650 -161 l  p ef
+pom
+gr
+23767 18828 m  20592 18828 l  20592 13113 l  26942 13113 l  26942 18828 l 
+23767 18828 l  pc
+gs
+pum
+22133 15795 t
+219 0 m  219 -534 l  19 -534 l  19 -605 l  499 -605 l  499 -534 l  299 -534 l 
+299 0 l  p ef
+583 0 m  583 -438 l  650 -438 l  650 -372 l  667 -403 683 -423 698 -433 ct 
+712 -443 728 -448 745 -448 ct 770 -448 796 -440 822 -424 ct 796 -355 l  778 -366 760 -371 742 -371 ct 
+725 -371 711 -366 698 -357 ct 685 -347 676 -333 670 -316 ct 662 -289 658 -261 658 -229 ct 
+658 0 l  p ef
+1162 -54 m  1134 -30 1108 -14 1082 -4 ct 1057 5 1029 9 1000 9 ct 952 9 915 -1 889 -25 ct 
+863 -48 850 -79 850 -115 ct 850 -137 855 -156 865 -174 ct 875 -192 887 -206 903 -217 ct 
+919 -228 937 -236 957 -241 ct 971 -245 993 -249 1023 -252 ct 1083 -259 1127 -268 1155 -278 ct 
+1156 -288 1156 -295 1156 -297 ct 1156 -328 1149 -349 1135 -361 ct 1116 -378 1087 -387 1050 -387 ct 
+1015 -387 989 -380 973 -368 ct 956 -356 944 -334 936 -303 ct 863 -313 l  869 -344 880 -369 896 -388 ct 
+911 -408 933 -422 961 -433 ct 990 -443 1023 -448 1061 -448 ct 1098 -448 1129 -444 1152 -435 ct 
+1175 -426 1193 -415 1204 -402 ct 1215 -388 1222 -371 1227 -351 ct 1229 -338 1231 -316 1231 -282 ct 
+1231 -183 l  1231 -114 1232 -70 1235 -52 ct 1238 -34 1245 -16 1254 0 ct 1176 0 l 
+1169 -15 l  1164 -33 l  p
+1155 -220 m  1128 -209 1088 -199 1034 -192 ct 1003 -187 982 -182 969 -177 ct 
+956 -171 947 -163 940 -153 ct 933 -142 929 -130 929 -117 ct 929 -97 937 -81 952 -68 ct 
+967 -54 989 -48 1018 -48 ct 1046 -48 1072 -54 1094 -67 ct 1117 -79 1133 -96 1143 -118 ct 
+1151 -135 1155 -160 1155 -192 ct p ef
+1325 0 m  1325 -438 l  1392 -438 l  1392 -376 l  1424 -424 1471 -448 1532 -448 ct 
+1558 -448 1583 -443 1605 -434 ct 1627 -424 1643 -412 1654 -396 ct 1666 -381 1673 -363 1678 -342 ct 
+1680 -328 1682 -304 1682 -269 ct 1682 0 l  1607 0 l  1607 -266 l  1607 -297 1605 -319 1599 -334 ct 
+1593 -349 1583 -361 1568 -370 ct 1553 -379 1536 -384 1516 -384 ct 1484 -384 1457 -374 1434 -354 ct 
+1411 -333 1400 -295 1400 -239 ct 1400 0 l  p ef
+1772 -130 m  1845 -142 l  1849 -113 1861 -90 1880 -74 ct 1898 -59 1925 -51 1959 -51 ct 
+1993 -51 2018 -58 2035 -72 ct 2051 -85 2059 -102 2059 -121 ct 2059 -137 2052 -151 2038 -160 ct 
+2027 -167 2002 -175 1962 -185 ct 1907 -199 1869 -211 1848 -221 ct 1827 -231 1811 -245 1800 -263 ct 
+1789 -281 1784 -300 1784 -322 ct 1784 -341 1788 -359 1797 -376 ct 1806 -393 1818 -407 1834 -418 ct 
+1845 -426 1861 -433 1881 -439 ct 1901 -445 1923 -448 1945 -448 ct 1980 -448 2010 -443 2036 -433 ct 
+2062 -423 2081 -410 2094 -393 ct 2106 -376 2115 -353 2119 -325 ct 2047 -315 l 
+2043 -338 2034 -355 2018 -368 ct 2002 -381 1980 -387 1951 -387 ct 1917 -387 1892 -381 1878 -370 ct 
+1863 -359 1856 -346 1856 -330 ct 1856 -321 1859 -312 1865 -304 ct 1871 -296 1880 -290 1893 -285 ct 
+1901 -282 1923 -275 1959 -266 ct 2012 -251 2048 -240 2069 -231 ct 2090 -222 2106 -209 2118 -192 ct 
+2130 -175 2136 -154 2136 -128 ct 2136 -104 2129 -80 2114 -58 ct 2100 -36 2079 -20 2052 -8 ct 
+2024 3 1993 9 1959 9 ct 1902 9 1859 -1 1829 -25 ct 1799 -49 l  1780 -84 l  p ef
+2198 0 m  2198 -438 l  2265 -438 l  2265 -377 l  2279 -398 2297 -415 2320 -428 ct 
+2343 -442 2369 -448 2398 -448 ct 2430 -448 2457 -441 2478 -428 ct 2499 -414 2513 -396 2522 -371 ct 
+2556 -423 2602 -448 2657 -448 ct 2701 -448 2734 -436 2758 -412 ct 2781 -388 2793 -351 2793 -301 ct 
+2793 0 l  2719 0 l  2719 -276 l  2719 -306 2716 -327 2712 -340 ct 2707 -353 2698 -364 2685 -372 ct 
+2673 -380 2658 -384 2641 -384 ct 2610 -384 2584 -373 2564 -353 ct 2543 -332 2533 -300 2533 -254 ct 
+2533 0 l  2459 0 l  2459 -285 l  2459 -318 2453 -342 2441 -359 ct 2429 -375 2409 -384 2381 -384 ct 
+2360 -384 2341 -378 2323 -367 ct 2305 -356 2293 -340 2285 -319 ct 2277 -298 2273 -267 2273 -227 ct 
+2273 0 l  p ef
+2914 -520 m  2914 -605 l  2988 -605 l  2988 -520 l  p
+2914 0 m  2914 -438 l  2988 -438 l  2988 0 l  p ef
+3261 -66 m  3271 0 l  3250 3 3232 5 3215 5 ct 3188 5 3167 1 3152 -7 ct 3138 -15 3127 -26 3121 -40 ct 
+3115 -54 3112 -83 3112 -128 ct 3112 -380 l  3057 -380 l  3057 -438 l  3112 -438 l 
+3112 -547 l  3186 -591 l  3186 -438 l  3261 -438 l  3261 -380 l  3186 -380 l 
+3186 -124 l  3186 -103 3187 -89 3190 -83 ct 3192 -77 3197 -72 3203 -68 ct 3208 -65 3217 -63 3228 -63 ct 
+3236 -63 l  3247 -64 l  p ef
+pom
+pum
+20955 16748 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+951 -54 m  923 -30 897 -14 871 -4 ct 846 5 818 9 789 9 ct 741 9 704 -1 678 -25 ct 
+652 -48 639 -79 639 -115 ct 639 -137 644 -156 654 -174 ct 664 -192 676 -206 692 -217 ct 
+708 -228 726 -236 746 -241 ct 760 -245 782 -249 812 -252 ct 872 -259 916 -268 944 -278 ct 
+945 -288 945 -295 945 -297 ct 945 -328 938 -349 924 -361 ct 905 -378 876 -387 839 -387 ct 
+804 -387 778 -380 762 -368 ct 745 -356 733 -334 725 -303 ct 652 -313 l  658 -344 669 -369 685 -388 ct 
+700 -408 722 -422 750 -433 ct 779 -443 812 -448 850 -448 ct 887 -448 918 -444 941 -435 ct 
+964 -426 982 -415 993 -402 ct 1004 -388 1011 -371 1016 -351 ct 1018 -338 1020 -316 1020 -282 ct 
+1020 -183 l  1020 -114 1021 -70 1024 -52 ct 1027 -34 1034 -16 1043 0 ct 965 0 l 
+958 -15 l  953 -33 l  p
+944 -220 m  917 -209 877 -199 823 -192 ct 792 -187 771 -182 758 -177 ct 745 -171 736 -163 729 -153 ct 
+722 -142 718 -130 718 -117 ct 718 -97 726 -81 741 -68 ct 756 -54 778 -48 807 -48 ct 
+835 -48 861 -54 883 -67 ct 906 -79 922 -96 932 -118 ct 940 -135 944 -160 944 -192 ct 
+p ef
+1401 0 m  1401 -64 l  1367 -14 1320 9 1262 9 ct 1236 9 1212 4 1189 -4 ct 1167 -14 1150 -27 1139 -42 ct 
+1128 -57 1121 -75 1116 -97 ct 1113 -112 1112 -135 1112 -166 ct 1112 -438 l  1186 -438 l 
+1186 -195 l  1186 -156 1187 -130 1191 -116 ct 1195 -97 1205 -82 1220 -70 ct 
+1235 -59 1254 -54 1276 -54 ct 1299 -54 1320 -59 1339 -71 ct 1359 -82 1373 -98 1381 -117 ct 
+1389 -137 1393 -166 1393 -203 ct 1393 -438 l  1467 -438 l  1467 0 l  p ef
+1577 36 m  1649 47 l  1652 69 1660 85 1674 95 ct 1693 109 1718 116 1750 116 ct 
+1784 116 1811 109 1829 95 ct 1848 82 1861 62 1867 38 ct 1871 22 1873 -8 1873 -57 ct 
+1840 -19 1800 0 1751 0 ct 1691 0 1644 -21 1611 -65 ct 1578 -108 1562 -160 1562 -221 ct 
+1562 -263 1569 -302 1584 -337 ct 1600 -373 1622 -400 1650 -419 ct 1679 -438 1713 -448 1752 -448 ct 
+1804 -448 1846 -427 1880 -385 ct 1880 -438 l  1948 -438 l  1948 -59 l  1948 8 1941 57 1928 85 ct 
+1914 114 1892 136 1861 153 ct 1831 169 1794 178 1750 178 ct 1698 178 1656 166 1623 142 ct 
+1591 119 l  1576 83 l  p
+1638 -227 m  1638 -169 1650 -127 1672 -101 ct 1695 -74 1724 -61 1758 -61 ct 
+1793 -61 1821 -74 1844 -101 ct 1867 -127 1879 -168 1879 -224 ct 1879 -278 1867 -318 1843 -346 ct 
+1819 -373 1791 -387 1757 -387 ct 1724 -387 1696 -373 1673 -346 ct 1650 -319 l 
+1638 -280 l  p ef
+2066 0 m  2066 -605 l  2141 -605 l  2141 -388 l  2175 -428 2219 -448 2272 -448 ct 
+2304 -448 2333 -442 2357 -429 ct 2381 -416 2398 -398 2408 -376 ct 2418 -353 2424 -320 2424 -278 ct 
+2424 0 l  2349 0 l  2349 -278 l  2349 -315 2341 -342 2325 -359 ct 2309 -376 2286 -384 2257 -384 ct 
+2235 -384 2214 -378 2195 -367 ct 2175 -356 2161 -340 2153 -320 ct 2145 -301 2141 -274 2141 -240 ct 
+2141 0 l  p ef
+2705 -66 m  2715 0 l  2694 3 2676 5 2659 5 ct 2632 5 2611 1 2596 -7 ct 2582 -15 2571 -26 2565 -40 ct 
+2559 -54 2556 -83 2556 -128 ct 2556 -380 l  2501 -380 l  2501 -438 l  2556 -438 l 
+2556 -547 l  2630 -591 l  2630 -438 l  2705 -438 l  2705 -380 l  2630 -380 l 
+2630 -124 l  2630 -103 2631 -89 2634 -83 ct 2636 -77 2641 -72 2647 -68 ct 2652 -65 2661 -63 2672 -63 ct 
+2680 -63 l  2691 -64 l  p ef
+3081 -141 m  3157 -131 l  3145 -86 3123 -52 3090 -27 ct 3057 -2 3015 9 2965 9 ct 
+2900 9 2849 -9 2812 -49 ct 2774 -88 2755 -144 2755 -215 ct 2755 -289 2774 -346 2812 -387 ct 
+2851 -428 2900 -448 2960 -448 ct 3019 -448 3067 -428 3104 -388 ct 3141 -348 3160 -292 3160 -220 ct 
+3160 -215 3160 -209 3159 -200 ct 2832 -200 l  2835 -152 2849 -115 2873 -89 ct 
+2898 -64 2928 -51 2965 -51 ct 2992 -51 3015 -58 3035 -72 ct 3054 -87 l  3069 -109 l 
+p
+2836 -261 m  3081 -261 l  3078 -298 3069 -326 3053 -344 ct 3030 -373 2999 -387 2961 -387 ct 
+2927 -387 2898 -376 2875 -353 ct 2852 -330 l  2839 -299 l  p ef
+3255 0 m  3255 -438 l  3322 -438 l  3322 -372 l  3339 -403 3355 -423 3370 -433 ct 
+3384 -443 3400 -448 3417 -448 ct 3442 -448 3468 -440 3494 -424 ct 3468 -355 l 
+3450 -366 3432 -371 3414 -371 ct 3397 -371 3383 -366 3370 -357 ct 3357 -347 3348 -333 3342 -316 ct 
+3334 -289 3330 -261 3330 -229 ct 3330 0 l  p ef
+3617 0 m  3548 0 l  3548 -605 l  3622 -605 l  3622 -389 l  3654 -428 3694 -448 3742 -448 ct 
+3769 -448 3795 -443 3819 -432 ct 3843 -421 3863 -406 3879 -386 ct 3894 -366 3906 -343 3915 -315 ct 
+3924 -287 3928 -257 3928 -225 ct 3928 -150 3910 -92 3873 -51 ct 3835 -10 3791 9 3739 9 ct 
+3687 9 3646 -11 3617 -54 ct p
+3616 -222 m  3616 -170 3623 -132 3638 -108 ct 3661 -70 3693 -51 3733 -51 ct 
+3765 -51 3793 -65 3817 -93 ct 3840 -121 3852 -163 3852 -219 ct 3852 -277 3841 -319 3818 -346 ct 
+3796 -373 3768 -387 3736 -387 ct 3703 -387 3675 -373 3652 -345 ct 3628 -316 l 
+3616 -276 l  p ef
+3970 -219 m  3970 -300 3992 -360 4037 -399 ct 4075 -432 4121 -448 4175 -448 ct 
+4236 -448 4285 -428 4323 -389 ct 4361 -349 4381 -295 4381 -225 ct 4381 -169 4372 -124 4355 -92 ct 
+4338 -59 4314 -34 4281 -16 ct 4249 0 4214 9 4175 9 ct 4114 9 4064 -9 4026 -49 ct 
+3989 -88 l  3970 -145 l  p
+4046 -219 m  4046 -163 4058 -121 4083 -93 ct 4107 -65 4138 -51 4175 -51 ct 4212 -51 4243 -65 4267 -93 ct 
+4292 -121 4304 -164 4304 -221 ct 4304 -276 4292 -317 4267 -345 ct 4243 -373 4212 -387 4175 -387 ct 
+4138 -387 4107 -373 4083 -345 ct 4058 -317 l  4046 -275 l  p ef
+4761 -54 m  4733 -30 4707 -14 4681 -4 ct 4656 5 4628 9 4599 9 ct 4551 9 4514 -1 4488 -25 ct 
+4462 -48 4449 -79 4449 -115 ct 4449 -137 4454 -156 4464 -174 ct 4474 -192 4486 -206 4502 -217 ct 
+4518 -228 4536 -236 4556 -241 ct 4570 -245 4592 -249 4622 -252 ct 4682 -259 4726 -268 4754 -278 ct 
+4755 -288 4755 -295 4755 -297 ct 4755 -328 4748 -349 4734 -361 ct 4715 -378 4686 -387 4649 -387 ct 
+4614 -387 4588 -380 4572 -368 ct 4555 -356 4543 -334 4535 -303 ct 4462 -313 l 
+4468 -344 4479 -369 4495 -388 ct 4510 -408 4532 -422 4560 -433 ct 4589 -443 4622 -448 4660 -448 ct 
+4697 -448 4728 -444 4751 -435 ct 4774 -426 4792 -415 4803 -402 ct 4814 -388 4821 -371 4826 -351 ct 
+4828 -338 4830 -316 4830 -282 ct 4830 -183 l  4830 -114 4831 -70 4834 -52 ct 
+4837 -34 4844 -16 4853 0 ct 4775 0 l  4768 -15 l  4763 -33 l  p
+4754 -220 m  4727 -209 4687 -199 4633 -192 ct 4602 -187 4581 -182 4568 -177 ct 
+4555 -171 4546 -163 4539 -153 ct 4532 -142 4528 -130 4528 -117 ct 4528 -97 4536 -81 4551 -68 ct 
+4566 -54 4588 -48 4617 -48 ct 4645 -48 4671 -54 4693 -67 ct 4716 -79 4732 -96 4742 -118 ct 
+4750 -135 4754 -160 4754 -192 ct p ef
+4922 0 m  4922 -438 l  4989 -438 l  4989 -372 l  5006 -403 5022 -423 5037 -433 ct 
+5051 -443 5067 -448 5084 -448 ct 5109 -448 5135 -440 5161 -424 ct 5135 -355 l 
+5117 -366 5099 -371 5081 -371 ct 5064 -371 5050 -366 5037 -357 ct 5024 -347 5015 -333 5009 -316 ct 
+5001 -289 4997 -261 4997 -229 ct 4997 0 l  p ef
+5499 0 m  5499 -55 l  5471 -11 5430 9 5376 9 ct 5341 9 5309 0 5280 -19 ct 5250 -38 5228 -65 5212 -99 ct 
+5195 -134 5187 -174 5187 -218 ct 5187 -262 5195 -302 5209 -338 ct 5224 -373 5246 -401 5275 -420 ct 
+5304 -439 5337 -448 5373 -448 ct 5399 -448 5423 -443 5444 -431 ct 5464 -420 5481 -406 5494 -388 ct 
+5494 -605 l  5568 -605 l  5568 0 l  p
+5264 -218 m  5264 -162 5276 -120 5299 -92 ct 5323 -65 5351 -51 5383 -51 ct 5416 -51 5443 -64 5466 -91 ct 
+5489 -117 5500 -158 5500 -212 ct 5500 -272 5489 -316 5465 -344 ct 5442 -373 5414 -387 5380 -387 ct 
+5347 -387 5319 -373 5297 -346 ct 5275 -319 l  5264 -277 l  p ef
+pom
+gr
+23767 12065 m  20592 12065 l  20592 6350 l  26942 6350 l  26942 12065 l 
+23767 12065 l  pc
+gs
+pum
+22239 9022 t
+66 0 m  66 -605 l  335 -605 l  389 -605 430 -600 458 -589 ct 486 -578 508 -559 525 -531 ct 
+542 -504 550 -473 550 -440 ct 550 -397 536 -361 508 -331 ct 481 -302 438 -283 380 -275 ct 
+401 -265 417 -255 428 -245 ct 451 -223 473 -197 494 -164 ct 600 0 l  499 0 l 
+419 -125 l  395 -162 376 -190 361 -209 ct 346 -228 332 -242 320 -249 ct 308 -257 296 -263 284 -266 ct 
+275 -267 260 -268 239 -268 ct 146 -268 l  146 0 l  p
+146 -338 m  318 -338 l  355 -338 384 -342 404 -349 ct 425 -357 441 -369 451 -386 ct 
+462 -402 468 -420 468 -440 ct 468 -468 457 -492 436 -510 ct 416 -529 383 -538 338 -538 ct 
+146 -538 l  p ef
+965 -141 m  1041 -131 l  1029 -86 1007 -52 974 -27 ct 941 -2 899 9 849 9 ct 
+784 9 733 -9 696 -49 ct 658 -88 639 -144 639 -215 ct 639 -289 658 -346 696 -387 ct 
+735 -428 784 -448 844 -448 ct 903 -448 951 -428 988 -388 ct 1025 -348 1044 -292 1044 -220 ct 
+1044 -215 1044 -209 1043 -200 ct 716 -200 l  719 -152 733 -115 757 -89 ct 782 -64 812 -51 849 -51 ct 
+876 -51 899 -58 919 -72 ct 938 -87 l  953 -109 l  p
+720 -261 m  965 -261 l  962 -298 953 -326 937 -344 ct 914 -373 883 -387 845 -387 ct 
+811 -387 782 -376 759 -353 ct 736 -330 l  723 -299 l  p ef
+1427 -160 m  1500 -151 l  1492 -100 1471 -61 1438 -32 ct 1405 -4 1365 9 1317 9 ct 
+1257 9 1209 -9 1172 -48 ct 1136 -88 1118 -144 1118 -217 ct 1118 -265 1125 -306 1141 -342 ct 
+1157 -377 1181 -404 1213 -421 ct 1245 -439 1280 -448 1317 -448 ct 1365 -448 1404 -436 1434 -412 ct 
+1465 -388 1484 -354 1493 -309 ct 1420 -298 l  1413 -328 1401 -350 1384 -365 ct 
+1366 -380 1345 -387 1320 -387 ct 1283 -387 1252 -374 1229 -347 ct 1206 -320 1194 -277 1194 -219 ct 
+1194 -160 1205 -118 1228 -91 ct 1250 -64 1280 -51 1316 -51 ct 1345 -51 1370 -60 1389 -78 ct 
+1409 -95 l  1421 -123 l  p ef
+1864 -141 m  1940 -131 l  1928 -86 1906 -52 1873 -27 ct 1840 -2 1798 9 1748 9 ct 
+1683 9 1632 -9 1595 -49 ct 1557 -88 1538 -144 1538 -215 ct 1538 -289 1557 -346 1595 -387 ct 
+1634 -428 1683 -448 1743 -448 ct 1802 -448 1850 -428 1887 -388 ct 1924 -348 1943 -292 1943 -220 ct 
+1943 -215 1943 -209 1942 -200 ct 1615 -200 l  1618 -152 1632 -115 1656 -89 ct 
+1681 -64 1711 -51 1748 -51 ct 1775 -51 1798 -58 1818 -72 ct 1837 -87 l  1852 -109 l 
+p
+1619 -261 m  1864 -261 l  1861 -298 1852 -326 1836 -344 ct 1813 -373 1782 -387 1744 -387 ct 
+1710 -387 1681 -376 1658 -353 ct 1635 -330 l  1622 -299 l  p ef
+2040 -520 m  2040 -605 l  2114 -605 l  2114 -520 l  p
+2040 0 m  2040 -438 l  2114 -438 l  2114 0 l  p ef
+2347 0 m  2180 -438 l  2259 -438 l  2353 -175 l  2363 -147 2372 -118 2381 -87 ct 
+2388 -110 2397 -138 2409 -171 ct 2506 -438 l  2583 -438 l  2417 0 l  p ef
+2949 -141 m  3025 -131 l  3013 -86 2991 -52 2958 -27 ct 2925 -2 2883 9 2833 9 ct 
+2768 9 2717 -9 2680 -49 ct 2642 -88 2623 -144 2623 -215 ct 2623 -289 2642 -346 2680 -387 ct 
+2719 -428 2768 -448 2828 -448 ct 2887 -448 2935 -428 2972 -388 ct 3009 -348 3028 -292 3028 -220 ct 
+3028 -215 3028 -209 3027 -200 ct 2700 -200 l  2703 -152 2717 -115 2741 -89 ct 
+2766 -64 2796 -51 2833 -51 ct 2860 -51 2883 -58 2903 -72 ct 2922 -87 l  2937 -109 l 
+p
+2704 -261 m  2949 -261 l  2946 -298 2937 -326 2921 -344 ct 2898 -373 2867 -387 2829 -387 ct 
+2795 -387 2766 -376 2743 -353 ct 2720 -330 l  2707 -299 l  p ef
+pom
+pum
+20955 9975 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+951 -54 m  923 -30 897 -14 871 -4 ct 846 5 818 9 789 9 ct 741 9 704 -1 678 -25 ct 
+652 -48 639 -79 639 -115 ct 639 -137 644 -156 654 -174 ct 664 -192 676 -206 692 -217 ct 
+708 -228 726 -236 746 -241 ct 760 -245 782 -249 812 -252 ct 872 -259 916 -268 944 -278 ct 
+945 -288 945 -295 945 -297 ct 945 -328 938 -349 924 -361 ct 905 -378 876 -387 839 -387 ct 
+804 -387 778 -380 762 -368 ct 745 -356 733 -334 725 -303 ct 652 -313 l  658 -344 669 -369 685 -388 ct 
+700 -408 722 -422 750 -433 ct 779 -443 812 -448 850 -448 ct 887 -448 918 -444 941 -435 ct 
+964 -426 982 -415 993 -402 ct 1004 -388 1011 -371 1016 -351 ct 1018 -338 1020 -316 1020 -282 ct 
+1020 -183 l  1020 -114 1021 -70 1024 -52 ct 1027 -34 1034 -16 1043 0 ct 965 0 l 
+958 -15 l  953 -33 l  p
+944 -220 m  917 -209 877 -199 823 -192 ct 792 -187 771 -182 758 -177 ct 745 -171 736 -163 729 -153 ct 
+722 -142 718 -130 718 -117 ct 718 -97 726 -81 741 -68 ct 756 -54 778 -48 807 -48 ct 
+835 -48 861 -54 883 -67 ct 906 -79 922 -96 932 -118 ct 940 -135 944 -160 944 -192 ct 
+p ef
+1401 0 m  1401 -64 l  1367 -14 1320 9 1262 9 ct 1236 9 1212 4 1189 -4 ct 1167 -14 1150 -27 1139 -42 ct 
+1128 -57 1121 -75 1116 -97 ct 1113 -112 1112 -135 1112 -166 ct 1112 -438 l  1186 -438 l 
+1186 -195 l  1186 -156 1187 -130 1191 -116 ct 1195 -97 1205 -82 1220 -70 ct 
+1235 -59 1254 -54 1276 -54 ct 1299 -54 1320 -59 1339 -71 ct 1359 -82 1373 -98 1381 -117 ct 
+1389 -137 1393 -166 1393 -203 ct 1393 -438 l  1467 -438 l  1467 0 l  p ef
+1577 36 m  1649 47 l  1652 69 1660 85 1674 95 ct 1693 109 1718 116 1750 116 ct 
+1784 116 1811 109 1829 95 ct 1848 82 1861 62 1867 38 ct 1871 22 1873 -8 1873 -57 ct 
+1840 -19 1800 0 1751 0 ct 1691 0 1644 -21 1611 -65 ct 1578 -108 1562 -160 1562 -221 ct 
+1562 -263 1569 -302 1584 -337 ct 1600 -373 1622 -400 1650 -419 ct 1679 -438 1713 -448 1752 -448 ct 
+1804 -448 1846 -427 1880 -385 ct 1880 -438 l  1948 -438 l  1948 -59 l  1948 8 1941 57 1928 85 ct 
+1914 114 1892 136 1861 153 ct 1831 169 1794 178 1750 178 ct 1698 178 1656 166 1623 142 ct 
+1591 119 l  1576 83 l  p
+1638 -227 m  1638 -169 1650 -127 1672 -101 ct 1695 -74 1724 -61 1758 -61 ct 
+1793 -61 1821 -74 1844 -101 ct 1867 -127 1879 -168 1879 -224 ct 1879 -278 1867 -318 1843 -346 ct 
+1819 -373 1791 -387 1757 -387 ct 1724 -387 1696 -373 1673 -346 ct 1650 -319 l 
+1638 -280 l  p ef
+2066 0 m  2066 -605 l  2141 -605 l  2141 -388 l  2175 -428 2219 -448 2272 -448 ct 
+2304 -448 2333 -442 2357 -429 ct 2381 -416 2398 -398 2408 -376 ct 2418 -353 2424 -320 2424 -278 ct 
+2424 0 l  2349 0 l  2349 -278 l  2349 -315 2341 -342 2325 -359 ct 2309 -376 2286 -384 2257 -384 ct 
+2235 -384 2214 -378 2195 -367 ct 2175 -356 2161 -340 2153 -320 ct 2145 -301 2141 -274 2141 -240 ct 
+2141 0 l  p ef
+2705 -66 m  2715 0 l  2694 3 2676 5 2659 5 ct 2632 5 2611 1 2596 -7 ct 2582 -15 2571 -26 2565 -40 ct 
+2559 -54 2556 -83 2556 -128 ct 2556 -380 l  2501 -380 l  2501 -438 l  2556 -438 l 
+2556 -547 l  2630 -591 l  2630 -438 l  2705 -438 l  2705 -380 l  2630 -380 l 
+2630 -124 l  2630 -103 2631 -89 2634 -83 ct 2636 -77 2641 -72 2647 -68 ct 2652 -65 2661 -63 2672 -63 ct 
+2680 -63 l  2691 -64 l  p ef
+3081 -141 m  3157 -131 l  3145 -86 3123 -52 3090 -27 ct 3057 -2 3015 9 2965 9 ct 
+2900 9 2849 -9 2812 -49 ct 2774 -88 2755 -144 2755 -215 ct 2755 -289 2774 -346 2812 -387 ct 
+2851 -428 2900 -448 2960 -448 ct 3019 -448 3067 -428 3104 -388 ct 3141 -348 3160 -292 3160 -220 ct 
+3160 -215 3160 -209 3159 -200 ct 2832 -200 l  2835 -152 2849 -115 2873 -89 ct 
+2898 -64 2928 -51 2965 -51 ct 2992 -51 3015 -58 3035 -72 ct 3054 -87 l  3069 -109 l 
+p
+2836 -261 m  3081 -261 l  3078 -298 3069 -326 3053 -344 ct 3030 -373 2999 -387 2961 -387 ct 
+2927 -387 2898 -376 2875 -353 ct 2852 -330 l  2839 -299 l  p ef
+3255 0 m  3255 -438 l  3322 -438 l  3322 -372 l  3339 -403 3355 -423 3370 -433 ct 
+3384 -443 3400 -448 3417 -448 ct 3442 -448 3468 -440 3494 -424 ct 3468 -355 l 
+3450 -366 3432 -371 3414 -371 ct 3397 -371 3383 -366 3370 -357 ct 3357 -347 3348 -333 3342 -316 ct 
+3334 -289 3330 -261 3330 -229 ct 3330 0 l  p ef
+3617 0 m  3548 0 l  3548 -605 l  3622 -605 l  3622 -389 l  3654 -428 3694 -448 3742 -448 ct 
+3769 -448 3795 -443 3819 -432 ct 3843 -421 3863 -406 3879 -386 ct 3894 -366 3906 -343 3915 -315 ct 
+3924 -287 3928 -257 3928 -225 ct 3928 -150 3910 -92 3873 -51 ct 3835 -10 3791 9 3739 9 ct 
+3687 9 3646 -11 3617 -54 ct p
+3616 -222 m  3616 -170 3623 -132 3638 -108 ct 3661 -70 3693 -51 3733 -51 ct 
+3765 -51 3793 -65 3817 -93 ct 3840 -121 3852 -163 3852 -219 ct 3852 -277 3841 -319 3818 -346 ct 
+3796 -373 3768 -387 3736 -387 ct 3703 -387 3675 -373 3652 -345 ct 3628 -316 l 
+3616 -276 l  p ef
+3970 -219 m  3970 -300 3992 -360 4037 -399 ct 4075 -432 4121 -448 4175 -448 ct 
+4236 -448 4285 -428 4323 -389 ct 4361 -349 4381 -295 4381 -225 ct 4381 -169 4372 -124 4355 -92 ct 
+4338 -59 4314 -34 4281 -16 ct 4249 0 4214 9 4175 9 ct 4114 9 4064 -9 4026 -49 ct 
+3989 -88 l  3970 -145 l  p
+4046 -219 m  4046 -163 4058 -121 4083 -93 ct 4107 -65 4138 -51 4175 -51 ct 4212 -51 4243 -65 4267 -93 ct 
+4292 -121 4304 -164 4304 -221 ct 4304 -276 4292 -317 4267 -345 ct 4243 -373 4212 -387 4175 -387 ct 
+4138 -387 4107 -373 4083 -345 ct 4058 -317 l  4046 -275 l  p ef
+4761 -54 m  4733 -30 4707 -14 4681 -4 ct 4656 5 4628 9 4599 9 ct 4551 9 4514 -1 4488 -25 ct 
+4462 -48 4449 -79 4449 -115 ct 4449 -137 4454 -156 4464 -174 ct 4474 -192 4486 -206 4502 -217 ct 
+4518 -228 4536 -236 4556 -241 ct 4570 -245 4592 -249 4622 -252 ct 4682 -259 4726 -268 4754 -278 ct 
+4755 -288 4755 -295 4755 -297 ct 4755 -328 4748 -349 4734 -361 ct 4715 -378 4686 -387 4649 -387 ct 
+4614 -387 4588 -380 4572 -368 ct 4555 -356 4543 -334 4535 -303 ct 4462 -313 l 
+4468 -344 4479 -369 4495 -388 ct 4510 -408 4532 -422 4560 -433 ct 4589 -443 4622 -448 4660 -448 ct 
+4697 -448 4728 -444 4751 -435 ct 4774 -426 4792 -415 4803 -402 ct 4814 -388 4821 -371 4826 -351 ct 
+4828 -338 4830 -316 4830 -282 ct 4830 -183 l  4830 -114 4831 -70 4834 -52 ct 
+4837 -34 4844 -16 4853 0 ct 4775 0 l  4768 -15 l  4763 -33 l  p
+4754 -220 m  4727 -209 4687 -199 4633 -192 ct 4602 -187 4581 -182 4568 -177 ct 
+4555 -171 4546 -163 4539 -153 ct 4532 -142 4528 -130 4528 -117 ct 4528 -97 4536 -81 4551 -68 ct 
+4566 -54 4588 -48 4617 -48 ct 4645 -48 4671 -54 4693 -67 ct 4716 -79 4732 -96 4742 -118 ct 
+4750 -135 4754 -160 4754 -192 ct p ef
+4922 0 m  4922 -438 l  4989 -438 l  4989 -372 l  5006 -403 5022 -423 5037 -433 ct 
+5051 -443 5067 -448 5084 -448 ct 5109 -448 5135 -440 5161 -424 ct 5135 -355 l 
+5117 -366 5099 -371 5081 -371 ct 5064 -371 5050 -366 5037 -357 ct 5024 -347 5015 -333 5009 -316 ct 
+5001 -289 4997 -261 4997 -229 ct 4997 0 l  p ef
+5499 0 m  5499 -55 l  5471 -11 5430 9 5376 9 ct 5341 9 5309 0 5280 -19 ct 5250 -38 5228 -65 5212 -99 ct 
+5195 -134 5187 -174 5187 -218 ct 5187 -262 5195 -302 5209 -338 ct 5224 -373 5246 -401 5275 -420 ct 
+5304 -439 5337 -448 5373 -448 ct 5399 -448 5423 -443 5444 -431 ct 5464 -420 5481 -406 5494 -388 ct 
+5494 -605 l  5568 -605 l  5568 0 l  p
+5264 -218 m  5264 -162 5276 -120 5299 -92 ct 5323 -65 5351 -51 5383 -51 ct 5416 -51 5443 -64 5466 -91 ct 
+5489 -117 5500 -158 5500 -212 ct 5500 -272 5489 -316 5465 -344 ct 5442 -373 5414 -387 5380 -387 ct 
+5347 -387 5319 -373 5297 -346 ct 5275 -319 l  5264 -277 l  p ef
+pom
+gr
+4245 18828 m  1070 18828 l  1070 13113 l  7420 13113 l  7420 18828 l  4245 18828 l 
+pc
+gs
+pum
+2607 15795 t
+219 0 m  219 -534 l  19 -534 l  19 -605 l  499 -605 l  499 -534 l  299 -534 l 
+299 0 l  p ef
+583 0 m  583 -438 l  650 -438 l  650 -372 l  667 -403 683 -423 698 -433 ct 
+712 -443 728 -448 745 -448 ct 770 -448 796 -440 822 -424 ct 796 -355 l  778 -366 760 -371 742 -371 ct 
+725 -371 711 -366 698 -357 ct 685 -347 676 -333 670 -316 ct 662 -289 658 -261 658 -229 ct 
+658 0 l  p ef
+1162 -54 m  1134 -30 1108 -14 1082 -4 ct 1057 5 1029 9 1000 9 ct 952 9 915 -1 889 -25 ct 
+863 -48 850 -79 850 -115 ct 850 -137 855 -156 865 -174 ct 875 -192 887 -206 903 -217 ct 
+919 -228 937 -236 957 -241 ct 971 -245 993 -249 1023 -252 ct 1083 -259 1127 -268 1155 -278 ct 
+1156 -288 1156 -295 1156 -297 ct 1156 -328 1149 -349 1135 -361 ct 1116 -378 1087 -387 1050 -387 ct 
+1015 -387 989 -380 973 -368 ct 956 -356 944 -334 936 -303 ct 863 -313 l  869 -344 880 -369 896 -388 ct 
+911 -408 933 -422 961 -433 ct 990 -443 1023 -448 1061 -448 ct 1098 -448 1129 -444 1152 -435 ct 
+1175 -426 1193 -415 1204 -402 ct 1215 -388 1222 -371 1227 -351 ct 1229 -338 1231 -316 1231 -282 ct 
+1231 -183 l  1231 -114 1232 -70 1235 -52 ct 1238 -34 1245 -16 1254 0 ct 1176 0 l 
+1169 -15 l  1164 -33 l  p
+1155 -220 m  1128 -209 1088 -199 1034 -192 ct 1003 -187 982 -182 969 -177 ct 
+956 -171 947 -163 940 -153 ct 933 -142 929 -130 929 -117 ct 929 -97 937 -81 952 -68 ct 
+967 -54 989 -48 1018 -48 ct 1046 -48 1072 -54 1094 -67 ct 1117 -79 1133 -96 1143 -118 ct 
+1151 -135 1155 -160 1155 -192 ct p ef
+1325 0 m  1325 -438 l  1392 -438 l  1392 -376 l  1424 -424 1471 -448 1532 -448 ct 
+1558 -448 1583 -443 1605 -434 ct 1627 -424 1643 -412 1654 -396 ct 1666 -381 1673 -363 1678 -342 ct 
+1680 -328 1682 -304 1682 -269 ct 1682 0 l  1607 0 l  1607 -266 l  1607 -297 1605 -319 1599 -334 ct 
+1593 -349 1583 -361 1568 -370 ct 1553 -379 1536 -384 1516 -384 ct 1484 -384 1457 -374 1434 -354 ct 
+1411 -333 1400 -295 1400 -239 ct 1400 0 l  p ef
+1772 -130 m  1845 -142 l  1849 -113 1861 -90 1880 -74 ct 1898 -59 1925 -51 1959 -51 ct 
+1993 -51 2018 -58 2035 -72 ct 2051 -85 2059 -102 2059 -121 ct 2059 -137 2052 -151 2038 -160 ct 
+2027 -167 2002 -175 1962 -185 ct 1907 -199 1869 -211 1848 -221 ct 1827 -231 1811 -245 1800 -263 ct 
+1789 -281 1784 -300 1784 -322 ct 1784 -341 1788 -359 1797 -376 ct 1806 -393 1818 -407 1834 -418 ct 
+1845 -426 1861 -433 1881 -439 ct 1901 -445 1923 -448 1945 -448 ct 1980 -448 2010 -443 2036 -433 ct 
+2062 -423 2081 -410 2094 -393 ct 2106 -376 2115 -353 2119 -325 ct 2047 -315 l 
+2043 -338 2034 -355 2018 -368 ct 2002 -381 1980 -387 1951 -387 ct 1917 -387 1892 -381 1878 -370 ct 
+1863 -359 1856 -346 1856 -330 ct 1856 -321 1859 -312 1865 -304 ct 1871 -296 1880 -290 1893 -285 ct 
+1901 -282 1923 -275 1959 -266 ct 2012 -251 2048 -240 2069 -231 ct 2090 -222 2106 -209 2118 -192 ct 
+2130 -175 2136 -154 2136 -128 ct 2136 -104 2129 -80 2114 -58 ct 2100 -36 2079 -20 2052 -8 ct 
+2024 3 1993 9 1959 9 ct 1902 9 1859 -1 1829 -25 ct 1799 -49 l  1780 -84 l  p ef
+2198 0 m  2198 -438 l  2265 -438 l  2265 -377 l  2279 -398 2297 -415 2320 -428 ct 
+2343 -442 2369 -448 2398 -448 ct 2430 -448 2457 -441 2478 -428 ct 2499 -414 2513 -396 2522 -371 ct 
+2556 -423 2602 -448 2657 -448 ct 2701 -448 2734 -436 2758 -412 ct 2781 -388 2793 -351 2793 -301 ct 
+2793 0 l  2719 0 l  2719 -276 l  2719 -306 2716 -327 2712 -340 ct 2707 -353 2698 -364 2685 -372 ct 
+2673 -380 2658 -384 2641 -384 ct 2610 -384 2584 -373 2564 -353 ct 2543 -332 2533 -300 2533 -254 ct 
+2533 0 l  2459 0 l  2459 -285 l  2459 -318 2453 -342 2441 -359 ct 2429 -375 2409 -384 2381 -384 ct 
+2360 -384 2341 -378 2323 -367 ct 2305 -356 2293 -340 2285 -319 ct 2277 -298 2273 -267 2273 -227 ct 
+2273 0 l  p ef
+2914 -520 m  2914 -605 l  2988 -605 l  2988 -520 l  p
+2914 0 m  2914 -438 l  2988 -438 l  2988 0 l  p ef
+3261 -66 m  3271 0 l  3250 3 3232 5 3215 5 ct 3188 5 3167 1 3152 -7 ct 3138 -15 3127 -26 3121 -40 ct 
+3115 -54 3112 -83 3112 -128 ct 3112 -380 l  3057 -380 l  3057 -438 l  3112 -438 l 
+3112 -547 l  3186 -591 l  3186 -438 l  3261 -438 l  3261 -380 l  3186 -380 l 
+3186 -124 l  3186 -103 3187 -89 3190 -83 ct 3192 -77 3197 -72 3203 -68 ct 3208 -65 3217 -63 3228 -63 ct 
+3236 -63 l  3247 -64 l  p ef
+pom
+pum
+1429 16748 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+951 -54 m  923 -30 897 -14 871 -4 ct 846 5 818 9 789 9 ct 741 9 704 -1 678 -25 ct 
+652 -48 639 -79 639 -115 ct 639 -137 644 -156 654 -174 ct 664 -192 676 -206 692 -217 ct 
+708 -228 726 -236 746 -241 ct 760 -245 782 -249 812 -252 ct 872 -259 916 -268 944 -278 ct 
+945 -288 945 -295 945 -297 ct 945 -328 938 -349 924 -361 ct 905 -378 876 -387 839 -387 ct 
+804 -387 778 -380 762 -368 ct 745 -356 733 -334 725 -303 ct 652 -313 l  658 -344 669 -369 685 -388 ct 
+700 -408 722 -422 750 -433 ct 779 -443 812 -448 850 -448 ct 887 -448 918 -444 941 -435 ct 
+964 -426 982 -415 993 -402 ct 1004 -388 1011 -371 1016 -351 ct 1018 -338 1020 -316 1020 -282 ct 
+1020 -183 l  1020 -114 1021 -70 1024 -52 ct 1027 -34 1034 -16 1043 0 ct 965 0 l 
+958 -15 l  953 -33 l  p
+944 -220 m  917 -209 877 -199 823 -192 ct 792 -187 771 -182 758 -177 ct 745 -171 736 -163 729 -153 ct 
+722 -142 718 -130 718 -117 ct 718 -97 726 -81 741 -68 ct 756 -54 778 -48 807 -48 ct 
+835 -48 861 -54 883 -67 ct 906 -79 922 -96 932 -118 ct 940 -135 944 -160 944 -192 ct 
+p ef
+1401 0 m  1401 -64 l  1367 -14 1320 9 1262 9 ct 1236 9 1212 4 1189 -4 ct 1167 -14 1150 -27 1139 -42 ct 
+1128 -57 1121 -75 1116 -97 ct 1113 -112 1112 -135 1112 -166 ct 1112 -438 l  1186 -438 l 
+1186 -195 l  1186 -156 1187 -130 1191 -116 ct 1195 -97 1205 -82 1220 -70 ct 
+1235 -59 1254 -54 1276 -54 ct 1299 -54 1320 -59 1339 -71 ct 1359 -82 1373 -98 1381 -117 ct 
+1389 -137 1393 -166 1393 -203 ct 1393 -438 l  1467 -438 l  1467 0 l  p ef
+1577 36 m  1649 47 l  1652 69 1660 85 1674 95 ct 1693 109 1718 116 1750 116 ct 
+1784 116 1811 109 1829 95 ct 1848 82 1861 62 1867 38 ct 1871 22 1873 -8 1873 -57 ct 
+1840 -19 1800 0 1751 0 ct 1691 0 1644 -21 1611 -65 ct 1578 -108 1562 -160 1562 -221 ct 
+1562 -263 1569 -302 1584 -337 ct 1600 -373 1622 -400 1650 -419 ct 1679 -438 1713 -448 1752 -448 ct 
+1804 -448 1846 -427 1880 -385 ct 1880 -438 l  1948 -438 l  1948 -59 l  1948 8 1941 57 1928 85 ct 
+1914 114 1892 136 1861 153 ct 1831 169 1794 178 1750 178 ct 1698 178 1656 166 1623 142 ct 
+1591 119 l  1576 83 l  p
+1638 -227 m  1638 -169 1650 -127 1672 -101 ct 1695 -74 1724 -61 1758 -61 ct 
+1793 -61 1821 -74 1844 -101 ct 1867 -127 1879 -168 1879 -224 ct 1879 -278 1867 -318 1843 -346 ct 
+1819 -373 1791 -387 1757 -387 ct 1724 -387 1696 -373 1673 -346 ct 1650 -319 l 
+1638 -280 l  p ef
+2066 0 m  2066 -605 l  2141 -605 l  2141 -388 l  2175 -428 2219 -448 2272 -448 ct 
+2304 -448 2333 -442 2357 -429 ct 2381 -416 2398 -398 2408 -376 ct 2418 -353 2424 -320 2424 -278 ct 
+2424 0 l  2349 0 l  2349 -278 l  2349 -315 2341 -342 2325 -359 ct 2309 -376 2286 -384 2257 -384 ct 
+2235 -384 2214 -378 2195 -367 ct 2175 -356 2161 -340 2153 -320 ct 2145 -301 2141 -274 2141 -240 ct 
+2141 0 l  p ef
+2705 -66 m  2715 0 l  2694 3 2676 5 2659 5 ct 2632 5 2611 1 2596 -7 ct 2582 -15 2571 -26 2565 -40 ct 
+2559 -54 2556 -83 2556 -128 ct 2556 -380 l  2501 -380 l  2501 -438 l  2556 -438 l 
+2556 -547 l  2630 -591 l  2630 -438 l  2705 -438 l  2705 -380 l  2630 -380 l 
+2630 -124 l  2630 -103 2631 -89 2634 -83 ct 2636 -77 2641 -72 2647 -68 ct 2652 -65 2661 -63 2672 -63 ct 
+2680 -63 l  2691 -64 l  p ef
+3081 -141 m  3157 -131 l  3145 -86 3123 -52 3090 -27 ct 3057 -2 3015 9 2965 9 ct 
+2900 9 2849 -9 2812 -49 ct 2774 -88 2755 -144 2755 -215 ct 2755 -289 2774 -346 2812 -387 ct 
+2851 -428 2900 -448 2960 -448 ct 3019 -448 3067 -428 3104 -388 ct 3141 -348 3160 -292 3160 -220 ct 
+3160 -215 3160 -209 3159 -200 ct 2832 -200 l  2835 -152 2849 -115 2873 -89 ct 
+2898 -64 2928 -51 2965 -51 ct 2992 -51 3015 -58 3035 -72 ct 3054 -87 l  3069 -109 l 
+p
+2836 -261 m  3081 -261 l  3078 -298 3069 -326 3053 -344 ct 3030 -373 2999 -387 2961 -387 ct 
+2927 -387 2898 -376 2875 -353 ct 2852 -330 l  2839 -299 l  p ef
+3255 0 m  3255 -438 l  3322 -438 l  3322 -372 l  3339 -403 3355 -423 3370 -433 ct 
+3384 -443 3400 -448 3417 -448 ct 3442 -448 3468 -440 3494 -424 ct 3468 -355 l 
+3450 -366 3432 -371 3414 -371 ct 3397 -371 3383 -366 3370 -357 ct 3357 -347 3348 -333 3342 -316 ct 
+3334 -289 3330 -261 3330 -229 ct 3330 0 l  p ef
+3617 0 m  3548 0 l  3548 -605 l  3622 -605 l  3622 -389 l  3654 -428 3694 -448 3742 -448 ct 
+3769 -448 3795 -443 3819 -432 ct 3843 -421 3863 -406 3879 -386 ct 3894 -366 3906 -343 3915 -315 ct 
+3924 -287 3928 -257 3928 -225 ct 3928 -150 3910 -92 3873 -51 ct 3835 -10 3791 9 3739 9 ct 
+3687 9 3646 -11 3617 -54 ct p
+3616 -222 m  3616 -170 3623 -132 3638 -108 ct 3661 -70 3693 -51 3733 -51 ct 
+3765 -51 3793 -65 3817 -93 ct 3840 -121 3852 -163 3852 -219 ct 3852 -277 3841 -319 3818 -346 ct 
+3796 -373 3768 -387 3736 -387 ct 3703 -387 3675 -373 3652 -345 ct 3628 -316 l 
+3616 -276 l  p ef
+3970 -219 m  3970 -300 3992 -360 4037 -399 ct 4075 -432 4121 -448 4175 -448 ct 
+4236 -448 4285 -428 4323 -389 ct 4361 -349 4381 -295 4381 -225 ct 4381 -169 4372 -124 4355 -92 ct 
+4338 -59 4314 -34 4281 -16 ct 4249 0 4214 9 4175 9 ct 4114 9 4064 -9 4026 -49 ct 
+3989 -88 l  3970 -145 l  p
+4046 -219 m  4046 -163 4058 -121 4083 -93 ct 4107 -65 4138 -51 4175 -51 ct 4212 -51 4243 -65 4267 -93 ct 
+4292 -121 4304 -164 4304 -221 ct 4304 -276 4292 -317 4267 -345 ct 4243 -373 4212 -387 4175 -387 ct 
+4138 -387 4107 -373 4083 -345 ct 4058 -317 l  4046 -275 l  p ef
+4761 -54 m  4733 -30 4707 -14 4681 -4 ct 4656 5 4628 9 4599 9 ct 4551 9 4514 -1 4488 -25 ct 
+4462 -48 4449 -79 4449 -115 ct 4449 -137 4454 -156 4464 -174 ct 4474 -192 4486 -206 4502 -217 ct 
+4518 -228 4536 -236 4556 -241 ct 4570 -245 4592 -249 4622 -252 ct 4682 -259 4726 -268 4754 -278 ct 
+4755 -288 4755 -295 4755 -297 ct 4755 -328 4748 -349 4734 -361 ct 4715 -378 4686 -387 4649 -387 ct 
+4614 -387 4588 -380 4572 -368 ct 4555 -356 4543 -334 4535 -303 ct 4462 -313 l 
+4468 -344 4479 -369 4495 -388 ct 4510 -408 4532 -422 4560 -433 ct 4589 -443 4622 -448 4660 -448 ct 
+4697 -448 4728 -444 4751 -435 ct 4774 -426 4792 -415 4803 -402 ct 4814 -388 4821 -371 4826 -351 ct 
+4828 -338 4830 -316 4830 -282 ct 4830 -183 l  4830 -114 4831 -70 4834 -52 ct 
+4837 -34 4844 -16 4853 0 ct 4775 0 l  4768 -15 l  4763 -33 l  p
+4754 -220 m  4727 -209 4687 -199 4633 -192 ct 4602 -187 4581 -182 4568 -177 ct 
+4555 -171 4546 -163 4539 -153 ct 4532 -142 4528 -130 4528 -117 ct 4528 -97 4536 -81 4551 -68 ct 
+4566 -54 4588 -48 4617 -48 ct 4645 -48 4671 -54 4693 -67 ct 4716 -79 4732 -96 4742 -118 ct 
+4750 -135 4754 -160 4754 -192 ct p ef
+4922 0 m  4922 -438 l  4989 -438 l  4989 -372 l  5006 -403 5022 -423 5037 -433 ct 
+5051 -443 5067 -448 5084 -448 ct 5109 -448 5135 -440 5161 -424 ct 5135 -355 l 
+5117 -366 5099 -371 5081 -371 ct 5064 -371 5050 -366 5037 -357 ct 5024 -347 5015 -333 5009 -316 ct 
+5001 -289 4997 -261 4997 -229 ct 4997 0 l  p ef
+5499 0 m  5499 -55 l  5471 -11 5430 9 5376 9 ct 5341 9 5309 0 5280 -19 ct 5250 -38 5228 -65 5212 -99 ct 
+5195 -134 5187 -174 5187 -218 ct 5187 -262 5195 -302 5209 -338 ct 5224 -373 5246 -401 5275 -420 ct 
+5304 -439 5337 -448 5373 -448 ct 5399 -448 5423 -443 5444 -431 ct 5464 -420 5481 -406 5494 -388 ct 
+5494 -605 l  5568 -605 l  5568 0 l  p
+5264 -218 m  5264 -162 5276 -120 5299 -92 ct 5323 -65 5351 -51 5383 -51 ct 5416 -51 5443 -64 5466 -91 ct 
+5489 -117 5500 -158 5500 -212 ct 5500 -272 5489 -316 5465 -344 ct 5442 -373 5414 -387 5380 -387 ct 
+5347 -387 5319 -373 5297 -346 ct 5275 -319 l  5264 -277 l  p ef
+pom
+gr
+4245 12065 m  1070 12065 l  1070 6350 l  7420 6350 l  7420 12065 l  4245 12065 l 
+pc
+gs
+pum
+2713 9022 t
+66 0 m  66 -605 l  335 -605 l  389 -605 430 -600 458 -589 ct 486 -578 508 -559 525 -531 ct 
+542 -504 550 -473 550 -440 ct 550 -397 536 -361 508 -331 ct 481 -302 438 -283 380 -275 ct 
+401 -265 417 -255 428 -245 ct 451 -223 473 -197 494 -164 ct 600 0 l  499 0 l 
+419 -125 l  395 -162 376 -190 361 -209 ct 346 -228 332 -242 320 -249 ct 308 -257 296 -263 284 -266 ct 
+275 -267 260 -268 239 -268 ct 146 -268 l  146 0 l  p
+146 -338 m  318 -338 l  355 -338 384 -342 404 -349 ct 425 -357 441 -369 451 -386 ct 
+462 -402 468 -420 468 -440 ct 468 -468 457 -492 436 -510 ct 416 -529 383 -538 338 -538 ct 
+146 -538 l  p ef
+965 -141 m  1041 -131 l  1029 -86 1007 -52 974 -27 ct 941 -2 899 9 849 9 ct 
+784 9 733 -9 696 -49 ct 658 -88 639 -144 639 -215 ct 639 -289 658 -346 696 -387 ct 
+735 -428 784 -448 844 -448 ct 903 -448 951 -428 988 -388 ct 1025 -348 1044 -292 1044 -220 ct 
+1044 -215 1044 -209 1043 -200 ct 716 -200 l  719 -152 733 -115 757 -89 ct 782 -64 812 -51 849 -51 ct 
+876 -51 899 -58 919 -72 ct 938 -87 l  953 -109 l  p
+720 -261 m  965 -261 l  962 -298 953 -326 937 -344 ct 914 -373 883 -387 845 -387 ct 
+811 -387 782 -376 759 -353 ct 736 -330 l  723 -299 l  p ef
+1427 -160 m  1500 -151 l  1492 -100 1471 -61 1438 -32 ct 1405 -4 1365 9 1317 9 ct 
+1257 9 1209 -9 1172 -48 ct 1136 -88 1118 -144 1118 -217 ct 1118 -265 1125 -306 1141 -342 ct 
+1157 -377 1181 -404 1213 -421 ct 1245 -439 1280 -448 1317 -448 ct 1365 -448 1404 -436 1434 -412 ct 
+1465 -388 1484 -354 1493 -309 ct 1420 -298 l  1413 -328 1401 -350 1384 -365 ct 
+1366 -380 1345 -387 1320 -387 ct 1283 -387 1252 -374 1229 -347 ct 1206 -320 1194 -277 1194 -219 ct 
+1194 -160 1205 -118 1228 -91 ct 1250 -64 1280 -51 1316 -51 ct 1345 -51 1370 -60 1389 -78 ct 
+1409 -95 l  1421 -123 l  p ef
+1864 -141 m  1940 -131 l  1928 -86 1906 -52 1873 -27 ct 1840 -2 1798 9 1748 9 ct 
+1683 9 1632 -9 1595 -49 ct 1557 -88 1538 -144 1538 -215 ct 1538 -289 1557 -346 1595 -387 ct 
+1634 -428 1683 -448 1743 -448 ct 1802 -448 1850 -428 1887 -388 ct 1924 -348 1943 -292 1943 -220 ct 
+1943 -215 1943 -209 1942 -200 ct 1615 -200 l  1618 -152 1632 -115 1656 -89 ct 
+1681 -64 1711 -51 1748 -51 ct 1775 -51 1798 -58 1818 -72 ct 1837 -87 l  1852 -109 l 
+p
+1619 -261 m  1864 -261 l  1861 -298 1852 -326 1836 -344 ct 1813 -373 1782 -387 1744 -387 ct 
+1710 -387 1681 -376 1658 -353 ct 1635 -330 l  1622 -299 l  p ef
+2040 -520 m  2040 -605 l  2114 -605 l  2114 -520 l  p
+2040 0 m  2040 -438 l  2114 -438 l  2114 0 l  p ef
+2347 0 m  2180 -438 l  2259 -438 l  2353 -175 l  2363 -147 2372 -118 2381 -87 ct 
+2388 -110 2397 -138 2409 -171 ct 2506 -438 l  2583 -438 l  2417 0 l  p ef
+2949 -141 m  3025 -131 l  3013 -86 2991 -52 2958 -27 ct 2925 -2 2883 9 2833 9 ct 
+2768 9 2717 -9 2680 -49 ct 2642 -88 2623 -144 2623 -215 ct 2623 -289 2642 -346 2680 -387 ct 
+2719 -428 2768 -448 2828 -448 ct 2887 -448 2935 -428 2972 -388 ct 3009 -348 3028 -292 3028 -220 ct 
+3028 -215 3028 -209 3027 -200 ct 2700 -200 l  2703 -152 2717 -115 2741 -89 ct 
+2766 -64 2796 -51 2833 -51 ct 2860 -51 2883 -58 2903 -72 ct 2922 -87 l  2937 -109 l 
+p
+2704 -261 m  2949 -261 l  2946 -298 2937 -326 2921 -344 ct 2898 -373 2867 -387 2829 -387 ct 
+2795 -387 2766 -376 2743 -353 ct 2720 -330 l  2707 -299 l  p ef
+pom
+pum
+1429 9975 t
+65 0 m  65 -605 l  273 -605 l  320 -605 356 -602 381 -596 ct 416 -588 445 -574 470 -553 ct 
+502 -526 526 -492 542 -450 ct 558 -408 565 -360 565 -306 ct 565 -260 560 -219 549 -183 ct 
+539 -148 525 -118 508 -95 ct 491 -72 473 -54 453 -40 ct 433 -27 409 -17 381 -10 ct 
+352 -3 320 0 283 0 ct p
+145 -71 m  274 -71 l  314 -71 345 -75 368 -82 ct 391 -90 409 -100 423 -114 ct 
+442 -133 456 -158 467 -190 ct 478 -222 483 -261 483 -307 ct 483 -370 472 -419 452 -453 ct 
+431 -487 406 -510 376 -521 ct 354 -530 320 -534 272 -534 ct 145 -534 l  p ef
+951 -54 m  923 -30 897 -14 871 -4 ct 846 5 818 9 789 9 ct 741 9 704 -1 678 -25 ct 
+652 -48 639 -79 639 -115 ct 639 -137 644 -156 654 -174 ct 664 -192 676 -206 692 -217 ct 
+708 -228 726 -236 746 -241 ct 760 -245 782 -249 812 -252 ct 872 -259 916 -268 944 -278 ct 
+945 -288 945 -295 945 -297 ct 945 -328 938 -349 924 -361 ct 905 -378 876 -387 839 -387 ct 
+804 -387 778 -380 762 -368 ct 745 -356 733 -334 725 -303 ct 652 -313 l  658 -344 669 -369 685 -388 ct 
+700 -408 722 -422 750 -433 ct 779 -443 812 -448 850 -448 ct 887 -448 918 -444 941 -435 ct 
+964 -426 982 -415 993 -402 ct 1004 -388 1011 -371 1016 -351 ct 1018 -338 1020 -316 1020 -282 ct 
+1020 -183 l  1020 -114 1021 -70 1024 -52 ct 1027 -34 1034 -16 1043 0 ct 965 0 l 
+958 -15 l  953 -33 l  p
+944 -220 m  917 -209 877 -199 823 -192 ct 792 -187 771 -182 758 -177 ct 745 -171 736 -163 729 -153 ct 
+722 -142 718 -130 718 -117 ct 718 -97 726 -81 741 -68 ct 756 -54 778 -48 807 -48 ct 
+835 -48 861 -54 883 -67 ct 906 -79 922 -96 932 -118 ct 940 -135 944 -160 944 -192 ct 
+p ef
+1401 0 m  1401 -64 l  1367 -14 1320 9 1262 9 ct 1236 9 1212 4 1189 -4 ct 1167 -14 1150 -27 1139 -42 ct 
+1128 -57 1121 -75 1116 -97 ct 1113 -112 1112 -135 1112 -166 ct 1112 -438 l  1186 -438 l 
+1186 -195 l  1186 -156 1187 -130 1191 -116 ct 1195 -97 1205 -82 1220 -70 ct 
+1235 -59 1254 -54 1276 -54 ct 1299 -54 1320 -59 1339 -71 ct 1359 -82 1373 -98 1381 -117 ct 
+1389 -137 1393 -166 1393 -203 ct 1393 -438 l  1467 -438 l  1467 0 l  p ef
+1577 36 m  1649 47 l  1652 69 1660 85 1674 95 ct 1693 109 1718 116 1750 116 ct 
+1784 116 1811 109 1829 95 ct 1848 82 1861 62 1867 38 ct 1871 22 1873 -8 1873 -57 ct 
+1840 -19 1800 0 1751 0 ct 1691 0 1644 -21 1611 -65 ct 1578 -108 1562 -160 1562 -221 ct 
+1562 -263 1569 -302 1584 -337 ct 1600 -373 1622 -400 1650 -419 ct 1679 -438 1713 -448 1752 -448 ct 
+1804 -448 1846 -427 1880 -385 ct 1880 -438 l  1948 -438 l  1948 -59 l  1948 8 1941 57 1928 85 ct 
+1914 114 1892 136 1861 153 ct 1831 169 1794 178 1750 178 ct 1698 178 1656 166 1623 142 ct 
+1591 119 l  1576 83 l  p
+1638 -227 m  1638 -169 1650 -127 1672 -101 ct 1695 -74 1724 -61 1758 -61 ct 
+1793 -61 1821 -74 1844 -101 ct 1867 -127 1879 -168 1879 -224 ct 1879 -278 1867 -318 1843 -346 ct 
+1819 -373 1791 -387 1757 -387 ct 1724 -387 1696 -373 1673 -346 ct 1650 -319 l 
+1638 -280 l  p ef
+2066 0 m  2066 -605 l  2141 -605 l  2141 -388 l  2175 -428 2219 -448 2272 -448 ct 
+2304 -448 2333 -442 2357 -429 ct 2381 -416 2398 -398 2408 -376 ct 2418 -353 2424 -320 2424 -278 ct 
+2424 0 l  2349 0 l  2349 -278 l  2349 -315 2341 -342 2325 -359 ct 2309 -376 2286 -384 2257 -384 ct 
+2235 -384 2214 -378 2195 -367 ct 2175 -356 2161 -340 2153 -320 ct 2145 -301 2141 -274 2141 -240 ct 
+2141 0 l  p ef
+2705 -66 m  2715 0 l  2694 3 2676 5 2659 5 ct 2632 5 2611 1 2596 -7 ct 2582 -15 2571 -26 2565 -40 ct 
+2559 -54 2556 -83 2556 -128 ct 2556 -380 l  2501 -380 l  2501 -438 l  2556 -438 l 
+2556 -547 l  2630 -591 l  2630 -438 l  2705 -438 l  2705 -380 l  2630 -380 l 
+2630 -124 l  2630 -103 2631 -89 2634 -83 ct 2636 -77 2641 -72 2647 -68 ct 2652 -65 2661 -63 2672 -63 ct 
+2680 -63 l  2691 -64 l  p ef
+3081 -141 m  3157 -131 l  3145 -86 3123 -52 3090 -27 ct 3057 -2 3015 9 2965 9 ct 
+2900 9 2849 -9 2812 -49 ct 2774 -88 2755 -144 2755 -215 ct 2755 -289 2774 -346 2812 -387 ct 
+2851 -428 2900 -448 2960 -448 ct 3019 -448 3067 -428 3104 -388 ct 3141 -348 3160 -292 3160 -220 ct 
+3160 -215 3160 -209 3159 -200 ct 2832 -200 l  2835 -152 2849 -115 2873 -89 ct 
+2898 -64 2928 -51 2965 -51 ct 2992 -51 3015 -58 3035 -72 ct 3054 -87 l  3069 -109 l 
+p
+2836 -261 m  3081 -261 l  3078 -298 3069 -326 3053 -344 ct 3030 -373 2999 -387 2961 -387 ct 
+2927 -387 2898 -376 2875 -353 ct 2852 -330 l  2839 -299 l  p ef
+3255 0 m  3255 -438 l  3322 -438 l  3322 -372 l  3339 -403 3355 -423 3370 -433 ct 
+3384 -443 3400 -448 3417 -448 ct 3442 -448 3468 -440 3494 -424 ct 3468 -355 l 
+3450 -366 3432 -371 3414 -371 ct 3397 -371 3383 -366 3370 -357 ct 3357 -347 3348 -333 3342 -316 ct 
+3334 -289 3330 -261 3330 -229 ct 3330 0 l  p ef
+3617 0 m  3548 0 l  3548 -605 l  3622 -605 l  3622 -389 l  3654 -428 3694 -448 3742 -448 ct 
+3769 -448 3795 -443 3819 -432 ct 3843 -421 3863 -406 3879 -386 ct 3894 -366 3906 -343 3915 -315 ct 
+3924 -287 3928 -257 3928 -225 ct 3928 -150 3910 -92 3873 -51 ct 3835 -10 3791 9 3739 9 ct 
+3687 9 3646 -11 3617 -54 ct p
+3616 -222 m  3616 -170 3623 -132 3638 -108 ct 3661 -70 3693 -51 3733 -51 ct 
+3765 -51 3793 -65 3817 -93 ct 3840 -121 3852 -163 3852 -219 ct 3852 -277 3841 -319 3818 -346 ct 
+3796 -373 3768 -387 3736 -387 ct 3703 -387 3675 -373 3652 -345 ct 3628 -316 l 
+3616 -276 l  p ef
+3970 -219 m  3970 -300 3992 -360 4037 -399 ct 4075 -432 4121 -448 4175 -448 ct 
+4236 -448 4285 -428 4323 -389 ct 4361 -349 4381 -295 4381 -225 ct 4381 -169 4372 -124 4355 -92 ct 
+4338 -59 4314 -34 4281 -16 ct 4249 0 4214 9 4175 9 ct 4114 9 4064 -9 4026 -49 ct 
+3989 -88 l  3970 -145 l  p
+4046 -219 m  4046 -163 4058 -121 4083 -93 ct 4107 -65 4138 -51 4175 -51 ct 4212 -51 4243 -65 4267 -93 ct 
+4292 -121 4304 -164 4304 -221 ct 4304 -276 4292 -317 4267 -345 ct 4243 -373 4212 -387 4175 -387 ct 
+4138 -387 4107 -373 4083 -345 ct 4058 -317 l  4046 -275 l  p ef
+4761 -54 m  4733 -30 4707 -14 4681 -4 ct 4656 5 4628 9 4599 9 ct 4551 9 4514 -1 4488 -25 ct 
+4462 -48 4449 -79 4449 -115 ct 4449 -137 4454 -156 4464 -174 ct 4474 -192 4486 -206 4502 -217 ct 
+4518 -228 4536 -236 4556 -241 ct 4570 -245 4592 -249 4622 -252 ct 4682 -259 4726 -268 4754 -278 ct 
+4755 -288 4755 -295 4755 -297 ct 4755 -328 4748 -349 4734 -361 ct 4715 -378 4686 -387 4649 -387 ct 
+4614 -387 4588 -380 4572 -368 ct 4555 -356 4543 -334 4535 -303 ct 4462 -313 l 
+4468 -344 4479 -369 4495 -388 ct 4510 -408 4532 -422 4560 -433 ct 4589 -443 4622 -448 4660 -448 ct 
+4697 -448 4728 -444 4751 -435 ct 4774 -426 4792 -415 4803 -402 ct 4814 -388 4821 -371 4826 -351 ct 
+4828 -338 4830 -316 4830 -282 ct 4830 -183 l  4830 -114 4831 -70 4834 -52 ct 
+4837 -34 4844 -16 4853 0 ct 4775 0 l  4768 -15 l  4763 -33 l  p
+4754 -220 m  4727 -209 4687 -199 4633 -192 ct 4602 -187 4581 -182 4568 -177 ct 
+4555 -171 4546 -163 4539 -153 ct 4532 -142 4528 -130 4528 -117 ct 4528 -97 4536 -81 4551 -68 ct 
+4566 -54 4588 -48 4617 -48 ct 4645 -48 4671 -54 4693 -67 ct 4716 -79 4732 -96 4742 -118 ct 
+4750 -135 4754 -160 4754 -192 ct p ef
+4922 0 m  4922 -438 l  4989 -438 l  4989 -372 l  5006 -403 5022 -423 5037 -433 ct 
+5051 -443 5067 -448 5084 -448 ct 5109 -448 5135 -440 5161 -424 ct 5135 -355 l 
+5117 -366 5099 -371 5081 -371 ct 5064 -371 5050 -366 5037 -357 ct 5024 -347 5015 -333 5009 -316 ct 
+5001 -289 4997 -261 4997 -229 ct 4997 0 l  p ef
+5499 0 m  5499 -55 l  5471 -11 5430 9 5376 9 ct 5341 9 5309 0 5280 -19 ct 5250 -38 5228 -65 5212 -99 ct 
+5195 -134 5187 -174 5187 -218 ct 5187 -262 5195 -302 5209 -338 ct 5224 -373 5246 -401 5275 -420 ct 
+5304 -439 5337 -448 5373 -448 ct 5399 -448 5423 -443 5444 -431 ct 5464 -420 5481 -406 5494 -388 ct 
+5494 -605 l  5568 -605 l  5568 0 l  p
+5264 -218 m  5264 -162 5276 -120 5299 -92 ct 5323 -65 5351 -51 5383 -51 ct 5416 -51 5443 -64 5466 -91 ct 
+5489 -117 5500 -158 5500 -212 ct 5500 -272 5489 -316 5465 -344 ct 5442 -373 5414 -387 5380 -387 ct 
+5347 -387 5319 -373 5297 -346 ct 5275 -319 l  5264 -277 l  p ef
+pom
+gr
+51 lw 13970 5080 m  13970 6350 l  ps
+11010 7920 m  11900 7920 l  ps
+11010 10460 m  11900 10460 l  ps
+11010 14605 m  11900 14605 l  ps
+11010 17245 m  11900 17245 l  ps
+7835 7955 m  7420 7955 l  ps
+7835 10460 m  7420 10460 l  ps
+7835 14605 m  7420 14605 l  ps
+7835 17245 m  7420 17245 l  ps
+16013 7955 m  16809 7955 l  ps
+19984 7920 m  20592 7920 l  ps
+19984 10460 m  20592 10460 l  ps
+16013 10495 m  16809 10495 l  ps
+16013 14605 m  16809 14605 l  ps
+16013 17245 m  16809 17245 l  ps
+19984 14605 m  20592 14605 l  ps
+19984 17245 m  20592 17245 l  ps
+gr
+0 20290 t 
+pom
+count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore
+%%PageTrailer
+%%Trailer
+%%EOF
diff --git a/docs/exploring-gnuradio/usrp-block-diagram.png b/docs/exploring-gnuradio/usrp-block-diagram.png
new file mode 100644 (file)
index 0000000..55a0f0b
Binary files /dev/null and b/docs/exploring-gnuradio/usrp-block-diagram.png differ
diff --git a/docs/howto-write-a-block/.gitignore b/docs/howto-write-a-block/.gitignore
new file mode 100644 (file)
index 0000000..f65ab6c
--- /dev/null
@@ -0,0 +1,18 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/howto-write-a-block.html
+/gr_block.h.xml
+/howto_1.i.xml
+/howto_square_ff.cc.xml
+/howto_square_ff.h.xml
+/qa_howto_1.py.xml
+/src_lib_Makefile_1.am.xml
+/src_lib_Makefile_2.am.xml
+/howto_square2_ff.cc.xml
+/howto_square2_ff.h.xml
diff --git a/docs/howto-write-a-block/Makefile.am b/docs/howto-write-a-block/Makefile.am
new file mode 100644 (file)
index 0000000..5f58a21
--- /dev/null
@@ -0,0 +1,81 @@
+#
+# 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.
+# 
+
+TARGETS = howto-write-a-block.html
+
+# To avoid build problems for folks who don't have xmlto installed, we
+# don't build the docs by default.
+
+# html: $(TARGETS)
+all: $(TARGETS)
+
+
+EXTRA_DIST =                           \
+       README                          \
+       howto-write-a-block.xml         \
+       howto_1.i                       \
+       make_numbered_listing.py        \
+       qa_howto_1.py                   \
+       src_lib_Makefile_1.am           \
+       src_lib_Makefile_2.am           
+
+
+BUILT_XML_FILES =                      \
+       gr_block.h.xml                  \
+       howto_1.i.xml                   \
+       howto_square_ff.cc.xml          \
+       howto_square_ff.h.xml           \
+       howto_square2_ff.cc.xml         \
+       howto_square2_ff.h.xml          \
+       qa_howto_1.py.xml               \
+       src_lib_Makefile_1.am.xml       \
+       src_lib_Makefile_2.am.xml       
+
+
+howto-write-a-block.html : howto-write-a-block.xml $(BUILT_XML_FILES)
+
+
+gr_block.h.xml: $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h
+
+howto_square_ff.cc.xml: $(top_srcdir)/src/lib/howto_square_ff.cc make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.cc 
+
+howto_square_ff.h.xml: $(top_srcdir)/src/lib/howto_square_ff.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.h 
+
+howto_square2_ff.cc.xml: $(top_srcdir)/src/lib/howto_square2_ff.cc make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.cc 
+
+howto_square2_ff.h.xml: $(top_srcdir)/src/lib/howto_square2_ff.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.h 
+
+
+# ----------------------------------------------------------------
+
+clean:
+       -${RM} -f $(TARGETS) $(BUILT_XML_FILES)
+
+%.html : %.xml
+       xmlto html-nochunks $<
+
+%.xml : % make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $<
diff --git a/docs/howto-write-a-block/README b/docs/howto-write-a-block/README
new file mode 100644 (file)
index 0000000..ff3b75e
--- /dev/null
@@ -0,0 +1 @@
+The contents of this directory are obsolete.
diff --git a/docs/howto-write-a-block/howto-write-a-block.xml b/docs/howto-write-a-block/howto-write-a-block.xml
new file mode 100644 (file)
index 0000000..f8027b4
--- /dev/null
@@ -0,0 +1,959 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "docbookx.dtd" [
+  <!ENTITY gnuradio "<application>GNU Radio</application>">
+  <!ENTITY SWIG "<application>SWIG</application>">
+  <!ENTITY gr_block "<classname>gr_block</classname>">
+  <!ENTITY square "<classname>howto_square_ff</classname>">
+
+  <!ENTITY were "we&apos;re">
+  <!ENTITY well "we&apos;ll">
+  <!ENTITY thats "that&apos;s">
+  <!ENTITY its "it&apos;s">
+  <!ENTITY lets "let&apos;s">
+  <!ENTITY youre "you&apos;re">
+
+  <!ENTITY gr_block_listing SYSTEM "gr_block.h.xml">
+  <!ENTITY qa_howto_1_listing SYSTEM "qa_howto_1.py.xml">
+  <!ENTITY howto_square_ff_h_listing SYSTEM "howto_square_ff.h.xml">
+  <!ENTITY howto_square_ff_cc_listing SYSTEM "howto_square_ff.cc.xml">
+  <!ENTITY howto_square2_ff_h_listing SYSTEM "howto_square2_ff.h.xml">
+  <!ENTITY howto_square2_ff_cc_listing SYSTEM "howto_square2_ff.cc.xml">
+  <!ENTITY howto_1_i_listing SYSTEM "howto_1.i.xml">
+  <!ENTITY src_lib_Makefile_1_am_listing SYSTEM "src_lib_Makefile_1.am.xml">
+  <!ENTITY src_lib_Makefile_2_am_listing SYSTEM "src_lib_Makefile_2.am.xml">
+
+]>
+
+<article>
+
+<articleinfo>
+<title>How to Write a Signal Processing Block</title>
+<author>
+  <firstname>Eric</firstname>
+  <surname>Blossom</surname>
+  <affiliation>
+    <address>
+      <email>eb@comsec.com</email>
+    </address>
+  </affiliation>
+</author>
+
+<revhistory>
+  <revision>
+  <revnumber>0.1</revnumber>
+  <date>2005-01-20</date>
+  </revision>
+  <revision>
+  <revnumber>0.2</revnumber>
+  <date>2005-02-02</date>
+  <revremark>Updated for SWIG 1.3.24</revremark>
+  </revision>
+  <revision>
+  <revnumber>0.3</revnumber>
+  <date>2006-07-21</date>
+  <revremark>Clarification of 1:1 fixed rate vs item size</revremark>
+  </revision>
+</revhistory>
+
+<copyright>
+  <year>2004</year>
+  <year>2005</year>
+  <holder>Free Software Foundation, Inc.</holder>
+</copyright>
+
+<abstract><para>This article explains how to write signal
+processing blocks for <application>GNU Radio</application>.
+</para></abstract>
+
+</articleinfo>
+
+<sect1 id="prereqs"><title>Prerequisites</title>
+<para>This article assumes that the reader has basic familiarity with
+GNU Radio and has read and understood 
+<ulink url="http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html">
+<citetitle>Exploring GNU Radio</citetitle></ulink>.
+</para>
+
+<para>There is a tarball of files that accompany this article.  It
+includes the examples, DocBook source for the article and all the
+Makefiles etc it takes to make it work.  Grab it at <ulink
+url="ftp://ftp.gnu.org/gnu/gnuradio">
+ftp://ftp.gnu.org/gnu/gnuradio</ulink> or one of the mirrors.  The
+file you want is
+<filename>gr-howto-write-a-block-X.Y.tar.gz</filename>.  Pick the one
+with the highest version number. 
+See <ulink url="http://comsec.com/wiki?CvsAccess">
+http://comsec.com/wiki?CvsAccess</ulink> for CVS Access.
+</para>
+
+
+</sect1>
+
+<sect1 id="intro"><title>Introduction</title>
+<para>&gnuradio; provides a framework for building software radios.
+Waveforms -- signal processing applications -- are built using a
+combination of Python code for high level organization, policy, GUI and
+other non performance-critical functions, while performance critical
+signal processing blocks are written in C++.</para>
+
+<para>From the Python point of view, &gnuradio; provides a data flow
+abstraction.  The fundamental concepts are signal processing
+blocks and the connections between them.  This abstraction is
+implemented by the Python <classname>gr.flow_graph</classname> class.
+Each block has a set of input ports and output ports.  Each port has
+an associated data type.  The most common port types are
+<classname>float</classname> and <classname>gr_complex</classname>
+(equivalent to std::complex&lt;float&gt;), though other types are used,
+including those representing structures, arrays or other types of
+packetized data.</para>  
+
+<para>From the high level point-of-view, infinite streams of data flow
+through the ports.  At the C++ level, streams are dealt with in
+convenient sized pieces, represented as contiguous arrays of the
+underlying type.</para>
+
+</sect1>
+
+<sect1 id="overview"><title>The View from 30,000 Feet</title>
+
+<para>This article will walk through the construction of several
+simple signal processing blocks, and explain the techniques and idioms
+used.  Later sections cover debugging signal processing blocks in the
+mixed Python/C++ environment and performance measurement and
+optimization.</para>
+
+<para>The example blocks will be built in the style of all &gnuradio;
+extensions. That is, they are built outside of the gnuradio-core build
+tree, and are constructed as shared libraries that may be dynamically
+loaded into Python using the "import" mechanism.  &SWIG;, the
+Simplified Wrapper and Interface Generator, is used to generate the
+glue that allows our code to be used from Python.</para>
+
+</sect1>
+
+
+<sect1 id="gr_block"><title></title>
+
+<para>The C++ class &gr_block; is the base of all signal processing
+blocks in &gnuradio;.  Writing a new signal processing block involves
+creating 3 files: The .h and .cc files that define the new class and
+the .i file that tells &SWIG; how to generate the glue that binds the
+class into Python.  The new class must derive from &gr_block; or
+one of it&apos;s subclasses.</para>
+
+<para>Our first examples will derive directly from &gr_block;.  Later
+we will look at some other subclasses that simplify the process for
+common cases.</para>
+
+</sect1><!-- end gr_block sect1 -->
+
+
+
+<!-- ================================================================ -->
+
+<sect1 id="autotools"><title>Autotools, Makefiles, and Directory Layout</title>
+
+<para>Before we dive into the code, &lets; talk a bit about the
+overall build environment and the directory structure that &well;
+be using.</para>
+
+<para>To reduce the amount of Makefile hacking that we have to do, and
+to facilitate portability across a variety of systems, we use the GNU
+<application>autoconf</application>,
+<application>automake</application>, and
+<application>libtool</application> tools.  These are collectively
+referred to as the autotools, and once you get over the initial
+shock, they will become your friends. (The good news is that we
+provide boilerplate that can be used pretty much as-is.)</para>
+
+<variablelist>
+
+<varlistentry><term>automake</term>
+
+<listitem><para>automake and configure work together to generate GNU
+compliant Makefiles from a much higher level description contained in
+the corresponding Makefile.am file.  <filename>Makefile.am</filename>
+specifies the libraries and programs to build and the source files
+that compose each.  Automake reads <filename>Makefile.am</filename>
+and produces <filename>Makefile.in</filename>.  Configure reads
+<filename>Makefile.in</filename> and produces
+<filename>Makefile</filename>.  The resulting Makefile contains a
+zillion rules that do the right right thing to build, check and
+install your code.  It is not uncommon for the the resulting
+<filename>Makefile</filename> to be 5 or 6 times larger than
+<filename>Makefile.am</filename>.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term>autoconf</term>
+<listitem><para>autoconf reads <filename>configure.ac</filename>
+and produces the <filename>configure</filename> shell
+script.  <filename>configure</filename> automatically tests for
+features of the underlying system and sets a bunch of variables and
+defines that can be used in the Makefiles and your C++ code to
+conditionalize the build.  If features are required but not found,
+configure will output an error message and stop.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>libtool</term>
+<listitem><para>libtool works behind the scenes and provides the magic
+to construct shared libraries on a wide variety of systems.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<para><xref linkend="dir-layout"/> shows the directory layout and
+common files &well; be using.  After renaming the
+<replaceable>topdir</replaceable> directory, use it in your projects
+too.  We'll talk about particular files as they come up later.</para>
+
+
+<table id="dir-layout"><title>Directory Layout</title>
+<tgroup cols="2">
+
+<thead><row>
+<entry>File/Dir Name</entry>
+<entry>Comment</entry>
+</row>
+</thead>
+
+<tbody>
+
+<row>
+<entry><replaceable>topdir</replaceable>/Makefile.am</entry>
+<entry>Top level Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/Makefile.common</entry>
+<entry>Common fragment included in sub-Makefiles</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/bootstrap</entry>
+<entry>Runs autoconf, automake, libtool first time through</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/config</entry>
+<entry>Directory of m4 macros used by configure.ac</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/configure.ac</entry>
+<entry>Input to autoconf</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/lib</entry>
+<entry>C++ code goes here</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/lib/Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python</entry>
+<entry>Python code goes here</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python/Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python/run_tests</entry>
+<entry>Script to run tests in the build tree</entry>
+</row>
+
+</tbody>
+</tgroup>
+</table>
+
+</sect1>
+
+<!-- ================================================================ -->
+
+<sect1 id="naming"><title>Naming Conventions</title>
+
+<para>&gnuradio; uses a set of naming conventions to assist in
+comprehending the code base and gluing C++ and Python together.
+Please follow them.</para>
+
+<sect2 id="camel-case"><title><emphasis>Death to CamelCaseNames!</emphasis></title>
+
+<para>We've returned to a kinder, gentler era.  We're now using the
+&quot;STL style&quot; naming convention with a couple of modifications
+since we're not using namespaces.</para>
+
+<para>With the exception of macros and other constant values, all
+identifiers shall be lower case with <literal>words_separated_like_this</literal>.</para>
+
+<para>Macros and constant values (e.g., enumerated values,
+<literal>static const int FOO = 23</literal>) shall be in <literal>UPPER_CASE</literal>.</para>
+
+</sect2>
+
+<sect2 id="global_names"><title>Global Names</title>
+
+<para>All globally visible names (types, functions, variables, consts, etc)
+shall begin with a "package prefix", followed by an underscore.  The bulk of
+the code in GNU Radio belongs to the "gr" package, hence
+names look like <literal>gr_open_file (...)</literal>.</para>
+
+<para>Large coherent bodies of code may use other package prefixes, but
+let's try to keep them to a well thought out list.  See the list
+below.</para>
+
+</sect2>
+
+<sect2 id="package_prefixes"><title>Package Prefixes</title>
+
+<para>These are the current package prefixes:
+
+<variablelist>
+
+<varlistentry><term>gr_</term>
+<listitem><para>Almost everything.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>gri_</term>
+<listitem><para>
+Implementation primitives.  Sometimes we
+have both a gr_<replaceable>foo</replaceable> and a gri_<replaceable>foo</replaceable>.  In that case,
+gr_<replaceable>foo</replaceable> would be derived from gr_block and gri_<replaceable>foo</replaceable>
+would be the low level guts of the function.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>atsc_</term>
+<listitem><para>Code related to the Advanced Television Standards Committee HDTV implementation
+</para></listitem>
+</varlistentry>
+
+<varlistentry><term>usrp_</term>
+<listitem><para>Universal Software Radio Peripheral.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>qa_</term>
+<listitem><para>Quality Assurance (Test code.)</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<sect2 id="class-data-members"><title>Class Data Members (instance variables)</title>
+
+<para>All class data members shall begin with d_<replaceable>foo</replaceable>.</para>
+
+<para>The big win is when you're staring at a block of code it's obvious
+which of the things being assigned to persist outside of the block.
+This also keeps you from having to be creative with parameter names
+for methods and constructors.  You just use the same name as the
+instance variable, without the d_. </para>
+
+<literallayout>
+class gr_wonderfulness {
+  std::string   d_name;
+  double        d_wonderfulness_factor;
+
+public:
+  gr_wonderfulness (std::string name, double wonderfulness_factor)
+    : d_name (name), d_wonderfulness_factor (wonderfulness_factor)
+  {
+    ...
+  }
+  ...
+};
+</literallayout>
+
+</sect2>
+
+<sect2 id="static-data-members"><title>Class Static Data Members (class variables)</title>
+
+<para>
+All class static data members shall begin with s_<replaceable>foo</replaceable>.
+</para>
+
+</sect2>
+
+<sect2 id="file-names"><title>File Names</title>
+
+<para>Each significant class shall be contained in its own file.  The
+declaration of class <classname>gr_foo</classname> shall be in 
+<filename>gr_foo.h</filename> and the definition in
+<filename>gr_foo.cc</filename>.</para>
+</sect2>
+
+
+<sect2><title>Suffixes</title>
+
+<para>By convention, we encode the input and output types of signal
+processing blocks in their name using suffixes.  The suffix is
+typically one or two characters long.  Source and sinks have single
+character suffixes.  Regular blocks that have both inputs and outputs
+have two character suffixes.  The first character indicates the type
+of the input streams, the second indicates the type of the output
+streams.  FIR filter blocks have a three character suffix, indicating
+the type of the inputs, outputs and taps, respectively.</para>
+
+<para>These are the suffix characters and their interpretations:
+<itemizedlist>
+<listitem><para>f - single precision floating point</para></listitem>
+<listitem><para>c - complex&lt;float&gt;</para></listitem>
+<listitem><para>s - short (16-bit integer)</para></listitem>
+<listitem><para>i - integer (32-bit integer)</para></listitem>
+</itemizedlist>
+</para>
+
+<para>In addition, for those cases where the block deals with streams
+of vectors, we use the character 'v' as the first character of the
+suffix.  An example of this usage is
+<classname>gr_fft_vcc</classname>.  The FFT block takes a vector of
+complex numbers on its input and produces a vector of complex
+numbers on its output.</para>
+
+</sect2>
+
+</sect1>
+
+
+
+
+<sect1 id="square"><title>First Block: &square;</title>
+
+<para>For our first example &well; create a block that computes
+the square of its single float input.  This block will accept a single
+float input stream and produce a single float output stream.</para>
+
+<para>Following the naming conventions, &well; use
+<literal>howto</literal> as our package prefix, and the block will
+be called <classname>howto_square_ff</classname>.</para>
+
+<para>We are going to arrange that this block, as well as the others
+that we write in this article, end up in the
+<literal>gnuradio.howto</literal> Python module.  This will allow us
+to access it from Python like this:
+<programlisting>
+from gnuradio import howto
+sqr = howto.square_ff ()
+</programlisting>
+</para>
+
+
+<sect2 id="test_driven"><title>Test Driven Programming</title>
+
+<para>We could just start banging out the C++ code, but being highly
+evolved modern programmers, &were; going to write the test code first.
+After all, we do have a good spec for the behavior: take a single
+stream of floats as the input and produce a single stream of floats as
+the output. The output should be the square of the input.</para>
+
+<para>How hard could this be?  Turns out that this is easy! Check out 
+<xref linkend="qa_howto_1.py"/>.</para>
+
+<example id="qa_howto_1.py">
+<title><filename>qa_howto.py</filename> (first version)</title>
+&qa_howto_1_listing;
+</example>
+
+<para>
+<classname>gr_unittest</classname> is an extension to the standard
+python module <classname>unittest</classname>.
+<classname>gr_unittest</classname> adds support for checking
+approximate equality of tuples of float and complex numbers.  
+Unittest uses Python&apos;s reflection mechanism to find all methods that start with
+<methodname>test_</methodname> and runs them.  Unittest wraps each call
+to <methodname>test_*</methodname> with matching calls to 
+<methodname>setUp</methodname> and <methodname>tearDown</methodname>.
+See the python <ulink url="http://docs.python.org/lib/module-unittest.html">
+unittest</ulink> documentation for details.
+</para>
+
+<para>When we run the test,
+gr_unittest.main is going to invoke
+<methodname>setUp</methodname>,
+<methodname>test_001_square_ff</methodname>, and
+<methodname>tearDown</methodname>.</para>
+<para>
+<methodname>test_001_square_ff</methodname> builds a small graph that
+contains three nodes.  gr.vector_source_f(src_data) will source the
+elements of src_data and then say that &its; finished.  howto.square_ff is the block
+&were; testing.  gr.vector_sink_f gathers the output of
+howto.square_ff.</para>
+
+<para>The <methodname>run</methodname> method runs the graph until all
+the blocks indicate they are finished.  Finally, we check that the
+result of executing square_ff on src_data matches what we expect.
+</para>
+
+</sect2>
+
+<sect2 id="build_vs_install"><title>Build Tree vs. Install Tree</title>
+
+<para>The build tree is everything from <replaceable>topdir</replaceable>
+(the one containing configure.ac) down.  The path to the install tree is
+<filename>
+<replaceable>prefix</replaceable>/lib/python<replaceable>version</replaceable>/site-packages</filename>,
+where <replaceable>prefix</replaceable> is the <literal>--prefix</literal>
+argument to configure (default <filename>/usr/local</filename>) and 
+<replaceable>version</replaceable> is the installed version of
+python. A typical value is 
+<filename>/usr/local/lib/python2.3/site-packages</filename>.</para>
+
+
+<para>We normally set our PYTHONPATH environment variable to point at
+the install tree, and do this in <filename>~/.bash_profile</filename> 
+or <filename>~/.profile</filename>.
+This allows our python apps to access all the standard python
+libraries, plus our locally installed stuff like GNU Radio.</para>
+
+<para>We write our applications such that they access the code and
+libraries in the install tree.  On the other hand, we want our test
+code to run on the build tree, where we can detect problems before
+installation.</para>
+
+</sect2>
+
+<sect2 id="make_check"><title>make check</title>
+
+
+<para>We use <command>make check</command> to run our tests.
+Make check invokes the <command>run_tests</command> shell script which 
+sets up the PYTHONPATH environment variable so that 
+our tests use the build tree versions of our code and libraries.
+It then runs all files
+which have names of the form <filename>qa_*.py</filename> and reports
+the overall success or failure.</para>
+
+<para>There is quite a bit of behind-the-scenes action required to use
+the non-installed versions of our code (look at
+<filename>runtest</filename> for a cheap thrill.)</para>
+
+<para>Finally, running <command>make check</command> in the python
+directory produces this result:
+<literallayout>
+  [eb@bufo python]$ make check
+  make  check-TESTS
+  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  Traceback (most recent call last):
+    File "./qa_howto.py", line 24, in ?
+      import howto
+  ImportError: No module named howto
+  Traceback (most recent call last):
+    File "./qa_howto_1.py", line 24, in ?
+      import howto
+  ImportError: No module named howto
+  FAIL: run_tests
+  ===================
+  1 of 1 tests failed
+  ===================
+  make[1]: *** [check-TESTS] Error 1
+  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  make: *** [check-am] Error 2
+  [eb@bufo python]$
+</literallayout>
+Excellent!  Our test failed, just as we expected.  The ImportError
+indicates that it can't find the module named
+<classname>howto</classname>.  No surprise, since we haven't written it yet.
+</para>
+
+</sect2>
+
+<sect2><title>The C++ code</title>
+<para>Now that we've got a test case written that successfully fails,
+let's write the C++ code.  As we mentioned earlier, all signal
+processing blocks are derived from <classname>gr_block</classname> or
+one of its subclasses.  Let's take a look at 
+<xref linkend="gr_block.h"/>.</para>
+
+<example id="gr_block.h">
+<title><filename>gr_block.h</filename></title>
+&gr_block_listing;
+</example>
+
+<para>A quick scan of <filename>gr_block.h</filename> reveals that
+since <methodname>general_work</methodname> is pure virtual, we
+definitely need to override that. 
+<methodname>general_work</methodname> is the method that does the
+actual signal processing.  For our squaring example we'll
+need to override <methodname>general_work</methodname> and provide a
+constructor and destructor and a bit of stuff to take advantage of
+the <ulink url="http://www.boost.org">boost</ulink>
+<ulink url="http://www.boost.org/libs/smart_ptr/smart_ptr.htm">
+<classname>shared_ptr</classname>s.</ulink>
+
+</para>
+
+
+<para><xref linkend="howto_square_ff.h"/> 
+and <xref linkend="howto_square_ff.cc"/> are the header and c++
+source.</para>
+
+<example id="howto_square_ff.h">
+<title><filename>howto_square_ff.h</filename></title>
+&howto_square_ff_h_listing;
+</example>
+
+<example id="howto_square_ff.cc">
+<title><filename>howto_square_ff.cc</filename></title>
+&howto_square_ff_cc_listing;
+</example>
+
+<para>Now we need a Makefile.am to get all this to build.  
+<xref linkend="src_lib_Makefile_1"/> 
+is enough to build a shared library from our source file.  We'll be
+adding additional rules to use &SWIG; in just a bit.  If you haven't
+already, this is a good time to browse all the Makefile.am&apos;s in
+the build tree and get an idea for how it all hangs together.</para>
+
+<example id="src_lib_Makefile_1">
+<title><filename>src/lib/Makefile.am</filename> (no &SWIG;)</title>
+&src_lib_Makefile_1_am_listing;
+</example>
+
+</sect2>
+
+
+<!-- ==============================
+
+<sect2 id="io_sig"><title><classname>gr_io_signature</classname></title>
+<para></para>
+</sect2>
+
+<sect2 id="forecast"><title><methodname>forecast</methodname></title>
+<para></para>
+</sect2>
+
+<sect2 id="output_multiple">
+<title><methodname>set_output_multiple</methodname></title>
+<para></para>
+</sect2>
+
+  ============================== -->
+
+
+<sect2 id="swig"><title>The &SWIG; .i file</title> 
+
+<para>Now that we've got something that will compile, we need to write
+the &SWIG; .i file.  This is a pared-down version of the .h file, plus
+a bit of magic that has python work with the boost shared_ptr&apos;s.
+To reduce code bloat, we only declare methods that &well; want to
+access from Python.</para>
+
+<para>We&apos;re going to call the .i file
+<filename>howto.i</filename>, and use it to hold the &SWIG;
+declarations for all classes from <literal>howto</literal> that will
+be accessible from python.  It&apos;s quite small:
+&howto_1_i_listing;
+</para>
+
+</sect2>
+
+<sect2><title>Putting it all together</title>
+<para>
+Now we need to modify <filename>src/lib/Makefile.am</filename>
+to run &SWIG; and to add the glue it generates to the shared library.</para>
+
+<example id="src_lib_Makefile_2">
+<title><filename>src/lib/Makefile.am</filename> (with &SWIG;)</title>
+&src_lib_Makefile_2_am_listing;
+</example>
+
+<para><command>make</command> now builds everything successfully.  We get a
+few warnings, but &thats; OK.</para>
+
+<para>Changing directories back to the python directory we try
+<command>make check</command> again:
+<literallayout>
+  [eb@bufo python]$ make check
+  make  check-TESTS
+  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  .
+  ----------------------------------------------------------------------
+  Ran 1 test in 0.004s
+  
+  OK
+  PASS: run_tests
+  ==================
+  All 1 tests passed
+  ==================
+  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  [eb@bufo python]$
+</literallayout>
+<emphasis>Victory! Our new block works!</emphasis>
+</para>
+
+</sect2>
+
+</sect1><!-- end First Block: square -->
+
+<sect1 id="additional_methods"><title>Additional gr_block methods</title>
+
+<para>In our <classname>howto_square_ff</classname> example above, we only
+had to override the <methodname>general_work</methodname> method to
+accomplish our goal.  <classname>gr_block</classname> provides a few other
+methods that are sometimes useful.</para>
+
+<sect2 id="forecast"><title>forecast</title>
+
+<para>Looking at <methodname>general_work</methodname> you may
+have wondered how the system knows how much data it needs to
+ensure is valid in each of the input arrays.  The
+<methodname>forecast</methodname> method provides this
+information.</para>
+
+<para>The default implementation of <methodname>forecast</methodname>
+says there is a 1:1 relationship between noutput_items and the
+requirements for each input stream.  The size of the items is defined by
+<classname>gr_io_signature</classname>s in the constructor of
+<classname>gr_block</classname>. The sizes of the input and output items
+can of course differ; this still qualifies as a 1:1 relationship.
+<programlisting>
+  // default implementation:  1:1
+
+  void
+  gr_block::forecast (int noutput_items,
+                      gr_vector_int &amp;ninput_items_required)
+  {
+    unsigned ninputs = ninput_items_required.size ();
+    for (unsigned i = 0; i &lt; ninputs; i++)
+      ninput_items_required[i] = noutput_items;
+  }
+</programlisting>
+</para>
+
+<para>Although the 1:1 implementation worked for howto_square_ff, it
+wouldn&apos;t be appropriate for interpolators, decimators, or blocks
+with a more complicated relationship between noutput_items and the
+input requirements.  That said, by deriving your classes from
+<classname>gr_sync_block</classname>,
+<classname>gr_sync_interpolator</classname> or
+<classname>gr_sync_decimator</classname> instead of
+<classname>gr_block</classname>, you can often avoid
+implementing <methodname>forecast</methodname>.</para>
+
+</sect2>
+
+<sect2 id="set_output_multiple"><title>set_output_multiple</title>
+
+<para>When implementing your <methodname>general_work</methodname>
+routine, &its; occasionally convenient to have the run time system
+ensure that you are only asked to produce a number of output items
+that is a multiple of some particular value.  This might occur if your
+algorithm naturally applies to a fixed sized block of data. 
+Call <methodname>set_output_multiple</methodname> in your constructor
+to specify this requirement. The default output multiple is 1.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="common_patterns">
+<title>Subclasses for common patterns</title>
+
+<para><classname>gr_block</classname> allows tremendous flexibility
+with regard to the consumption of input streams and the production of
+output streams.  Adroit use of <methodname>forecast</methodname> and
+<methodname>consume</methodname> allows variable rate blocks to be
+built.  It is possible to construct blocks that consume data at
+different rates on each input, and produce output at a rate that
+is a function of the contents of the input data.</para>
+
+<para>On the other hand, it is very common for signal processing
+blocks to have a fixed relationship between the input rate and the
+output rate.  Many are 1:1, while others have 1:N or N:1
+relationships.</para>
+
+<para>Another common requirement is the need to examine more than one
+input sample to produce a single output sample.  This is orthogonal to
+the relationship between input and output rate.  For example, a
+non-decimating, non-interpolating FIR filter needs to examine N input
+samples for each output sample it produces, where N is the number of
+taps in the filter.  However, it only consumes a single input sample
+to produce a single output.  We call this concept "history", but you
+could also think of it as "look-ahead".</para>
+
+<sect2 id="gr_sync_block"><title><classname>gr_sync_block</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__block.html">
+<classname>gr_block</classname></ulink>
+and implements a 1:1 block with
+optional history.  Given that we know the input to output rate,
+certain simplifications are possible.  From the implementor&apos;s
+point-of-view, the primary change is that we define a
+<methodname>work</methodname> method instead of
+<methodname>general_work</methodname>.  <methodname>work</methodname>
+has a slightly different calling sequence;
+It omits the unnecessary ninput_items parameter, and arranges for
+<methodname>consume_each</methodname> to be called on our
+behalf.</para>
+<programlisting>
+  /*!
+   * \brief Just like gr_block::general_work, only this arranges to
+   *  call consume_each for you.
+   *
+   * The user must override work to define the signal processing code
+   */
+  virtual int work (int noutput_items,
+                    gr_vector_const_void_star &amp;input_items,
+                    gr_vector_void_star &amp;output_items) = 0;
+</programlisting>
+
+<para>This gives us fewer things to worry about, and less code to
+write.  If the block requires history greater than 1, call
+<methodname>set_history</methodname> in the constructor, or any time
+the requirement changes.</para>
+
+<para><classname>gr_sync_block</classname> provides a
+version of <methodname>forecast</methodname> that handles the
+history requirement.</para>
+
+</sect2>
+
+<sect2 id="gr_sync_decimator"><title><classname>gr_sync_decimator</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__decimator.html">
+<classname>gr_sync_decimator</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+and implements a N:1 block with optional history.  
+</para>
+
+</sect2>
+
+<sect2 id="gr_sync_interpolator"><title><classname>gr_sync_interpolator</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__interpolator.html">
+<classname>gr_sync_interpolator</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+and implements a 1:N block with optional history.  
+</para>
+
+</sect2>
+
+
+</sect1>
+
+<sect1 id="square2">
+<title>Second Block: <classname>howto_square2_ff</classname></title>
+
+<para>Given that we now know about
+<classname>gr_sync_block</classname>, the way 
+<classname>howto_square_ff</classname> should really be implemented is
+by subclassing <classname>gr_sync_block</classname>.</para>
+
+<para>Here are the revised sources: <xref
+linkend="howto_square2_ff.h"/>, 
+<xref linkend="howto_square2_ff.cc"/>.  
+The accompanying files contain the additional test code.
+</para>
+
+<example id="howto_square2_ff.h">
+<title><filename>howto_square2_ff.h</filename></title>
+&howto_square2_ff_h_listing;
+</example>
+
+<example id="howto_square2_ff.cc">
+<title><filename>howto_square2_ff.cc</filename></title>
+&howto_square2_ff_cc_listing;
+</example>
+
+</sect1>
+
+<sect1 id="where_to"><title>Where to from Here?</title>
+
+<para>At this point, we&apos;ve got a basic overview of how the system
+goes together.  For more insight, I suggest that you look at the code
+of the system.  The doxygen generated <ulink
+url="http://www.gnu.org/software/gnuradio/doc/hierarchy.html"> class
+hierarchy</ulink> is a useful way to find things that might interest
+you.</para>
+
+</sect1>
+
+
+<sect1 id="tips"><title>Miscellaneous Tips</title>
+
+<sect2 id="sources_and_sinks"><title>Sources and Sinks</title>
+
+<para>Sources and sinks are derived from
+<classname>gr_sync_block</classname>.  The only thing different about
+them is that sources have no inputs and sinks have no outputs.  This
+is reflected in the <classname>gr_io_signature</classname>s that are
+passed to the <classname>gr_sync_block</classname> constructor.
+Take a look at <filename>gr_file_source.{h,cc}</filename> and
+<filename>gr_file_sink.{h,cc}</filename> for some very straight-forward examples.
+</para>
+
+</sect2>
+
+<sect2 id="debugging">
+<title>Debugging with <application>gdb</application></title>
+
+<para>If your block isn&apos;t working, and you can&apos;t sort it
+out through python test cases or a few printfs in the code, you may want to
+use <application>gdb</application> to debug it.  The trick of course
+is that all of &gnuradio;, including your new block, is dynamically
+loaded into python for execution.</para>
+
+<para>Try this:  In your python test code, after the relevant imports,
+print out the process id and wait for a keystroke.  In another
+window run gdb and tell it to attach to the python process with the
+given process id.  At this point you can set breakpoints or whatever
+in your code.  Go back to the python window and hit Enter so
+it&apos;ll continue.</para>
+
+<programlisting>
+  #!/usr/bin/env python
+  from gnuradio import gr
+  from gnuradio import my_buggy_module
+
+  # insert this in your test code...
+  import os
+  print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
+  raw_input ('Press Enter to continue: ')
+  # remainder of your test code follows...
+</programlisting>
+
+<para>Another SNAFU you might run into is that gdb 6.2 isn&apos;t
+able to set breakpoints in the constructors or destructors generated
+by g++ 3.4.  In this case, insert a call to the nop function
+gri_debugger_hook in the constructor and recompile.  Load the code as
+before and set a break point on gri_debugger_hook.</para>
+
+</sect2>
+
+<sect2 id="oprofile">
+<title>Performance Measurement with <application>oprofile</application></title>
+<para>Oprofile is your friend.  
+See <ulink url="http://oprofile.sourceforge.net">http://oprofile.sourceforge.net</ulink>.
+</para>
+</sect2>
+
+</sect1><!-- end tips -->
+
+<sect1 id="futures"><title>Coming Attractions</title>
+<para></para>
+
+<sect2 id="types"><title>Improved Type System</title>
+<para></para>
+</sect2>
+
+<sect2 id="hierarchy"><title>Hierarchical Blocks</title>
+<para></para>
+</sect2>
+
+</sect1><!-- end Coming Attractions -->
+
+</article>
diff --git a/docs/howto-write-a-block/howto_1.i b/docs/howto-write-a-block/howto_1.i
new file mode 100644 (file)
index 0000000..640d089
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "howto_square_ff.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+/*
+ * First arg is the package prefix.
+ * Second arg is the name of the class minus the prefix.
+ *
+ * This does some behind-the-scenes magic so we can
+ * access howto_square_ff from python as howto.square_ff
+ */
+GR_SWIG_BLOCK_MAGIC(howto,square_ff);
+
+howto_square_ff_sptr howto_make_square_ff ();
+
+class howto_square_ff : public gr_block
+{
+private:
+  howto_square_ff ();
+};
diff --git a/docs/howto-write-a-block/make_numbered_listing.py b/docs/howto-write-a-block/make_numbered_listing.py
new file mode 100755 (executable)
index 0000000..889c2d7
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+import sys
+import os, os.path
+from optparse import OptionParser
+
+def quote_line (line):
+    line = line.replace ('&', '&amp;')
+    line = line.replace ('<', '&lt;')
+    line = line.replace ('>', '&gt;')
+    line = line.replace ("'", '&apos;')
+    line = line.replace ('"', '&quot;')
+    return line
+
+def generate_listing (input_filename, title=None):
+    inf = open (input_filename, "r")
+    output_filename = os.path.basename (input_filename) + '.xml'
+    outf = open (output_filename, "w")
+    outf.write ('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
+    # outf.write ('<example id="%s">\n' % (input_filename,))
+    # if not title:
+    #     title = input_filename
+    # outf.write ('<title>')
+    # outf.write (title)
+    # outf.write ('</title>\n')
+    outf.write ('<programlisting>\n');
+
+    lineno = 0
+    for line in inf:
+        line = line.expandtabs (8)
+        line = quote_line (line)
+        lineno = lineno + 1
+        outf.write ('%3d  %s' % (lineno, line))
+
+    outf.write ('</programlisting>\n')
+    # outf.write ('</example>\n')
+
+
+def main ():
+    for file in sys.argv[1:]:
+        generate_listing (file)
+
+if __name__ == '__main__':
+    main ()
+    
diff --git a/docs/howto-write-a-block/qa_howto_1.py b/docs/howto-write-a-block/qa_howto_1.py
new file mode 100755 (executable)
index 0000000..3173110
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+import howto
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_square_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto.square_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/docs/howto-write-a-block/src_lib_Makefile_1.am b/docs/howto-write-a-block/src_lib_Makefile_1.am
new file mode 100644 (file)
index 0000000..e97d70d
--- /dev/null
@@ -0,0 +1,25 @@
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.howto module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+ourlib_LTLIBRARIES = _howto.la
+
+# These are the source files that go into the shared library
+_howto_la_SOURCES =                    \
+       howto_square_ff.cc              
+
+# magic flags
+_howto_la_LDFLAGS = -module -avoid-version
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       howto_square_ff.h               
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/docs/howto-write-a-block/src_lib_Makefile_2.am b/docs/howto-write-a-block/src_lib_Makefile_2.am
new file mode 100644 (file)
index 0000000..dca236e
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Copyright 2004,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.howto module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+SWIGCPPPYTHONARGS = -noruntime -c++ -python $(PYTHON_CPPFLAGS) \
+       -I$(swigincludedir) -I$(grincludedir) $(WITH_SWIG_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
+
+
+LOCAL_IFILES =                                 \
+       howto.i                         
+
+# These files are built by SWIG.  The first is the C++ glue.
+# The second is the python wrapper that loads the _howto shared library
+# and knows how to call our extensions.
+
+BUILT_SOURCES =                        \
+       howto.cc                        \
+       howto.py                                
+
+# This gets howto.py installed in the right place
+ourpython_PYTHON =                     \
+       howto.py
+
+ourlib_LTLIBRARIES = _howto.la
+
+# These are the source files that go into the shared library
+_howto_la_SOURCES =                    \
+       howto.cc                        \
+       howto_square_ff.cc              
+
+# magic flags
+_howto_la_LDFLAGS = -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+_howto_la_LIBADD =                     \
+       -lgrswigrunpy                   \
+       -lstdc++                        
+
+howto.cc howto.py: howto.i $(ALL_IFILES)
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module howto -o howto.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       howto_square_ff.h               
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/dtools/README b/dtools/README
new file mode 100644 (file)
index 0000000..938ef6d
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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.
+# 
+
+This is a collection of tools that are useful for building tarball
+distributions of GNU Radio.  They're probably not of general interest.
+
+To use, add dtools/bin to PATH and dtools/python to PYTHONPATH
diff --git a/dtools/bin/check-config-files b/dtools/bin/check-config-files
new file mode 100755 (executable)
index 0000000..7111c95
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# usage: takes list of directories on command line
+
+import sys
+import os
+import os.path
+from itertools import ifilter, ifilterfalse, imap, izip
+import md5
+from pprint import pprint
+from sets import Set
+
+class info(object):
+    def __init__(self, dir, name, md5sum):
+        self.dir = dir
+        self.name = name
+        self.md5sum = md5sum
+    def __repr__(self):
+        return '<%r, %r, %r>' % (self.dir, self.name, self.md5sum)
+
+
+def md5sum_file(filename):
+    f = open(filename, 'r')
+    m = md5.new(f.read())
+    return m.hexdigest()
+
+def process_dir(dir):
+    files = list(ifilterfalse(lambda s: s.endswith('~'),
+                              _filter(os.listdir(dir), ('CVS','Makefile', 'Makefile.in', '.svn'))))
+    return [info(dir, f, md5sum_file(os.path.join(dir, f))) for f in files]
+
+
+# Return a copy with items that occur in skip removed.
+#
+def _filter(flist, skip):
+    return list(ifilterfalse(skip.__contains__, flist))
+
+def main():
+    dirs = sys.argv[1:]
+    r = []
+    for d in dirs:
+        r += process_dir(d)
+
+    names = Set([x.name for x in r])
+    #pprint(names)
+
+    # check for missing files across the union of names
+    for d in dirs:
+        names_in_dir = Set([x.name for x in r if x.dir == d])
+        diff = names.difference(names_in_dir)
+        if len(diff) != 0:
+            print "%s is missing %r" % (d, diff)
+
+    # check for different versions of files
+    name_list = [n for n in names]
+    name_list.sort()
+
+    for name in name_list:
+        vers = {}
+        pairs = [(x.dir, x.md5sum) for x in r if x.name == name]
+        for (dir, sum) in pairs:
+            if vers.has_key(sum):
+                vers[sum].append(dir)
+            else:
+                vers[sum] = [ dir ]
+        if len(vers) != 1:     # multiple versions
+            print "Multiple versions of %s:" % (name,)
+            pprint(vers)
+    
+    # pprint(r)
+
+if __name__ == '__main__':
+    main()
diff --git a/dtools/bin/check-imports b/dtools/bin/check-imports
new file mode 100755 (executable)
index 0000000..75ca547
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+find . -name '*.py' | xargs grep -h -E '^(from|import)' | sort -u 
+
diff --git a/dtools/bin/check-tarball-h-files b/dtools/bin/check-tarball-h-files
new file mode 100755 (executable)
index 0000000..6e3e1e7
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+tarball=$1
+if [ "x$tarball" = "x" ]
+then
+  echo "usage: $0 tarball" 1>&2
+  exit 1
+fi
+
+path=${tarball%%.tar.gz}
+
+tar tzf $tarball  \
+  | grep -E '\.(h|py|v|vh)$'   \
+  | sed -e "s/$path/./"  \
+  | sort >/tmp/tarball-h-files
+
+find . \( -name '*.h' -o -name '*.py' -o -name '*.v' -o -name '*.vh' \) -print \
+  | grep -v ./$path | sort >/tmp/build-h-files
+
+comm -23 /tmp/build-h-files /tmp/tarball-h-files \
+ | grep -Ev '(GrAtsc|_swig_|limbo|config\.h|std_paths\.h)'
+
+# rm /tmp/tarball-h-files /tmp/build-h-files
+
+
diff --git a/dtools/bin/get-config-files b/dtools/bin/get-config-files
new file mode 100755 (executable)
index 0000000..d9e8811
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# fetch latest config.guess and config.sub
+
+# They've moved...
+# wget -O config.guess 'http://savannah.gnu.org/cgi-bin/viewcvs/config/config/config.guess?rev=HEAD&content-type=text/plain'
+# wget -O config.sub 'http://savannah.gnu.org/cgi-bin/viewcvs/config/config/config.sub?rev=HEAD&content-type=text/plain'
+
+wget -O config.guess 'http://cvs.savannah.gnu.org/viewvc/*checkout*/config/config/config.guess?content-type=text%2Fplain&revision=HEAD'
+wget -O config.sub   'http://cvs.savannah.gnu.org/viewvc/*checkout*/config/config/config.sub?content-type=text%2Fplain&revision=HEAD'
diff --git a/dtools/bin/install-tbb b/dtools/bin/install-tbb
new file mode 100755 (executable)
index 0000000..95ffbed
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+"""
+Install the release and debug libs and includes under --prefix
+"""
+
+from optparse import OptionParser
+import os
+import os.path
+import glob
+
+default_prefix="/usr/local"
+
+pkgconfig_filename = "tbb.pc"
+pkgconfig_file_contents = """\
+prefix=%s
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: tbb
+Description: Intel Threading Building Blocks
+Requires: 
+Version: 2.0
+Libs: -L${libdir} -ltbb -ltbbmalloc
+Cflags: -I${includedir}
+"""
+
+debug_pkgconfig_filename = "tbb_debug.pc"
+debug_pkgconfig_file_contents = """\
+prefix=%s
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: tbb
+Description: Intel Threading Building Blocks
+Requires: 
+Version: 2.0
+Libs: -L${libdir} -ltbb_debug -ltbbmalloc_debug
+Cflags: -I${includedir}
+"""
+
+def main():
+   parser = OptionParser()
+   parser.add_option('','--prefix', default=default_prefix,
+                     help="install architecture-independent files in PREFIX [default=%default]")
+   (options, args) = parser.parse_args()
+   if len(args) != 0:
+      parser.print_help()
+      raise SystemExit, 1
+
+   prefix = options.prefix
+   
+   # are we installing 64-bit libs?
+
+   is_64bit = False
+   files = glob.glob('build/*_em64t_*_release')
+   # print "files: ", files
+   if len(files) != 0:
+      is_64bit = True
+
+   # FIXME add 32 and 64-bit PPC support
+
+   if is_64bit:
+      lib = 'lib64'
+   else:
+      lib = 'lib'
+      
+   os.system('install -d ' + os.path.join(prefix, 'include/tbb'))
+   os.system('install -d ' + os.path.join(prefix, 'include/tbb/machine'))
+   os.system('install -d ' + os.path.join(prefix, lib))
+   os.system('install -d ' + os.path.join(prefix, lib, 'pkgconfig'))
+   os.system('install -t ' + os.path.join(prefix, lib) + ' build/linux*release/*.so*')
+   os.system('install -t ' + os.path.join(prefix, lib) + ' build/linux*debug/*.so*')
+   os.system('install -t ' + os.path.join(prefix, 'include/tbb') + ' include/tbb/*.h')
+   os.system('install -t ' + os.path.join(prefix, 'include/tbb/machine') + ' include/tbb/machine/*.h')
+
+   f = open(os.path.join(prefix, lib, 'pkgconfig', pkgconfig_filename), 'w')
+   f.write(pkgconfig_file_contents % (prefix,))
+   f.close()
+   
+   f = open(os.path.join(prefix, lib, 'pkgconfig', debug_pkgconfig_filename), 'w')
+   f.write(debug_pkgconfig_file_contents % (prefix,))
+   f.close()
+   
+if __name__ == "__main__":
+   main()
diff --git a/dtools/bin/make-upload b/dtools/bin/make-upload
new file mode 100755 (executable)
index 0000000..967dcfa
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+read -s -p "GPG Passphrase: " passphrase
+
+for file in "$@"
+do
+  (
+    echo "version: 1.1"
+    echo "directory: gnuradio"
+    echo "filename: $file"
+  )> $file.directive
+  echo "$passphrase" | gpg --passphrase-fd 0 --clearsign $file.directive
+  rm $file.directive
+  echo "$passphrase" | gpg --passphrase-fd 0 -b $file
+done
+passphrase="XYZabcdefhghakdsj;lasjdf;ajfdiuiwjr;lajv;laoisfuaoieurlkajdsflkajsdfoiuew"
diff --git a/dtools/bin/tweak-cell-for-cross-compiling b/dtools/bin/tweak-cell-for-cross-compiling
new file mode 100755 (executable)
index 0000000..e637004
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+
+"""
+This should only be run on a native Cell machine.  E.g., ps3, qs21, etc.
+
+It makes a few modifications to the file system and some pseudo shared libs
+so that cross compiling from a build machine over NFS works.  The changes
+do not harm local compilation.
+
+We create a symlink from /mnt/cell-root that points to /
+This allows the local and build machine to access the root filesystem
+using a common name, /mnt/cell-root.  This is required because
+configure hardcodes absolute paths into the generated Makefiles.
+
+There are some .so files that aren't really shared libraries, but rather are
+ascii linker scripts containing instructions to the linker.  Most of them
+contain a GROUP directive that includes hard-coded paths relative to /.
+We modify those files such that the hard-coded paths are relative to /mnt/cell-root
+instead of /.  This allows them to work locally and while cross compiling over NFS.
+
+E.g., /usr/lib/libc.so originally contains:
+
+    /* GNU ld script
+       Use the shared library, but some functions are only in
+       the static library, so try that secondarily.  */
+    OUTPUT_FORMAT(elf32-powerpc)
+    GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld.so.1 ) )
+
+We modify it such that it reads:
+
+    /* GNU ld script
+       Use the shared library, but some functions are only in
+       the static library, so try that secondarily.  */
+    OUTPUT_FORMAT(elf32-powerpc)
+    GROUP ( /mnt/cell-root/lib/libc.so.6 /mnt/cell-root/usr/lib/libc_nonshared.a  AS_NEEDED ( /mnt/cell-root/lib/ld.so.1 ) )
+
+We backup <foo>.so to <foo>.so.original
+
+"""
+
+import os
+import os.path
+import sys
+import shutil
+import re
+
+cell_root_path = '/mnt/cell-root'
+
+def ensure_cell():
+    s = open('/proc/cpuinfo','r').read()
+    if s.find('Cell Broadband Engine') == -1:
+        sys.stderr.write('This program should only be run on Cell machines.\n')
+        raise SystemExit, 1
+
+def make_symlinks():
+    create_symlink_if_reqd(cell_root_path, "..")
+    create_symlink_if_reqd("/opt/cell/toolchain", "../../usr")
+    create_symlink_if_reqd("/opt/cell/sysroot", "../..")
+
+def symlink_exists_and_is_ok(path, contents):
+    return (os.path.islink(path) and os.readlink(path) == contents)
+
+def create_symlink_if_reqd(path, contents):
+    if symlink_exists_and_is_ok(path, contents):
+        return
+
+    if os.path.islink(path):
+        # Is a symlink but points wrong place
+        os.remove(path)
+        os.symlink(contents, path)
+        return
+
+    if os.path.isdir(path):
+        # if it's empty we'll remove it and create the link
+        try:
+            os.rmdir(path)
+        except:
+            # directory wasn't empty
+            sys.stderr.write("There's already something at %s.\n" % (path,))
+            sys.stderr.write("Please remove it or move it out of the way and try again.\n")
+            raise SystemExit, 1
+        os.symlink(contents, path)
+        return
+        
+    if os.path.exists(path):
+        # There's something here, return an error
+        sys.stderr.write("There's already something at %s.\n" % (path,))
+        sys.stderr.write("Please remove it or move it out of the way and try again.\n")
+        raise SystemExit, 1
+
+    # nothing there; go ahead and create the symlink
+    os.symlink(contents, path)
+
+
+def find_ascii_shared_libs():
+    cmd = "find /lib /lib64 /usr/lib /usr/lib64 -name '*.so' -type f -print 2>/dev/null | xargs file | grep -v ELF | cut -d: -f 1"
+    pipe = os.popen(cmd, 'r')
+    filenames = pipe.read().splitlines()
+    return filenames
+
+
+def make_backup_copy(src):
+    dst = src + '.original'
+    if not os.path.exists(dst):
+        shutil.copy2(src, dst)
+
+
+def edit_file(name):
+    def replace_group_body(mo):
+        pat = ' /(?!' + cell_root_path[1:] + ')'  # negative lookahead assertion
+        new = re.sub(pat, ' ' + cell_root_path + '/', mo.group(2))
+        return mo.group(1) + new + mo.group(3)
+        
+    f = open(name,'r')
+    s = f.read()
+    f.close()
+    
+    pat = re.compile(r'^( *GROUP *\()(.*)(\) *)$', re.M)
+    t = pat.sub(replace_group_body, s)
+
+    f = open(name,'w')
+    f.write(t)
+    f.close()
+
+
+def edit_ascii_shared_libs():
+    print "Please be patient, this takes awhile..."
+    filenames = find_ascii_shared_libs()
+    for f in filenames:
+        make_backup_copy(f)
+        edit_file(f)
+
+
+def main():
+    ensure_cell()
+    make_symlinks()
+    edit_ascii_shared_libs()
+
+
+if __name__ == '__main__':
+    main()
+    
+
diff --git a/dtools/bin/update_fsf_address b/dtools/bin/update_fsf_address
new file mode 100755 (executable)
index 0000000..ec67ef0
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+#
+# 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import re
+import os
+import os.path
+import sys
+from optparse import OptionParser
+
+dry_run = False
+modified_files = []
+
+dirs_to_ignore = ('CVS', '.svn', '.deps', '.libs')
+extensions_to_ignore = ('.o', '.lo',
+                        '.a', '.la', '.lai',
+                        '.so', '.soT',
+                        '.pyc', '.pyo',
+                        '.ko', '.fasl', '.rwbak',
+                        '.tar', '.gz', '.log',
+                        '.eps', '.ps', '.pdf',
+                        '.png', '.jpg', '.jpeg', '.bmp',
+                        '.dat', '.ihx',
+                        '.diff',
+                        '.lib', '.lst', '.rel', '.sym', '.asm', '.rst', 'mem', '.map', # sdcc output
+                        '.rbf', '.esf', '.qpf', '.psf', '.quartus', '.bsf', '.cmp'     # quartus
+                        )
+
+def destructively_remove(list, predicate):
+    """
+    Destructively remove elements from LIST for which PREDICATE is true
+    """
+    for i in range(len(list)):
+        if predicate(list[i]):
+            del list[i]
+            destructively_remove(list, predicate)
+            return
+
+
+def expunge_unwanted_dirnames(dirnames):
+    """
+    Destructively remove directory names that we don't want to visit.
+    This is a _very_ non-functional approach to programming...
+    """
+    destructively_remove(dirnames, lambda d: d in dirs_to_ignore)
+
+def expunge_unwanted_filenames(filenames):
+    """
+    Destructively remove filenames that we don't want to visit.
+    This is a _very_ non-functional approach to programming...
+    """
+    destructively_remove(filenames,
+                         lambda f: f.endswith('~') or os.path.splitext(f)[1] in extensions_to_ignore)
+
+
+def walk_directory(dirname):
+    for dirpath, dirnames, filenames in os.walk(dirname):
+        expunge_unwanted_dirnames(dirnames)
+        expunge_unwanted_filenames(filenames)
+        for f in filenames:
+            update_one(os.path.join(dirpath, f))
+
+
+addr_pattern = re.compile(r'\b59 Temple Place(,| *-) *Suite 330\b', re.IGNORECASE)
+addr_replacement = '51 Franklin Street'
+zip_pattern  = re.compile(r'\b02111-1307\b')
+zip_replacement = '02110-1301'
+
+def update_one(filename):
+    f = open(filename, 'r')
+    s = f.read()
+    f.close()
+    t = s
+    t = addr_pattern.sub(addr_replacement, t)
+    t = zip_pattern.sub(zip_replacement, t)
+    if s != t:
+        modified_files.append(filename)
+        if not dry_run:
+            f = open(filename, 'w')
+            f.write(t)
+
+
+def handle_file_or_dir(file_or_dir):
+    if os.path.isfile(file_or_dir):
+        update_one(file_or_dir)
+    elif os.path.isdir(file_or_dir):
+        walk_directory(file_or_dir)
+    else:
+        pass   # ignore the other cases
+
+
+def main():
+    global dry_run
+    
+    usage = '%prog: [options] [file_or_dir...]'
+    parser = OptionParser (usage=usage)
+    parser.add_option('-l', '--list-modified-files', action='store_true', default=False,
+                      help='List modified files to stdout [default=%default]')
+    parser.add_option('', '--dry-run', action='store_true', default=False,
+                      help="Don't modify any files, just report what would be modified [default=%default]")
+    (options, args) = parser.parse_args()
+
+    dry_run = options.dry_run
+    if options.dry_run:
+        options.list_modified_files = True
+        
+    for file_or_dir in args:
+        handle_file_or_dir(file_or_dir)
+
+    if options.list_modified_files:
+        for f in modified_files:
+            sys.stdout.write(f + '\n')
+
+        
+if __name__ == '__main__':
+    main()
+    
diff --git a/dtools/microblaze/mb-gcc-4.1.1-gr-1.patch b/dtools/microblaze/mb-gcc-4.1.1-gr-1.patch
new file mode 100644 (file)
index 0000000..fe7d18d
--- /dev/null
@@ -0,0 +1,47 @@
+--- orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss.patch     2008-01-29 15:42:56.000000000 -0800
++++ new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss.patch      2008-10-05 08:47:12.000000000 -0700
+@@ -232,7 +232,7 @@
+ +all: ${CRT} ${OBJS}\r
+  \r
+  install: ${CRT}\r
+-      @for crt in ${CRT}; do\\r
++      @for crt in ${CRT}; do \\r
+ diff -urNp --exclude '*.swp' newlib-orig/libgloss/microblaze/open.c newlib/libgloss/microblaze/open.c\r
+ --- newlib-orig/libgloss/microblaze/open.c    1969-12-31 16:00:00.000000000 -0800\r
+ +++ newlib/libgloss/microblaze/open.c 2007-05-07 19:07:04.000000000 -0700\r
+diff -urN orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss_more_funcs.patch new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss_more_funcs.patch
+--- orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss_more_funcs.patch  2008-01-29 15:42:56.000000000 -0800
++++ new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libgloss_more_funcs.patch   2008-10-05 08:47:12.000000000 -0700
+@@ -1007,7 +1007,7 @@
+ @@ -71,7 +71,7 @@ all: ${CRT} ${LIB}
+  
+  install: ${CRT} ${LIB}
+-      @for crt in ${CRT}; do\
++      @for crt in ${CRT}; do \
+ -     $(INSTALL_PROGRAM) $${crt} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${crt}; \
+ +     $(INSTALL_PROGRAM) $${crt} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${crt}; \
+       done
+diff -urN orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libmb.patch new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libmb.patch
+--- orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libmb.patch        2008-01-29 15:42:56.000000000 -0800
++++ new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14.0_libmb.patch 2008-10-05 08:47:12.000000000 -0700
+@@ -25,7 +25,7 @@
+  \r
+ -install: ${CRT}\r
+ +install: ${CRT} ${LIB}\r
+-      @for crt in ${CRT}; do\\r
++      @for crt in ${CRT}; do \\r
+       $(INSTALL_PROGRAM) $${crt} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${crt}; \\r
+       done\r
+ +     $(INSTALL_PROGRAM) ${LIB} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}\r
+diff -urN orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14_crt.patch new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14_crt.patch
+--- orig/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14_crt.patch    2008-01-29 15:42:56.000000000 -0800
++++ new/Xilinx_EDK_GNU_10.1i/mb/srcs/newlib-1.14_crt.patch     2008-10-05 08:47:12.000000000 -0700
+@@ -619,7 +619,7 @@
+ +all: ${CRT} 
+ +
+ +install: ${CRT}
+-+     @for crt in ${CRT}; do\
+++     @for crt in ${CRT}; do \
+ +     $(INSTALL_PROGRAM) $${crt} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${crt}; \
+ +     done
+ +
diff --git a/dtools/release-checklist b/dtools/release-checklist
new file mode 100644 (file)
index 0000000..9e2e377
--- /dev/null
@@ -0,0 +1,11 @@
+Caveats:
+
+* gr-howto-write-a-block must be checked out into it's own top-level
+  working copy for build, otherwise automake will grab the depcomp,
+  install-sh, etc. files from the parent directory, and not put them
+  in the distribution tarball.
+
+* Ubuntu's automake (at least) will copy config.guess and config.sub from
+  Ubuntu's system directory, even if there is already one in the directory.
+  You need to 'svn revert config.guess config.sub' after running bootstrap
+  and before running configure.
\ No newline at end of file
diff --git a/gcell/.gitignore b/gcell/.gitignore
new file mode 100644 (file)
index 0000000..a553089
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/gcell.pc
+/gcell_spu.pc
diff --git a/gcell/apps/.gitignore b/gcell/apps/.gitignore
new file mode 100644 (file)
index 0000000..b80e1a9
--- /dev/null
@@ -0,0 +1,12 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/test_all
+/benchmark_nop
+/benchmark_dma
+/benchmark_roundtrip
index 7cf9122a34eb0b1ad737e59d062870f1b91f8577..c3a2092a33b05b64e69fb854e76a5f07d181afa9 100644 (file)
@@ -22,9 +22,7 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = spu .
 
-AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) \
-       $(GCELL_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES)
-
+AM_CPPFLAGS = $(DEFINES) $(GCELL_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES)
 
 GCELL_QA_LA = $(top_builddir)/gcell/lib/libgcell-qa.la
 
index a84defe3709c305f9dff93d4a785dc80f18750aa..bc3b3f3289f4914e9f8f2966e2033e99cbb5c505 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 #include <gcell/gc_job_manager.h>
-#include <gnuradio/omni_time.h>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <getopt.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -95,6 +95,8 @@ init_jd(gc_job_desc *jd, unsigned int usecs,
 static void
 run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size, int getput_mask)
 {
+  using namespace boost::posix_time;
+
   static const int64_t TOTAL_SIZE_DMA = 5LL << 30;
   static const int NJDS = 64;
   unsigned int njobs = (unsigned int)(TOTAL_SIZE_DMA / dma_size);
@@ -148,7 +150,7 @@ run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size, int getp
 
   for (int iter = 0; iter < 1; iter++){
 
-    omni_time t_start = omni_time::time();
+    ptime t_start(microsec_clock::universal_time());
 
     nsubmitted = 0;
     ncompleted = 0;
@@ -203,9 +205,9 @@ run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size, int getp
     }
 
     // stop timing
-    omni_time t_stop = omni_time::time();
+    ptime t_stop(microsec_clock::universal_time());
 
-    double delta = (t_stop - t_start).double_time();
+    double delta = (t_stop - t_start).total_microseconds() * 1e-6;
     printf("nspes: %2d  udelay: %4d  elapsed_time: %7.3f  dma_size: %5d  dma_throughput: %7.3e\n",
           mgr->nspes(), usecs, delta, dma_size,
           (double) njobs * dma_size / delta * (getput_mask == BENCHMARK_GET_PUT ? 2.0 : 1.0));
index dee46c84208e708e41b1aa4acdcd75871e2cedf7..a27373db406a4effd9f46dce0cdbdeacb38055b5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 #include <gcell/gc_job_manager.h>
-#include <gnuradio/omni_time.h>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <getopt.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -47,6 +47,8 @@ init_jd(gc_job_desc *jd, unsigned int usecs)
 static void
 run_test(unsigned int nspes, unsigned int usecs, int njobs)
 {
+  using namespace boost::posix_time;
+
   static const int NJDS = 64;
   int nsubmitted = 0;
   int ncompleted = 0;
@@ -73,7 +75,7 @@ run_test(unsigned int nspes, unsigned int usecs, int njobs)
     init_jd(all_jds[i], usecs);
   }
 
-  omni_time t_start = omni_time::time();
+  ptime t_start(microsec_clock::universal_time());
 
   ci = 0;
   njds[0] = 0;
@@ -122,8 +124,8 @@ run_test(unsigned int nspes, unsigned int usecs, int njobs)
   }
 
   // stop timing
-  omni_time t_stop = omni_time::time();
-  double delta = (t_stop - t_start).double_time();
+  ptime t_stop(microsec_clock::universal_time());
+  double delta = (t_stop - t_start).total_microseconds() * 1e-6;
   printf("nspes: %2d  udelay: %4d  elapsed_time: %7.3f  njobs: %g  speedup: %6.3f\n",
         mgr->nspes(), usecs, delta, (double) njobs,
         njobs * usecs * 1e-6 / delta);
index 8ba37c968e168a8ea6014e94bc3a30593561658f..b994182a88ae086b8ffbf7f57d96b7de66ed5cb4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 #include <gcell/gc_job_manager.h>
-#include <gnuradio/omni_time.h>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <getopt.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -96,6 +96,8 @@ static void
 run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size,
         int getput_mask, int njobs_at_once)
 {
+  using namespace boost::posix_time;
+
   int NJDS = njobs_at_once;
   gc_job_desc *all_jds[NJDS];
   bool done[NJDS];
@@ -140,7 +142,7 @@ run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size,
   }
 
   int niter = 100000;
-  omni_time t_start = omni_time::time();
+  ptime t_start(microsec_clock::universal_time());
 
   for (int iter = 0; iter < niter; iter++){
 
@@ -164,8 +166,8 @@ run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size,
   }
 
   // stop timing
-  omni_time t_stop = omni_time::time();
-  double delta = (t_stop - t_start).double_time();
+  ptime t_stop(microsec_clock::universal_time());
+  double delta = (t_stop - t_start).total_microseconds() * 1e-6;
   printf("nspes: %2d  udelay: %4d  elapsed_time: %7.3f  dma_size: %5d  dma_throughput: %7.3e  round_trip: %gus\n",
         mgr->nspes(), usecs, delta, dma_size,
         (double) NJDS * niter * dma_size / delta * (getput_mask == BENCHMARK_GET_PUT ? 2.0 : 1.0),
diff --git a/gcell/apps/gen_script.py b/gcell/apps/gen_script.py
new file mode 100755 (executable)
index 0000000..2ad0fb7
--- /dev/null
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+
+import sys
+import time
+import os
+
+from optparse import OptionParser
+
+
+def get_svn_rev():
+    try:
+        f = os.popen("svn info", "r")
+        lines = f.readlines()
+        f.close()
+    except:
+        return "unk"
+
+    svn_rev = "unk"
+    for l in lines:
+        if l.startswith('Revision:'):
+            t = l.rstrip()
+            svn_rev = t.split()[-1]
+    return svn_rev
+    
+def is_ps3():
+    try:
+        f = open("/proc/cpuinfo")
+        s = f.read()
+    except:
+        return False
+
+    return s.find('PS3') != -1
+
+
+def main():
+
+    def make_fname(suffix):
+        return basename + '.' + suffix
+
+    max_spes_default = 16
+    if is_ps3():
+        max_spes_default = 6
+        
+    parser = OptionParser()
+    parser.add_option("-m", "--max-spes", type="int", default=max_spes_default,
+                      metavar="NSPES",
+                      help="maximum number of SPEs to use [default=%default]")
+    parser.add_option("", "--min-spes", type="int", default=1,
+                      metavar="NSPES",
+                      help="minimum number of SPEs to use [default=%default]")
+    parser.add_option("-p", "--oprofile", action="store_true", default=False,
+                      help="emit oprofile commands")
+    parser.add_option("-t", "--tag", default=None,
+                      help="additional goodie in generated filenames")
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    #FIXME to use git now
+    svn_rev = get_svn_rev()
+
+    os.environ['TZ'] = 'PST8PDT'        # always pacific
+    time.tzset()
+
+    tag = ''
+    if options.tag:
+        tag = '-' + options.tag
+        
+    basename = 'R-%s%s-%s' % (svn_rev, tag, time.strftime('%Y%m%d-%H%M'))
+
+    base_njobs = int(500e3)
+    njobs = {
+         1 : base_njobs,
+        10 : base_njobs,
+        50 : base_njobs,
+       100 : base_njobs, 
+       200 : int(base_njobs/2),
+       250 : int(base_njobs/2.5),
+       300 : int(base_njobs/3),
+       400 : int(base_njobs/4),
+       500 : int(base_njobs/5)
+        }
+
+    
+    f_results = make_fname('results')
+    f_opreport = make_fname('opreport')
+    f_avg = make_fname('avg')
+    f_png = make_fname('png')
+
+    f = sys.stdout
+    f.write("#!/bin/bash\n")
+
+    if options.oprofile:
+        f.write("opcontrol --stop\n")
+        f.write("opcontrol --reset\n")
+        f.write("opcontrol --start\n")
+
+    f.write("(\n")
+
+    for udelay in (10, 50, 100, 200, 300):
+        for nspes in range(options.min_spes, options.max_spes+1):
+            cmd = "./benchmark_nop -n %d -u %d -N %d\n" % (nspes, udelay, njobs[udelay])
+            f.write(cmd)
+            f.write(cmd)
+
+    f.write(") | tee %s\n" % (f_results,))
+
+    if options.oprofile:
+        f.write("opcontrol --dump\n")
+        f.write("opcontrol --stop\n")
+        f.write("opreport -l | head -100 > %s\n" % (f_opreport,))
+
+    f.write("./split_and_avg_results.py %s > %s\n" % (f_results, f_avg))
+    f.write("./plot_speedup.py %s -o %s\n" % (f_avg, f_png))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/gcell/apps/plot_speedup.py b/gcell/apps/plot_speedup.py
new file mode 100755 (executable)
index 0000000..37822a7
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+from pylab import *
+from pprint import pprint
+import os.path
+
+
+def add_entry(d, nspes, speedup, work_incr):
+    if d.has_key(work_incr):
+        d[work_incr].append((nspes, speedup))
+    else:
+        d[work_incr] = [(nspes, speedup)]
+    
+def parse_file(f):
+    d = {}
+    for line in f:
+        items = [float(x) for x in line.split()]
+        # print "items =", items
+        nspes = items[0]
+        work_incr = int(1e6 * items[1])
+        speedup = items[4]
+        add_entry(d, nspes, speedup, work_incr)
+    return d
+
+
+class plot_data(object):
+    def __init__(self, filenames, output_filename):
+        self.fig = figure(1, figsize=(8, 6), facecolor='w')
+        self.sp = self.fig.add_subplot(1,1,1)
+        self.sp.set_xlabel("nspes", fontweight="bold")
+        self.sp.set_ylabel("speedup", fontweight="bold")
+        self.sp.grid(True)
+        # print 'rcParams["legend.fontsize"] =', rcParams["legend.fontsize"]
+        rcParams["legend.fontsize"] = 10
+
+
+        self.markers = {
+              5 : 'x',
+             10 : 'o',
+             50 : 's',
+            100 : '^',
+            200 : 'D',
+            300 : 'v',
+            400 : '>',
+            500 : 'h'
+            }
+        
+        if len(filenames) == 1:
+            f = filenames[0]
+            d = parse_file(open(f))
+            self.make_single_plot(d, f)
+            
+        else:
+            for f in filenames:
+                d = parse_file(open(f))
+                self.make_plot(d, f, f == filenames[0])
+
+        if output_filename:
+            savefig(output_filename)
+        else:
+            show()
+
+
+    def make_single_plot(self, d, filename):
+        def style(k):
+            return self.markers[k]
+
+        tag, ext = os.path.splitext(os.path.basename(filename))
+        title(tag)
+        keys = d.keys()
+        keys.sort()
+        keys.reverse()
+        for k in keys:
+            vlist = d[k]         # list of 2-tuples
+            xs = [v[0] for v in vlist]
+            ys = [v[1] for v in vlist]
+            plot(xs, ys, style(k), label="%d us" % (k,))
+
+        x = legend(loc=2)
+
+    def make_plot(self, d, filename, first):
+        def style(k):
+            if first:
+                return self.markers[k]
+            else:
+                return 'k' + self.markers[k]
+
+        tag, ext = os.path.splitext(os.path.basename(filename))
+        keys = d.keys()
+        keys.sort()
+        keys.reverse()
+        for k in keys:
+            vlist = d[k]         # list of 2-tuples
+            xs = [v[0] for v in vlist]
+            ys = [v[1] for v in vlist]
+            plot(xs, ys, style(k), label="%s %d us" % (tag, k))
+
+        x = legend(loc=2)
+
+def main():
+    usage="%prog: [options] input_filename..."
+    description = "Plot R*.avg files from benchmark_nop.py"
+    parser = OptionParser(usage=usage, description=description)
+    parser.add_option('-o', '--output', default=None,  metavar="FILE",
+                      help="generate .png file")
+    (options, args) = parser.parse_args()
+    if len(args) < 1:
+        parser.print_help()
+        raise SystemExit, 1
+
+    filenames = args
+    dc = plot_data(filenames, options.output)
+
+
+        
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+
diff --git a/gcell/apps/results-071223 b/gcell/apps/results-071223
new file mode 100644 (file)
index 0000000..2716171
--- /dev/null
@@ -0,0 +1,126 @@
+nspes:  1  udelay:    1  elapsed_time:  26.117  njobs: 1e+06  us/job:  26.117
+nspes:  1  udelay:    1  elapsed_time:  26.058  njobs: 1e+06  us/job:  26.058
+nspes:  1  udelay:    1  elapsed_time:  26.737  njobs: 1e+06  us/job:  26.737
+nspes:  2  udelay:    1  elapsed_time:  23.585  njobs: 1e+06  us/job:  23.585
+nspes:  2  udelay:    1  elapsed_time:  21.958  njobs: 1e+06  us/job:  21.958
+nspes:  2  udelay:    1  elapsed_time:  21.034  njobs: 1e+06  us/job:  21.034
+nspes:  3  udelay:    1  elapsed_time:  25.819  njobs: 1e+06  us/job:  25.819
+nspes:  3  udelay:    1  elapsed_time:  23.719  njobs: 1e+06  us/job:  23.719
+nspes:  3  udelay:    1  elapsed_time:  21.711  njobs: 1e+06  us/job:  21.711
+nspes:  4  udelay:    1  elapsed_time:  20.210  njobs: 1e+06  us/job:  20.210
+nspes:  4  udelay:    1  elapsed_time:  20.558  njobs: 1e+06  us/job:  20.558
+nspes:  4  udelay:    1  elapsed_time:  20.957  njobs: 1e+06  us/job:  20.957
+nspes:  5  udelay:    1  elapsed_time:  24.571  njobs: 1e+06  us/job:  24.571
+nspes:  5  udelay:    1  elapsed_time:  20.207  njobs: 1e+06  us/job:  20.207
+nspes:  5  udelay:    1  elapsed_time:  21.976  njobs: 1e+06  us/job:  21.976
+nspes:  6  udelay:    1  elapsed_time:  22.601  njobs: 1e+06  us/job:  22.601
+nspes:  6  udelay:    1  elapsed_time:  18.794  njobs: 1e+06  us/job:  18.794
+nspes:  6  udelay:    1  elapsed_time:  19.755  njobs: 1e+06  us/job:  19.755
+nspes:  1  udelay:    5  elapsed_time:  28.047  njobs: 1e+06  us/job:  28.047
+nspes:  1  udelay:    5  elapsed_time:  27.265  njobs: 1e+06  us/job:  27.265
+nspes:  1  udelay:    5  elapsed_time:  27.555  njobs: 1e+06  us/job:  27.555
+nspes:  2  udelay:    5  elapsed_time:  21.130  njobs: 1e+06  us/job:  21.130
+nspes:  2  udelay:    5  elapsed_time:  21.067  njobs: 1e+06  us/job:  21.067
+nspes:  2  udelay:    5  elapsed_time:  21.607  njobs: 1e+06  us/job:  21.607
+nspes:  3  udelay:    5  elapsed_time:  23.712  njobs: 1e+06  us/job:  23.712
+nspes:  3  udelay:    5  elapsed_time:  23.658  njobs: 1e+06  us/job:  23.658
+nspes:  3  udelay:    5  elapsed_time:  25.277  njobs: 1e+06  us/job:  25.277
+nspes:  4  udelay:    5  elapsed_time:  22.264  njobs: 1e+06  us/job:  22.264
+nspes:  4  udelay:    5  elapsed_time:  20.970  njobs: 1e+06  us/job:  20.970
+nspes:  4  udelay:    5  elapsed_time:  21.533  njobs: 1e+06  us/job:  21.533
+nspes:  5  udelay:    5  elapsed_time:  21.504  njobs: 1e+06  us/job:  21.504
+nspes:  5  udelay:    5  elapsed_time:  21.956  njobs: 1e+06  us/job:  21.956
+nspes:  5  udelay:    5  elapsed_time:  21.333  njobs: 1e+06  us/job:  21.333
+nspes:  6  udelay:    5  elapsed_time:  20.639  njobs: 1e+06  us/job:  20.639
+nspes:  6  udelay:    5  elapsed_time:  23.022  njobs: 1e+06  us/job:  23.022
+nspes:  6  udelay:    5  elapsed_time:  22.453  njobs: 1e+06  us/job:  22.453
+nspes:  1  udelay:   10  elapsed_time:  27.780  njobs: 1e+06  us/job:  27.780
+nspes:  1  udelay:   10  elapsed_time:  27.683  njobs: 1e+06  us/job:  27.683
+nspes:  1  udelay:   10  elapsed_time:  26.803  njobs: 1e+06  us/job:  26.803
+nspes:  2  udelay:   10  elapsed_time:  20.878  njobs: 1e+06  us/job:  20.878
+nspes:  2  udelay:   10  elapsed_time:  22.430  njobs: 1e+06  us/job:  22.430
+nspes:  2  udelay:   10  elapsed_time:  20.952  njobs: 1e+06  us/job:  20.952
+nspes:  3  udelay:   10  elapsed_time:  22.752  njobs: 1e+06  us/job:  22.752
+nspes:  3  udelay:   10  elapsed_time:  24.294  njobs: 1e+06  us/job:  24.294
+nspes:  3  udelay:   10  elapsed_time:  23.935  njobs: 1e+06  us/job:  23.935
+nspes:  4  udelay:   10  elapsed_time:  20.437  njobs: 1e+06  us/job:  20.437
+nspes:  4  udelay:   10  elapsed_time:  21.498  njobs: 1e+06  us/job:  21.498
+nspes:  4  udelay:   10  elapsed_time:  20.521  njobs: 1e+06  us/job:  20.521
+nspes:  5  udelay:   10  elapsed_time:  22.704  njobs: 1e+06  us/job:  22.704
+nspes:  5  udelay:   10  elapsed_time:  21.106  njobs: 1e+06  us/job:  21.106
+nspes:  5  udelay:   10  elapsed_time:  22.800  njobs: 1e+06  us/job:  22.800
+nspes:  6  udelay:   10  elapsed_time:  21.098  njobs: 1e+06  us/job:  21.098
+nspes:  6  udelay:   10  elapsed_time:  22.749  njobs: 1e+06  us/job:  22.749
+nspes:  6  udelay:   10  elapsed_time:  19.651  njobs: 1e+06  us/job:  19.651
+nspes:  1  udelay:   50  elapsed_time:  54.621  njobs: 1e+06  us/job:  54.621
+nspes:  1  udelay:   50  elapsed_time:  54.548  njobs: 1e+06  us/job:  54.548
+nspes:  1  udelay:   50  elapsed_time:  54.641  njobs: 1e+06  us/job:  54.641
+nspes:  2  udelay:   50  elapsed_time:  30.837  njobs: 1e+06  us/job:  30.837
+nspes:  2  udelay:   50  elapsed_time:  30.933  njobs: 1e+06  us/job:  30.933
+nspes:  2  udelay:   50  elapsed_time:  30.044  njobs: 1e+06  us/job:  30.044
+nspes:  3  udelay:   50  elapsed_time:  24.170  njobs: 1e+06  us/job:  24.170
+nspes:  3  udelay:   50  elapsed_time:  23.798  njobs: 1e+06  us/job:  23.798
+nspes:  3  udelay:   50  elapsed_time:  23.515  njobs: 1e+06  us/job:  23.515
+nspes:  4  udelay:   50  elapsed_time:  23.011  njobs: 1e+06  us/job:  23.011
+nspes:  4  udelay:   50  elapsed_time:  21.382  njobs: 1e+06  us/job:  21.382
+nspes:  4  udelay:   50  elapsed_time:  20.531  njobs: 1e+06  us/job:  20.531
+nspes:  5  udelay:   50  elapsed_time:  24.157  njobs: 1e+06  us/job:  24.157
+nspes:  5  udelay:   50  elapsed_time:  21.119  njobs: 1e+06  us/job:  21.119
+nspes:  5  udelay:   50  elapsed_time:  22.055  njobs: 1e+06  us/job:  22.055
+nspes:  6  udelay:   50  elapsed_time:  19.136  njobs: 1e+06  us/job:  19.136
+nspes:  6  udelay:   50  elapsed_time:  20.607  njobs: 1e+06  us/job:  20.607
+nspes:  6  udelay:   50  elapsed_time:  20.527  njobs: 1e+06  us/job:  20.527
+nspes:  1  udelay:  100  elapsed_time: 107.531  njobs: 1e+06  us/job: 107.531
+nspes:  1  udelay:  100  elapsed_time: 107.607  njobs: 1e+06  us/job: 107.607
+nspes:  1  udelay:  100  elapsed_time: 107.532  njobs: 1e+06  us/job: 107.532
+nspes:  2  udelay:  100  elapsed_time:  53.950  njobs: 1e+06  us/job:  53.950
+nspes:  2  udelay:  100  elapsed_time:  53.920  njobs: 1e+06  us/job:  53.920
+nspes:  2  udelay:  100  elapsed_time:  54.232  njobs: 1e+06  us/job:  54.232
+nspes:  3  udelay:  100  elapsed_time:  37.987  njobs: 1e+06  us/job:  37.987
+nspes:  3  udelay:  100  elapsed_time:  38.778  njobs: 1e+06  us/job:  38.778
+nspes:  3  udelay:  100  elapsed_time:  39.042  njobs: 1e+06  us/job:  39.042
+nspes:  4  udelay:  100  elapsed_time:  31.192  njobs: 1e+06  us/job:  31.192
+nspes:  4  udelay:  100  elapsed_time:  31.090  njobs: 1e+06  us/job:  31.090
+nspes:  4  udelay:  100  elapsed_time:  31.472  njobs: 1e+06  us/job:  31.472
+nspes:  5  udelay:  100  elapsed_time:  28.490  njobs: 1e+06  us/job:  28.490
+nspes:  5  udelay:  100  elapsed_time:  27.574  njobs: 1e+06  us/job:  27.574
+nspes:  5  udelay:  100  elapsed_time:  27.013  njobs: 1e+06  us/job:  27.013
+nspes:  6  udelay:  100  elapsed_time:  26.635  njobs: 1e+06  us/job:  26.635
+nspes:  6  udelay:  100  elapsed_time:  24.036  njobs: 1e+06  us/job:  24.036
+nspes:  6  udelay:  100  elapsed_time:  26.174  njobs: 1e+06  us/job:  26.174
+nspes:  1  udelay:  300  elapsed_time: 320.618  njobs: 1e+06  us/job: 320.618
+nspes:  1  udelay:  300  elapsed_time: 320.635  njobs: 1e+06  us/job: 320.635
+nspes:  1  udelay:  300  elapsed_time: 320.699  njobs: 1e+06  us/job: 320.699
+nspes:  2  udelay:  300  elapsed_time: 160.314  njobs: 1e+06  us/job: 160.314
+nspes:  2  udelay:  300  elapsed_time: 160.340  njobs: 1e+06  us/job: 160.340
+nspes:  2  udelay:  300  elapsed_time: 160.312  njobs: 1e+06  us/job: 160.312
+nspes:  3  udelay:  300  elapsed_time: 106.878  njobs: 1e+06  us/job: 106.878
+nspes:  3  udelay:  300  elapsed_time: 106.875  njobs: 1e+06  us/job: 106.875
+nspes:  3  udelay:  300  elapsed_time: 106.871  njobs: 1e+06  us/job: 106.871
+nspes:  4  udelay:  300  elapsed_time:  80.158  njobs: 1e+06  us/job:  80.158
+nspes:  4  udelay:  300  elapsed_time:  80.163  njobs: 1e+06  us/job:  80.163
+nspes:  4  udelay:  300  elapsed_time:  80.154  njobs: 1e+06  us/job:  80.154
+nspes:  5  udelay:  300  elapsed_time:  64.156  njobs: 1e+06  us/job:  64.156
+nspes:  5  udelay:  300  elapsed_time:  64.250  njobs: 1e+06  us/job:  64.250
+nspes:  5  udelay:  300  elapsed_time:  64.158  njobs: 1e+06  us/job:  64.158
+nspes:  6  udelay:  300  elapsed_time:  53.633  njobs: 1e+06  us/job:  53.633
+nspes:  6  udelay:  300  elapsed_time:  53.541  njobs: 1e+06  us/job:  53.541
+nspes:  6  udelay:  300  elapsed_time:  53.617  njobs: 1e+06  us/job:  53.617
+nspes:  1  udelay:  500  elapsed_time: 533.638  njobs: 1e+06  us/job: 533.638
+nspes:  1  udelay:  500  elapsed_time: 533.649  njobs: 1e+06  us/job: 533.649
+nspes:  1  udelay:  500  elapsed_time: 533.618  njobs: 1e+06  us/job: 533.618
+nspes:  2  udelay:  500  elapsed_time: 266.810  njobs: 1e+06  us/job: 266.810
+nspes:  2  udelay:  500  elapsed_time: 266.814  njobs: 1e+06  us/job: 266.814
+nspes:  2  udelay:  500  elapsed_time: 266.893  njobs: 1e+06  us/job: 266.893
+nspes:  3  udelay:  500  elapsed_time: 177.875  njobs: 1e+06  us/job: 177.875
+nspes:  3  udelay:  500  elapsed_time: 177.878  njobs: 1e+06  us/job: 177.878
+nspes:  3  udelay:  500  elapsed_time: 177.875  njobs: 1e+06  us/job: 177.875
+nspes:  4  udelay:  500  elapsed_time: 133.417  njobs: 1e+06  us/job: 133.417
+nspes:  4  udelay:  500  elapsed_time: 133.483  njobs: 1e+06  us/job: 133.483
+nspes:  4  udelay:  500  elapsed_time: 133.407  njobs: 1e+06  us/job: 133.407
+nspes:  5  udelay:  500  elapsed_time: 106.723  njobs: 1e+06  us/job: 106.723
+nspes:  5  udelay:  500  elapsed_time: 106.728  njobs: 1e+06  us/job: 106.728
+nspes:  5  udelay:  500  elapsed_time: 106.722  njobs: 1e+06  us/job: 106.722
+nspes:  6  udelay:  500  elapsed_time:  88.943  njobs: 1e+06  us/job:  88.943
+nspes:  6  udelay:  500  elapsed_time:  88.941  njobs: 1e+06  us/job:  88.941
+nspes:  6  udelay:  500  elapsed_time:  88.944  njobs: 1e+06  us/job:  88.944
diff --git a/gcell/apps/split_and_avg_results.py b/gcell/apps/split_and_avg_results.py
new file mode 100755 (executable)
index 0000000..8a750fa
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+input file looks like this:
+
+nspes:  1  udelay:   10  elapsed_time:   6.842  njobs: 500000  speedup:  0.731
+nspes:  2  udelay:   10  elapsed_time:   4.093  njobs: 500000  speedup:  1.221
+"""
+
+import sys
+from optparse import OptionParser
+from pprint import pprint
+
+class data(object):
+    def __init__(self, nspes, work_per_job, elapsed_time, njobs):
+        self.nspes = nspes
+        self.work_per_job = work_per_job  # seconds
+        self.elapsed_time = elapsed_time  # seconds
+        self.njobs = njobs
+        self.speedup = work_per_job * njobs / elapsed_time
+
+    def __repr__(self):
+        return "<data nspes=%d work_per_job=%s elapsed_time=%s njobs=%s speedup=%s>" % (
+            self.nspes, (self.work_per_job),
+            (self.elapsed_time),
+            (self.njobs),
+            (self.speedup))
+
+def cmp_data(x, y):
+    t = x.nspes - y.nspes
+    if t == 0:
+        t = x.work_per_job - y.work_per_job
+        if t < 0:
+            return -1
+        elif t > 0:
+            return +1
+        else:
+            return 0
+    return t
+
+def main():
+    usage = "usage: %prog [options] input_filename"
+    parser = OptionParser(usage=usage)
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        raise SystemExit, 1
+    input_filename = args[0]
+
+    
+    m = {}
+    for line in open(input_filename, "r"):
+        s = line.split()
+        nspes = int(s[1])
+        work_per_job = int(s[3]) * 1e-6
+        elapsed_time = float(s[5])
+        njobs = float(s[7])
+        d = data(nspes, work_per_job, elapsed_time, njobs)
+
+        # collect lists that have the same values for nspes and work_per_job
+        # so we can generate an average elapsed_time from all observations
+        key = (nspes, work_per_job)
+        v = m.get(key, [])
+        v.append(d)
+        m[key] = v
+
+    r = []
+    for k, v in m.iteritems():
+        total_elapsed_time = sum([x.elapsed_time for x in v])
+        r.append(data(v[0].nspes,
+                      v[0].work_per_job,
+                      total_elapsed_time/len(v),
+                      v[0].njobs))
+
+    r.sort(cmp_data)
+
+    #pprint(r)
+    for t in r:
+        print t.nspes, t.work_per_job, t.elapsed_time, t.njobs, t.speedup
+
+if __name__ == '__main__':
+    main()
diff --git a/gcell/apps/spu/.gitignore b/gcell/apps/spu/.gitignore
new file mode 100644 (file)
index 0000000..c50e521
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/*.a
+/*.la
+/*.lo
+/.deps
+/.libs
+/benchmark_procs
index d88d0fb674462155f7623fc599f9c8719d527317..1a3cd9c26acffb84084bc214a5f770fb69a9e4fc 100644 (file)
@@ -6,7 +6,7 @@ gcell_embedspu_libtool=@bindir@/gcell-embedspu-libtool
 
 Name: gcell
 Description: The GNU Radio SPE scheduler and RPC mechanism
-Requires: gnuradio-omnithread
-Version: @VERSION@
+Requires:
+Version: @LIBVER@
 Libs: -L${libdir} -lgcell
 Cflags: -I${includedir} @DEFINES@
diff --git a/gcell/ibm/.gitignore b/gcell/ibm/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gcell/include/.gitignore b/gcell/include/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gcell/include/gcell/.gitignore b/gcell/include/gcell/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gcell/include/gcell/spu/.gitignore b/gcell/include/gcell/spu/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gcell/lib/.gitignore b/gcell/lib/.gitignore
new file mode 100644 (file)
index 0000000..3531485
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
index e7b349331d52b25864ff48576b04363ef273874d..7a727ea84739a1d28d21a02f7bdcec9733c96398 100644 (file)
@@ -27,24 +27,18 @@ SUBDIRS = spu runtime general wrapper .
 lib_LTLIBRARIES = libgcell.la libgcell-qa.la
 
 libgcell_la_SOURCES = 
-libgcell_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libgcell_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
 libgcell_qa_la_SOURCES = 
-libgcell_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libgcell_qa_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
 libgcell_la_LIBADD = \
        runtime/libruntime.la \
        wrapper/libwrapper.la \
        -lspe2 \
-       $(OMNITHREAD_LA)
+       $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB)
 
 libgcell_qa_la_LIBADD = \
        runtime/libruntime-qa.la \
        wrapper/libwrapper-qa.la \
        $(CPPUNIT_LIBS)
-
-
-
-
-
-
diff --git a/gcell/lib/general/.gitignore b/gcell/lib/general/.gitignore
new file mode 100644 (file)
index 0000000..3531485
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
diff --git a/gcell/lib/general/spu/.gitignore b/gcell/lib/general/spu/.gitignore
new file mode 100644 (file)
index 0000000..3531485
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
diff --git a/gcell/lib/runtime/.gitignore b/gcell/lib/runtime/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index 2c653918e69cf24a0003f3ee5fa1d200ef9048ca..4d13790cd2df64b82df82ba709ec269cafbbf273 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2007,2008 Free Software Foundation, Inc.
+# Copyright 2007,2008,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -23,7 +23,7 @@ include $(top_srcdir)/Makefile.common
 IBM_PPU_SYNC_INCLUDES = -I$(top_srcdir)/gcell/ibm/sync/ppu_source
 
 
-AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(MBLOCK_INCLUDES) $(CPPUNIT_INCLUDES) \
+AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \
        $(GCELL_INCLUDES) $(IBM_PPU_SYNC_INCLUDES) $(WITH_INCLUDES)
 
 
index 9f46ecca77f15a3adcf6948257f3ee42b40110fb..e49c070975ef64bb7f297a43a34ce15841ff85f3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -21,7 +21,7 @@
 #ifndef INCLUDED_GC_CLIENT_THREAD_INFO_H
 #define INCLUDED_GC_CLIENT_THREAD_INFO_H
 
-#include <gnuradio/omnithread.h>
+#include <boost/thread.hpp>
 #include <boost/utility.hpp>
 
 enum gc_ct_state {
@@ -40,7 +40,7 @@ enum gc_ct_state {
 class gc_client_thread_info : boost::noncopyable {
 public:
   gc_client_thread_info() :
-    d_free(1), d_cond(&d_mutex), d_state(CT_NOT_WAITING),
+    d_free(1), d_cond(), d_state(CT_NOT_WAITING),
     d_jobs_done(0), d_njobs_waiting_for(0),
     d_jobs_waiting_for(0){ }
 
@@ -59,10 +59,10 @@ public:
   uint16_t       d_client_id;
 
   //! hold this mutex to manipulate anything below here
-  omni_mutex     d_mutex;
+  boost::mutex   d_mutex;
 
   //! signaled by event handler to wake client thread up
-  omni_condition  d_cond;
+  boost::condition_variable d_cond;
 
   //! Is this client waiting?
   gc_ct_state    d_state;
index cc49fd1f3a4bce97e921fef5f1bf11d075674454..58597cf2766c173506dd75e1b4572678889bf671 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -39,6 +39,7 @@
 #include <string.h>
 #include <sched.h>
 
+typedef boost::unique_lock<boost::mutex> scoped_lock;
 
 #define __nop() __asm__ volatile ("ori 0,0,0" : : : "memory")
 #define __cctpl() __asm__ volatile ("or 1,1,1" : : : "memory")
@@ -116,9 +117,9 @@ is_power_of_2(uint32_t x)
 
 gc_job_manager_impl::gc_job_manager_impl(const gc_jm_options *options)
   : d_debug(0), d_spu_args(0),
-    d_eh_cond(&d_eh_mutex), d_eh_thread(0), d_eh_state(EHS_INIT),
+    d_eh_cond(), d_eh_thread(0), d_eh_state(EHS_INIT),
     d_shutdown_requested(false),
-    d_jc_cond(&d_jc_mutex), d_jc_thread(0), d_jc_state(JCS_INIT), d_jc_njobs_active(0),
+    d_jc_cond(), d_jc_thread(0), d_jc_state(JCS_INIT), d_jc_njobs_active(0),
     d_ntell(0), d_tell_start(0),
     d_client_thread(0), d_ea_args_maxsize(0),
     d_proc_def(0), d_proc_def_ls_addr(0), d_nproc_defs(0)
@@ -368,12 +369,12 @@ gc_job_manager_impl::~gc_job_manager_impl()
 bool
 gc_job_manager_impl::shutdown()
 {
-  omni_mutex_lock      l(d_eh_mutex);
+  scoped_lock  l(d_eh_mutex);
 
   {
-    omni_mutex_lock    l2(d_jc_mutex);
+    scoped_lock        l2(d_jc_mutex);
     d_shutdown_requested = true;       // set flag for event handler thread
-    d_jc_cond.signal();                        // wake up job completer
+    d_jc_cond.notify_one();                    // wake up job completer
   }
 
   // should only happens during early QA code
@@ -381,7 +382,7 @@ gc_job_manager_impl::shutdown()
     return false;
 
   while (d_eh_state != EHS_DEAD)       // wait for it to finish
-    d_eh_cond.wait();
+    d_eh_cond.wait(l);
 
   return true;
 }
@@ -459,13 +460,13 @@ gc_job_manager_impl::free_job_desc(gc_job_desc *jd)
 inline bool
 gc_job_manager_impl::incr_njobs_active()
 {
-  omni_mutex_lock      l(d_jc_mutex);
+  scoped_lock  l(d_jc_mutex);
 
   if (d_shutdown_requested)
     return false;
 
   if (d_jc_njobs_active++ == 0)        // signal on 0 to 1 transition
-    d_jc_cond.signal();
+    d_jc_cond.notify_one();
 
   return true;
 }
@@ -473,7 +474,7 @@ gc_job_manager_impl::incr_njobs_active()
 inline void
 gc_job_manager_impl::decr_njobs_active(int n)
 {
-  omni_mutex_lock      l(d_jc_mutex);
+  scoped_lock  l(d_jc_mutex);
   d_jc_njobs_active -= n;
 }
 
@@ -614,7 +615,7 @@ gc_job_manager_impl::wait_jobs(unsigned int njobs,
   }
 
   {
-    omni_mutex_lock    l(cti->d_mutex);
+    scoped_lock        l(cti->d_mutex);
 
     // setup info for event handler
     cti->d_state = (mode == GC_WAIT_ANY) ? CT_WAIT_ANY : CT_WAIT_ALL;
@@ -646,7 +647,7 @@ gc_job_manager_impl::wait_jobs(unsigned int njobs,
 
       // FIXME what happens when somebody calls shutdown?
 
-      cti->d_cond.wait();      // wait for event handler to wake us up
+      cti->d_cond.wait(l);     // wait for event handler to wake us up
     }
 
     cti->d_state = CT_NOT_WAITING;  
@@ -835,17 +836,17 @@ gc_job_manager_impl::create_event_handler()
 void
 gc_job_manager_impl::set_eh_state(evt_handler_state s)
 {
-  omni_mutex_lock      l(d_eh_mutex);
+  scoped_lock  l(d_eh_mutex);
   d_eh_state = s;
-  d_eh_cond.broadcast();
+  d_eh_cond.notify_all();
 }
 
 void
 gc_job_manager_impl::set_ea_args_maxsize(int maxsize)
 {
-  omni_mutex_lock      l(d_eh_mutex);
+  scoped_lock  l(d_eh_mutex);
   d_ea_args_maxsize = maxsize;
-  d_eh_cond.broadcast();
+  d_eh_cond.notify_all();
 }
 
 void
@@ -956,7 +957,7 @@ gc_job_manager_impl::notify_clients_jobs_are_done(unsigned int spe_num,
       // FIXME we could distinguish between CT_WAIT_ALL & CT_WAIT_ANY
 
       if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL)
-       last_cti->d_cond.signal();      // wake client thread up
+       last_cti->d_cond.notify_one();  // wake client thread up
 
       last_cti->d_mutex.unlock();
       cti->d_mutex.lock();
@@ -970,7 +971,7 @@ gc_job_manager_impl::notify_clients_jobs_are_done(unsigned int spe_num,
   // "wind-out"
 
   if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL)
-    last_cti->d_cond.signal(); // wake client thread up
+    last_cti->d_cond.notify_one();     // wake client thread up
   last_cti->d_mutex.unlock();
 
   ci->in_use = 0;              // clear flag so SPE knows we're done with it
@@ -1189,13 +1190,13 @@ gc_job_manager_impl::job_completer_loop()
 
   while (1){
     {
-      omni_mutex_lock  l(d_jc_mutex);
+      scoped_lock l(d_jc_mutex);
       if (d_jc_njobs_active == 0){
        if (d_shutdown_requested){
          d_jc_state = JCS_DEAD;
          return;
        }
-       d_jc_cond.wait();
+       d_jc_cond.wait(l);
       }
     }
 
@@ -1280,10 +1281,10 @@ gc_job_manager_impl::free_cti(gc_client_thread_info *cti)
 int
 gc_job_manager_impl::ea_args_maxsize()
 {
-  omni_mutex_lock      l(d_eh_mutex);
+  scoped_lock  l(d_eh_mutex);
 
   while (d_ea_args_maxsize == 0)       // wait for it to be initialized
-    d_eh_cond.wait();
+    d_eh_cond.wait(l);
 
   return d_ea_args_maxsize;
 }
index a56117870b6df2f644bd30d67348ce9d77d71cdb..640fdfe793a5d585b1e9a9ecc4eb440d73ee3a1c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -107,16 +107,16 @@ class gc_job_manager_impl : public gc_job_manager
   boost::shared_ptr<void> _d_comp_info_boost;  // hack for automatic storage mgmt
 
   // used to coordinate communication w/ the event handling thread
-  omni_mutex            d_eh_mutex;
-  omni_condition        d_eh_cond;
+  boost::mutex          d_eh_mutex;
+  boost::condition_variable d_eh_cond;
   pthread_t             d_eh_thread;           // the event handler thread
   volatile evt_handler_state   d_eh_state;
   volatile bool                        d_shutdown_requested;
   spe_event_handler     d_spe_event_handler;
   
   // used to coordinate communication w/ the job completer thread
-  omni_mutex            d_jc_mutex;
-  omni_condition        d_jc_cond;
+  boost::mutex          d_jc_mutex;
+  boost::condition_variable d_jc_cond;
   pthread_t             d_jc_thread;           // the job completion thread
   volatile job_completer_state d_jc_state;
   int                   d_jc_njobs_active;     // # of jobs submitted but not yet reaped
diff --git a/gcell/lib/runtime/spu/.gitignore b/gcell/lib/runtime/spu/.gitignore
new file mode 100644 (file)
index 0000000..36b5755
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/*.a
+/*.la
+/*.lo
+/.deps
+/.libs
+/test_spu
+/gcell_spu_main
+/gcell_qa
diff --git a/gcell/lib/spu/.gitignore b/gcell/lib/spu/.gitignore
new file mode 100644 (file)
index 0000000..547d220
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
+/gcell_general_qa
+/gcell_runtime_qa
+/gcell_all
diff --git a/gcell/lib/wrapper/.gitignore b/gcell/lib/wrapper/.gitignore
new file mode 100644 (file)
index 0000000..3531485
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
diff --git a/gcell/lib/wrapper/qa_gcp_fft_1d_r2.cc b/gcell/lib/wrapper/qa_gcp_fft_1d_r2.cc
new file mode 100644 (file)
index 0000000..742c624
--- /dev/null
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "qa_gcp_fft_1d_r2.h"
+#include <cppunit/TestAssert.h>
+#include <gcell/gcp_fft_1d_r2.h>
+#include <fftw3.h>
+#include <stdio.h>
+#include <stdlib.h>    // random, posix_memalign
+#include <algorithm>
+#include <string.h>
+
+typedef boost::shared_ptr<void> void_sptr;
+
+// handle to embedded SPU executable
+extern spe_program_handle_t gcell_all_spx;
+
+/*
+ * Return pointer to cache-aligned chunk of storage of size size bytes.
+ * Throw if can't allocate memory.  The storage should be freed
+ * with "free" when done.  The memory is initialized to zero.
+ */
+static void *
+aligned_alloc(size_t size, size_t alignment = 128)
+{
+  void *p = 0;
+  if (posix_memalign(&p, alignment, size) != 0){
+    perror("posix_memalign");
+    throw std::runtime_error("memory");
+  }
+  memset(p, 0, size);          // zero the memory
+  return p;
+}
+
+class free_deleter {
+public:
+  void operator()(void *p) {
+    free(p);
+  }
+};
+
+static boost::shared_ptr<void>
+aligned_alloc_sptr(size_t size, size_t alignment = 128)
+{
+  return boost::shared_ptr<void>(aligned_alloc(size, alignment), free_deleter());
+}
+
+// test forward FFT
+void
+qa_gcp_fft_1d_r2::t1()
+{
+  gc_jm_options opts;
+  opts.program_handle = gc_program_handle_from_address(&gcell_all_spx);
+  opts.nspes = 1;
+  gc_job_manager_sptr mgr = gc_make_job_manager(&opts);
+
+#if 1
+  for (int log2_fft_size = 5; log2_fft_size <= 12; log2_fft_size++){
+    test(mgr, log2_fft_size, true);
+  }
+#else
+  test(mgr, 5, true);
+#endif
+}
+
+// test inverse FFT
+void
+qa_gcp_fft_1d_r2::t2()
+{
+  gc_jm_options opts;
+  opts.program_handle = gc_program_handle_from_address(&gcell_all_spx);
+  opts.nspes = 1;
+  gc_job_manager_sptr mgr = gc_make_job_manager(&opts);
+
+#if 1
+  for (int log2_fft_size = 5; log2_fft_size <= 12; log2_fft_size++){
+    test(mgr, log2_fft_size, false);
+  }
+#else
+  test(mgr, 5, false);
+#endif
+}
+
+void
+qa_gcp_fft_1d_r2::t3()
+{
+  // FIXME Test fwd and inv with windowing option
+}
+
+void
+qa_gcp_fft_1d_r2::t4()
+{
+  // FIXME Test fwd and inv with shift option
+}
+
+static inline float
+abs_diff(std::complex<float> x, std::complex<float> y)
+{
+  return std::max(std::abs(x.real()-y.real()),
+                 std::abs(x.imag()-y.imag()));
+}
+
+static float
+float_abs_rel_error(float ref, float actual)
+{
+  float delta = ref - actual;
+  if (std::abs(ref) < 1e-18)
+    ref = 1e-18;
+  return std::abs(delta/ref);
+}
+
+static float
+abs_rel_error(std::complex<float> ref, std::complex<float> actual)
+{
+  return std::max(float_abs_rel_error(ref.real(), actual.real()),
+                 float_abs_rel_error(ref.imag(), actual.imag()));
+}
+
+void 
+qa_gcp_fft_1d_r2::test(gc_job_manager_sptr mgr, int log2_fft_size, bool forward)
+{
+  int fft_size = 1 << log2_fft_size;
+
+  // allocate aligned buffers with boost shared_ptr's
+  void_sptr fftw_in_void = aligned_alloc_sptr(fft_size * sizeof(std::complex<float>), 128);
+  void_sptr fftw_out_void = aligned_alloc_sptr(fft_size * sizeof(std::complex<float>), 128);
+  void_sptr cell_in_void = aligned_alloc_sptr(fft_size * sizeof(std::complex<float>), 128);
+  void_sptr cell_out_void = aligned_alloc_sptr(fft_size * sizeof(std::complex<float>), 128);
+  void_sptr cell_twiddle_void = aligned_alloc_sptr(fft_size/4 * sizeof(std::complex<float>), 128);
+
+  // cast them to the type we really want
+  std::complex<float> *fftw_in = (std::complex<float> *) fftw_in_void.get();
+  std::complex<float> *fftw_out = (std::complex<float> *) fftw_out_void.get();
+  std::complex<float> *cell_in = (std::complex<float> *) cell_in_void.get();
+  std::complex<float> *cell_out = (std::complex<float> *) cell_out_void.get();
+  std::complex<float> *cell_twiddle = (std::complex<float> *) cell_twiddle_void.get();
+
+  gcp_fft_1d_r2_twiddle(log2_fft_size, cell_twiddle);
+
+  srandom(1);          // we want reproducibility
+
+  // initialize the input buffers
+  for (int i = 0; i < fft_size; i++){
+    std::complex<float> t((float) (random() & 0xfffff), (float) (random() & 0xfffff));
+    fftw_in[i] = t;
+    cell_in[i] = t;
+  }
+
+  // ------------------------------------------------------------------------
+  // compute the reference answer
+  fftwf_plan plan = fftwf_plan_dft_1d (fft_size,
+                                      reinterpret_cast<fftwf_complex *>(fftw_in), 
+                                      reinterpret_cast<fftwf_complex *>(fftw_out),
+                                      forward ? FFTW_FORWARD : FFTW_BACKWARD,
+                                      FFTW_ESTIMATE);
+  if (plan == 0){
+    fprintf(stderr, "qa_gcp_fft_1d_r2: error creating FFTW plan\n");
+    throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
+  }
+  
+  fftwf_execute(plan);
+  fftwf_destroy_plan(plan);
+
+  // ------------------------------------------------------------------------
+  // compute the answer on the cell
+  gc_job_desc_sptr jd = gcp_fft_1d_r2_submit(mgr, log2_fft_size, forward, false,
+                                            cell_out, cell_in, cell_twiddle, 0);
+  if (!mgr->wait_job(jd.get())){
+    fprintf(stderr, "wait_job failed: %s\n", gc_job_status_string(jd->status).c_str());
+    CPPUNIT_ASSERT(0);
+  }
+
+  // ------------------------------------------------------------------------
+  // compute the maximum of the relative error
+  float max_rel = 0.0;
+  for (int i = 0; i < fft_size; i++){
+    max_rel = std::max(max_rel, abs_rel_error(fftw_out[i], cell_out[i]));
+    if (0)
+      printf("(%16.3f, %16.3fj)  (%16.3f, %16.3fj)  (%16.3f, %16.3fj)\n",
+            fftw_out[i].real(), fftw_out[i].imag(),
+            cell_out[i].real(), cell_out[i].imag(),
+            fftw_out[i].real() - cell_out[i].real(),
+            fftw_out[i].imag() - cell_out[i].imag());
+  }
+
+  fprintf(stdout, "%s fft_size = %4d  max_rel_error = %e\n",
+         forward ? "fwd" : "rev", fft_size, max_rel);
+
+  CPPUNIT_ASSERT(max_rel <= 5e-3);
+}
diff --git a/gcell/lib/wrapper/spu/.gitignore b/gcell/lib/wrapper/spu/.gitignore
new file mode 100644 (file)
index 0000000..3531485
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.a
+/*.o
diff --git a/gnuradio-core/.gitignore b/gnuradio-core/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
index d5447c17a44e2aef905a4a18a25bb956df3eadba..107ff785b1fa47035e2b8965559d95edcd16c1d0 100644 (file)
@@ -29,5 +29,5 @@ SUBDIRS = src
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = gnuradio-core.pc
 
-etcdir = $(gr_sysconfdir)
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gnuradio-core.conf
index 2c507fa22738b840d478c62df29f145d3587baa8..5d743a4e9096929040c4d1f5943d7375616afa7c 100644 (file)
@@ -5,7 +5,8 @@ includedir=@includedir@/gnuradio
 
 Name: gnuradio-core
 Description: GNU Software Radio toolkit
-Requires: gruel fftw3f gsl gnuradio-omnithread
-Version: @VERSION@
-Libs: -L${libdir} -lgnuradio-core @BOOST_LDFLAGS@ @BOOST_THREAD_LIB@ @BOOST_DATE_TIME_LIB@
-Cflags: @BOOST_CPPFLAGS@ @BOOST_CXXFLAGS@ -I${includedir} @DEFINES@
+Requires: gruel fftw3f gsl
+Version: @LIBVER@
+Libs.private: @BOOST_LDFLAGS@ @BOOST_THREAD_LIB@ @BOOST_DATE_TIME_LIB@
+Libs: -L${libdir} -lgnuradio-core
+Cflags: @BOOST_CPPFLAGS@ @BOOST_CXXFLAGS@ -I${includedir}
diff --git a/gnuradio-core/src/.gitignore b/gnuradio-core/src/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index 7b325974a6da98dcf396bc450fba8cf40284db19..eb979fe58be6c64e136d7d92f00df14ef4a734cd 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2004 Free Software Foundation, Inc.
+# Copyright 2001,2004,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -21,6 +21,9 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = gen_interpolator_taps lib tests python
+SUBDIRS = gen_interpolator_taps lib tests
+if PYTHON
+SUBDIRS += python
+endif
 
 DIST_SUBDIRS = gen_interpolator_taps lib tests python utils
diff --git a/gnuradio-core/src/gen_interpolator_taps/.gitignore b/gnuradio-core/src/gen_interpolator_taps/.gitignore
new file mode 100644 (file)
index 0000000..363c633
--- /dev/null
@@ -0,0 +1,7 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/gen_interpolator_taps
index 5f3a6cb25401e7380b244ebdbbf3615c3a63ed4b..d244e7f5468a7e5e77618b3efc0cb809acdab317 100644 (file)
 
 include $(top_srcdir)/Makefile.common
 
-EXTRA_DIST                     = praxis.txt simpson.h
+EXTRA_DIST                     = praxis.txt simpson.h objective_fct.c gen_interpolator_taps.c simpson.c praxis.f
 
-if ENABLE_FORTRAN
-noinst_PROGRAMS                        = gen_interpolator_taps
-noinst_HEADERS                 = simpson.h
-
-gen_interpolator_taps_SOURCES  = gen_interpolator_taps.c objective_fct.c simpson.c praxis.f
-gen_interpolator_taps_LDADD    = $(FLIBS) -lm
-
-endif
+if ENABLE_FORTRAN
+# noinst_PROGRAMS                      = gen_interpolator_taps
+# noinst_HEADERS                       = simpson.h
+# 
+# gen_interpolator_taps_SOURCES        = gen_interpolator_taps.c objective_fct.c simpson.c praxis.f
+# gen_interpolator_taps_LDADD  = $(FLIBS) -lm
+#
+endif
diff --git a/gnuradio-core/src/lib/.gitignore b/gnuradio-core/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..e3bc1ee
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/gnuradio-config-info
index fcb4d4ea5b1a574416b790178c5e9e7767616cf5..f3a3accdb2f4ef9f762f8c7945ddeb47aae64dce 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2004 Free Software Foundation, Inc.
+# Copyright 2001,2004,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -24,14 +24,20 @@ include $(top_srcdir)/Makefile.common
 ## Process this file with automake to produce Makefile.in
 
 # We've got to build . before swig
-SUBDIRS = missing runtime filter viterbi general gengen g72x reed-solomon io hier . swig
+SUBDIRS = missing runtime filter viterbi general gengen g72x reed-solomon io hier .
+if PYTHON
+SUBDIRS += swig
+endif
+
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES)
 
 # generate libgnuradio-core.la from the convenience libraries in subdirs
 
-lib_LTLIBRARIES = libgnuradio-core.la libgnuradio-core-qa.la
+lib_LTLIBRARIES = libgnuradio-core.la
+noinst_LTLIBRARIES = libgnuradio-core-qa.la
 
 libgnuradio_core_la_SOURCES = bug_work_around_6.cc
-libgnuradio_core_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libgnuradio_core_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
 libgnuradio_core_qa_la_SOURCES = bug_work_around_6.cc
 libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \
@@ -49,7 +55,6 @@ libgnuradio_core_la_LIBADD  =                 \
        reed-solomon/librs.la           \
        runtime/libruntime.la           \
        hier/libhier.la                 \
-       $(OMNITHREAD_LA)                \
        $(GRUEL_LA)                     \
        $(FFTW3F_LIBS)                  \
        $(GSL_LIBS)                     \
@@ -61,3 +66,7 @@ libgnuradio_core_qa_la_LIBADD  =      \
        runtime/libruntime-qa.la        \
        libgnuradio-core.la             \
        $(CPPUNIT_LIBS)                 
+
+bin_PROGRAMS = gnuradio-config-info
+gnuradio_config_info_SOURCES = gnuradio-config-info.cc
+gnuradio_config_info_LDADD = libgnuradio-core.la $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB)
diff --git a/gnuradio-core/src/lib/filter/.gitignore b/gnuradio-core/src/lib/filter/.gitignore
new file mode 100644 (file)
index 0000000..2d009f1
--- /dev/null
@@ -0,0 +1,214 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/generate-stamp
+/#
+/---
+/generate
+/files:
+/don't
+/go
+/in
+/CVS
+/---
+/GrFIRfilterCCC.cc
+/GrFIRfilterCCC.h
+/GrFIRfilterCCF.cc
+/GrFIRfilterCCF.h
+/GrFIRfilterFCC.cc
+/GrFIRfilterFCC.h
+/GrFIRfilterFFF.cc
+/GrFIRfilterFFF.h
+/GrFIRfilterFSF.cc
+/GrFIRfilterFSF.h
+/GrFIRfilterSCC.cc
+/GrFIRfilterSCC.h
+/GrFIRfilterSIS.cc
+/GrFIRfilterSIS.h
+/GrFreqXlatingFIRfilterCCC.cc
+/GrFreqXlatingFIRfilterCCC.h
+/GrFreqXlatingFIRfilterCCF.cc
+/GrFreqXlatingFIRfilterCCF.h
+/GrFreqXlatingFIRfilterFCC.cc
+/GrFreqXlatingFIRfilterFCC.h
+/GrFreqXlatingFIRfilterFCF.cc
+/GrFreqXlatingFIRfilterFCF.h
+/GrFreqXlatingFIRfilterSCC.cc
+/GrFreqXlatingFIRfilterSCC.h
+/GrFreqXlatingFIRfilterSCF.cc
+/GrFreqXlatingFIRfilterSCF.h
+/gr_fir_CCC.cc
+/gr_fir_CCC.h
+/gr_fir_CCC_generic.cc
+/gr_fir_CCC_generic.h
+/gr_fir_CCF.cc
+/gr_fir_CCF.h
+/gr_fir_CCF_generic.cc
+/gr_fir_CCF_generic.h
+/gr_fir_FCC.cc
+/gr_fir_FCC.h
+/gr_fir_FCC_generic.cc
+/gr_fir_FCC_generic.h
+/gr_fir_FFF.cc
+/gr_fir_FFF.h
+/gr_fir_FFF_generic.cc
+/gr_fir_FFF_generic.h
+/gr_fir_FSF.cc
+/gr_fir_FSF.h
+/gr_fir_FSF_generic.cc
+/gr_fir_FSF_generic.h
+/gr_fir_SCC.cc
+/gr_fir_SCC.h
+/gr_fir_SCC_generic.cc
+/gr_fir_SCC_generic.h
+/gr_fir_SIS.cc
+/gr_fir_SIS.h
+/gr_fir_SIS_generic.cc
+/gr_fir_SIS_generic.h
+/gr_fir_sysconfig.cc
+/gr_fir_sysconfig.h
+/gr_fir_sysconfig_generic.cc
+/gr_fir_sysconfig_generic.h
+/gr_fir_util.cc
+/gr_fir_util.h
+/GrFIRfilterCCC.i
+/GrFIRfilterCCF.i
+/GrFIRfilterFCC.i
+/GrFIRfilterFFF.i
+/GrFIRfilterFSF.i
+/GrFIRfilterSCC.i
+/GrFIRfilterSIS.i
+/GrFreqXlatingFIRfilterCCC.i
+/GrFreqXlatingFIRfilterCCF.i
+/GrFreqXlatingFIRfilterFCC.i
+/GrFreqXlatingFIRfilterFCF.i
+/GrFreqXlatingFIRfilterSCC.i
+/GrFreqXlatingFIRfilterSCF.i
+/#
+/---
+/end
+/generated
+/files
+/---
+/filter_generated.i
+/gr_fir_ccc.cc
+/gr_fir_ccc.h
+/gr_fir_ccc_generic.cc
+/gr_fir_ccc_generic.h
+/gr_fir_ccf.cc
+/gr_fir_ccf.h
+/gr_fir_ccf_generic.cc
+/gr_fir_ccf_generic.h
+/gr_fir_fcc.cc
+/gr_fir_fcc.h
+/gr_fir_fcc_generic.cc
+/gr_fir_fcc_generic.h
+/gr_fir_fff.cc
+/gr_fir_fff.h
+/gr_fir_fff_generic.cc
+/gr_fir_fff_generic.h
+/gr_fir_fsf.cc
+/gr_fir_fsf.h
+/gr_fir_fsf_generic.cc
+/gr_fir_fsf_generic.h
+/gr_fir_scc.cc
+/gr_fir_scc.h
+/gr_fir_scc_generic.cc
+/gr_fir_scc_generic.h
+/gr_fir_filter_ccc.cc
+/gr_fir_filter_ccc.h
+/gr_fir_filter_ccc.i
+/gr_fir_filter_ccf.cc
+/gr_fir_filter_ccf.h
+/gr_fir_filter_ccf.i
+/gr_fir_filter_fcc.cc
+/gr_fir_filter_fcc.h
+/gr_fir_filter_fcc.i
+/gr_fir_filter_fff.cc
+/gr_fir_filter_fff.h
+/gr_fir_filter_fff.i
+/gr_fir_filter_fsf.cc
+/gr_fir_filter_fsf.h
+/gr_fir_filter_fsf.i
+/gr_fir_filter_scc.cc
+/gr_fir_filter_scc.h
+/gr_fir_filter_scc.i
+/gr_freq_xlating_fir_filter_ccc.cc
+/gr_freq_xlating_fir_filter_ccc.h
+/gr_freq_xlating_fir_filter_ccc.i
+/gr_freq_xlating_fir_filter_ccf.cc
+/gr_freq_xlating_fir_filter_ccf.h
+/gr_freq_xlating_fir_filter_ccf.i
+/gr_freq_xlating_fir_filter_fcc.cc
+/gr_freq_xlating_fir_filter_fcc.h
+/gr_freq_xlating_fir_filter_fcc.i
+/gr_freq_xlating_fir_filter_fcf.cc
+/gr_freq_xlating_fir_filter_fcf.h
+/gr_freq_xlating_fir_filter_fcf.i
+/gr_freq_xlating_fir_filter_scc.cc
+/gr_freq_xlating_fir_filter_scc.h
+/gr_freq_xlating_fir_filter_scc.i
+/gr_freq_xlating_fir_filter_scf.cc
+/gr_freq_xlating_fir_filter_scf.h
+/gr_freq_xlating_fir_filter_scf.i
+/gr_interp_fir_filter_ccc.cc
+/gr_interp_fir_filter_ccc.h
+/gr_interp_fir_filter_ccc.i
+/gr_interp_fir_filter_ccf.cc
+/gr_interp_fir_filter_ccf.h
+/gr_interp_fir_filter_ccf.i
+/gr_interp_fir_filter_fcc.cc
+/gr_interp_fir_filter_fcc.h
+/gr_interp_fir_filter_fcc.i
+/gr_interp_fir_filter_fff.cc
+/gr_interp_fir_filter_fff.h
+/gr_interp_fir_filter_fff.i
+/gr_interp_fir_filter_fsf.cc
+/gr_interp_fir_filter_fsf.h
+/gr_interp_fir_filter_fsf.i
+/gr_interp_fir_filter_scc.cc
+/gr_interp_fir_filter_scc.h
+/gr_interp_fir_filter_scc.i
+/gr_rational_resampler_ccc.cc
+/gr_rational_resampler_ccc.h
+/gr_rational_resampler_ccc.i
+/gr_rational_resampler_ccf.cc
+/gr_rational_resampler_ccf.h
+/gr_rational_resampler_ccf.i
+/gr_rational_resampler_fcc.cc
+/gr_rational_resampler_fcc.h
+/gr_rational_resampler_fcc.i
+/gr_rational_resampler_fff.cc
+/gr_rational_resampler_fff.h
+/gr_rational_resampler_fff.i
+/gr_rational_resampler_fsf.cc
+/gr_rational_resampler_fsf.h
+/gr_rational_resampler_fsf.i
+/gr_rational_resampler_scc.cc
+/gr_rational_resampler_scc.h
+/gr_rational_resampler_scc.i
+/gr_rational_resampler_base_ccc.cc
+/gr_rational_resampler_base_ccc.h
+/gr_rational_resampler_base_ccc.i
+/gr_rational_resampler_base_ccf.cc
+/gr_rational_resampler_base_ccf.h
+/gr_rational_resampler_base_ccf.i
+/gr_rational_resampler_base_fcc.cc
+/gr_rational_resampler_base_fcc.h
+/gr_rational_resampler_base_fcc.i
+/gr_rational_resampler_base_fff.cc
+/gr_rational_resampler_base_fff.h
+/gr_rational_resampler_base_fff.i
+/gr_rational_resampler_base_fsf.cc
+/gr_rational_resampler_base_fsf.h
+/gr_rational_resampler_base_fsf.i
+/gr_rational_resampler_base_scc.cc
+/gr_rational_resampler_base_scc.h
+/gr_rational_resampler_base_scc.i
+/stamp-*
index b7fd0f58aac9f9c6436e7164101e36640c438094..23c1dadc3607d870d004ed2de1c66cfbb6f70a9e 100644 (file)
@@ -148,6 +148,15 @@ powerpc_CODE = \
 powerpc_qa_CODE = \
        qa_dotprod_powerpc.cc
 
+armv7_a_CODE = \
+       sysconfig_armv7_a.cc \
+       gr_fir_sysconfig_armv7_a.cc \
+       gr_cpu_armv7_a.cc \
+       gr_fir_fff_armv7_a.cc \
+       dotprod_fff_armv7_a.c
+
+armv7_a_qa_CODE = \
+       qa_dotprod_armv7_a.cc
 
 #
 # include each <foo>_CODE entry here...
@@ -160,7 +169,9 @@ EXTRA_libfilter_la_SOURCES =                \
        $(x86_64_SUBCODE)               \
        $(x86_qa_CODE)                  \
        $(powerpc_CODE)                 \
-       $(powerpc_qa_CODE)
+       $(powerpc_qa_CODE)              \
+       $(armv7_a_CODE)         \
+       $(armv7_a_qa_CODE)
 
 
 EXTRA_DIST =                                   \
@@ -173,6 +184,8 @@ libfilter_la_common_SOURCES =               \
        $(GENERATED_CC)                 \
        gr_adaptive_fir_ccf.cc          \
        gr_cma_equalizer_cc.cc          \
+       gri_fft_filter_fff_generic.cc   \
+       gri_fft_filter_ccc_generic.cc   \
        gr_fft_filter_ccc.cc            \
        gr_fft_filter_fff.cc            \
        gr_goertzel_fc.cc               \
@@ -190,7 +203,13 @@ libfilter_la_common_SOURCES =              \
        complex_dotprod_generic.cc      \
        ccomplex_dotprod_generic.cc     \
        float_dotprod_generic.c         \
-       short_dotprod_generic.c         
+       short_dotprod_generic.c         \
+       gr_pfb_channelizer_ccf.cc       \
+       gr_pfb_decimator_ccf.cc         \
+       gr_pfb_interpolator_ccf.cc      \
+       gr_pfb_arb_resampler_ccf.cc     \
+       gr_pfb_clock_sync_ccf.cc        \
+       gr_pfb_clock_sync_fff.cc
 
 libfilter_qa_la_common_SOURCES =       \
        qa_filter.cc                    \
@@ -223,6 +242,11 @@ libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(powerpc_CODE)
 libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(powerpc_qa_CODE)
 endif
 
+if MD_CPU_armv7_a
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(armv7_a_CODE)
+libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(armv7_a_qa_CODE)
+endif
+
 
 grinclude_HEADERS =                    \
        $(GENERATED_H)                  \
@@ -237,6 +261,8 @@ grinclude_HEADERS =                         \
        gr_altivec.h                    \
        gr_cma_equalizer_cc.h           \
        gr_cpu.h                        \
+       gri_fft_filter_fff_generic.h    \
+       gri_fft_filter_ccc_generic.h    \
        gr_fft_filter_ccc.h             \
        gr_fft_filter_fff.h             \
        gr_filter_delay_fc.h            \
@@ -260,11 +286,18 @@ grinclude_HEADERS =                       \
        qa_filter.h                     \
        short_dotprod_generic.h         \
        short_dotprod_x86.h             \
-       sse_debug.h
+       sse_debug.h                     \
+       gr_pfb_channelizer_ccf.h        \
+       gr_pfb_decimator_ccf.h          \
+       gr_pfb_interpolator_ccf.h       \
+       gr_pfb_arb_resampler_ccf.h      \
+       gr_pfb_clock_sync_ccf.h         \
+       gr_pfb_clock_sync_fff.h
 
 noinst_HEADERS =                       \
        assembly.h                      \
        dotprod_fff_altivec.h           \
+       dotprod_fff_armv7_a.h           \
        gr_fir_scc_simd.h               \
        gr_fir_scc_x86.h                \
        gr_fir_fcc_simd.h               \
@@ -274,6 +307,7 @@ noinst_HEADERS =                    \
        gr_fir_ccc_simd.h               \
        gr_fir_ccc_x86.h                \
        gr_fir_fff_altivec.h            \
+       gr_fir_fff_armv7_a.h            \
        gr_fir_fff_simd.h               \
        gr_fir_fff_x86.h                \
        gr_fir_fsf_simd.h               \
@@ -293,7 +327,7 @@ noinst_HEADERS =                    \
        qa_gri_mmse_fir_interpolator_cc.h       
 
 
-
+if PYTHON
 swiginclude_HEADERS =                  \
        filter.i                        \
        filter_generated.i              \
@@ -309,7 +343,14 @@ swiginclude_HEADERS =                      \
        gr_iir_filter_ffd.i             \
        gr_single_pole_iir_filter_ff.i  \
        gr_single_pole_iir_filter_cc.i  \
+       gr_pfb_channelizer_ccf.i        \
+       gr_pfb_decimator_ccf.i          \
+       gr_pfb_interpolator_ccf.i       \
+       gr_pfb_arb_resampler_ccf.i      \
+       gr_pfb_clock_sync_ccf.i         \
+       gr_pfb_clock_sync_fff.i         \
        $(GENERATED_I)
+endif
 
 # Do creation and inclusion of other Makefiles last
 
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c
new file mode 100644 (file)
index 0000000..bd1b88e
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dotprod_fff_armv7_a.h>
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded down to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_down(size_t x, size_t pow2)
+{
+  return x & -pow2;
+}
+
+
+#if 0
+
+float
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
+{
+  float        sum = 0;
+  size_t i;
+  for (i = 0; i < n; i++){
+    sum += a[i] * b[i];
+  }
+  return sum;
+}
+
+#else
+
+/*
+ *  preconditions:
+ *
+ *    n > 0 and a multiple of 4
+ *    a   4-byte aligned
+ *    b  16-byte aligned
+ */
+float
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
+{
+     float s = 0;
+
+    asm ("vmov.f32  q8, #0.0                  \n\t"
+         "vmov.f32  q9, #0.0                  \n\t"
+         "1:                                  \n\t"
+         "subs      %3, %3, #8                \n\t"
+         "vld1.32   {d0,d1,d2,d3}, [%1]!      \n\t"
+         "vld1.32   {d4,d5,d6,d7}, [%2]!      \n\t"
+         "vmla.f32  q8, q0, q2                \n\t"
+         "vmla.f32  q9, q1, q3                \n\t"
+         "bgt       1b                        \n\t"
+         "vadd.f32  q8, q8, q9                \n\t"
+         "vpadd.f32 d0, d16, d17              \n\t"
+         "vadd.f32  %0, s0, s1                \n\t"
+         : "=w"(s), "+r"(a), "+r"(b), "+r"(n)
+         :: "q0", "q1", "q2", "q3", "q8", "q9");
+
+    return s;
+
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h
new file mode 100644 (file)
index 0000000..e72621a
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DOTPROD_FFF_ARMV7_A_H
+#define INCLUDED_DOTPROD_FFF_ARMV7_A_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * <pre>
+ *
+ *  preconditions:
+ *
+ *    n > 0 and a multiple of 4
+ *    a   4-byte aligned
+ *    b  16-byte aligned
+ *
+ * </pre>
+ */
+float 
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* INCLUDED_DOTPROD_FFF_ARMV7_A_H */
index 7931a4d534475a1ca2f1cf64aa77345d90016ce7..bdfb8fa8d2d20d342adbf745a8a2455cba74a811 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2005,2006,2007 Free Software Foundation, Inc.
+ * Copyright 2004,2005,2006,2007,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_fractional_interpolator_cc.h>
 #include <gr_goertzel_fc.h>
 #include <gr_cma_equalizer_cc.h>
+#include <gr_pfb_channelizer_ccf.h>
+#include <gr_pfb_decimator_ccf.h>
+#include <gr_pfb_interpolator_ccf.h>
+#include <gr_pfb_arb_resampler_ccf.h>
+#include <gr_pfb_clock_sync_ccf.h>
+#include <gr_pfb_clock_sync_fff.h>
 %}
 
 %include "gr_iir_filter_ffd.i"
 %include "gr_fractional_interpolator_cc.i"
 %include "gr_goertzel_fc.i"
 %include "gr_cma_equalizer_cc.i"
+%include "gr_pfb_channelizer_ccf.i"
+%include "gr_pfb_decimator_ccf.i"
+%include "gr_pfb_interpolator_ccf.i"
+%include "gr_pfb_arb_resampler_ccf.i"
+%include "gr_pfb_decimator_ccf.i"
+%include "gr_pfb_interpolator_ccf.i"
+%include "gr_pfb_arb_resampler_ccf.i"
+%include "gr_pfb_clock_sync_ccf.i"
+%include "gr_pfb_clock_sync_fff.i"
 
 %include "filter_generated.i"
index ef10beae1ff953f53480e623a55709609c444a40..01d719020a10a3d5f1e73bccbbc0c9ad31dd015f 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2002,2008 Free Software Foundation, Inc.
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -34,6 +34,7 @@ struct gr_cpu {
   static bool has_3dnow ();
   static bool has_3dnowext ();
   static bool has_altivec ();
+  static bool has_armv7_a ();
 };
 
 #endif /* _GR_CPU_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc
new file mode 100644 (file)
index 0000000..e06d269
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_cpu.h>
+
+bool
+gr_cpu::has_mmx ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_altivec ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_armv7_a ()
+{
+  return true;
+}
index 35c342aaa7b4ed9560329ba2fd5874461e04dc0d..d253e44399797229d540ef21a737046a1115a06c 100644 (file)
@@ -57,3 +57,9 @@ gr_cpu::has_altivec ()
 {
   return true;         // FIXME assume we've always got it
 }
+
+bool
+gr_cpu::has_armv7_a ()
+{
+  return false;
+}
index a13a69c06fecb1c3c95c025dd73436513a3bee75..ac8a2eeb78645a56bb9d9ceaa09fcf9060af4f8e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2002 Free Software Foundation, Inc.
+ * Copyright 2002,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -111,3 +111,10 @@ gr_cpu::has_altivec ()
 {
   return false;
 }
+
+bool
+gr_cpu::has_armv7_a ()
+{
+  return false;
+}
+
index 3dd40d56dcd3c7a31a9f3b1bcc698b97155e30f3..4540c6e4ad00a4812e26d72d9b19e8cd290557cf 100644 (file)
@@ -30,6 +30,8 @@
 #endif
 
 #include <gr_fft_filter_ccc.h>
+//#include <gri_fft_filter_ccc_sse.h>
+#include <gri_fft_filter_ccc_generic.h>
 #include <gr_io_signature.h>
 #include <gri_fft.h>
 #include <math.h>
@@ -52,32 +54,23 @@ gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_compl
                       gr_make_io_signature (1, 1, sizeof (gr_complex)),
                       gr_make_io_signature (1, 1, sizeof (gr_complex)),
                       decimation),
-    d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+    d_updated(false)
 {
-  // if (decimation != 1)
-  //    throw std::invalid_argument("gr_fft_filter_ccc: decimation must be 1");
-
   set_history(1);
-  actual_set_taps(taps);
+#if 1 // don't enable the sse version until handling it is worked out
+  d_filter = new gri_fft_filter_ccc_generic(decimation, taps);
+#else
+  d_filter = new gri_fft_filter_ccc_sse(decimation, taps);
+#endif
+  d_nsamples = d_filter->set_taps(taps);
+  set_output_multiple(d_nsamples);
 }
 
 gr_fft_filter_ccc::~gr_fft_filter_ccc ()
 {
-  delete d_fwdfft;
-  delete d_invfft;
+  delete d_filter;
 }
 
-#if 0
-static void 
-print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
-{
-  std::cout << label;
-  for (unsigned i = 0; i < x.size(); i++)
-    std::cout << x[i] << " ";
-  std::cout << "\n";
-}
-#endif
-
 void
 gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
 {
@@ -85,130 +78,26 @@ gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
   d_updated = true;
 }
 
-/*
- * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
- */
-void
-gr_fft_filter_ccc::actual_set_taps (const std::vector<gr_complex> &taps)
-{
-  int i = 0;
-  compute_sizes(taps.size());
-
-  d_tail.resize(tailsize());
-  for (i = 0; i < tailsize(); i++)
-    d_tail[i] = 0;
-
-  gr_complex *in = d_fwdfft->get_inbuf();
-  gr_complex *out = d_fwdfft->get_outbuf();
-
-  float scale = 1.0 / d_fftsize;
-  
-  // Compute forward xform of taps.
-  // Copy taps into first ntaps slots, then pad with zeros
-  for (i = 0; i < d_ntaps; i++)
-    in[i] = taps[i] * scale;
-
-  for (; i < d_fftsize; i++)
-    in[i] = 0;
-
-  d_fwdfft->execute();         // do the xform
-
-  // now copy output to d_xformed_taps
-  for (i = 0; i < d_fftsize; i++)
-    d_xformed_taps[i] = out[i];
-
-  //print_vector_complex("transformed taps:", d_xformed_taps);
-}
-
-// determine and set d_ntaps, d_nsamples, d_fftsize
-
-void
-gr_fft_filter_ccc::compute_sizes(int ntaps)
-{
-  int old_fftsize = d_fftsize;
-  d_ntaps = ntaps;
-  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
-  d_nsamples = d_fftsize - d_ntaps + 1;
-
-  if (0)
-    fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
-           d_ntaps, d_fftsize, d_nsamples);
-
-  assert(d_fftsize == d_ntaps + d_nsamples -1 );
-
-  if (d_fftsize != old_fftsize){       // compute new plans
-    delete d_fwdfft;
-    delete d_invfft;
-    d_fwdfft = new gri_fft_complex(d_fftsize, true);
-    d_invfft = new gri_fft_complex(d_fftsize, false);
-    d_xformed_taps.resize(d_fftsize);
-  }
-
-  set_output_multiple(d_nsamples);
-}
-
 int
 gr_fft_filter_ccc::work (int noutput_items,
                         gr_vector_const_void_star &input_items,
                         gr_vector_void_star &output_items)
 {
-  gr_complex *in = (gr_complex *) input_items[0];
+  const gr_complex *in = (const gr_complex *) input_items[0];
   gr_complex *out = (gr_complex *) output_items[0];
 
   if (d_updated){
-    actual_set_taps(d_new_taps);
+    d_nsamples = d_filter->set_taps(d_new_taps);
     d_updated = false;
+    set_output_multiple(d_nsamples);
     return 0;                          // output multiple may have changed
   }
 
   assert(noutput_items % d_nsamples == 0);
 
-  int dec_ctr = 0;
-  int j = 0;
-  int ninput_items = noutput_items * decimation();
-
-  for (int i = 0; i < ninput_items; i += d_nsamples){
-    
-    memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(gr_complex));
-
-    for (j = d_nsamples; j < d_fftsize; j++)
-      d_fwdfft->get_inbuf()[j] = 0;
-
-    d_fwdfft->execute();       // compute fwd xform
-
-    gr_complex *a = d_fwdfft->get_outbuf();
-    gr_complex *b = &d_xformed_taps[0];
-    gr_complex *c = d_invfft->get_inbuf();
-
-    for (j = 0; j < d_fftsize; j++)    // filter in the freq domain
-      c[j] = a[j] * b[j];
-    
-    d_invfft->execute();       // compute inv xform
-
-    // add in the overlapping tail
-
-    for (j = 0; j < tailsize(); j++)
-      d_invfft->get_outbuf()[j] += d_tail[j];
-
-    // copy nsamples to output
-
-    //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(gr_complex));
-    //out += d_nsamples;
-
-    j = dec_ctr;
-    while (j < d_nsamples) {
-      *out++ = d_invfft->get_outbuf()[j];
-      j += decimation();
-    }
-    dec_ctr = (j - d_nsamples);
-
-    // stash the tail
-    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
-          tailsize() * sizeof(gr_complex));
-  }
+  d_filter->filter(noutput_items, in, out);
 
-  assert((out - (gr_complex *) output_items[0]) == noutput_items);
-  assert(dec_ctr == 0);
+  //assert((out - (gr_complex *) output_items[0]) == noutput_items);
 
   return noutput_items;
 }
index c5363dcbb0f1208797879b2c88657e934124f418..68b19e775b9da1c70d0b5f1e0966f73f0ef2e32e 100644 (file)
@@ -28,8 +28,8 @@ class gr_fft_filter_ccc;
 typedef boost::shared_ptr<gr_fft_filter_ccc> gr_fft_filter_ccc_sptr;
 gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
 
-class gr_fir_ccc;
-class gri_fft_complex;
+//class gri_fft_filter_ccc_sse;
+class gri_fft_filter_ccc_generic;
 
 /*!
  * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
@@ -40,15 +40,14 @@ class gr_fft_filter_ccc : public gr_sync_decimator
  private:
   friend gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
 
-  int                     d_ntaps;
   int                     d_nsamples;
-  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
-  gri_fft_complex        *d_fwdfft;            // forward "plan"
-  gri_fft_complex        *d_invfft;            // inverse "plan"
-  std::vector<gr_complex>  d_tail;             // state carried between blocks for overlap-add
-  std::vector<gr_complex>  d_xformed_taps;     // Fourier xformed taps
-  std::vector<gr_complex>  d_new_taps;
   bool                    d_updated;
+#if 1  // don't enable the sse version until handling it is worked out
+  gri_fft_filter_ccc_generic  *d_filter;  
+#else
+  gri_fft_filter_ccc_sse  *d_filter;  
+#endif
+  std::vector<gr_complex>  d_new_taps;
 
   /*!
    * Construct a FFT filter with the given taps
@@ -58,10 +57,6 @@ class gr_fft_filter_ccc : public gr_sync_decimator
    */
   gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
 
-  void compute_sizes(int ntaps);
-  int tailsize() const { return d_ntaps - 1; }
-  void actual_set_taps (const std::vector<gr_complex> &taps);
-
  public:
   ~gr_fft_filter_ccc ();
 
index 57232f3fb2e354e1e4beeeb5f2af29294ce6ab13..e8857fe8cfbd5d45fdfed39bbc95cd6c85e21f47 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #endif
 
 #include <gr_fft_filter_fff.h>
+#include <gri_fft_filter_fff_generic.h>
+//#include <gri_fft_filter_fff_sse.h>
 #include <gr_io_signature.h>
-#include <gri_fft.h>
-#include <math.h>
 #include <assert.h>
 #include <stdexcept>
-#include <gr_firdes.h>
-
 
 #include <cstdio>
 #include <iostream>
@@ -48,37 +46,24 @@ gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> &
                       gr_make_io_signature (1, 1, sizeof (float)),
                       gr_make_io_signature (1, 1, sizeof (float)),
                       decimation),
-    d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+    d_updated(false)
 {
   set_history(1);
-  actual_set_taps(taps);
-}
-
-gr_fft_filter_fff::~gr_fft_filter_fff ()
-{
-  delete d_fwdfft;
-  delete d_invfft;
-}
+  
+#if 1 // don't enable the sse version until handling it is worked out
+    d_filter = new gri_fft_filter_fff_generic(decimation, taps);
+#else
+    d_filter = new gri_fft_filter_fff_sse(decimation, taps);
+#endif
 
-#if 0
-static void 
-print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
-{
-  std::cout << label;
-  for (unsigned i = 0; i < x.size(); i++)
-    std::cout << x[i] << " ";
-  std::cout << "\n";
+  d_nsamples = d_filter->set_taps(taps);
+  set_output_multiple(d_nsamples);
 }
 
-static void 
-print_vector_float(const std::string label, const std::vector<float> &x)
+gr_fft_filter_fff::~gr_fft_filter_fff ()
 {
-  std::cout << label;
-  for (unsigned i = 0; i < x.size(); i++)
-    std::cout << x[i] << " ";
-  std::cout << "\n";
+  delete d_filter;
 }
-#endif
 
 void
 gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
@@ -87,68 +72,6 @@ gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
   d_updated = true;
 }
 
-/*
- * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
- */
-void
-gr_fft_filter_fff::actual_set_taps (const std::vector<float> &taps)
-{
-  int i = 0;
-  compute_sizes(taps.size());
-
-  d_tail.resize(tailsize());
-  for (i = 0; i < tailsize(); i++)
-    d_tail[i] = 0;
-
-  float *in = d_fwdfft->get_inbuf();
-  gr_complex *out = d_fwdfft->get_outbuf();
-
-  float scale = 1.0 / d_fftsize;
-  
-  // Compute forward xform of taps.
-  // Copy taps into first ntaps slots, then pad with zeros
-  for (i = 0; i < d_ntaps; i++)
-    in[i] = taps[i] * scale;
-
-  for (; i < d_fftsize; i++)
-    in[i] = 0;
-
-  d_fwdfft->execute();         // do the xform
-
-  // now copy output to d_xformed_taps
-  for (i = 0; i < d_fftsize/2+1; i++)
-    d_xformed_taps[i] = out[i];
-
-  //print_vector_complex("transformed taps:", d_xformed_taps);
-}
-
-// determine and set d_ntaps, d_nsamples, d_fftsize
-
-void
-gr_fft_filter_fff::compute_sizes(int ntaps)
-{
-  int old_fftsize = d_fftsize;
-  d_ntaps = ntaps;
-  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
-  d_nsamples = d_fftsize - d_ntaps + 1;
-
-  if (0)
-    fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
-           d_ntaps, d_fftsize, d_nsamples);
-
-  assert(d_fftsize == d_ntaps + d_nsamples -1 );
-
-  if (d_fftsize != old_fftsize){       // compute new plans
-    delete d_fwdfft;
-    delete d_invfft;
-    d_fwdfft = new gri_fft_real_fwd(d_fftsize);
-    d_invfft = new gri_fft_real_rev(d_fftsize);
-    d_xformed_taps.resize(d_fftsize/2+1);
-  }
-
-  set_output_multiple(d_nsamples);
-}
-
 int
 gr_fft_filter_fff::work (int noutput_items,
                         gr_vector_const_void_star &input_items,
@@ -158,59 +81,17 @@ gr_fft_filter_fff::work (int noutput_items,
   float *out = (float *) output_items[0];
 
   if (d_updated){
-    actual_set_taps(d_new_taps);
+    d_nsamples = d_filter->set_taps(d_new_taps);
     d_updated = false;
+    set_output_multiple(d_nsamples);
     return 0;                          // output multiple may have changed
   }
 
   assert(noutput_items % d_nsamples == 0);
+  
+  d_filter->filter(noutput_items, in, out);
 
-  int dec_ctr = 0;
-  int j = 0;
-  int ninput_items = noutput_items * decimation();
-
-  for (int i = 0; i < ninput_items; i += d_nsamples){
-    
-    memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(float));
-
-    for (j = d_nsamples; j < d_fftsize; j++)
-      d_fwdfft->get_inbuf()[j] = 0;
-
-    d_fwdfft->execute();       // compute fwd xform
-
-    gr_complex *a = d_fwdfft->get_outbuf();
-    gr_complex *b = &d_xformed_taps[0];
-    gr_complex *c = d_invfft->get_inbuf();
-
-    for (j = 0; j < d_fftsize/2+1; j++)        // filter in the freq domain
-      c[j] = a[j] * b[j];
-    
-    d_invfft->execute();       // compute inv xform
-
-    // add in the overlapping tail
-
-    for (j = 0; j < tailsize(); j++)
-      d_invfft->get_outbuf()[j] += d_tail[j];
-
-    // copy nsamples to output
-
-    //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
-    //out += d_nsamples;
-
-    j = dec_ctr;
-    while (j < d_nsamples) {
-      *out++ = d_invfft->get_outbuf()[j];
-      j += decimation();
-    }
-    dec_ctr = (j - d_nsamples);
-
-    // stash the tail
-    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
-          tailsize() * sizeof(float));
-  }
-
-  assert((out - (float *) output_items[0]) == noutput_items);
-  assert(dec_ctr == 0);
+  //assert((out - (float *) output_items[0]) == noutput_items);
 
   return noutput_items;
 }
index b26361107925640d4bfa0303de76b83cf0d2bc5e..6eaa21500a8c0923cf13eb11eba8dc00ce9c0073 100644 (file)
@@ -28,9 +28,8 @@ class gr_fft_filter_fff;
 typedef boost::shared_ptr<gr_fft_filter_fff> gr_fft_filter_fff_sptr;
 gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
 
-class gr_fir_fff;
-class gri_fft_real_fwd;
-class gri_fft_real_rev;
+class gri_fft_filter_fff_generic;
+//class gri_fft_filter_fff_sse;
 
 /*!
  * \brief Fast FFT filter with float input, float output and float taps
@@ -41,15 +40,14 @@ class gr_fft_filter_fff : public gr_sync_decimator
  private:
   friend gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
 
-  int                     d_ntaps;
   int                     d_nsamples;
-  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
-  gri_fft_real_fwd       *d_fwdfft;            // forward "plan"
-  gri_fft_real_rev       *d_invfft;            // inverse "plan"
-  std::vector<float>       d_tail;             // state carried between blocks for overlap-add
-  std::vector<gr_complex>  d_xformed_taps;     // Fourier xformed taps
-  std::vector<float>      d_new_taps;
   bool                    d_updated;
+#if 1 // don't enable the sse version until handling it is worked out
+  gri_fft_filter_fff_generic  *d_filter;
+#else
+  gri_fft_filter_fff_sse  *d_filter;
+#endif
+  std::vector<float>      d_new_taps;
 
   /*!
    * Construct a FFT filter with the given taps
@@ -58,10 +56,6 @@ class gr_fft_filter_fff : public gr_sync_decimator
    * \param taps        float filter taps
    */
   gr_fft_filter_fff (int decimation, const std::vector<float> &taps);
-
-  void compute_sizes(int ntaps);
-  int tailsize() const { return d_ntaps - 1; }
-  void actual_set_taps (const std::vector<float> &taps);
   
  public:
   ~gr_fft_filter_fff ();
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc
new file mode 100644 (file)
index 0000000..5a62b10
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_fff_armv7_a.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdexcept>
+#include <assert.h>
+#include <gr_math.h>
+#include <dotprod_fff_armv7_a.h>
+
+#define FLOATS_PER_VEC 8
+
+gr_fir_fff_armv7_a::gr_fir_fff_armv7_a()
+  : gr_fir_fff_generic(),
+    d_naligned_taps(0), d_aligned_taps(0)
+{
+}
+
+gr_fir_fff_armv7_a::gr_fir_fff_armv7_a (const std::vector<float> &new_taps)
+  : gr_fir_fff_generic(new_taps),
+    d_naligned_taps(0), d_aligned_taps(0)
+{
+  set_taps(new_taps);
+}
+
+gr_fir_fff_armv7_a::~gr_fir_fff_armv7_a()
+{
+  if (d_aligned_taps){
+    free(d_aligned_taps);
+    d_aligned_taps = 0;
+  }
+}
+
+void
+gr_fir_fff_armv7_a::set_taps(const std::vector<float> &inew_taps)
+{
+  gr_fir_fff_generic::set_taps(inew_taps);     // call superclass
+  d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC);
+
+  if (d_aligned_taps){
+    free(d_aligned_taps);
+    d_aligned_taps = 0;
+  }
+  void *p;
+  int r = posix_memalign(&p,  sizeof(float), d_naligned_taps * sizeof(d_aligned_taps[0]));
+  if (r != 0){
+    throw std::bad_alloc();
+  }
+  d_aligned_taps = (float *) p;
+  memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0]));
+  for (size_t i = ntaps(); i < d_naligned_taps; i++)
+    d_aligned_taps[i] = 0.0;
+}
+
+
+float 
+gr_fir_fff_armv7_a::filter (const float input[])
+{
+  if (d_naligned_taps == 0)
+    return 0.0;
+  
+  return dotprod_fff_armv7_a(input, d_aligned_taps, d_naligned_taps);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h
new file mode 100644 (file)
index 0000000..d6097cf
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_ARMV7_A_H
+#define INCLUDED_GR_FIR_FFF_ARMV7_A_H
+
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief armv7_a using NEON coprocessor version of gr_fir_fff
+ */
+class gr_fir_fff_armv7_a : public gr_fir_fff_generic
+{
+protected:
+
+  size_t    d_naligned_taps;  // number of taps (multiple of 4)
+  float           *d_aligned_taps;   // 16-byte aligned, and zero padded to multiple of 4
+
+public:
+  gr_fir_fff_armv7_a();
+  gr_fir_fff_armv7_a(const std::vector<float> &taps);
+  ~gr_fir_fff_armv7_a();
+
+  virtual void set_taps (const std::vector<float> &taps);
+  virtual float filter (const float input[]);
+};
+
+#endif /* INCLUDED_GR_FIR_FFF_ARMV7_A*_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc
new file mode 100644 (file)
index 0000000..34c7d4c
--- /dev/null
@@ -0,0 +1,340 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_sysconfig_armv7_a.h>
+#include <gr_cpu.h>
+
+#include <gr_fir_ccf.h>
+#include <gr_fir_ccf_generic.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_fcc_generic.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_fff_generic.h>
+#include <gr_fir_fff_armv7_a.h>
+#include <gr_fir_fsf.h>
+#include <gr_fir_fsf_generic.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_ccc_generic.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_scc_generic.h>
+
+#include <iostream>
+using std::cerr;
+
+///\todo Remove commented out code for altivec and replace with NEON versions.
+
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors...
+ * ----------------------------------------------------------------
+ */
+
+#if 0
+static gr_fir_ccf *
+make_gr_fir_ccf_altivec(const std::vector<float> &taps)
+{
+  return new gr_fir_ccf_altivec(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_altivec(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_fcc_altivec(taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_altivec (const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_ccc_altivec (taps);
+}
+#endif
+
+static gr_fir_fff *
+make_gr_fir_fff_armv7_a (const std::vector<float> &taps)
+{
+  return new gr_fir_fff_armv7_a (taps);
+}
+
+#if 0
+static gr_fir_fsf *
+make_gr_fir_fsf_altivec (const std::vector<float> &taps)
+{
+  return new gr_fir_fsf_altivec (taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_altivec(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_scc_altivec(taps);
+}
+#endif
+
+/*
+ * ----------------------------------------------------------------
+ * Return instances of the fastest arm versions of these classes.
+ *
+ * check CPUID, if has armv7-a, return armv7-a version,
+ *             else return generic version. This will break 
+ *             when someone makes an armv7-a without a NEON
+ *             coprocessor.
+ * ----------------------------------------------------------------
+ */
+
+gr_fir_ccf *
+gr_fir_sysconfig_armv7_a::create_gr_fir_ccf (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+#if 0
+  if (gr_cpu::has_altivec ()){
+    if (first){
+      cerr << ">>> gr_fir_ccf: using altivec\n";
+      first = false;
+    }
+    return make_gr_fir_ccf_altivec (taps);
+  }
+#endif
+
+  if (0 && first){
+    cerr << ">>> gr_fir_ccf: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_ccf (taps);
+}
+
+gr_fir_fcc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fcc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+#if 0
+  if (gr_cpu::has_altivec ()){
+    if (first){
+      cerr << ">>> gr_fir_fcc: using altivec\n";
+      first = false;
+    }
+    return make_gr_fir_fcc_altivec (taps);
+  }
+#endif
+
+  if (0 && first){
+    cerr << ">>> gr_fir_fcc: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_fcc (taps);
+}
+
+gr_fir_ccc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_ccc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+#if 0
+  if (gr_cpu::has_altivec ()){
+    if (first){
+      cerr << ">>> gr_fir_ccc: using altivec\n";
+      first = false;
+    }
+    return make_gr_fir_ccc_altivec (taps);
+  }
+#endif
+  
+  if (0 && first){
+    cerr << ">>> gr_fir_ccc: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_ccc (taps);
+}
+
+gr_fir_fff *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fff (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_armv7_a ()){
+    if (first){
+      cerr << ">>> gr_fir_fff: using armv7_a\n";
+      first = false;
+    }
+    return make_gr_fir_fff_armv7_a (taps);
+  }
+  
+  if (0 && first){
+    cerr << ">>> gr_fir_fff: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_fff (taps);
+}
+
+gr_fir_fsf *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fsf (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+#if 0
+  if (gr_cpu::has_altivec ()){
+    if (first){
+      cerr << ">>> gr_fir_fsf: using altivec\n";
+      first = false;
+    }
+    return make_gr_fir_fsf_altivec (taps);
+  }
+#endif
+  
+  if (0 && first){
+    cerr << ">>> gr_fir_fsf: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps);
+}
+
+
+gr_fir_scc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_scc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+#if 0
+  if (gr_cpu::has_altivec ()){
+    if (first){
+      cerr << ">>> gr_fir_scc: using altivec\n";
+      first = false;
+    }
+    return make_gr_fir_scc_altivec (taps);
+  }
+#endif
+
+  if (0 && first){
+    cerr << ">>> gr_fir_scc: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_scc (taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ *         Return info about available implementations
+ * ----------------------------------------------------------------
+ */
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info);
+
+#if 0  
+  // add our stuff...
+  gr_fir_ccf_info      t;
+  if (gr_cpu::has_altivec ()){
+    t.name = "altivec";
+    t.create = make_gr_fir_ccf_altivec;
+    (*info).push_back (t);
+  }
+#endif
+}
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info);
+
+#if 0
+  // add our stuff...
+  gr_fir_fcc_info      t;
+  if (gr_cpu::has_altivec ()){
+    t.name = "altivec";
+    t.create = make_gr_fir_fcc_altivec;
+    (*info).push_back (t);
+  }
+#endif
+}
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info);
+
+#if 0
+  // add our stuff...
+  gr_fir_ccc_info      t;
+  if (gr_cpu::has_altivec ()){
+    t.name = "altivec";
+    t.create = make_gr_fir_ccc_altivec;
+    (*info).push_back (t);
+  }
+#endif
+}
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fff_info (info);
+
+  // add our stuff...
+  gr_fir_fff_info      t;
+  if (gr_cpu::has_armv7_a ()){
+    t.name = "armv7_a";
+    t.create = make_gr_fir_fff_armv7_a;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info);
+
+#if 0
+  // add our stuff...
+  gr_fir_fsf_info      t;
+  if (gr_cpu::has_altivec ()){
+    t.name = "altivec";
+    t.create = make_gr_fir_fsf_altivec;
+    (*info).push_back (t);
+  }
+#endif
+}
+
+void 
+gr_fir_sysconfig_armv7_a::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info)
+{
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_scc_info (info);
+
+#if 0
+  // add our stuff...
+  gr_fir_scc_info      t;
+  if (gr_cpu::has_altivec ()){
+    t.name = "altivec";
+    t.create = make_gr_fir_scc_altivec;
+    (*info).push_back (t);
+  }
+#endif
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h
new file mode 100644 (file)
index 0000000..c77b810
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 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.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_ARMV7_A_H
+#define INCLUDED_GR_FIR_SYSCONFIG_ARMV7_A_H
+
+#include <gr_fir_sysconfig_generic.h>
+
+class gr_fir_sysconfig_armv7_a : public gr_fir_sysconfig_generic {
+public:
+  virtual gr_fir_ccf *create_gr_fir_ccf (const std::vector<float> &taps);
+  virtual gr_fir_fcc *create_gr_fir_fcc (const std::vector<gr_complex> &taps);
+  virtual gr_fir_fff *create_gr_fir_fff (const std::vector<float> &taps);
+  virtual gr_fir_fsf *create_gr_fir_fsf (const std::vector<float> &taps);
+  virtual gr_fir_scc *create_gr_fir_scc (const std::vector<gr_complex> &taps);
+  virtual gr_fir_ccc *create_gr_fir_ccc (const std::vector<gr_complex> &taps);
+//virtual gr_fir_sss *create_gr_fir_sss (const std::vector<short> &taps);
+
+  virtual void get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info);
+  virtual void get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info);
+  virtual void get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info);
+  virtual void get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info);
+  virtual void get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info);
+  virtual void get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info);
+//virtual void get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc
new file mode 100644 (file)
index 0000000..5a6e753
--- /dev/null
@@ -0,0 +1,211 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_arb_resampler_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, 
+                                                            const std::vector<float> &taps,
+                                                            unsigned int filter_size)
+{
+  return gr_pfb_arb_resampler_ccf_sptr (new gr_pfb_arb_resampler_ccf (rate, taps,
+                                                                     filter_size));
+}
+
+
+gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, 
+                                                   const std::vector<float> &taps,
+                                                   unsigned int filter_size)
+  : gr_block ("pfb_arb_resampler_ccf",
+             gr_make_io_signature (1, 1, sizeof(gr_complex)),
+             gr_make_io_signature (1, 1, sizeof(gr_complex))),
+    d_updated (false)
+{
+  d_acc = 0; // start accumulator at 0
+
+  /* The number of filters is specified by the user as the filter size;
+     this is also the interpolation rate of the filter. We use it and the
+     rate provided to determine the decimation rate. This acts as a
+     rational resampler. The flt_rate is calculated as the residual
+     between the integer decimation rate and the real decimation rate and
+     will be used to determine to interpolation point of the resampling
+     process.
+  */
+  d_int_rate = filter_size;
+  d_dec_rate = (unsigned int)floor(d_int_rate/rate);
+  d_flt_rate = (d_int_rate/rate) - d_dec_rate;
+
+  // Store the last filter between calls to work
+  d_last_filter = 0;
+
+  d_start_index = 0;
+  
+  d_filters = std::vector<gr_fir_ccf*>(d_int_rate);
+  d_diff_filters = std::vector<gr_fir_ccf*>(d_int_rate);
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_int_rate);
+  for(int i = 0; i < d_int_rate; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+    d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+  }
+
+  // Now, actually set the filters' taps
+  std::vector<float> dtaps;
+  create_diff_taps(taps, dtaps);
+  create_taps(taps, d_taps, d_filters);
+  create_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf ()
+{
+  for(unsigned int i = 0; i < d_int_rate; i++) {
+    delete d_filters[i];
+  }
+}
+
+void
+gr_pfb_arb_resampler_ccf::create_taps (const std::vector<float> &newtaps,
+                                      std::vector< std::vector<float> > &ourtaps,
+                                      std::vector<gr_fir_ccf*> &ourfilter)
+{
+  int i,j;
+
+  unsigned int ntaps = newtaps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate);
+
+  // Create d_numchan vectors to store each channel's taps
+  ourtaps.resize(d_int_rate);
+  
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = newtaps;
+  while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  
+  // Partition the filter
+  for(i = 0; i < d_int_rate; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate];
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter + 1);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_arb_resampler_ccf::create_diff_taps(const std::vector<float> &newtaps,
+                                          std::vector<float> &difftaps)
+{
+  // Calculate the differential taps (derivative filter) by taking the difference
+  // between two taps. Duplicate the last one to make both filters the same length.
+  float tap;
+  difftaps.clear();
+  for(unsigned int i = 0; i < newtaps.size()-1; i++) {
+    tap = newtaps[i+1] - newtaps[i];
+    difftaps.push_back(tap);
+  }
+  difftaps.push_back(tap);
+}
+
+void
+gr_pfb_arb_resampler_ccf::print_taps()
+{
+  unsigned int i, j;
+  for(i = 0; i < d_int_rate; i++) {
+    printf("filter[%d]: [", i);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      printf(" %.4e", d_taps[i][j]);
+    }
+    printf("]\n");
+  }
+}
+
+int
+gr_pfb_arb_resampler_ccf::general_work (int noutput_items,
+                                       gr_vector_int &ninput_items,
+                                       gr_vector_const_void_star &input_items,
+                                       gr_vector_void_star &output_items)
+{
+  gr_complex *in = (gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int i = 0, j, count = d_start_index;
+  gr_complex o0, o1;
+
+  // Restore the last filter position
+  j = d_last_filter;
+
+  // produce output as long as we can and there are enough input samples
+  while((i < noutput_items) && (count < ninput_items[0]-1)) {
+
+    // start j by wrapping around mod the number of channels
+    while((j < d_int_rate) && (i < noutput_items)) {
+      // Take the current filter and derivative filter output
+      o0 = d_filters[j]->filter(&in[count]);
+      o1 = d_diff_filters[j]->filter(&in[count]);
+
+      out[i] = o0 + o1*d_acc;     // linearly interpolate between samples
+      i++;
+
+      // Adjust accumulator and index into filterbank
+      d_acc += d_flt_rate;
+      j += d_dec_rate + (int)floor(d_acc);
+      d_acc = fmodf(d_acc, 1.0);
+    }
+    if(i < noutput_items) {              // keep state for next entry
+      float ss = (int)(j / d_int_rate);  // number of items to skip ahead by
+      count += ss;                       // we have fully consumed another input
+      j = j % d_int_rate;                // roll filter around
+    }
+  }
+
+  // Store the current filter position and start of next sample
+  d_last_filter = j;
+  d_start_index = std::max(0, count - ninput_items[0]);
+
+  // consume all we've processed but no more than we can
+  consume_each(std::min(count, ninput_items[0]));
+  return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h
new file mode 100644 (file)
index 0000000..cf5a79d
--- /dev/null
@@ -0,0 +1,171 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H
+#define        INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H
+
+#include <gr_block.h>
+
+class gr_pfb_arb_resampler_ccf;
+typedef boost::shared_ptr<gr_pfb_arb_resampler_ccf> gr_pfb_arb_resampler_ccf_sptr;
+gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+                                                            const std::vector<float> &taps,
+                                                            unsigned int filter_size=32);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_arb_resampler_ccf
+ *
+ * \brief Polyphase filterbank arbitrary resampler with 
+ *        gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * 
+ * This block takes in a signal stream and performs arbitrary
+ * resampling. The resampling rate can be any real
+ * number <EM>r</EM>. The resampling is done by constructing
+ * <EM>N</EM> filters where <EM>N</EM> is the interpolation rate.  We
+ * then calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
+ *
+ * Using <EM>N</EM> and <EM>D</EM>, we can perform rational resampling
+ * where <EM>N/D</EM> is a rational number close to the input rate
+ * <EM>r</EM> where we have <EM>N</EM> filters and we cycle through
+ * them as a polyphase filterbank with a stride of <EM>D</EM> so that
+ * <EM>i+1 = (i + D) % N</EM>.
+ *
+ * To get the arbitrary rate, we want to interpolate between two
+ * points. For each value out, we take an output from the current
+ * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
+ * linearly interpolate between the two based on the real resampling
+ * rate we want.
+ *
+ * The linear interpolation only provides us with an approximation to
+ * the real sampling rate specified. The error is a quantization error
+ * between the two filters we used as our interpolation points.  To
+ * this end, the number of filters, <EM>N</EM>, used determines the
+ * quantization error; the larger <EM>N</EM>, the smaller the
+ * noise. You can design for a specified noise floor by setting the
+ * filter size (parameters <EM>filter_size</EM>). The size defaults to
+ * 32 filters, which is about as good as most implementations need.
+ *
+ * The trick with designing this filter is in how to specify the taps
+ * of the prototype filter. Like the PFB interpolator, the taps are
+ * specified using the interpolated filter rate. In this case, that
+ * rate is the input sample rate multiplied by the number of filters
+ * in the filterbank, which is also the interpolation rate. All other
+ * values should be relative to this rate.
+ *
+ * For example, for a 32-filter arbitrary resampler and using the
+ * GNU Radio's firdes utility to build the filter, we build a low-pass
+ * filter with a sampling rate of <EM>fs</EM>, a 3-dB bandwidth of
+ * <EM>BW</EM> and a transition bandwidth of <EM>TB</EM>. We can also
+ * specify the out-of-band attenuation to use, <EM>ATT</EM>, and the
+ * filter window function (a Blackman-harris window in this case). The
+ * first input is the gain of the filter, which we specify here as the
+ * interpolation rate (<EM>32</EM>).
+ *
+ *      <B><EM>self._taps = gr.firdes.low_pass_2(32, 32*fs, BW, TB, 
+ *           attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The theory behind this block can be found in Chapter 7.5 of 
+ * the following book.
+ *
+ *    <B><EM>f. harris, "Multirate Signal Processing for Communication 
+ *       Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+class gr_pfb_arb_resampler_ccf : public gr_block
+{
+ private:
+  /*!
+   * Build the polyphase filterbank arbitray resampler.
+   * \param rate  (float) Specifies the resampling rate to use
+   * \param taps  (vector/list of floats) The prototype filter to populate the filterbank. The taps
+   *                                      should be generated at the filter_size sampling rate.
+   * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+                                       related to quantization noise introduced during the resampling.
+                                      Defaults to 32 filters.
+   */
+  friend gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+                                                                     const std::vector<float> &taps,
+                                                                     unsigned int filter_size);
+
+  std::vector<gr_fir_ccf*> d_filters;
+  std::vector<gr_fir_ccf*> d_diff_filters;
+  std::vector< std::vector<float> > d_taps;
+  std::vector< std::vector<float> > d_dtaps;
+  unsigned int             d_int_rate;          // the number of filters (interpolation rate)
+  unsigned int             d_dec_rate;          // the stride through the filters (decimation rate)
+  float                    d_flt_rate;          // residual rate for the linear interpolation
+  float                    d_acc;
+  unsigned int             d_last_filter;
+  int                      d_start_index;
+  unsigned int             d_taps_per_filter;
+  bool                    d_updated;
+
+  /*!
+   * Build the polyphase filterbank arbitray resampler.
+   * \param rate  (float) Specifies the resampling rate to use
+   * \param taps  (vector/list of floats) The prototype filter to populate the filterbank. The taps
+   *                                      should be generated at the filter_size sampling rate.
+   * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+                                       related to quantization noise introduced during the resampling.
+                                      Defaults to 32 filters.
+   */
+  gr_pfb_arb_resampler_ccf (float rate, 
+                           const std::vector<float> &taps,
+                           unsigned int filter_size);
+
+  void create_diff_taps(const std::vector<float> &newtaps,
+                       std::vector<float> &difftaps);
+
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   * \param newtaps    (vector of floats) The prototype filter to populate the filterbank. 
+   *                   The taps should be generated at the interpolated sampling rate.
+   * \param ourtaps    (vector of floats) Reference to our internal member of holding the taps.
+   * \param ourfilter  (vector of filters) Reference to our internal filter to set the taps for.
+   */
+  void create_taps (const std::vector<float> &newtaps,
+                   std::vector< std::vector<float> > &ourtaps,
+                   std::vector<gr_fir_ccf*> &ourfilter);
+
+  
+public:
+  ~gr_pfb_arb_resampler_ccf ();
+
+  // FIXME: See about a set_taps function during runtime.
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+  
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i
new file mode 100644 (file)
index 0000000..4f07af8
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_arb_resampler_ccf);
+
+gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+                                                            const std::vector<float> &taps,
+                                                            unsigned int filter_size=32);
+
+class gr_pfb_arb_resampler_ccf : public gr_block
+{
+ private:
+  gr_pfb_arb_resampler_ccf (float rate,
+                           const std::vector<float> &taps,
+                           unsigned int filter_size);
+
+ public:
+  ~gr_pfb_arb_resampler_ccf ();
+
+  //void set_taps (const std::vector<float> &taps);
+  void print_taps();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc
new file mode 100644 (file)
index 0000000..5fda478
--- /dev/null
@@ -0,0 +1,199 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_channelizer_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <cstring>
+
+gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, 
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate)
+{
+  return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps,
+                                                                 oversample_rate));
+}
+
+
+gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans, 
+                                               const std::vector<float> &taps,
+                                               float oversample_rate)
+  : gr_block ("pfb_channelizer_ccf",
+             gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
+             gr_make_io_signature (1, 1, numchans*sizeof(gr_complex))),
+    d_updated (false), d_numchans(numchans), d_oversample_rate(oversample_rate)
+{
+  // The over sampling rate must be rationally related to the number of channels
+  // in that it must be N/i for i in [1,N], which gives an outputsample rate 
+  // of [fs/N, fs] where fs is the input sample rate.
+  // This tests the specified input sample rate to see if it conforms to this
+  // requirement within a few significant figures.
+  double intp = 0;
+  double x = (10000.0*rint(numchans / oversample_rate)) / 10000.0;
+  double fltp = modf(numchans / oversample_rate, &intp);
+  if(fltp != 0.0)
+    throw std::invalid_argument("gr_pfb_channelizer: oversample rate must be N/i for i in [1, N]"); 
+
+  d_filters = std::vector<gr_fir_ccf*>(d_numchans);
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_numchans);
+  for(unsigned int i = 0; i < d_numchans; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+  }
+
+  // Now, actually set the filters' taps
+  set_taps(taps);
+
+  // Create the FFT to handle the output de-spinning of the channels
+  d_fft = new gri_fft_complex (d_numchans, false);
+
+  // Although the filters change, we use this look up table
+  // to set the index of the FFT input buffer, which equivalently
+  // performs the FFT shift operation on every other turn.
+  d_rate_ratio = (int)rintf(d_numchans / d_oversample_rate);
+  d_idxlut = new int[d_numchans];
+  for(unsigned int i = 0; i < d_numchans; i++) {
+    d_idxlut[i] = d_numchans - ((i + d_rate_ratio) % d_numchans) - 1;
+  }
+
+  // Calculate the number of filtering rounds to do to evenly
+  // align the input vectors with the output channels
+  d_output_multiple = 1;
+  while((d_output_multiple * d_rate_ratio) % d_numchans != 0)
+    d_output_multiple++;
+  set_output_multiple(d_output_multiple);
+}
+
+gr_pfb_channelizer_ccf::~gr_pfb_channelizer_ccf ()
+{
+  delete [] d_idxlut; 
+  
+  for(unsigned int i = 0; i < d_numchans; i++) {
+    delete d_filters[i];
+  }
+}
+
+void
+gr_pfb_channelizer_ccf::set_taps (const std::vector<float> &taps)
+{
+  unsigned int i,j;
+
+  unsigned int ntaps = taps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+  // Create d_numchan vectors to store each channel's taps
+  d_taps.resize(d_numchans);
+
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = taps;
+  while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  // Partition the filter
+  for(i = 0; i < d_numchans; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      d_taps[i][j] = tmp_taps[i + j*d_numchans];  // add taps to channels in reverse order
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    d_filters[i]->set_taps(d_taps[i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter+1);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_channelizer_ccf::print_taps()
+{
+  unsigned int i, j;
+  for(i = 0; i < d_numchans; i++) {
+    printf("filter[%d]: [", i);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      printf(" %.4e", d_taps[i][j]);
+    }
+    printf("]\n\n");
+  }
+}
+
+
+int
+gr_pfb_channelizer_ccf::general_work (int noutput_items,
+                                     gr_vector_int &ninput_items,
+                                     gr_vector_const_void_star &input_items,
+                                     gr_vector_void_star &output_items)
+{
+  gr_complex *in = (gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int n=1, i=-1, j=0, last;
+  int toconsume = (int)rintf(noutput_items/d_oversample_rate);
+  while(n <= toconsume) {
+    j = 0;
+    i = (i + d_rate_ratio) % d_numchans;
+    last = i;
+    while(i >= 0) {
+      in = (gr_complex*)input_items[j];
+      d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n]);
+      j++;
+      i--;
+    }
+
+    i = d_numchans-1;
+    while(i > last) {
+      in = (gr_complex*)input_items[j];
+      d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n-1]);
+      j++;
+      i--;
+    }
+
+    n += (i+d_rate_ratio) >= (int)d_numchans;
+
+    // despin through FFT
+    d_fft->execute();
+    memcpy(out, d_fft->get_outbuf(), d_numchans*sizeof(gr_complex));
+    out += d_numchans;
+  }
+
+  consume_each(toconsume);
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h
new file mode 100644 (file)
index 0000000..751673b
--- /dev/null
@@ -0,0 +1,178 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CHANNELIZER_CCF_H
+#define        INCLUDED_GR_PFB_CHANNELIZER_CCF_H
+
+#include <gr_block.h>
+
+class gr_pfb_channelizer_ccf;
+typedef boost::shared_ptr<gr_pfb_channelizer_ccf> gr_pfb_channelizer_ccf_sptr;
+gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, 
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate=1);
+
+class gr_fir_ccf;
+class gri_fft_complex;
+
+
+/*!
+ * \class gr_pfb_channelizer_ccf
+ *
+ * \brief Polyphase filterbank channelizer with 
+ *        gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ *
+ * This block takes in complex inputs and channelizes it to <EM>M</EM>
+ * channels of equal bandwidth. Each of the resulting channels is
+ * decimated to the new rate that is the input sampling rate
+ * <EM>fs</EM> divided by the number of channels, <EM>M</EM>.
+ *
+ * The PFB channelizer code takes the taps generated above and builds
+ * a set of filters. The set contains <EM>M</EM> number of filters
+ * and each filter contains ceil(taps.size()/decim) number of taps.
+ * Each tap from the filter prototype is sequentially inserted into
+ * the next filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure each
+ * filter has the same number of taps.
+ *
+ * Each filter operates using the gr_fir filter classs of GNU Radio,
+ * which takes the input stream at <EM>i</EM> and performs the inner
+ * product calculation to <EM>i+(n-1)</EM> where <EM>n</EM> is the
+ * number of filter taps. To efficiently handle this in the GNU Radio
+ * structure, each filter input must come from its own input
+ * stream. So the channelizer must be provided with <EM>M</EM> streams
+ * where the input stream has been deinterleaved. This is most easily
+ * done using the gr_stream_to_streams block.
+ *
+ * The output is then produced as a vector, where index <EM>i</EM> in
+ * the vector is the next sample from the <EM>i</EM>th channel. This
+ * is most easily handled by sending the output to a
+ * gr_vector_to_streams block to handle the conversion and passing
+ * <EM>M</EM> streams out.
+ *
+ * The input and output formatting is done using a hier_block2 called
+ * pfb_channelizer_ccf. This can take in a single stream and outputs
+ * <EM>M</EM> streams based on the behavior described above.
+ *
+ * The filter's taps should be based on the input sampling rate.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of 
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first input
+ *  is the gain of the filter, which we specify here as unity.
+ *
+ *      <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB, 
+ *           attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The filter output can also be overs ampled. The over sampling rate 
+ * is the ratio of the the actual output sampling rate to the normal 
+ * output sampling rate. It must be rationally related to the number 
+ * of channels as N/i for i in [1,N], which gives an outputsample rate
+ * of [fs/N, fs] where fs is the input sample rate and N is the number
+ * of channels.
+ *
+ * For example, for 6 channels with fs = 6000 Hz, the normal rate is 
+ * 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4, 
+ * 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample
+ * ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2,
+ * so the output rate would be 1200 Hz.
+ *
+ * The theory behind this block can be found in Chapter 6 of 
+ * the following book.
+ *
+ *    <B><EM>f. harris, "Multirate Signal Processing for Communication 
+ *       Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ *
+ */
+
+class gr_pfb_channelizer_ccf : public gr_block
+{
+ private:
+  /*!
+   * Build the polyphase filterbank decimator.
+   * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param oversample_rate (float)   The over sampling rate is the ratio of the the actual
+   *                                  output sampling rate to the normal output sampling rate.
+   *                                   It must be rationally related to the number of channels
+   *                                 as N/i for i in [1,N], which gives an outputsample rate 
+   *                                 of [fs/N, fs] where fs is the input sample rate and N is
+   *                                 the number of channels.
+   *                                 
+   *                                 For example, for 6 channels with fs = 6000 Hz, the normal
+   *                                 rate is 6000/6 = 1000 Hz. Allowable oversampling rates
+   *                                 are 6/6, 6/5, 6/4, 6/3, 6/2, and 6/1 where the output
+   *                                 sample rate of a 6/1 oversample ratio is 6000 Hz, or
+   *                                 6 times the normal 1000 Hz.
+   */
+  friend gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+                                                                 const std::vector<float> &taps,
+                                                                 float oversample_rate);
+
+  bool                    d_updated;
+  unsigned int             d_numchans;
+  float                    d_oversample_rate;
+  std::vector<gr_fir_ccf*> d_filters;
+  std::vector< std::vector<float> > d_taps;
+  unsigned int             d_taps_per_filter;
+  gri_fft_complex         *d_fft;
+  int                     *d_idxlut;
+  int                      d_rate_ratio;
+  int                      d_output_multiple;
+
+  /*!
+   * Build the polyphase filterbank decimator.
+   * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param oversample_rate (float)   The output over sampling rate.
+   */
+  gr_pfb_channelizer_ccf (unsigned int numchans, 
+                         const std::vector<float> &taps,
+                         float oversample_rate);
+
+public:
+  ~gr_pfb_channelizer_ccf ();
+  
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   */
+  void set_taps (const std::vector<float> &taps);
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+  
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i
new file mode 100644 (file)
index 0000000..63e3e0f
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_channelizer_ccf);
+
+gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+                                                        const std::vector<float> &taps,
+                                                        float oversample_rate=1);
+
+class gr_pfb_channelizer_ccf : public gr_block
+{
+ private:
+  gr_pfb_channelizer_ccf (unsigned int numchans,
+                         const std::vector<float> &taps,
+                         float oversample_rate);
+
+ public:
+  ~gr_pfb_channelizer_ccf ();
+
+  void set_taps (const std::vector<float> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
new file mode 100644 (file)
index 0000000..ff4fb70
--- /dev/null
@@ -0,0 +1,290 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <gr_pfb_clock_sync_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size,
+                                                      float init_phase,
+                                                      float max_rate_deviation)
+{
+  return gr_pfb_clock_sync_ccf_sptr (new gr_pfb_clock_sync_ccf (sps, gain, taps,
+                                                               filter_size,
+                                                               init_phase,
+                                                               max_rate_deviation));
+}
+
+static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float gain,
+                                             const std::vector<float> &taps,
+                                             unsigned int filter_size,
+                                             float init_phase,
+                                             float max_rate_deviation)
+  : gr_block ("pfb_clock_sync_ccf",
+             gr_make_io_signature (1, 1, sizeof(gr_complex)),
+             gr_make_io_signaturev (1, 4, iosig)),
+    d_updated (false), d_nfilters(filter_size),
+    d_max_dev(max_rate_deviation)
+{
+  d_nfilters = filter_size;
+  d_sps = floor(sps);
+
+  // Store the last filter between calls to work
+  // The accumulator keeps track of overflow to increment the stride correctly.
+  // set it here to the fractional difference based on the initial phaes
+  set_alpha(gain);
+  set_beta(0.25*gain*gain);
+  d_k = init_phase;
+  d_rate = (sps-floor(sps))*(double)d_nfilters;
+  d_rate_i = (int)floor(d_rate);
+  d_rate_f = d_rate - (float)d_rate_i;
+  d_filtnum = (int)floor(d_k);
+
+  d_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+  d_diff_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_nfilters);
+  for(int i = 0; i < d_nfilters; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+    d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+  }
+
+  // Now, actually set the filters' taps
+  std::vector<float> dtaps;
+  create_diff_taps(taps, dtaps);
+  set_taps(taps, d_taps, d_filters);
+  set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_clock_sync_ccf::~gr_pfb_clock_sync_ccf ()
+{
+  for(int i = 0; i < d_nfilters; i++) {
+    delete d_filters[i];
+    delete d_diff_filters[i];
+  }
+}
+
+bool
+gr_pfb_clock_sync_ccf::check_topology(int ninputs, int noutputs)
+{
+  return noutputs == 1 || noutputs == 4;
+}
+
+void
+gr_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps,
+                                std::vector< std::vector<float> > &ourtaps,
+                                std::vector<gr_fir_ccf*> &ourfilter)
+{
+  int i,j;
+
+  unsigned int ntaps = newtaps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+  // Create d_numchan vectors to store each channel's taps
+  ourtaps.resize(d_nfilters);
+  
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = newtaps;
+  while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  
+  // Partition the filter
+  for(i = 0; i < d_nfilters; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters];
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter + d_sps);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps,
+                                       std::vector<float> &difftaps)
+{
+  float maxtap = 1e-20;
+  difftaps.clear();
+  difftaps.push_back(0); //newtaps[0]);
+  for(unsigned int i = 1; i < newtaps.size()-1; i++) {
+    float tap = newtaps[i+1] - newtaps[i-1];
+    difftaps.push_back(tap);
+    if(tap > maxtap) {
+      maxtap = tap;
+    }
+  }
+  difftaps.push_back(0);//-newtaps[newtaps.size()-1]);
+
+  // Scale the differential taps; helps scale error term to better update state
+  // FIXME: should this be scaled this way or use the same gain as the taps?
+  for(unsigned int i = 0; i < difftaps.size(); i++) {
+    difftaps[i] /= maxtap;
+  }
+}
+
+void
+gr_pfb_clock_sync_ccf::print_taps()
+{
+  int i, j;
+  printf("[ ");
+  for(i = 0; i < d_nfilters; i++) {
+    printf("[%.4e, ", d_taps[i][0]);
+    for(j = 1; j < d_taps_per_filter-1; j++) {
+      printf("%.4e,", d_taps[i][j]);
+    }
+    printf("%.4e],", d_taps[i][j]);
+  }
+  printf(" ]\n");
+}
+
+void
+gr_pfb_clock_sync_ccf::print_diff_taps()
+{
+  int i, j;
+  printf("[ ");
+  for(i = 0; i < d_nfilters; i++) {
+    printf("[%.4e, ", d_dtaps[i][0]);
+    for(j = 1; j < d_taps_per_filter-1; j++) {
+      printf("%.4e,", d_dtaps[i][j]);
+    }
+    printf("%.4e],", d_dtaps[i][j]);
+  }
+  printf(" ]\n");
+}
+
+
+std::vector<float>
+gr_pfb_clock_sync_ccf::channel_taps(int channel)
+{
+  std::vector<float> taps;
+  for(int i = 0; i < d_taps_per_filter; i++) {
+    taps.push_back(d_taps[channel][i]);
+  }
+  return taps;
+}
+
+std::vector<float>
+gr_pfb_clock_sync_ccf::diff_channel_taps(int channel)
+{
+  std::vector<float> taps;
+  for(int i = 0; i < d_taps_per_filter; i++) {
+    taps.push_back(d_dtaps[channel][i]);
+  }
+  return taps;
+}
+
+
+int
+gr_pfb_clock_sync_ccf::general_work (int noutput_items,
+                                    gr_vector_int &ninput_items,
+                                    gr_vector_const_void_star &input_items,
+                                    gr_vector_void_star &output_items)
+{
+  gr_complex *in = (gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  float *err = 0, *outrate = 0, *outk = 0;
+  if(output_items.size() == 4) {
+    err = (float *) output_items[1];
+    outrate = (float*)output_items[2];
+    outk = (float*)output_items[3];
+  }
+  
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  // We need this many to process one output
+  int nrequired = ninput_items[0] - d_taps_per_filter;
+
+  int i = 0, count = 0;
+  float error, error_r, error_i;
+
+  // produce output as long as we can and there are enough input samples
+  while((i < noutput_items) && (count < nrequired)) {
+    d_filtnum = (int)floor(d_k);
+
+    // Keep the current filter number in [0, d_nfilters]
+    // If we've run beyond the last filter, wrap around and go to next sample
+    // If we've go below 0, wrap around and go to previous sample
+    while(d_filtnum >= d_nfilters) {
+      d_k -= d_nfilters;
+      d_filtnum -= d_nfilters;
+      count += 1;
+    }
+    while(d_filtnum < 0) {
+      d_k += d_nfilters;
+      d_filtnum += d_nfilters;
+      count -= 1;
+    }
+
+    out[i] = d_filters[d_filtnum]->filter(&in[count]);
+    gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+    error_r  = out[i].real() * diff.real();
+    error_i  = out[i].imag() * diff.imag();
+    error = (error_i + error_r) / 2.0;       // average error from I&Q channel
+
+    // Run the control loop to update the current phase (k) and tracking rate
+    d_k = d_k + d_alpha*error + d_rate_i + d_rate_f;
+    d_rate_f = d_rate_f + d_beta*error;
+    
+    // Keep our rate within a good range
+    d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+    i++;
+    count += (int)floor(d_sps);
+
+    if(output_items.size() == 4) {
+      err[i] = error;
+      outrate[i] = d_rate_f;
+      outk[i] = d_k;
+    }
+  }
+  consume_each(count);
+
+  return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
new file mode 100644 (file)
index 0000000..4e6ef5f
--- /dev/null
@@ -0,0 +1,225 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CLOCK_SYNC_CCF_H
+#define        INCLUDED_GR_PFB_CLOCK_SYNC_CCF_H
+
+#include <gr_block.h>
+
+class gr_pfb_clock_sync_ccf;
+typedef boost::shared_ptr<gr_pfb_clock_sync_ccf> gr_pfb_clock_sync_ccf_sptr;
+gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size=32,
+                                                      float init_phase=0,
+                                                      float max_rate_deviation=1.5);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_clock_sync_ccf
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * 
+ * This block performs timing synchronization for PAM signals by minimizing the
+ * derivative of the filtered signal, which in turn maximizes the SNR and 
+ * minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbanke contains the 
+ * signal's pulse shaping matched filter (such as a root raised cosine filter),
+ * where each branch of the filterbank contains a different phase of the filter.
+ * The second filterbank contains the derivatives of the filters in the first 
+ * filterbank. Thinking of this in the time domain, the first filterbank contains
+ * filters that have a sinc shape to them. We want to align the output signal to
+ * be sampled at exactly the peak of the sinc shape. The derivative of the sinc
+ * contains a zero at the maximum point of the sinc (sinc(0) = 1, sinc(0)' = 0).
+ * Furthermore, the region around the zero point is relatively linear. We make
+ * use of this fact to generate the error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith filter, and
+ * the output of the matched filter is x_i[n], we calculate the error as:
+ *    e[n] = (Re{x_i[n]} * Re{d_i[n]} + Im{x_i[n]} * Im{d_i[n]}) / 2.0
+ * This equation averages the error in the real and imaginary parts. There are two
+ * reasons we multiply by the signal itself. First, if the symbol could be positive
+ * or negative going, but we want the error term to always tell us to go in the 
+ * same direction depending on which side of the zero point we are on. The sign of
+ * x_i[n] adjusts the error term to do this. Second, the magnitude of x_i[n] scales
+ * the error term depending on the symbol's amplitude, so larger signals give us
+ * a stronger error term because we have more confidence in that symbol's value.
+ * Using the magnitude of x_i[n] instead of just the sign is especially good for
+ * signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far away from the zero
+ * point we are in the derivative signal. We want to drive this value to zero, so we
+ * set up a second order loop. We have two variables for this loop; d_k is the filter
+ * number in the filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock differences between
+ * the transmitter and receiver, d_rate represents that difference and would traverse
+ * the filter phase paths to keep the receiver locked. Thinking of this as a second-order
+ * PLL, the d_rate is the frequency and d_k is the phase. So we update d_rate and d_k
+ * using the standard loop equations based on two error signals, d_alpha and d_beta.
+ * We have these two values set based on each other for a critically damped system, so in
+ * the block constructor, we just ask for "gain," which is d_alpha while d_beta is
+ * equal to (gain^2)/4.
+ *
+ * The clock sync block needs to know the number of samples per second (sps), because it
+ * only returns a single point representing the sample. The sps can be any positive real
+ * number and does not need to be an integer. The filter taps must also be specified. The
+ * taps are generated by first conceiving of the prototype filter that would be the signal's
+ * matched filter. Then interpolate this by the number of filters in the filterbank. These
+ * are then distributed among all of the filters. So if the prototype filter was to have
+ * 45 taps in it, then each path of the filterbank will also have 45 taps. This is easily
+ * done by building the filter with the sample rate multiplied by the number of filters
+ * to use.
+ *
+ * The number of filters can also be set and defaults to 32. With 32 filters, you get a
+ * good enough resolution in the phase to produce very small, almost unnoticeable, ISI.
+ * Going to 64 filters can reduce this more, but after that there is very little gained
+ * for the extra complexity.
+ *
+ * The initial phase is another settable parameter and refers to the filter path the
+ * algorithm initially looks at (i.e., d_k starts at init_phase). This value defaults 
+ * to zero, but it might be useful to start at a different phase offset, such as the mid-
+ * point of the filters.
+ *
+ * The final parameter is the max_rate_devitation, which defaults to 1.5. This is how far
+ * we allow d_rate to swing, positive or negative, from 0. Constraining the rate can help
+ * keep the algorithm from walking too far away to lock during times when there is no signal.
+ *
+ */
+
+class gr_pfb_clock_sync_ccf : public gr_block
+{
+ private:
+  /*!
+   * Build the polyphase filterbank timing synchronizer.
+   * \param sps (double) The number of samples per second in the incoming signal
+   * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default.
+   * \param taps (vector<int>) The filter taps.
+   * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+   * \param init_phase (float) The initial phase to look at, or which filter to start 
+   *                           with (default = 0).
+   * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+   *
+   */
+  friend gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain,
+                                                               const std::vector<float> &taps,
+                                                               unsigned int filter_size,
+                                                               float init_phase,
+                                                               float max_rate_deviation);
+
+  bool                    d_updated;
+  double                   d_sps;
+  double                   d_sample_num;
+  float                    d_alpha;
+  float                    d_beta;
+  int                      d_nfilters;
+  std::vector<gr_fir_ccf*> d_filters;
+  std::vector<gr_fir_ccf*> d_diff_filters;
+  std::vector< std::vector<float> > d_taps;
+  std::vector< std::vector<float> > d_dtaps;
+  float                    d_k;
+  float                    d_rate;
+  float                    d_rate_i;
+  float                    d_rate_f;
+  float                    d_max_dev;
+  int                      d_filtnum;
+  int                      d_taps_per_filter;
+
+  /*!
+   * Build the polyphase filterbank timing synchronizer.
+   */
+  gr_pfb_clock_sync_ccf (double sps, float gain,
+                        const std::vector<float> &taps,
+                        unsigned int filter_size,
+                        float init_phase,
+                        float max_rate_deviation);
+  
+  void create_diff_taps(const std::vector<float> &newtaps,
+                       std::vector<float> &difftaps);
+
+public:
+  ~gr_pfb_clock_sync_ccf ();
+  
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   */
+  void set_taps (const std::vector<float> &taps,
+                std::vector< std::vector<float> > &ourtaps,
+                std::vector<gr_fir_ccf*> &ourfilter);
+
+  /*!
+   * Returns the taps of the matched filter
+   */
+  std::vector<float> channel_taps(int channel);
+
+  /*!
+   * Returns the taps in the derivative filter
+   */
+  std::vector<float> diff_channel_taps(int channel);
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+
+  /*!
+   * Print all of the filterbank taps of the derivative filter to screen.
+   */
+  void print_diff_taps();
+
+  /*!
+   * Set the gain value alpha for the control loop
+   */  
+  void set_alpha(float alpha)
+  {
+    d_alpha = alpha;
+  }
+
+  /*!
+   * Set the gain value beta for the control loop
+   */  
+  void set_beta(float beta)
+  {
+    d_beta = beta;
+  }
+
+  /*!
+   * Set the maximum deviation from 0 d_rate can have
+   */  
+  void set_max_rate_deviation(float m)
+  {
+    d_max_dev = m;
+  }
+  
+  bool check_topology(int ninputs, int noutputs);
+
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i
new file mode 100644 (file)
index 0000000..1979842
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_clock_sync_ccf);
+
+gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size=32,
+                                                      float init_phase=0,
+                                                      float max_rate_deviation=1.5);
+
+class gr_pfb_clock_sync_ccf : public gr_block
+{
+ private:
+  gr_pfb_clock_sync_ccf (double sps, float gain,
+                        const std::vector<float> &taps,
+                        unsigned int filter_size,
+                        float init_phase,
+                        float max_rate_deviation);
+
+ public:
+  ~gr_pfb_clock_sync_ccf ();
+
+  void set_taps (const std::vector<float> &taps,
+                std::vector< std::vector<float> > &ourtaps,
+                std::vector<gr_fir_ccf*> &ourfilter);
+
+  std::vector<float> channel_taps(int channel);
+  std::vector<float> diff_channel_taps(int channel);
+  void print_taps();
+  void print_diff_taps();
+  void set_alpha(float alpha);
+  void set_beta(float beta);
+  void set_max_rate_deviation(float m);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
new file mode 100644 (file)
index 0000000..86de3b5
--- /dev/null
@@ -0,0 +1,288 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <gr_pfb_clock_sync_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size,
+                                                      float init_phase,
+                                                      float max_rate_deviation)
+{
+  return gr_pfb_clock_sync_fff_sptr (new gr_pfb_clock_sync_fff (sps, gain, taps,
+                                                               filter_size,
+                                                               init_phase,
+                                                               max_rate_deviation));
+}
+
+static int ios[] = {sizeof(float), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+gr_pfb_clock_sync_fff::gr_pfb_clock_sync_fff (double sps, float gain,
+                                             const std::vector<float> &taps,
+                                             unsigned int filter_size,
+                                             float init_phase,
+                                             float max_rate_deviation)
+  : gr_block ("pfb_clock_sync_fff",
+             gr_make_io_signature (1, 1, sizeof(float)),
+             gr_make_io_signaturev (1, 4, iosig)),
+    d_updated (false), d_nfilters(filter_size),
+    d_max_dev(max_rate_deviation)
+{
+  d_nfilters = filter_size;
+  d_sps = floor(sps);
+
+  // Store the last filter between calls to work
+  // The accumulator keeps track of overflow to increment the stride correctly.
+  // set it here to the fractional difference based on the initial phaes
+  set_alpha(gain);
+  set_beta(0.25*gain*gain);
+  d_k = init_phase;
+  d_rate = (sps-floor(sps))*(double)d_nfilters;
+  d_rate_i = (int)floor(d_rate);
+  d_rate_f = d_rate - (float)d_rate_i;
+  d_filtnum = (int)floor(d_k);
+
+  d_filters = std::vector<gr_fir_fff*>(d_nfilters);
+  d_diff_filters = std::vector<gr_fir_fff*>(d_nfilters);
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_nfilters);
+  for(int i = 0; i < d_nfilters; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+    d_diff_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+  }
+
+  // Now, actually set the filters' taps
+  std::vector<float> dtaps;
+  create_diff_taps(taps, dtaps);
+  set_taps(taps, d_taps, d_filters);
+  set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_clock_sync_fff::~gr_pfb_clock_sync_fff ()
+{
+  for(int i = 0; i < d_nfilters; i++) {
+    delete d_filters[i];
+    delete d_diff_filters[i];
+  }
+}
+
+bool
+gr_pfb_clock_sync_fff::check_topology(int ninputs, int noutputs)
+{
+  return noutputs == 1 || noutputs == 4;
+}
+
+void
+gr_pfb_clock_sync_fff::set_taps (const std::vector<float> &newtaps,
+                                std::vector< std::vector<float> > &ourtaps,
+                                std::vector<gr_fir_fff*> &ourfilter)
+{
+  int i,j;
+
+  unsigned int ntaps = newtaps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+  // Create d_numchan vectors to store each channel's taps
+  ourtaps.resize(d_nfilters);
+  
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = newtaps;
+  while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  
+  // Partition the filter
+  for(i = 0; i < d_nfilters; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters];
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter + d_sps);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_clock_sync_fff::create_diff_taps(const std::vector<float> &newtaps,
+                                       std::vector<float> &difftaps)
+{
+  float maxtap = 1e-20;
+  difftaps.clear();
+  difftaps.push_back(0); //newtaps[0]);
+  for(unsigned int i = 1; i < newtaps.size()-1; i++) {
+    float tap = newtaps[i+1] - newtaps[i-1];
+    difftaps.push_back(tap);
+    if(tap > maxtap) {
+      maxtap = tap;
+    }
+  }
+  difftaps.push_back(0);//-newtaps[newtaps.size()-1]);
+
+  // Scale the differential taps; helps scale error term to better update state
+  // FIXME: should this be scaled this way or use the same gain as the taps?
+  for(unsigned int i = 0; i < difftaps.size(); i++) {
+    difftaps[i] /= maxtap;
+  }
+}
+
+void
+gr_pfb_clock_sync_fff::print_taps()
+{
+  int i, j;
+  printf("[ ");
+  for(i = 0; i < d_nfilters; i++) {
+    printf("[%.4e, ", d_taps[i][0]);
+    for(j = 1; j < d_taps_per_filter-1; j++) {
+      printf("%.4e,", d_taps[i][j]);
+    }
+    printf("%.4e],", d_taps[i][j]);
+  }
+  printf(" ]\n");
+}
+
+void
+gr_pfb_clock_sync_fff::print_diff_taps()
+{
+  int i, j;
+  printf("[ ");
+  for(i = 0; i < d_nfilters; i++) {
+    printf("[%.4e, ", d_dtaps[i][0]);
+    for(j = 1; j < d_taps_per_filter-1; j++) {
+      printf("%.4e,", d_dtaps[i][j]);
+    }
+    printf("%.4e],", d_dtaps[i][j]);
+  }
+  printf(" ]\n");
+}
+
+
+std::vector<float>
+gr_pfb_clock_sync_fff::channel_taps(int channel)
+{
+  std::vector<float> taps;
+  for(int i = 0; i < d_taps_per_filter; i++) {
+    taps.push_back(d_taps[channel][i]);
+  }
+  return taps;
+}
+
+std::vector<float>
+gr_pfb_clock_sync_fff::diff_channel_taps(int channel)
+{
+  std::vector<float> taps;
+  for(int i = 0; i < d_taps_per_filter; i++) {
+    taps.push_back(d_dtaps[channel][i]);
+  }
+  return taps;
+}
+
+
+int
+gr_pfb_clock_sync_fff::general_work (int noutput_items,
+                                    gr_vector_int &ninput_items,
+                                    gr_vector_const_void_star &input_items,
+                                    gr_vector_void_star &output_items)
+{
+  float *in = (float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  float *err = 0, *outrate = 0, *outk = 0;
+  if(output_items.size() == 4) {
+    err = (float *) output_items[1];
+    outrate = (float*)output_items[2];
+    outk = (float*)output_items[3];
+  }
+  
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  // We need this many to process one output
+  int nrequired = ninput_items[0] - d_taps_per_filter;
+
+  int i = 0, count = 0;
+  float error;
+
+  // produce output as long as we can and there are enough input samples
+  while((i < noutput_items) && (count < nrequired)) {
+    d_filtnum = (int)floor(d_k);
+
+    // Keep the current filter number in [0, d_nfilters]
+    // If we've run beyond the last filter, wrap around and go to next sample
+    // If we've go below 0, wrap around and go to previous sample
+    while(d_filtnum >= d_nfilters) {
+      d_k -= d_nfilters;
+      d_filtnum -= d_nfilters;
+      count += 1;
+    }
+    while(d_filtnum < 0) {
+      d_k += d_nfilters;
+      d_filtnum += d_nfilters;
+      count -= 1;
+    }
+
+    out[i] = d_filters[d_filtnum]->filter(&in[count]);
+    float diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+    error  = out[i] * diff;
+
+    // Run the control loop to update the current phase (k) and tracking rate
+    d_k = d_k + d_alpha*error + d_rate_i + d_rate_f;
+    d_rate_f = d_rate_f + d_beta*error;
+    
+    // Keep our rate within a good range
+    d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+    i++;
+    count += (int)floor(d_sps);
+
+    if(output_items.size() == 4) {
+      err[i] = error;
+      outrate[i] = d_rate_f;
+      outk[i] = d_k;
+    }
+  }
+  consume_each(count);
+
+  return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
new file mode 100644 (file)
index 0000000..fa1279a
--- /dev/null
@@ -0,0 +1,225 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CLOCK_SYNC_FFF_H
+#define        INCLUDED_GR_PFB_CLOCK_SYNC_FFF_H
+
+#include <gr_block.h>
+
+class gr_pfb_clock_sync_fff;
+typedef boost::shared_ptr<gr_pfb_clock_sync_fff> gr_pfb_clock_sync_fff_sptr;
+gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size=32,
+                                                      float init_phase=0,
+                                                      float max_rate_deviation=1.5);
+
+class gr_fir_fff;
+
+/*!
+ * \class gr_pfb_clock_sync_fff
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * 
+ * This block performs timing synchronization for PAM signals by minimizing the
+ * derivative of the filtered signal, which in turn maximizes the SNR and 
+ * minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbanke contains the 
+ * signal's pulse shaping matched filter (such as a root raised cosine filter),
+ * where each branch of the filterbank contains a different phase of the filter.
+ * The second filterbank contains the derivatives of the filters in the first 
+ * filterbank. Thinking of this in the time domain, the first filterbank contains
+ * filters that have a sinc shape to them. We want to align the output signal to
+ * be sampled at exactly the peak of the sinc shape. The derivative of the sinc
+ * contains a zero at the maximum point of the sinc (sinc(0) = 1, sinc(0)' = 0).
+ * Furthermore, the region around the zero point is relatively linear. We make
+ * use of this fact to generate the error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith filter, and
+ * the output of the matched filter is x_i[n], we calculate the error as:
+ *    e[n] = (Re{x_i[n]} * Re{d_i[n]} + Im{x_i[n]} * Im{d_i[n]}) / 2.0
+ * This equation averages the error in the real and imaginary parts. There are two
+ * reasons we multiply by the signal itself. First, if the symbol could be positive
+ * or negative going, but we want the error term to always tell us to go in the 
+ * same direction depending on which side of the zero point we are on. The sign of
+ * x_i[n] adjusts the error term to do this. Second, the magnitude of x_i[n] scales
+ * the error term depending on the symbol's amplitude, so larger signals give us
+ * a stronger error term because we have more confidence in that symbol's value.
+ * Using the magnitude of x_i[n] instead of just the sign is especially good for
+ * signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far away from the zero
+ * point we are in the derivative signal. We want to drive this value to zero, so we
+ * set up a second order loop. We have two variables for this loop; d_k is the filter
+ * number in the filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock differences between
+ * the transmitter and receiver, d_rate represents that difference and would traverse
+ * the filter phase paths to keep the receiver locked. Thinking of this as a second-order
+ * PLL, the d_rate is the frequency and d_k is the phase. So we update d_rate and d_k
+ * using the standard loop equations based on two error signals, d_alpha and d_beta.
+ * We have these two values set based on each other for a critically damped system, so in
+ * the block constructor, we just ask for "gain," which is d_alpha while d_beta is
+ * equal to (gain^2)/4.
+ *
+ * The clock sync block needs to know the number of samples per second (sps), because it
+ * only returns a single point representing the sample. The sps can be any positive real
+ * number and does not need to be an integer. The filter taps must also be specified. The
+ * taps are generated by first conceiving of the prototype filter that would be the signal's
+ * matched filter. Then interpolate this by the number of filters in the filterbank. These
+ * are then distributed among all of the filters. So if the prototype filter was to have
+ * 45 taps in it, then each path of the filterbank will also have 45 taps. This is easily
+ * done by building the filter with the sample rate multiplied by the number of filters
+ * to use.
+ *
+ * The number of filters can also be set and defaults to 32. With 32 filters, you get a
+ * good enough resolution in the phase to produce very small, almost unnoticeable, ISI.
+ * Going to 64 filters can reduce this more, but after that there is very little gained
+ * for the extra complexity.
+ *
+ * The initial phase is another settable parameter and refers to the filter path the
+ * algorithm initially looks at (i.e., d_k starts at init_phase). This value defaults 
+ * to zero, but it might be useful to start at a different phase offset, such as the mid-
+ * point of the filters.
+ *
+ * The final parameter is the max_rate_devitation, which defaults to 1.5. This is how far
+ * we allow d_rate to swing, positive or negative, from 0. Constraining the rate can help
+ * keep the algorithm from walking too far away to lock during times when there is no signal.
+ *
+ */
+
+class gr_pfb_clock_sync_fff : public gr_block
+{
+ private:
+  /*!
+   * Build the polyphase filterbank timing synchronizer.
+   * \param sps (double) The number of samples per second in the incoming signal
+   * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default.
+   * \param taps (vector<int>) The filter taps.
+   * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+   * \param init_phase (float) The initial phase to look at, or which filter to start 
+   *                           with (default = 0).
+   * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+   *
+   */
+  friend gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+                                                               const std::vector<float> &taps,
+                                                               unsigned int filter_size,
+                                                               float init_phase,
+                                                               float max_rate_deviation);
+
+  bool                    d_updated;
+  double                   d_sps;
+  double                   d_sample_num;
+  float                    d_alpha;
+  float                    d_beta;
+  int                      d_nfilters;
+  std::vector<gr_fir_fff*> d_filters;
+  std::vector<gr_fir_fff*> d_diff_filters;
+  std::vector< std::vector<float> > d_taps;
+  std::vector< std::vector<float> > d_dtaps;
+  float                    d_k;
+  float                    d_rate;
+  float                    d_rate_i;
+  float                    d_rate_f;
+  float                    d_max_dev;
+  int                      d_filtnum;
+  int                      d_taps_per_filter;
+
+  /*!
+   * Build the polyphase filterbank timing synchronizer.
+   */
+  gr_pfb_clock_sync_fff (double sps, float gain,
+                        const std::vector<float> &taps,
+                        unsigned int filter_size,
+                        float init_phase,
+                        float max_rate_deviation);
+  
+  void create_diff_taps(const std::vector<float> &newtaps,
+                       std::vector<float> &difftaps);
+
+public:
+  ~gr_pfb_clock_sync_fff ();
+  
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   */
+  void set_taps (const std::vector<float> &taps,
+                std::vector< std::vector<float> > &ourtaps,
+                std::vector<gr_fir_fff*> &ourfilter);
+
+  /*!
+   * Returns the taps of the matched filter
+   */
+  std::vector<float> channel_taps(int channel);
+
+  /*!
+   * Returns the taps in the derivative filter
+   */
+  std::vector<float> diff_channel_taps(int channel);
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+
+  /*!
+   * Print all of the filterbank taps of the derivative filter to screen.
+   */
+  void print_diff_taps();
+
+  /*!
+   * Set the gain value alpha for the control loop
+   */  
+  void set_alpha(float alpha)
+  {
+    d_alpha = alpha;
+  }
+
+  /*!
+   * Set the gain value beta for the control loop
+   */  
+  void set_beta(float beta)
+  {
+    d_beta = beta;
+  }
+
+  /*!
+   * Set the maximum deviation from 0 d_rate can have
+   */  
+  void set_max_rate_deviation(float m)
+  {
+    d_max_dev = m;
+  }
+
+  bool check_topology(int ninputs, int noutputs);
+
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i
new file mode 100644 (file)
index 0000000..d6bb787
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_clock_sync_fff);
+
+gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+                                                      const std::vector<float> &taps,
+                                                      unsigned int filter_size=32,
+                                                      float init_phase=0,
+                                                      float max_rate_deviation=1.5);
+
+class gr_pfb_clock_sync_fff : public gr_block
+{
+ private:
+  gr_pfb_clock_sync_fff (double sps, float gain,
+                        const std::vector<float> &taps,
+                        unsigned int filter_size,
+                        float init_phase,
+                        float max_rate_deviation);
+
+ public:
+  ~gr_pfb_clock_sync_fff ();
+
+  void set_taps (const std::vector<float> &taps,
+                std::vector< std::vector<float> > &ourtaps,
+                std::vector<gr_fir_fff*> &ourfilter);
+
+  std::vector<float> channel_taps(int channel);
+  std::vector<float> diff_channel_taps(int channel);
+  void print_taps();
+  void print_diff_taps();
+  void set_alpha(float alpha);
+  void set_beta(float beta);
+  void set_max_rate_deviation(float m);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc
new file mode 100644 (file)
index 0000000..e05e18f
--- /dev/null
@@ -0,0 +1,175 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_decimator_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <cstdio>
+
+gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, 
+                                                    const std::vector<float> &taps,
+                                                    unsigned int channel)
+{
+  return gr_pfb_decimator_ccf_sptr (new gr_pfb_decimator_ccf (decim, taps, channel));
+}
+
+
+gr_pfb_decimator_ccf::gr_pfb_decimator_ccf (unsigned int decim, 
+                                           const std::vector<float> &taps,
+                                           unsigned int channel)
+  : gr_sync_block ("pfb_decimator_ccf",
+                  gr_make_io_signature (decim, decim, sizeof(gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof(gr_complex))),
+    d_updated (false)
+{
+  d_rate = decim;
+  d_filters = std::vector<gr_fir_ccf*>(d_rate);
+  d_chan = channel;
+  d_rotator = new gr_complex[d_rate];
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_rate);
+  for(unsigned int i = 0; i < d_rate; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+    d_rotator[i] = gr_expj(i*2*M_PI*d_chan/d_rate);
+  }
+
+  // Now, actually set the filters' taps
+  set_taps(taps);
+
+  // Create the FFT to handle the output de-spinning of the channels
+  d_fft = new gri_fft_complex (d_rate, false);
+}
+
+gr_pfb_decimator_ccf::~gr_pfb_decimator_ccf ()
+{
+  for(unsigned int i = 0; i < d_rate; i++) {
+    delete d_filters[i];
+  }
+}
+
+void
+gr_pfb_decimator_ccf::set_taps (const std::vector<float> &taps)
+{
+  unsigned int i,j;
+
+  unsigned int ntaps = taps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate);
+
+  // Create d_numchan vectors to store each channel's taps
+  d_taps.resize(d_rate);
+
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = taps;
+  while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  
+  // Partition the filter
+  for(i = 0; i < d_rate; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      d_taps[i][j] = tmp_taps[i + j*d_rate];  // add taps to channels in reverse order
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    d_filters[i]->set_taps(d_taps[i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_decimator_ccf::print_taps()
+{
+  unsigned int i, j;
+  for(i = 0; i < d_rate; i++) {
+    printf("filter[%d]: [", i);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      printf(" %.4e", d_taps[i][j]);
+    }
+    printf("]\n\n");
+  }
+}
+
+#define ROTATEFFT
+
+int
+gr_pfb_decimator_ccf::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  gr_complex *in;
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int i;
+  for(i = 0; i < noutput_items; i++) {
+    // Move through filters from bottom to top
+    out[i] = 0;
+    for(int j = d_rate-1; j >= 0; j--) {
+      // Take in the items from the first input stream to d_rate
+      in = (gr_complex*)input_items[d_rate - 1 - j];
+
+      // Filter current input stream from bottom filter to top
+      // The rotate them by expj(j*k*2pi/M) where M is the number of filters
+      // (the decimation rate) and k is the channel number to extract
+      
+      // This is the real math that goes on; we abuse the FFT to do this quickly
+      // for decimation rates > N where N is a small number (~5):
+      //       out[i] += d_filters[j]->filter(&in[i])*gr_expj(j*d_chan*2*M_PI/d_rate);
+#ifdef ROTATEFFT
+      d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]);
+#else
+      out[i] += d_filters[j]->filter(&in[i])*d_rotator[i];
+#endif
+    }
+
+#ifdef ROTATEFFT
+    // Perform the FFT to do the complex multiply despinning for all channels
+    d_fft->execute();
+
+    // Select only the desired channel out
+    out[i] = d_fft->get_outbuf()[d_chan];
+#endif
+    
+  }
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h
new file mode 100644 (file)
index 0000000..200adee
--- /dev/null
@@ -0,0 +1,148 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_DECIMATOR_CCF_H
+#define        INCLUDED_GR_PFB_DECIMATOR_CCF_H
+
+#include <gr_sync_block.h>
+
+class gr_pfb_decimator_ccf;
+typedef boost::shared_ptr<gr_pfb_decimator_ccf> gr_pfb_decimator_ccf_sptr;
+gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, 
+                                                    const std::vector<float> &taps,
+                                                    unsigned int channel=0);
+
+class gr_fir_ccf;
+class gri_fft_complex;
+
+/*!
+ * \class gr_pfb_decimator_ccf
+ * \brief Polyphase filterbank bandpass decimator with gr_complex 
+ *        input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * 
+ * This block takes in a signal stream and performs interger down-
+ * sampling (decimation) with a polyphase filterbank. The first input
+ * is the integer specifying how much to decimate by. The second
+ * input is a vector (Python list) of floating-point taps of the 
+ * prototype filter. The third input specifies the channel to extract.
+ * By default, the zeroth channel is used, which is the baseband 
+ * channel (first Nyquist zone).
+ *
+ * The <EM>channel</EM> parameter specifies which channel to use since
+ * this class is capable of bandpass decimation. Given a complex input
+ * stream at a sampling rate of <EM>fs</EM> and a decimation rate of
+ * <EM>decim</EM>, the input frequency domain is split into 
+ * <EM>decim</EM> channels that represent the Nyquist zones. Using the
+ * polyphase filterbank, we can select any one of these channels to
+ * decimate.
+ *
+ * The output signal will be the basebanded and decimated signal from
+ * that channel. This concept is very similar to the PFB channelizer
+ * (see #gr_pfb_channelizer_ccf) where only a single channel is 
+ * extracted at a time.
+ *
+ * The filter's taps should be based on the sampling rate before
+ * decimation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of 
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first input
+ *  is the gain of the filter, which we specify here as unity.
+ *
+ *      <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB, 
+ *           attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB decimator code takes the taps generated above and builds a
+ * set of filters. The set contains <EM>decim</EM> number of filters
+ * and each filter contains ceil(taps.size()/decim) number of taps.
+ * Each tap from the filter prototype is sequentially inserted into
+ * the next filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure each 
+ * filter has the same number of taps.
+ *
+ * The theory behind this block can be found in Chapter 6 of 
+ * the following book.
+ *
+ *    <B><EM>f. harris, "Multirate Signal Processing for Communication 
+ *       Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+class gr_pfb_decimator_ccf : public gr_sync_block
+{
+ private:
+  /*!
+   * Build the polyphase filterbank decimator.
+   * \param decim   (unsigned integer) Specifies the decimation rate to use
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param channel (unsigned integer) Selects the channel to return [default=0].
+   */
+  friend gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+                                                             const std::vector<float> &taps,
+                                                             unsigned int channel);
+
+  std::vector<gr_fir_ccf*> d_filters;
+  std::vector< std::vector<float> > d_taps;
+  gri_fft_complex         *d_fft;
+  unsigned int             d_rate;
+  unsigned int             d_chan;
+  unsigned int             d_taps_per_filter;
+  bool                    d_updated;
+  gr_complex              *d_rotator;
+
+  /*!
+   * Build the polyphase filterbank decimator.
+   * \param decim   (unsigned integer) Specifies the decimation rate to use
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param channel (unsigned integer) Selects the channel to return [default=0].
+   */
+  gr_pfb_decimator_ccf (unsigned int decim, 
+                       const std::vector<float> &taps,
+                       unsigned int channel);
+
+public:
+  ~gr_pfb_decimator_ccf ();
+  
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   */
+   void set_taps (const std::vector<float> &taps);
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+   
+ //void set_channel (unsigned int channel);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i
new file mode 100644 (file)
index 0000000..c4215fc
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_decimator_ccf);
+
+gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+                                                    const std::vector<float> &taps,
+                                                    unsigned int channel);
+
+class gr_pfb_decimator_ccf : public gr_sync_block
+{
+ private:
+  gr_pfb_decimator_ccf (unsigned int decim,
+                       const std::vector<float> &taps,
+                       unsigned int channel);
+
+ public:
+  ~gr_pfb_decimator_ccf ();
+
+  void set_taps (const std::vector<float> &taps);
+  //void set_channel (unsigned int channel);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc
new file mode 100644 (file)
index 0000000..6a9598f
--- /dev/null
@@ -0,0 +1,143 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_interpolator_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, 
+                                                          const std::vector<float> &taps)
+{
+  return gr_pfb_interpolator_ccf_sptr (new gr_pfb_interpolator_ccf (interp, taps));
+}
+
+
+gr_pfb_interpolator_ccf::gr_pfb_interpolator_ccf (unsigned int interp, 
+                                                 const std::vector<float> &taps)
+  : gr_sync_interpolator ("pfb_interpolator_ccf",
+                         gr_make_io_signature (1, 1, sizeof(gr_complex)),
+                         gr_make_io_signature (1, 1, sizeof(gr_complex)),
+                         interp),
+    d_updated (false)
+{
+  d_rate = interp;
+  d_filters = std::vector<gr_fir_ccf*>(d_rate);
+
+  // Create an FIR filter for each channel and zero out the taps
+  std::vector<float> vtaps(0, d_rate);
+  for(unsigned int i = 0; i < d_rate; i++) {
+    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+  }
+
+  // Now, actually set the filters' taps
+  set_taps(taps);
+}
+
+gr_pfb_interpolator_ccf::~gr_pfb_interpolator_ccf ()
+{
+  for(unsigned int i = 0; i < d_rate; i++) {
+    delete d_filters[i];
+  }
+}
+
+void
+gr_pfb_interpolator_ccf::set_taps (const std::vector<float> &taps)
+{
+  unsigned int i,j;
+
+  unsigned int ntaps = taps.size();
+  d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate);
+
+  // Create d_numchan vectors to store each channel's taps
+  //std::vector< std::vector<float> > vtaps(d_rate);
+  d_taps.resize(d_rate);
+
+  // Make a vector of the taps plus fill it out with 0's to fill
+  // each polyphase filter with exactly d_taps_per_filter
+  std::vector<float> tmp_taps;
+  tmp_taps = taps;
+  while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) {
+    tmp_taps.push_back(0.0);
+  }
+  
+  // Partition the filter
+  for(i = 0; i < d_rate; i++) {
+    // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+    d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      d_taps[i][j] = tmp_taps[i + j*d_rate];  // add taps to channels in reverse order
+    }
+    
+    // Build a filter for each channel and add it's taps to it
+    d_filters[i]->set_taps(d_taps[i]);
+  }
+
+  // Set the history to ensure enough input items for each filter
+  set_history (d_taps_per_filter);
+
+  d_updated = true;
+}
+
+void
+gr_pfb_interpolator_ccf::print_taps()
+{
+  unsigned int i, j;
+  for(i = 0; i < d_rate; i++) {
+    printf("filter[%d]: [", i);
+    for(j = 0; j < d_taps_per_filter; j++) {
+      printf(" %.4e", d_taps[i][j]);
+    }
+    printf("]\n\n");
+  }
+}
+
+int
+gr_pfb_interpolator_ccf::work (int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  gr_complex *in = (gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int i = 0, count = 0;
+
+  while(i < noutput_items) {
+    for(int j = 0; j < d_rate; j++) {
+      out[i] = d_filters[j]->filter(&in[count]);
+      i++;
+    }
+    count++;
+  }
+  
+  return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h
new file mode 100644 (file)
index 0000000..d2efc59
--- /dev/null
@@ -0,0 +1,129 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_INTERPOLATOR_CCF_H
+#define        INCLUDED_GR_PFB_INTERPOLATOR_CCF_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_pfb_interpolator_ccf;
+typedef boost::shared_ptr<gr_pfb_interpolator_ccf> gr_pfb_interpolator_ccf_sptr;
+gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, 
+                                                          const std::vector<float> &taps);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_interpolator_ccf
+ * \brief Polyphase filterbank interpolator with gr_complex input,
+ * gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * 
+ * This block takes in a signal stream and performs interger up-
+ * sampling (interpolation) with a polyphase filterbank. The first
+ * input is the integer specifying how much to interpolate by. The
+ * second input is a vector (Python list) of floating-point taps of
+ * the prototype filter.
+ *
+ * The filter's taps should be based on the interpolation rate
+ * specified. That is, the bandwidth specified is relative to the
+ * bandwidth after interpolation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, ATT, and the filter window function (a
+ * Blackman-harris window in this case). The first input is the gain,
+ * which is also specified as the interpolation rate so that the
+ * output levels are the same as the input (this creates an overall
+ * increase in power).
+ *
+ *      <B><EM>self._taps = gr.firdes.low_pass_2(interp, interp*fs, BW, TB, 
+ *           attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB interpolator code takes the taps generated above and builds
+ * a set of filters. The set contains <EM>interp</EM> number of
+ * filters and each filter contains ceil(taps.size()/interp) number of
+ * taps. Each tap from the filter prototype is sequentially inserted
+ * into the next filter. When all of the input taps are used, the
+ * remaining filters in the filterbank are filled out with 0's to make
+ * sure each filter has the same number of taps.
+ *
+ * The theory behind this block can be found in Chapter 7.1 of the
+ * following book.
+ *
+ *    <B><EM>f. harris, "Multirate Signal Processing for Communication
+ *       Systems</EM>," Upper Saddle River, NJ: Prentice Hall,
+ *       Inc. 2004.</EM></B>
+ */
+
+class gr_pfb_interpolator_ccf : public gr_sync_interpolator
+{
+ private:
+  /*!
+   * Build the polyphase filterbank interpolator.
+   * \param interp  (unsigned integer) Specifies the interpolation rate to use
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank. The taps
+   *                                        should be generated at the interpolated sampling rate.
+   */
+  friend gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+                                                                   const std::vector<float> &taps);
+
+  std::vector<gr_fir_ccf*> d_filters;
+  std::vector< std::vector<float> > d_taps;
+  unsigned int             d_rate;
+  unsigned int             d_taps_per_filter;
+  bool                    d_updated;
+
+  /*!
+   * Construct a Polyphase filterbank interpolator
+   * \param interp  (unsigned integer) Specifies the interpolation rate to use
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank. The taps
+   *                                        should be generated at the interpolated sampling rate.
+   */
+  gr_pfb_interpolator_ccf (unsigned int interp, 
+                          const std::vector<float> &taps);
+  
+public:
+  ~gr_pfb_interpolator_ccf ();
+  
+  /*!
+   * Resets the filterbank's filter taps with the new prototype filter
+   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank. The taps
+   *                                        should be generated at the interpolated sampling rate.
+   */
+  void set_taps (const std::vector<float> &taps);
+
+  /*!
+   * Print all of the filterbank taps to screen.
+   */
+  void print_taps();
+  
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i
new file mode 100644 (file)
index 0000000..cf4302d
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_interpolator_ccf);
+
+gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+                                                          const std::vector<float> &taps);
+
+class gr_pfb_interpolator_ccf : public gr_sync_interpolator
+{
+ private:
+  gr_pfb_interpolator_ccf (unsigned int interp,
+                          const std::vector<float> &taps);
+
+ public:
+  ~gr_pfb_interpolator_ccf ();
+
+  void set_taps (const std::vector<float> &taps);
+  void print_taps();
+};
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc
new file mode 100644 (file)
index 0000000..1bf4a6f
--- /dev/null
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_generic.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_generic::gri_fft_filter_ccc_generic (int decimation, 
+                                                       const std::vector<gr_complex> &taps)
+  : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+  set_taps(taps);
+}
+
+gri_fft_filter_ccc_generic::~gri_fft_filter_ccc_generic ()
+{
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+#if 0
+static void 
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+  std::cout << label;
+  for (unsigned i = 0; i < x.size(); i++)
+    std::cout << x[i] << " ";
+  std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_generic::set_taps (const std::vector<gr_complex> &taps)
+{
+  int i = 0;
+  compute_sizes(taps.size());
+
+  d_tail.resize(tailsize());
+  for (i = 0; i < tailsize(); i++)
+    d_tail[i] = 0;
+
+  gr_complex *in = d_fwdfft->get_inbuf();
+  gr_complex *out = d_fwdfft->get_outbuf();
+
+  float scale = 1.0 / d_fftsize;
+  
+  // Compute forward xform of taps.
+  // Copy taps into first ntaps slots, then pad with zeros
+  for (i = 0; i < d_ntaps; i++)
+    in[i] = taps[i] * scale;
+
+  for (; i < d_fftsize; i++)
+    in[i] = 0;
+
+  d_fwdfft->execute();         // do the xform
+
+  // now copy output to d_xformed_taps
+  for (i = 0; i < d_fftsize; i++)
+    d_xformed_taps[i] = out[i];
+  
+  return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_generic::compute_sizes(int ntaps)
+{
+  int old_fftsize = d_fftsize;
+  d_ntaps = ntaps;
+  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+  d_nsamples = d_fftsize - d_ntaps + 1;
+
+  if (0)
+    fprintf(stderr, "gri_fft_filter_ccc_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+           d_ntaps, d_fftsize, d_nsamples);
+
+  assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+  if (d_fftsize != old_fftsize){       // compute new plans
+    delete d_fwdfft;
+    delete d_invfft;
+    d_fwdfft = new gri_fft_complex(d_fftsize, true);
+    d_invfft = new gri_fft_complex(d_fftsize, false);
+    d_xformed_taps.resize(d_fftsize);
+  }
+}
+
+int
+gri_fft_filter_ccc_generic::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+  int dec_ctr = 0;
+  int j = 0;
+  int ninput_items = nitems * d_decimation;
+
+  for (int i = 0; i < ninput_items; i += d_nsamples){
+    
+    memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+    for (j = d_nsamples; j < d_fftsize; j++)
+      d_fwdfft->get_inbuf()[j] = 0;
+
+    d_fwdfft->execute();       // compute fwd xform
+    
+    gr_complex *a = d_fwdfft->get_outbuf();
+    gr_complex *b = &d_xformed_taps[0];
+    gr_complex *c = d_invfft->get_inbuf();
+
+    for (j = 0; j < d_fftsize; j+=1) { // filter in the freq domain
+      c[j] = a[j] * b[j];
+    } 
+    
+    d_invfft->execute();       // compute inv xform
+
+    // add in the overlapping tail
+
+    for (j = 0; j < tailsize(); j++)
+      d_invfft->get_outbuf()[j] += d_tail[j];
+
+    // copy nsamples to output
+    j = dec_ctr;
+    while (j < d_nsamples) {
+      *output++ = d_invfft->get_outbuf()[j];
+      j += d_decimation;
+    }
+    dec_ctr = (j - d_nsamples);
+
+    // stash the tail
+    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+          tailsize() * sizeof(gr_complex));
+  }
+
+  assert(dec_ctr == 0);
+
+  return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h
new file mode 100644 (file)
index 0000000..3cd9105
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class gri_fft_filter_ccc_generic
+{
+ private:
+  int                     d_ntaps;
+  int                     d_nsamples;
+  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
+  int                      d_decimation;
+  gri_fft_complex        *d_fwdfft;            // forward "plan"
+  gri_fft_complex        *d_invfft;            // inverse "plan"
+  std::vector<gr_complex>  d_tail;             // state carried between blocks for overlap-add
+  std::vector<gr_complex>  d_xformed_taps;     // Fourier xformed taps
+  std::vector<gr_complex>  d_new_taps;
+
+  void compute_sizes(int ntaps);
+  int tailsize() const { return d_ntaps - 1; }
+  
+ public:
+  /*!
+   * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+   *
+   * This is the basic implementation for performing FFT filter for fast convolution
+   * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+   * \param decimation The decimation rate of the filter (int)
+   * \param taps       The filter taps (complex)
+   */
+  gri_fft_filter_ccc_generic (int decimation, const std::vector<gr_complex> &taps);
+  ~gri_fft_filter_ccc_generic ();
+
+  /*!
+   * \brief Set new taps for the filter.
+   *
+   * Sets new taps and resets the class properties to handle different sizes
+   * \param taps       The filter taps (complex)
+   */
+  int set_taps (const std::vector<gr_complex> &taps);
+  
+  /*!
+   * \brief Perform the filter operation
+   *
+   * \param nitems  The number of items to produce
+   * \param input   The input vector to be filtered
+   * \param output  The result of the filter operation
+   */
+  int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc
new file mode 100644 (file)
index 0000000..b7d925f
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_sse::gri_fft_filter_ccc_sse (int decimation,
+                                               const std::vector<gr_complex> &taps)
+  : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+  d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+  set_taps(taps);
+}
+
+gri_fft_filter_ccc_sse::~gri_fft_filter_ccc_sse ()
+{
+  fftwf_free(d_xformed_taps);
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+#if 0
+static void 
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+  std::cout << label;
+  for (unsigned i = 0; i < x.size(); i++)
+    std::cout << x[i] << " ";
+  std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_sse::set_taps (const std::vector<gr_complex> &taps)
+{
+  int i = 0;
+  compute_sizes(taps.size());
+
+  d_tail.resize(tailsize());
+  for (i = 0; i < tailsize(); i++)
+    d_tail[i] = 0;
+
+  gr_complex *in = d_fwdfft->get_inbuf();
+  gr_complex *out = d_fwdfft->get_outbuf();
+
+  float scale = 1.0 / d_fftsize;
+  
+  // Compute forward xform of taps.
+  // Copy taps into first ntaps slots, then pad with zeros
+  for (i = 0; i < d_ntaps; i++)
+    in[i] = taps[i] * scale;
+
+  for (; i < d_fftsize; i++)
+    in[i] = 0;
+
+  d_fwdfft->execute();         // do the xform
+
+  // now copy output to d_xformed_taps
+  for (i = 0; i < d_fftsize; i++)
+    d_xformed_taps[i] = out[i];
+  
+  return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_sse::compute_sizes(int ntaps)
+{
+  int old_fftsize = d_fftsize;
+  d_ntaps = ntaps;
+  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+  d_nsamples = d_fftsize - d_ntaps + 1;
+
+  if (0)
+    fprintf(stderr, "gri_fft_filter_ccc_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+           d_ntaps, d_fftsize, d_nsamples);
+
+  assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+  if (d_fftsize != old_fftsize){       // compute new plans
+    delete d_fwdfft;
+    delete d_invfft;
+    d_fwdfft = new gri_fft_complex(d_fftsize, true);
+    d_invfft = new gri_fft_complex(d_fftsize, false);
+    
+    fftwf_free(d_xformed_taps);
+    d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize)*sizeof(gr_complex));
+  }
+}
+
+int
+gri_fft_filter_ccc_sse::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+  int dec_ctr = 0;
+  int j = 0;
+  int ninput_items = nitems * d_decimation;
+
+  for (int i = 0; i < ninput_items; i += d_nsamples){
+    
+    memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+    for (j = d_nsamples; j < d_fftsize; j++)
+      d_fwdfft->get_inbuf()[j] = 0;
+
+    d_fwdfft->execute();       // compute fwd xform
+    
+    float *a = (float*)(d_fwdfft->get_outbuf());
+    float *b = (float*)(&d_xformed_taps[0]);
+    float *c = (float*)(d_invfft->get_inbuf());
+
+    __m128 x0, x1, x2, t0, t1, m;
+    m = _mm_set_ps(-1, 1, -1, 1);
+    for (j = 0; j < 2*d_fftsize; j+=4) {       // filter in the freq domain
+      x0 = _mm_load_ps(&a[j]);
+      t0 = _mm_load_ps(&b[j]);
+      
+      t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+      t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+      t1 = _mm_mul_ps(t1, m);
+
+      x1 = _mm_mul_ps(x0, t0);
+      x2 = _mm_mul_ps(x0, t1);
+
+      x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+      x2 = _mm_add_ps(x1, x2);
+
+      _mm_store_ps(&c[j], x2);
+    }
+
+    d_invfft->execute();       // compute inv xform
+
+    // add in the overlapping tail
+
+    for (j = 0; j < tailsize(); j++)
+      d_invfft->get_outbuf()[j] += d_tail[j];
+
+    // copy nsamples to output
+    j = dec_ctr;
+    while (j < d_nsamples) {
+      *output++ = d_invfft->get_outbuf()[j];
+      j += d_decimation;
+    }
+    dec_ctr = (j - d_nsamples);
+
+    // stash the tail
+    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+          tailsize() * sizeof(gr_complex));
+  }
+
+  assert(dec_ctr == 0);
+
+  return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h
new file mode 100644 (file)
index 0000000..d1c54f0
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class gri_fft_filter_ccc_sse
+{
+ private:
+  int                     d_ntaps;
+  int                     d_nsamples;
+  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
+  int                      d_decimation;
+  gri_fft_complex        *d_fwdfft;            // forward "plan"
+  gri_fft_complex        *d_invfft;            // inverse "plan"
+  std::vector<gr_complex>  d_tail;             // state carried between blocks for overlap-add
+  gr_complex              *d_xformed_taps;
+  std::vector<gr_complex>  d_new_taps;
+
+  void compute_sizes(int ntaps);
+  int tailsize() const { return d_ntaps - 1; }
+  
+ public:
+  /*!
+   * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+   *
+   * This is the basic implementation for performing FFT filter for fast convolution
+   * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+   * \param decimation The decimation rate of the filter (int)
+   * \param taps       The filter taps (complex)
+   */
+  gri_fft_filter_ccc_sse (int decimation, const std::vector<gr_complex> &taps);
+  ~gri_fft_filter_ccc_sse ();
+
+  /*!
+   * \brief Set new taps for the filter.
+   *
+   * Sets new taps and resets the class properties to handle different sizes
+   * \param taps       The filter taps (complex)
+   */
+  int set_taps (const std::vector<gr_complex> &taps);
+  
+  /*!
+   * \brief Perform the filter operation
+   *
+   * \param nitems  The number of items to produce
+   * \param input   The input vector to be filtered
+   * \param output  The result of the filter operation
+   */
+  int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_SSE_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc
new file mode 100644 (file)
index 0000000..74058fa
--- /dev/null
@@ -0,0 +1,158 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_generic.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+
+gri_fft_filter_fff_generic::gri_fft_filter_fff_generic (int decimation, 
+                                                       const std::vector<float> &taps)
+  : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+  set_taps(taps);
+}
+
+gri_fft_filter_fff_generic::~gri_fft_filter_fff_generic ()
+{
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_generic::set_taps (const std::vector<float> &taps)
+{
+  int i = 0;
+  compute_sizes(taps.size());
+
+  d_tail.resize(tailsize());
+  for (i = 0; i < tailsize(); i++)
+    d_tail[i] = 0;
+
+  float *in = d_fwdfft->get_inbuf();
+  gr_complex *out = d_fwdfft->get_outbuf();
+
+  float scale = 1.0 / d_fftsize;
+  
+  // Compute forward xform of taps.
+  // Copy taps into first ntaps slots, then pad with zeros
+  for (i = 0; i < d_ntaps; i++)
+    in[i] = taps[i] * scale;
+
+  for (; i < d_fftsize; i++)
+    in[i] = 0;
+
+  d_fwdfft->execute();         // do the xform
+
+  // now copy output to d_xformed_taps
+  for (i = 0; i < d_fftsize/2+1; i++)
+    d_xformed_taps[i] = out[i];
+  
+  return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_generic::compute_sizes(int ntaps)
+{
+  int old_fftsize = d_fftsize;
+  d_ntaps = ntaps;
+  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+  d_nsamples = d_fftsize - d_ntaps + 1;
+
+  if (0)
+    fprintf(stderr, "gri_fft_filter_fff_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+           d_ntaps, d_fftsize, d_nsamples);
+
+  assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+  if (d_fftsize != old_fftsize){       // compute new plans
+    delete d_fwdfft;
+    delete d_invfft;
+    d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+    d_invfft = new gri_fft_real_rev(d_fftsize);
+    d_xformed_taps.resize(d_fftsize/2+1);
+  }
+}
+
+int
+gri_fft_filter_fff_generic::filter (int nitems, const float *input, float *output)
+{
+  int dec_ctr = 0;
+  int j = 0;
+  int ninput_items = nitems * d_decimation;
+
+  for (int i = 0; i < ninput_items; i += d_nsamples){
+    
+    memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+    for (j = d_nsamples; j < d_fftsize; j++)
+      d_fwdfft->get_inbuf()[j] = 0;
+
+    d_fwdfft->execute();       // compute fwd xform
+
+    gr_complex *a = d_fwdfft->get_outbuf();
+    gr_complex *b = &d_xformed_taps[0];
+    gr_complex *c = d_invfft->get_inbuf();
+
+    for (j = 0; j < d_fftsize/2+1; j++) {      // filter in the freq domain
+      c[j] = a[j] * b[j];
+    }      
+   
+    d_invfft->execute();       // compute inv xform
+
+    // add in the overlapping tail
+
+    for (j = 0; j < tailsize(); j++)
+      d_invfft->get_outbuf()[j] += d_tail[j];
+
+    // copy nsamples to output
+
+    //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+    //out += d_nsamples;
+
+    j = dec_ctr;
+    while (j < d_nsamples) {
+      *output++ = d_invfft->get_outbuf()[j];
+      j += d_decimation;
+    }
+    dec_ctr = (j - d_nsamples);
+
+    // stash the tail
+    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+          tailsize() * sizeof(float));
+  }
+
+  assert(dec_ctr == 0);
+
+  return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h
new file mode 100644 (file)
index 0000000..6c31632
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class gri_fft_filter_fff_generic
+{
+ private:
+  int                     d_ntaps;
+  int                     d_nsamples;
+  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
+  int                      d_decimation;
+  gri_fft_real_fwd       *d_fwdfft;            // forward "plan"
+  gri_fft_real_rev       *d_invfft;            // inverse "plan"
+  std::vector<float>       d_tail;             // state carried between blocks for overlap-add
+  std::vector<gr_complex>  d_xformed_taps;     // Fourier xformed taps
+  std::vector<float>      d_new_taps;
+
+
+  void compute_sizes(int ntaps);
+  int tailsize() const { return d_ntaps - 1; }
+  
+ public:
+  /*!
+   * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+   *
+   * This is the basic implementation for performing FFT filter for fast convolution
+   * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+   * \param decimation The decimation rate of the filter (int)
+   * \param taps       The filter taps (float)
+   */
+  gri_fft_filter_fff_generic (int decimation, const std::vector<float> &taps);
+  ~gri_fft_filter_fff_generic ();
+
+  /*!
+   * \brief Set new taps for the filter.
+   *
+   * Sets new taps and resets the class properties to handle different sizes
+   * \param taps       The filter taps (float)
+   */
+  int set_taps (const std::vector<float> &taps);
+  
+  /*!
+   * \brief Perform the filter operation
+   *
+   * \param nitems  The number of items to produce
+   * \param input   The input vector to be filtered
+   * \param output  The result of the filter operation
+   */
+  int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc
new file mode 100644 (file)
index 0000000..2680e65
--- /dev/null
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_fff_sse::gri_fft_filter_fff_sse (int decimation, 
+                                                       const std::vector<float> &taps)
+  : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+  d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+  set_taps(taps);
+}
+
+gri_fft_filter_fff_sse::~gri_fft_filter_fff_sse ()
+{
+  fftwf_free(d_xformed_taps);
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_sse::set_taps (const std::vector<float> &taps)
+{
+  int i = 0;
+  compute_sizes(taps.size());
+
+  d_tail.resize(tailsize());
+  for (i = 0; i < tailsize(); i++)
+    d_tail[i] = 0;
+
+  float *in = d_fwdfft->get_inbuf();
+  gr_complex *out = d_fwdfft->get_outbuf();
+
+  float scale = 1.0 / d_fftsize;
+  
+  // Compute forward xform of taps.
+  // Copy taps into first ntaps slots, then pad with zeros
+  for (i = 0; i < d_ntaps; i++)
+    in[i] = taps[i] * scale;
+
+  for (; i < d_fftsize; i++)
+    in[i] = 0;
+
+  d_fwdfft->execute();         // do the xform
+
+  // now copy output to d_xformed_taps
+  for (i = 0; i < d_fftsize/2+1; i++)
+    d_xformed_taps[i] = out[i];
+  
+  return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_sse::compute_sizes(int ntaps)
+{
+  int old_fftsize = d_fftsize;
+  d_ntaps = ntaps;
+  d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+  d_nsamples = d_fftsize - d_ntaps + 1;
+
+  if (0)
+    fprintf(stderr, "gri_fft_filter_fff_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+           d_ntaps, d_fftsize, d_nsamples);
+
+  assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+  if (d_fftsize != old_fftsize){       // compute new plans
+    delete d_fwdfft;
+    delete d_invfft;
+    d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+    d_invfft = new gri_fft_real_rev(d_fftsize);
+    //d_xformed_taps.resize(d_fftsize/2+1);
+
+    fftwf_free(d_xformed_taps);
+    d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize/2+1)*sizeof(gr_complex));
+  }
+}
+
+int
+gri_fft_filter_fff_sse::filter (int nitems, const float *input, float *output)
+{
+  int dec_ctr = 0;
+  int j = 0;
+  int ninput_items = nitems * d_decimation;
+
+  for (int i = 0; i < ninput_items; i += d_nsamples){
+    
+    memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+    for (j = d_nsamples; j < d_fftsize; j++)
+      d_fwdfft->get_inbuf()[j] = 0;
+
+    d_fwdfft->execute();       // compute fwd xform
+
+    float *a = (float*)(d_fwdfft->get_outbuf());
+    float *b = (float*)(&d_xformed_taps[0]);
+    float *c = (float*)(d_invfft->get_inbuf());
+
+    __m128 x0, x1, x2, t0, t1, m;
+    m = _mm_set_ps(-1, 1, -1, 1);
+    for (j = 0; j < d_fftsize; j+=4) { // filter in the freq domain
+      x0 = _mm_load_ps(&a[j]);
+      t0 = _mm_load_ps(&b[j]);
+      
+      t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+      t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+      t1 = _mm_mul_ps(t1, m);
+
+      x1 = _mm_mul_ps(x0, t0);
+      x2 = _mm_mul_ps(x0, t1);
+
+      x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+      x2 = _mm_add_ps(x1, x2);
+
+      _mm_store_ps(&c[j], x2);
+    }
+    
+    // Finish off the last one; do the complex multiply as floats
+    j = d_fftsize/2;
+    c[j] = (a[j] * b[j]) - (a[j+1] * b[j+1]);
+    c[j+1] = (a[j] * b[j+1]) + (a[j+1] * b[j]);
+
+    d_invfft->execute();       // compute inv xform
+
+    // add in the overlapping tail
+
+    for (j = 0; j < tailsize(); j++)
+      d_invfft->get_outbuf()[j] += d_tail[j];
+
+    // copy nsamples to output
+
+    //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+    //out += d_nsamples;
+
+    j = dec_ctr;
+    while (j < d_nsamples) {
+      *output++ = d_invfft->get_outbuf()[j];
+      j += d_decimation;
+    }
+    dec_ctr = (j - d_nsamples);
+
+    // stash the tail
+    memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+          tailsize() * sizeof(float));
+  }
+
+  assert(dec_ctr == 0);
+
+  return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h
new file mode 100644 (file)
index 0000000..8258bb8
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class gri_fft_filter_fff_sse
+{
+ private:
+  int                     d_ntaps;
+  int                     d_nsamples;
+  int                     d_fftsize;           // fftsize = ntaps + nsamples - 1
+  int                      d_decimation;
+  gri_fft_real_fwd       *d_fwdfft;            // forward "plan"
+  gri_fft_real_rev       *d_invfft;            // inverse "plan"
+  std::vector<float>       d_tail;             // state carried between blocks for overlap-add
+  //std::vector<gr_complex>  d_xformed_taps;   // Fourier xformed taps
+  gr_complex              *d_xformed_taps;
+  std::vector<float>      d_new_taps;
+
+
+  void compute_sizes(int ntaps);
+  int tailsize() const { return d_ntaps - 1; }
+  
+ public:
+  /*!
+   * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+   *
+   * This is the basic implementation for performing FFT filter for fast convolution
+   * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+   * \param decimation The decimation rate of the filter (int)
+   * \param taps       The filter taps (float)
+   */
+  gri_fft_filter_fff_sse (int decimation, const std::vector<float> &taps);
+  ~gri_fft_filter_fff_sse ();
+
+  /*!
+   * \brief Set new taps for the filter.
+   *
+   * Sets new taps and resets the class properties to handle different sizes
+   * \param taps       The filter taps (float)
+   */
+  int set_taps (const std::vector<float> &taps);
+  
+  /*!
+   * \brief Perform the filter operation
+   *
+   * \param nitems  The number of items to produce
+   * \param input   The input vector to be filtered
+   * \param output  The result of the filter operation
+   */
+  int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_SSE_H */
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc b/gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc
new file mode 100644 (file)
index 0000000..e2971c8
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "qa_dotprod.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+  CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+  // empty test suite
+
+  return s;
+}
diff --git a/gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc b/gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc
new file mode 100644 (file)
index 0000000..b9c2174
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_sysconfig_armv7_a.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+  static gr_fir_sysconfig *singleton = 0;
+
+  if (singleton)
+    return singleton;
+
+  singleton = new gr_fir_sysconfig_armv7_a ();
+  return singleton;
+}
diff --git a/gnuradio-core/src/lib/g72x/.gitignore b/gnuradio-core/src/lib/g72x/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gnuradio-core/src/lib/general/.gitignore b/gnuradio-core/src/lib/general/.gitignore
new file mode 100644 (file)
index 0000000..4f3696f
--- /dev/null
@@ -0,0 +1,323 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/generate-stamp
+/gr_constants.cc
+/GrFIRfilterCCC.cc
+/GrFIRfilterCCC.h
+/GrFIRfilterCCF.cc
+/GrFIRfilterCCF.h
+/GrFIRfilterFCC.cc
+/GrFIRfilterFCC.h
+/GrFIRfilterFFF.cc
+/GrFIRfilterFFF.h
+/GrFIRfilterFSF.cc
+/GrFIRfilterFSF.h
+/GrFIRfilterSCC.cc
+/GrFIRfilterSCC.h
+/GrFIRfilterSIS.cc
+/GrFIRfilterSIS.h
+/GrFreqXlatingFIRfilterCCC.cc
+/GrFreqXlatingFIRfilterCCC.h
+/GrFreqXlatingFIRfilterCCF.cc
+/GrFreqXlatingFIRfilterCCF.h
+/GrFreqXlatingFIRfilterFCC.cc
+/GrFreqXlatingFIRfilterFCC.h
+/GrFreqXlatingFIRfilterFCF.cc
+/GrFreqXlatingFIRfilterFCF.h
+/GrFreqXlatingFIRfilterSCC.cc
+/GrFreqXlatingFIRfilterSCC.h
+/GrFreqXlatingFIRfilterSCF.cc
+/GrFreqXlatingFIRfilterSCF.h
+/gr_fir_CCC.cc
+/gr_fir_CCC.h
+/gr_fir_CCC_generic.cc
+/gr_fir_CCC_generic.h
+/gr_fir_CCF.cc
+/gr_fir_CCF.h
+/gr_fir_CCF_generic.cc
+/gr_fir_CCF_generic.h
+/gr_fir_FCC.cc
+/gr_fir_FCC.h
+/gr_fir_FCC_generic.cc
+/gr_fir_FCC_generic.h
+/gr_fir_FFF.cc
+/gr_fir_FFF.h
+/gr_fir_FFF_generic.cc
+/gr_fir_FFF_generic.h
+/gr_fir_FSF.cc
+/gr_fir_FSF.h
+/gr_fir_FSF_generic.cc
+/gr_fir_FSF_generic.h
+/gr_fir_SCC.cc
+/gr_fir_SCC.h
+/gr_fir_SCC_generic.cc
+/gr_fir_SCC_generic.h
+/gr_fir_SIS.cc
+/gr_fir_SIS.h
+/gr_fir_SIS_generic.cc
+/gr_fir_SIS_generic.h
+/gr_fir_sysconfig.cc
+/gr_fir_sysconfig.h
+/gr_fir_sysconfig_generic.cc
+/gr_fir_sysconfig_generic.h
+/gr_fir_util.cc
+/gr_fir_util.h
+/GrFIRfilterCCC.i
+/GrFIRfilterCCF.i
+/GrFIRfilterFCC.i
+/GrFIRfilterFFF.i
+/GrFIRfilterFSF.i
+/GrFIRfilterSCC.i
+/GrFIRfilterSIS.i
+/GrFreqXlatingFIRfilterCCC.i
+/GrFreqXlatingFIRfilterCCF.i
+/GrFreqXlatingFIRfilterFCC.i
+/GrFreqXlatingFIRfilterFCF.i
+/GrFreqXlatingFIRfilterSCC.i
+/GrFreqXlatingFIRfilterSCF.i
+/# --- generated files ---
+/gr_add_cc.cc
+/gr_add_cc.h
+/gr_add_cc.i
+/gr_add_const_c.cc
+/gr_add_const_c.h
+/gr_add_const_c.i
+/gr_add_const_cc.cc
+/gr_add_const_cc.h
+/gr_add_const_cc.i
+/gr_add_const_f.cc
+/gr_add_const_f.h
+/gr_add_const_f.i
+/gr_add_const_ff.cc
+/gr_add_const_ff.h
+/gr_add_const_ff.i
+/gr_add_const_i.cc
+/gr_add_const_i.h
+/gr_add_const_i.i
+/gr_add_const_ii.cc
+/gr_add_const_ii.h
+/gr_add_const_ii.i
+/gr_add_const_s.cc
+/gr_add_const_s.h
+/gr_add_const_s.i
+/gr_add_const_sf.cc
+/gr_add_const_sf.h
+/gr_add_const_sf.i
+/gr_add_const_ss.cc
+/gr_add_const_ss.h
+/gr_add_const_ss.i
+/gr_add_const_vcc.cc
+/gr_add_const_vcc.h
+/gr_add_const_vcc.i
+/gr_add_const_vff.cc
+/gr_add_const_vff.h
+/gr_add_const_vff.i
+/gr_add_const_vii.cc
+/gr_add_const_vii.h
+/gr_add_const_vii.i
+/gr_add_const_vss.cc
+/gr_add_const_vss.h
+/gr_add_const_vss.i
+/gr_add_ff.cc
+/gr_add_ff.h
+/gr_add_ff.i
+/gr_add_ii.cc
+/gr_add_ii.h
+/gr_add_ii.i
+/gr_add_ss.cc
+/gr_add_ss.h
+/gr_add_ss.i
+/gr_add_vcc.cc
+/gr_add_vcc.h
+/gr_add_vcc.i
+/gr_add_vff.cc
+/gr_add_vff.h
+/gr_add_vff.i
+/gr_add_vii.cc
+/gr_add_vii.h
+/gr_add_vii.i
+/gr_add_vss.cc
+/gr_add_vss.h
+/gr_add_vss.i
+/gr_divide_cc.cc
+/gr_divide_cc.h
+/gr_divide_cc.i
+/gr_divide_ff.cc
+/gr_divide_ff.h
+/gr_divide_ff.i
+/gr_divide_ii.cc
+/gr_divide_ii.h
+/gr_divide_ii.i
+/gr_divide_ss.cc
+/gr_divide_ss.h
+/gr_divide_ss.i
+/gr_multiply_cc.cc
+/gr_multiply_cc.h
+/gr_multiply_cc.i
+/gr_multiply_const_cc.cc
+/gr_multiply_const_cc.h
+/gr_multiply_const_cc.i
+/gr_multiply_const_ff.cc
+/gr_multiply_const_ff.h
+/gr_multiply_const_ff.i
+/gr_multiply_const_ii.cc
+/gr_multiply_const_ii.h
+/gr_multiply_const_ii.i
+/gr_multiply_const_ss.cc
+/gr_multiply_const_ss.h
+/gr_multiply_const_ss.i
+/gr_multiply_ff.cc
+/gr_multiply_ff.h
+/gr_multiply_ff.i
+/gr_multiply_ii.cc
+/gr_multiply_ii.h
+/gr_multiply_ii.i
+/gr_multiply_ss.cc
+/gr_multiply_ss.h
+/gr_multiply_ss.i
+/gr_multiply_vcc.cc
+/gr_multiply_vcc.h
+/gr_multiply_vcc.i
+/gr_multiply_vff.cc
+/gr_multiply_vff.h
+/gr_multiply_vff.i
+/gr_multiply_vii.cc
+/gr_multiply_vii.h
+/gr_multiply_vii.i
+/gr_multiply_vss.cc
+/gr_multiply_vss.h
+/gr_multiply_vss.i
+/gr_multiply_const_vcc.cc
+/gr_multiply_const_vcc.h
+/gr_multiply_const_vcc.i
+/gr_multiply_const_vff.cc
+/gr_multiply_const_vff.h
+/gr_multiply_const_vff.i
+/gr_multiply_const_vii.cc
+/gr_multiply_const_vii.h
+/gr_multiply_const_vii.i
+/gr_multiply_const_vss.cc
+/gr_multiply_const_vss.h
+/gr_multiply_const_vss.i
+/gr_noise_source_c.cc
+/gr_noise_source_c.h
+/gr_noise_source_c.i
+/gr_noise_source_f.cc
+/gr_noise_source_f.h
+/gr_noise_source_f.i
+/gr_noise_source_i.cc
+/gr_noise_source_i.h
+/gr_noise_source_i.i
+/gr_noise_source_s.cc
+/gr_noise_source_s.h
+/gr_noise_source_s.i
+/gr_sig_source_c.cc
+/gr_sig_source_c.h
+/gr_sig_source_c.i
+/gr_sig_source_f.cc
+/gr_sig_source_f.h
+/gr_sig_source_f.i
+/gr_sig_source_i.cc
+/gr_sig_source_i.h
+/gr_sig_source_i.i
+/gr_sig_source_s.cc
+/gr_sig_source_s.h
+/gr_sig_source_s.i
+/gr_sub_cc.cc
+/gr_sub_cc.h
+/gr_sub_cc.i
+/gr_sub_ff.cc
+/gr_sub_ff.h
+/gr_sub_ff.i
+/gr_sub_ii.cc
+/gr_sub_ii.h
+/gr_sub_ii.i
+/gr_sub_ss.cc
+/gr_sub_ss.h
+/gr_sub_ss.i
+/gr_vector_sink_b.cc
+/gr_vector_sink_b.h
+/gr_vector_sink_b.i
+/gr_vector_sink_c.cc
+/gr_vector_sink_c.h
+/gr_vector_sink_c.i
+/gr_vector_sink_f.cc
+/gr_vector_sink_f.h
+/gr_vector_sink_f.i
+/gr_vector_sink_i.cc
+/gr_vector_sink_i.h
+/gr_vector_sink_i.i
+/gr_vector_sink_s.cc
+/gr_vector_sink_s.h
+/gr_vector_sink_s.i
+/gr_vector_source_b.cc
+/gr_vector_source_b.h
+/gr_vector_source_b.i
+/gr_vector_source_c.cc
+/gr_vector_source_c.h
+/gr_vector_source_c.i
+/gr_vector_source_f.cc
+/gr_vector_source_f.h
+/gr_vector_source_f.i
+/gr_vector_source_i.cc
+/gr_vector_source_i.h
+/gr_vector_source_i.i
+/gr_vector_source_s.cc
+/gr_vector_source_s.h
+/gr_vector_source_s.i
+/gr_mute_cc.cc
+/gr_mute_cc.h
+/gr_mute_cc.i
+/gr_mute_ff.cc
+/gr_mute_ff.h
+/gr_mute_ff.i
+/gr_mute_ii.cc
+/gr_mute_ii.h
+/gr_mute_ii.i
+/gr_mute_ss.cc
+/gr_mute_ss.h
+/gr_mute_ss.i
+/gr_chunks_to_symbols_bc.cc
+/gr_chunks_to_symbols_bc.h
+/gr_chunks_to_symbols_bc.i
+/gr_chunks_to_symbols_bf.cc
+/gr_chunks_to_symbols_bf.h
+/gr_chunks_to_symbols_bf.i
+/gr_chunks_to_symbols_ic.cc
+/gr_chunks_to_symbols_ic.h
+/gr_chunks_to_symbols_ic.i
+/gr_chunks_to_symbols_if.cc
+/gr_chunks_to_symbols_if.h
+/gr_chunks_to_symbols_if.i
+/gr_chunks_to_symbols_sc.cc
+/gr_chunks_to_symbols_sc.h
+/gr_chunks_to_symbols_sc.i
+/gr_chunks_to_symbols_sf.cc
+/gr_chunks_to_symbols_sf.h
+/gr_chunks_to_symbols_sf.i
+/gr_packed_to_unpacked_bb.cc
+/gr_packed_to_unpacked_bb.h
+/gr_packed_to_unpacked_bb.i
+/gr_packed_to_unpacked_ii.cc
+/gr_packed_to_unpacked_ii.h
+/gr_packed_to_unpacked_ii.i
+/gr_packed_to_unpacked_ss.cc
+/gr_packed_to_unpacked_ss.h
+/gr_packed_to_unpacked_ss.i
+/gr_unpacked_to_packed_bb.cc
+/gr_unpacked_to_packed_bb.h
+/gr_unpacked_to_packed_bb.i
+/gr_unpacked_to_packed_ii.cc
+/gr_unpacked_to_packed_ii.h
+/gr_unpacked_to_packed_ii.i
+/gr_unpacked_to_packed_ss.cc
+/gr_unpacked_to_packed_ss.h
+/gr_unpacked_to_packed_ss.i
+/# --- end generated files ---
index 4ceb7248626cfcd199327aa7ca4c801d130cbc0b..3d8a42805cd0ce4ad3dafed04b88e55de4575ffe 100644 (file)
@@ -31,9 +31,10 @@ BUILT_SOURCES =
 
 EXTRA_DIST =                           \
        gen_sine_table.py               \
-       gr_prefix.cc.in                 
+       gr_constants.cc.in                      
 
 libgeneral_la_SOURCES =                \
+       gr_additive_scrambler_bb.cc     \
        gr_agc_cc.cc                    \
        gr_agc_ff.cc                    \
        gr_agc2_cc.cc                   \
@@ -51,6 +52,7 @@ libgeneral_la_SOURCES =               \
        gr_complex_to_interleaved_short.cc \
        gr_complex_to_xxx.cc            \
        gr_conjugate_cc.cc              \
+       gr_copy.cc                      \
        gr_constellation_decoder_cb.cc  \
        gr_correlate_access_code_bb.cc  \
        gr_costas_loop_cc.cc            \
@@ -58,7 +60,6 @@ libgeneral_la_SOURCES =               \
        gr_cpfsk_bc.cc                  \
        gr_crc32.cc                     \
        gr_ctcss_squelch_ff.cc          \
-       gr_dd_mpsk_sync_cc.cc           \
        gr_decode_ccsds_27_fb.cc        \
        gr_deinterleave.cc              \
        gr_delay.cc                     \
@@ -75,6 +76,7 @@ libgeneral_la_SOURCES =               \
        gr_fft_vcc_fftw.cc              \
        gr_fft_vfc.cc                   \
        gr_firdes.cc                    \
+       gr_fll_band_edge_cc.cc          \
        gr_float_to_char.cc             \
        gr_float_to_complex.cc          \
        gr_float_to_short.cc            \
@@ -117,7 +119,7 @@ libgeneral_la_SOURCES =             \
        gr_pll_freqdet_cf.cc            \
        gr_pll_refout_cc.cc             \
        gr_pn_correlator_cc.cc          \
-       gr_prefix.cc                    \
+       gr_constants.cc                 \
        gr_prefs.cc                     \
        gr_probe_avg_mag_sqrd_c.cc      \
        gr_probe_avg_mag_sqrd_cf.cc     \
@@ -186,6 +188,7 @@ libgeneral_qa_la_SOURCES =          \
        qa_gri_lfsr.cc
 
 grinclude_HEADERS =                    \
+       gr_additive_scrambler_bb.h      \
        gr_agc_cc.h                     \
        gr_agc_ff.h                     \
        gr_agc2_cc.h                    \
@@ -204,13 +207,13 @@ grinclude_HEADERS =                       \
        gr_complex_to_xxx.h             \
        gr_conjugate_cc.h               \
        gr_constellation_decoder_cb.h   \
+       gr_copy.h                       \
        gr_correlate_access_code_bb.h   \
        gr_costas_loop_cc.h             \
        gr_count_bits.h                 \
        gr_cpfsk_bc.h                   \
        gr_crc32.h                      \
        gr_ctcss_squelch_ff.h           \
-       gr_dd_mpsk_sync_cc.h            \
        gr_decode_ccsds_27_fb.h         \
        gr_diff_decoder_bb.h            \
        gr_diff_encoder_bb.h            \
@@ -227,6 +230,7 @@ grinclude_HEADERS =                         \
        gr_fft_vcc_fftw.h               \
        gr_fft_vfc.h                    \
        gr_firdes.h                     \
+       gr_fll_band_edge_cc.h           \
        gr_float_to_char.h              \
        gr_float_to_complex.h           \
        gr_float_to_short.h             \
@@ -273,7 +277,7 @@ grinclude_HEADERS =                         \
        gr_pll_freqdet_cf.h             \
        gr_pll_refout_cc.h              \
        gr_pn_correlator_cc.h           \
-       gr_prefix.h                     \
+       gr_constants.h                  \
        gr_prefs.h                      \
        gr_probe_avg_mag_sqrd_c.h       \
        gr_probe_avg_mag_sqrd_cf.h      \
@@ -353,8 +357,10 @@ noinst_HEADERS =                   \
        sine_table.h                    \
        qa_gr_math.h
 
+if PYTHON
 swiginclude_HEADERS =                  \
        general.i                       \
+       gr_additive_scrambler_bb.i      \
        gr_agc_cc.i                     \
        gr_agc_ff.i                     \
        gr_agc2_cc.i                    \
@@ -372,12 +378,12 @@ swiginclude_HEADERS =                     \
        gr_complex_to_xxx.i             \
        gr_conjugate_cc.i               \
        gr_constellation_decoder_cb.i   \
+       gr_copy.i                       \
        gr_correlate_access_code_bb.i   \
        gr_costas_loop_cc.i             \
        gr_cpfsk_bc.i                   \
        gr_crc32.i                      \
        gr_ctcss_squelch_ff.i           \
-       gr_dd_mpsk_sync_cc.i            \
        gr_decode_ccsds_27_fb.i         \
        gr_diff_decoder_bb.i            \
        gr_diff_encoder_bb.i            \
@@ -392,6 +398,7 @@ swiginclude_HEADERS =                       \
        gr_fft_vcc.i                    \
        gr_fft_vfc.i                    \
        gr_firdes.i                     \
+       gr_fll_band_edge_cc.i           \
        gr_float_to_char.i              \
        gr_float_to_complex.i           \
        gr_float_to_short.i             \
@@ -431,7 +438,7 @@ swiginclude_HEADERS =                       \
        gr_pll_freqdet_cf.i             \
        gr_pll_refout_cc.i              \
        gr_pn_correlator_cc.i           \
-       gr_prefix.i                     \
+       gr_constants.i                  \
        gr_prefs.i                      \
        gr_probe_avg_mag_sqrd_c.i       \
        gr_probe_avg_mag_sqrd_cf.i      \
@@ -478,3 +485,4 @@ swiginclude_HEADERS =                       \
        gr_scrambler_bb.i               \
        gr_probe_mpsk_snr_c.i           \
        gr_probe_density_b.i
+endif
diff --git a/gnuradio-core/src/lib/general/atsc_rrc1x.dat b/gnuradio-core/src/lib/general/atsc_rrc1x.dat
new file mode 100644 (file)
index 0000000..3466412
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:ROOT RAISED COSINE            12H
+ * PASSBAND RIPPLE IN -dB            -.0500
+ * STOPBAND RIPPLE IN -dB          -50.0000
+ * SYMBOL RATE                  .538112E+07 HERTZ              
+ * ROLLOF FACTOR                .115200    
+ * SAMPLING FREQUENCY           .107622E+08 HERTZ              
+ * SAMPLING FREQUENCY           .107622E+08 HERTZ              
+ */
+   .1821269281208515e-02,
+  -.9323525242507458e-02,
+  -.8581001311540604e-02,
+   .2809949219226837e-02,
+   .9649330750107765e-03,
+  -.4944681189954281e-02,
+   .1624439377337694e-02,
+   .6519509013742209e-02,
+  -.4803944379091263e-02,
+  -.8026130497455597e-02,
+   .8922342676669359e-02,
+   .9611152112483978e-02,
+  -.1463735569268465e-01,
+  -.1107082655653358e-01,
+   .2262782817706466e-01,
+   .1240625558421016e-01,
+  -.3461387194693089e-01,
+  -.1348070800304413e-01,
+   .5474480940029025e-01,
+   .1432673400267959e-01,
+  -.9872047463431954e-01,
+  -.1482593175023794e-01,
+   .3077511447481811e+00,
+   .5007477863691747e+00,
+   .3077511447481811e+00,
+  -.1482593175023794e-01,
+  -.9872047463431954e-01,
+   .1432673400267959e-01,
+   .5474480940029025e-01,
+  -.1348070800304413e-01,
+  -.3461387194693089e-01,
+   .1240625558421016e-01,
+   .2262782817706466e-01,
+  -.1107082655653358e-01,
+  -.1463735569268465e-01,
+   .9611152112483978e-02,
+   .8922342676669359e-02,
+  -.8026130497455597e-02,
+  -.4803944379091263e-02,
+   .6519509013742209e-02,
+   .1624439377337694e-02,
+  -.4944681189954281e-02,
+   .9649330750107765e-03,
+   .2809949219226837e-02,
+  -.8581001311540604e-02,
+  -.9323525242507458e-02,
+   .1821269281208515e-02
diff --git a/gnuradio-core/src/lib/general/atsc_rrc20.dat b/gnuradio-core/src/lib/general/atsc_rrc20.dat
new file mode 100644 (file)
index 0000000..94445e9
--- /dev/null
@@ -0,0 +1,101 @@
+  -.1141865178942680e-01,
+   .2192483097314835e-01,
+  -.6814673542976379e-04,
+  -.5894266534596682e-02,
+  -.3580642864108086e-02,
+   .7064016535878182e-03,
+   .3225978463888168e-02,
+   .2832664176821709e-02,
+   .4997388459742069e-03,
+  -.1796286087483168e-02,
+  -.2396093215793371e-02,
+  -.1009003724902868e-02,
+   .1184449531137943e-02,
+   .2406611572951078e-02,
+   .1609810627996922e-02,
+  -.6790305487811565e-03,
+  -.2634476870298386e-02,
+  -.2524725627154112e-02,
+  -.1492514275014401e-03,
+   .2789965830743313e-02,
+   .3848167601972818e-02,
+   .1755146309733391e-02,
+  -.2288600429892540e-02,
+  -.5209952127188444e-02,
+  -.4314901307225227e-02,
+   .3885449841618538e-03,
+   .5747230723500252e-02,
+   .7460035849362612e-02,
+   .3387423232197762e-02,
+  -.4307936877012253e-02,
+  -.1007711654528976e-01,
+  -.8849395904690027e-02,
+  -.1979861408472061e-03,
+   .1040456583723426e-01,
+   .1484309835359454e-01,
+   .8285604882985354e-02,
+  -.6346960552036762e-02,
+  -.1915087224915624e-01,
+  -.1949162455275655e-01,
+  -.4145141225308180e-02,
+   .1850909460335970e-01,
+   .3220130456611514e-01,
+   .2337836893275380e-01,
+  -.7863232865929604e-02,
+  -.4402747144922614e-01,
+  -.5751598253846169e-01,
+  -.2598480274900794e-01,
+   .5246857088059187e-01,
+   .1544690094888210e+00,
+   .2405302016995847e+00,
+   .2741314689628780e+00,
+   .2405302016995847e+00,
+   .1544690094888210e+00,
+   .5246857088059187e-01,
+  -.2598480274900794e-01,
+  -.5751598253846169e-01,
+  -.4402747144922614e-01,
+  -.7863232865929604e-02,
+   .2337836893275380e-01,
+   .3220130456611514e-01,
+   .1850909460335970e-01,
+  -.4145141225308180e-02,
+  -.1949162455275655e-01,
+  -.1915087224915624e-01,
+  -.6346960552036762e-02,
+   .8285604882985354e-02,
+   .1484309835359454e-01,
+   .1040456583723426e-01,
+  -.1979861408472061e-03,
+  -.8849395904690027e-02,
+  -.1007711654528976e-01,
+  -.4307936877012253e-02,
+   .3387423232197762e-02,
+   .7460035849362612e-02,
+   .5747230723500252e-02,
+   .3885449841618538e-03,
+  -.4314901307225227e-02,
+  -.5209952127188444e-02,
+  -.2288600429892540e-02,
+   .1755146309733391e-02,
+   .3848167601972818e-02,
+   .2789965830743313e-02,
+  -.1492514275014401e-03,
+  -.2524725627154112e-02,
+  -.2634476870298386e-02,
+  -.6790305487811565e-03,
+   .1609810627996922e-02,
+   .2406611572951078e-02,
+   .1184449531137943e-02,
+  -.1009003724902868e-02,
+  -.2396093215793371e-02,
+  -.1796286087483168e-02,
+   .4997388459742069e-03,
+   .2832664176821709e-02,
+   .3225978463888168e-02,
+   .7064016535878182e-03,
+  -.3580642864108086e-02,
+  -.5894266534596682e-02,
+  -.6814673542976379e-04,
+   .2192483097314835e-01,
+  -.1141865178942680e-01
diff --git a/gnuradio-core/src/lib/general/atsc_rrc2x.dat b/gnuradio-core/src/lib/general/atsc_rrc2x.dat
new file mode 100644 (file)
index 0000000..ca7812c
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:ROOT RAISED COSINE            12H
+ * PASSBAND RIPPLE IN -dB            -.0500
+ * STOPBAND RIPPLE IN -dB          -50.0000
+ * SYMBOL RATE                  .538112E+07 HERTZ              
+ * ROLLOF FACTOR                .115200    
+ * SAMPLING FREQUENCY           .215245E+08 HERTZ
+*/
+   .8186036720871925E-03,
+  -.1256920862942934E-02,
+  -.4844595678150654E-02,
+  -.6055080797523260E-02,
+  -.4247304052114487E-02,
+  -.9502284228801727E-03,
+   .1615938264876604E-02,
+   .2120061777532101E-02,
+   .6354246288537979E-03,
+  -.1464351080358028E-02,
+  -.2508673351258040E-02,
+  -.1573510002344847E-02,
+   .8145328611135483E-03,
+   .2996938303112984E-02,
+   .3244197461754084E-02,
+   .1038576476275921E-02,
+  -.2401810139417648E-02,
+  -.4728596191853285E-02,
+  -.4019895102828741E-02,
+  -.2215979620814323E-03,
+   .4481043666601181E-02,
+   .6867439020425081E-02,
+   .4793671425431967E-02,
+  -.1089230179786682E-02,
+  -.7325290236622095E-02,
+  -.9580074809491634E-02,
+  -.5532339215278626E-02,
+   .3166179172694683E-02,
+   .1132524851709604E-01,
+   .1316944882273674E-01,
+   .6192639470100403E-02,
+  -.6509334780275822E-02,
+  -.1730504119768739E-01,
+  -.1832502009347081E-01,
+  -.6741075310856104E-02,
+   .1229691226035357E-01,
+   .2738198731094599E-01,
+   .2702147699892521E-01,
+   .7156732492148876E-02,
+  -.2432488137856126E-01,
+  -.4934547096490860E-01,
+  -.4763523396104574E-01,
+  -.7410581223666668E-02,
+   .6681889295578003E-01,
+   .1538293845951557E+00,
+   .2236228249967098E+00,
+   .2502835178747773E+00,
+   .2236228249967098E+00,
+   .1538293845951557E+00,
+   .6681889295578003E-01,
+  -.7410581223666668E-02,
+  -.4763523396104574E-01,
+  -.4934547096490860E-01,
+  -.2432488137856126E-01,
+   .7156732492148876E-02,
+   .2702147699892521E-01,
+   .2738198731094599E-01,
+   .1229691226035357E-01,
+  -.6741075310856104E-02,
+  -.1832502009347081E-01,
+  -.1730504119768739E-01,
+  -.6509334780275822E-02,
+   .6192639470100403E-02,
+   .1316944882273674E-01,
+   .1132524851709604E-01,
+   .3166179172694683E-02,
+  -.5532339215278626E-02,
+  -.9580074809491634E-02,
+  -.7325290236622095E-02,
+  -.1089230179786682E-02,
+   .4793671425431967E-02,
+   .6867439020425081E-02,
+   .4481043666601181E-02,
+  -.2215979620814323E-03,
+  -.4019895102828741E-02,
+  -.4728596191853285E-02,
+  -.2401810139417648E-02,
+   .1038576476275921E-02,
+   .3244197461754084E-02,
+   .2996938303112984E-02,
+   .8145328611135483E-03,
+  -.1573510002344847E-02,
+  -.2508673351258040E-02,
+  -.1464351080358028E-02,
+   .6354246288537979E-03,
+   .2120061777532101E-02,
+   .1615938264876604E-02,
+  -.9502284228801727E-03,
+  -.4247304052114487E-02,
+  -.6055080797523260E-02,
+  -.4844595678150654E-02,
+  -.1256920862942934E-02,
+   .8186036720871925E-03
index 0cb54870efc46627b68756b27e7341d98e5ff8fe..68cafce2e6de301ae4ac95f30ca279d7843a27ff 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -80,7 +80,6 @@
 #include <gr_threshold_ff.h>
 #include <gr_clock_recovery_mm_ff.h>
 #include <gr_clock_recovery_mm_cc.h>
-#include <gr_dd_mpsk_sync_cc.h>
 #include <gr_packet_sink.h>
 #include <gr_lms_dfe_cc.h>
 #include <gr_lms_dfe_ff.h>
 #include <gr_pa_2x2_phase_combiner.h>
 #include <gr_kludge_copy.h>
 #include <gr_prefs.h>
-#include <gr_prefix.h>
+#include <gr_constants.h>
 #include <gr_test_types.h>
 #include <gr_test.h>
 #include <gr_unpack_k_bits_bb.h>
 #include <gr_stretch_ff.h>
 #include <gr_wavelet_ff.h>
 #include <gr_wvps_ff.h>
-
+#include <gr_copy.h>
+#include <gr_fll_band_edge_cc.h>
+#include <gr_additive_scrambler_bb.h>
 %}
 
 %include "gr_nop.i"
 %include "gr_threshold_ff.i"
 %include "gr_clock_recovery_mm_ff.i"
 %include "gr_clock_recovery_mm_cc.i"
-%include "gr_dd_mpsk_sync_cc.i"
 %include "gr_packet_sink.i"
 %include "gr_lms_dfe_cc.i"
 %include "gr_lms_dfe_ff.i"
 %include "gr_pa_2x2_phase_combiner.i"
 %include "gr_kludge_copy.i"
 %include "gr_prefs.i"
-%include "gr_prefix.i"
+%include "gr_constants.i"
 %include "gr_test_types.h"
 %include "gr_test.i"
 %include "gr_unpack_k_bits_bb.i"
 %include "gr_stretch_ff.i"
 %include "gr_wavelet_ff.i"
 %include "gr_wvps_ff.i"
+%include "gr_copy.i"
+%include "gr_fll_band_edge_cc.i"
+%include "gr_additive_scrambler_bb.i"
diff --git a/gnuradio-core/src/lib/general/general_generated.i b/gnuradio-core/src/lib/general/general_generated.i
new file mode 100644 (file)
index 0000000..a41f30a
--- /dev/null
@@ -0,0 +1,156 @@
+//
+// This file is machine generated.  All edits will be overwritten
+//
+%{
+#include <gr_add_cc.h>
+#include <gr_add_const_cc.h>
+#include <gr_add_const_ff.h>
+#include <gr_add_const_ii.h>
+#include <gr_add_const_sf.h>
+#include <gr_add_const_ss.h>
+#include <gr_add_const_vcc.h>
+#include <gr_add_const_vff.h>
+#include <gr_add_const_vii.h>
+#include <gr_add_const_vss.h>
+#include <gr_add_ff.h>
+#include <gr_add_ii.h>
+#include <gr_add_ss.h>
+#include <gr_add_vcc.h>
+#include <gr_add_vff.h>
+#include <gr_add_vii.h>
+#include <gr_add_vss.h>
+#include <gr_chunks_to_symbols_bc.h>
+#include <gr_chunks_to_symbols_bf.h>
+#include <gr_chunks_to_symbols_ic.h>
+#include <gr_chunks_to_symbols_if.h>
+#include <gr_chunks_to_symbols_sc.h>
+#include <gr_chunks_to_symbols_sf.h>
+#include <gr_divide_cc.h>
+#include <gr_divide_ff.h>
+#include <gr_divide_ii.h>
+#include <gr_divide_ss.h>
+#include <gr_multiply_cc.h>
+#include <gr_multiply_const_cc.h>
+#include <gr_multiply_const_ff.h>
+#include <gr_multiply_const_ii.h>
+#include <gr_multiply_const_ss.h>
+#include <gr_multiply_const_vcc.h>
+#include <gr_multiply_const_vff.h>
+#include <gr_multiply_const_vii.h>
+#include <gr_multiply_const_vss.h>
+#include <gr_multiply_ff.h>
+#include <gr_multiply_ii.h>
+#include <gr_multiply_ss.h>
+#include <gr_multiply_vcc.h>
+#include <gr_multiply_vff.h>
+#include <gr_multiply_vii.h>
+#include <gr_multiply_vss.h>
+#include <gr_mute_cc.h>
+#include <gr_mute_ff.h>
+#include <gr_mute_ii.h>
+#include <gr_mute_ss.h>
+#include <gr_noise_source_c.h>
+#include <gr_noise_source_f.h>
+#include <gr_noise_source_i.h>
+#include <gr_noise_source_s.h>
+#include <gr_packed_to_unpacked_bb.h>
+#include <gr_packed_to_unpacked_ii.h>
+#include <gr_packed_to_unpacked_ss.h>
+#include <gr_sig_source_c.h>
+#include <gr_sig_source_f.h>
+#include <gr_sig_source_i.h>
+#include <gr_sig_source_s.h>
+#include <gr_sub_cc.h>
+#include <gr_sub_ff.h>
+#include <gr_sub_ii.h>
+#include <gr_sub_ss.h>
+#include <gr_unpacked_to_packed_bb.h>
+#include <gr_unpacked_to_packed_ii.h>
+#include <gr_unpacked_to_packed_ss.h>
+#include <gr_vector_sink_b.h>
+#include <gr_vector_sink_c.h>
+#include <gr_vector_sink_f.h>
+#include <gr_vector_sink_i.h>
+#include <gr_vector_sink_s.h>
+#include <gr_vector_source_b.h>
+#include <gr_vector_source_c.h>
+#include <gr_vector_source_f.h>
+#include <gr_vector_source_i.h>
+#include <gr_vector_source_s.h>
+%}
+
+%include <gr_add_cc.i>
+%include <gr_add_const_cc.i>
+%include <gr_add_const_ff.i>
+%include <gr_add_const_ii.i>
+%include <gr_add_const_sf.i>
+%include <gr_add_const_ss.i>
+%include <gr_add_const_vcc.i>
+%include <gr_add_const_vff.i>
+%include <gr_add_const_vii.i>
+%include <gr_add_const_vss.i>
+%include <gr_add_ff.i>
+%include <gr_add_ii.i>
+%include <gr_add_ss.i>
+%include <gr_add_vcc.i>
+%include <gr_add_vff.i>
+%include <gr_add_vii.i>
+%include <gr_add_vss.i>
+%include <gr_chunks_to_symbols_bc.i>
+%include <gr_chunks_to_symbols_bf.i>
+%include <gr_chunks_to_symbols_ic.i>
+%include <gr_chunks_to_symbols_if.i>
+%include <gr_chunks_to_symbols_sc.i>
+%include <gr_chunks_to_symbols_sf.i>
+%include <gr_divide_cc.i>
+%include <gr_divide_ff.i>
+%include <gr_divide_ii.i>
+%include <gr_divide_ss.i>
+%include <gr_multiply_cc.i>
+%include <gr_multiply_const_cc.i>
+%include <gr_multiply_const_ff.i>
+%include <gr_multiply_const_ii.i>
+%include <gr_multiply_const_ss.i>
+%include <gr_multiply_const_vcc.i>
+%include <gr_multiply_const_vff.i>
+%include <gr_multiply_const_vii.i>
+%include <gr_multiply_const_vss.i>
+%include <gr_multiply_ff.i>
+%include <gr_multiply_ii.i>
+%include <gr_multiply_ss.i>
+%include <gr_multiply_vcc.i>
+%include <gr_multiply_vff.i>
+%include <gr_multiply_vii.i>
+%include <gr_multiply_vss.i>
+%include <gr_mute_cc.i>
+%include <gr_mute_ff.i>
+%include <gr_mute_ii.i>
+%include <gr_mute_ss.i>
+%include <gr_noise_source_c.i>
+%include <gr_noise_source_f.i>
+%include <gr_noise_source_i.i>
+%include <gr_noise_source_s.i>
+%include <gr_packed_to_unpacked_bb.i>
+%include <gr_packed_to_unpacked_ii.i>
+%include <gr_packed_to_unpacked_ss.i>
+%include <gr_sig_source_c.i>
+%include <gr_sig_source_f.i>
+%include <gr_sig_source_i.i>
+%include <gr_sig_source_s.i>
+%include <gr_sub_cc.i>
+%include <gr_sub_ff.i>
+%include <gr_sub_ii.i>
+%include <gr_sub_ss.i>
+%include <gr_unpacked_to_packed_bb.i>
+%include <gr_unpacked_to_packed_ii.i>
+%include <gr_unpacked_to_packed_ss.i>
+%include <gr_vector_sink_b.i>
+%include <gr_vector_sink_c.i>
+%include <gr_vector_sink_f.i>
+%include <gr_vector_sink_i.i>
+%include <gr_vector_sink_s.i>
+%include <gr_vector_source_b.i>
+%include <gr_vector_source_c.i>
+%include <gr_vector_source_f.i>
+%include <gr_vector_source_i.i>
+%include <gr_vector_source_s.i>
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc
new file mode 100644 (file)
index 0000000..91e02c2
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_additive_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_additive_scrambler_bb_sptr
+gr_make_additive_scrambler_bb(int mask, int seed, int len, int count)
+{
+  return gr_additive_scrambler_bb_sptr(new gr_additive_scrambler_bb(mask, seed, len, count));
+}
+
+gr_additive_scrambler_bb::gr_additive_scrambler_bb(int mask, int seed, int len, int count)
+  : gr_sync_block("additive_scrambler_bb",
+                 gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                 gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_lfsr(mask, seed, len),
+    d_count(count),
+    d_bits(0)
+{
+}
+
+int
+gr_additive_scrambler_bb::work(int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  const unsigned char *in = (const unsigned char *) input_items[0];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++) {
+    out[i] = in[i]^d_lfsr.next_bit();
+    if (d_count > 0) {
+      if (++d_bits == d_count) {
+       d_lfsr.reset();
+       d_bits = 0;
+      }
+    }
+  }
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h
new file mode 100644 (file)
index 0000000..6c94930
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 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.
+ */
+#ifndef INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+#define INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_additive_scrambler_bb;
+typedef boost::shared_ptr<gr_additive_scrambler_bb> gr_additive_scrambler_bb_sptr;
+
+gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
+
+/*!
+ * Scramble an input stream using an LFSR.  This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and 
+ * produces the same format on its output.
+ * 
+ * \param mask     Polynomial mask for LFSR
+ * \param seed     Initial shift register contents
+ * \param len      Shift register length
+ * \param count    Number of bits after which shift register is reset, 0=never
+ *
+ * The scrambler works by XORing the incoming bit stream by the output of
+ * the LFSR.  Optionally, after 'count' bits have been processed, the shift
+ * register is reset to the seed value.  This allows processing fixed length
+ * vectors of samples.
+ * 
+ * \ingroup coding_blk
+ */
+
+class gr_additive_scrambler_bb : public gr_sync_block
+{
+  friend gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count);
+
+  gri_lfsr d_lfsr;
+  int      d_count;
+  int      d_bits;
+
+  gr_additive_scrambler_bb(int mask, int seed, int len, int count);
+
+public:
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i
new file mode 100644 (file)
index 0000000..0ca9c1c
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,additive_scrambler_bb);
+
+gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
+
+class gr_additive_scrambler_bb : public gr_sync_block
+{
+private:
+  gr_additive_scrambler_bb(int mask, int seed, int len, int count);
+};
diff --git a/gnuradio-core/src/lib/general/gr_constants.cc.in b/gnuradio-core/src/lib/general/gr_constants.cc.in
new file mode 100644 (file)
index 0000000..71a47eb
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_constants.h>
+
+const std::string
+gr_prefix()
+{
+  return "@prefix@";
+}
+
+const std::string
+gr_sysconfdir()
+{
+  return "@SYSCONFDIR@";
+}
+
+const std::string
+gr_prefsdir()
+{
+  return "@GR_PREFSDIR@";
+}
+
+const std::string
+gr_build_date()
+{
+  return "@BUILD_DATE@";
+}
+
+const std::string
+gr_version()
+{
+  return "@VERSION@";
+}
diff --git a/gnuradio-core/src/lib/general/gr_constants.h b/gnuradio-core/src/lib/general/gr_constants.h
new file mode 100644 (file)
index 0000000..449d41c
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+#ifndef INCLUDED_GR_CONSTANTS_H
+#define INCLUDED_GR_CONSTANTS_H
+
+#include <string>
+
+/*!
+ * \brief return ./configure --prefix argument.  Typically /usr/local
+ */
+const std::string gr_prefix();
+
+/*!
+ * \brief return ./configure --sysconfdir argument.  Typically $prefix/etc or /etc
+ */
+const std::string gr_sysconfdir();
+
+/*!
+ * \brief return preferences file directory.  Typically $sysconfdir/etc/conf.d
+ */
+const std::string gr_prefsdir();
+
+/*!
+ * \brief return date/time of build, as set when 'bootstrap' is run
+ */
+const std::string gr_build_date();
+
+/*!
+ * \brief return version string defined in configure.ac
+ */
+const std::string gr_version();
+
+#endif /* INCLUDED_GR_CONSTANTS_H */
diff --git a/gnuradio-core/src/lib/general/gr_constants.i b/gnuradio-core/src/lib/general/gr_constants.i
new file mode 100644 (file)
index 0000000..a5aef14
--- /dev/null
@@ -0,0 +1,13 @@
+/* -*- c++ -*- */
+
+%rename(prefix) gr_prefix;
+%rename(sysconfdir) gr_sysconfdir;
+%rename(prefsdir) gr_prefsdir;
+%rename(build_date) gr_build_date;
+%rename(version) gr_version;
+
+const std::string gr_prefix();
+const std::string gr_sysconfdir();
+const std::string gr_prefsdir();
+const std::string gr_build_date();
+const std::string gr_version();
diff --git a/gnuradio-core/src/lib/general/gr_copy.cc b/gnuradio-core/src/lib/general/gr_copy.cc
new file mode 100644 (file)
index 0000000..c6564c2
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_copy.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_copy_sptr
+gr_make_copy(size_t itemsize)
+{
+  return gnuradio::get_initial_sptr(new gr_copy(itemsize));
+}
+
+gr_copy::gr_copy(size_t itemsize)
+  : gr_block ("copy",
+             gr_make_io_signature (1, 1, itemsize),
+             gr_make_io_signature (1, 1, itemsize)),
+    d_itemsize(itemsize),
+    d_enabled(true)
+{
+}
+
+bool
+gr_copy::check_topology(int ninputs, int noutputs)
+{
+  return ninputs == noutputs;
+}
+
+int
+gr_copy::general_work(int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  const uint8_t *in = (const uint8_t *) input_items[0];
+  uint8_t *out = (uint8_t *) output_items[0];
+
+  int n = std::min<int>(ninput_items[0], noutput_items);
+  int j = 0;
+
+  if (d_enabled) {
+    memcpy(out, in, n*d_itemsize);
+    j = n;
+  }
+
+  consume_each(n);
+  return j;
+}
diff --git a/gnuradio-core/src/lib/general/gr_copy.h b/gnuradio-core/src/lib/general/gr_copy.h
new file mode 100644 (file)
index 0000000..d99aef8
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+
+#ifndef INCLUDED_GR_COPY_H
+#define INCLUDED_GR_COPY_H
+
+#include <gr_block.h>
+
+class gr_copy;
+typedef boost::shared_ptr<gr_copy> gr_copy_sptr;
+
+gr_copy_sptr gr_make_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup misc_blk
+ *
+ * When enabled (default), this block copies its input to its output.
+ * When disabled, this block drops its input on the floor.
+ *
+ */
+class gr_copy : public gr_block
+{
+  size_t               d_itemsize;
+  bool                 d_enabled;
+
+  friend gr_copy_sptr gr_make_copy(size_t itemsize);
+  gr_copy(size_t itemsize);
+
+ public:
+
+  bool check_topology(int ninputs, int noutputs);
+
+  void set_enabled(bool enable) { d_enabled = enable; }
+  bool enabled() const { return d_enabled;}
+
+  int general_work(int noutput_items,
+                  gr_vector_int &ninput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_copy.i b/gnuradio-core/src/lib/general/gr_copy.i
new file mode 100644 (file)
index 0000000..e260d8e
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,copy)
+
+gr_copy_sptr gr_make_copy(size_t itemsize);
+
+class gr_copy : public gr_block
+{
+ private:
+  gr_copy(size_t itemsize);
+
+public:
+
+  void set_enabled(bool enabled);
+  bool enabled();
+};
diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc
new file mode 100644 (file)
index 0000000..7f2c468
--- /dev/null
@@ -0,0 +1,213 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fll_band_edge_cc.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_util.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_math.h>
+#include <cstdio>
+
+#define M_TWOPI (2*M_PI)
+
+float sinc(float x)
+{
+  if(x == 0)
+    return 1;
+  else
+    return sin(M_PI*x)/(M_PI*x);
+}
+  
+
+
+gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                                                  int filter_size, float gain_alpha, float gain_beta)
+{
+  return gr_fll_band_edge_cc_sptr (new gr_fll_band_edge_cc (samps_per_sym, rolloff,
+                                                           filter_size, gain_alpha, gain_beta));
+}
+
+
+static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(gr_complex)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                                         int filter_size, float alpha, float beta)
+  : gr_sync_block ("fll_band_edge_cc",
+                  gr_make_io_signature (1, 1, sizeof(gr_complex)),
+                  gr_make_io_signaturev (1, 4, iosig)),
+    d_alpha(alpha), d_beta(beta), d_updated (false)
+{
+  // base this on the number of samples per symbol
+  d_max_freq =  M_TWOPI * (2.0/samps_per_sym);
+  d_min_freq = -M_TWOPI * (2.0/samps_per_sym);
+
+  d_freq = 0;
+  d_phase = 0;
+
+  set_alpha(alpha);
+
+  design_filter(samps_per_sym, rolloff, filter_size);
+}
+
+gr_fll_band_edge_cc::~gr_fll_band_edge_cc ()
+{
+  delete d_filter_lower;
+  delete d_filter_upper;
+}
+
+void
+gr_fll_band_edge_cc::set_alpha(float alpha) 
+{ 
+  //float eta = sqrt(2.0)/2.0;
+  //float theta = alpha;
+  //d_alpha = (4*eta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
+  //d_beta = (4*theta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
+  d_alpha = alpha;
+}
+
+void
+gr_fll_band_edge_cc::design_filter(float samps_per_sym, float rolloff, int filter_size)
+{
+  int M = rint(filter_size / samps_per_sym);
+  float power = 0;
+  std::vector<float> bb_taps;
+  for(int i = 0; i < filter_size; i++) {
+    float k = -M + i*2.0/samps_per_sym;
+    float tap = sinc(rolloff*k - 0.5) + sinc(rolloff*k + 0.5);
+    power += tap;
+
+    bb_taps.push_back(tap);
+  }
+
+  int N = (bb_taps.size() - 1.0)/2.0;
+  std::vector<gr_complex> taps_lower;
+  std::vector<gr_complex> taps_upper;
+  for(unsigned int i = 0; i < bb_taps.size(); i++) {
+    float tap = bb_taps[i] / power;
+
+    float k = (-N + (int)i)/(2.0*samps_per_sym);
+    
+    gr_complex t1 = tap * gr_expj(-2*M_PI*(1+rolloff)*k);
+    gr_complex t2 = tap * gr_expj(2*M_PI*(1+rolloff)*k);
+
+    taps_lower.push_back(t1);
+    taps_upper.push_back(t2);
+  }
+
+  std::vector<gr_complex> vtaps(0, taps_lower.size());
+  d_filter_upper = gr_fir_util::create_gr_fir_ccc(vtaps);
+  d_filter_lower = gr_fir_util::create_gr_fir_ccc(vtaps);
+
+  d_filter_lower->set_taps(taps_lower);
+  d_filter_upper->set_taps(taps_upper);
+
+  d_updated = true;
+
+  // Set the history to ensure enough input items for each filter
+  set_history(filter_size+1);
+
+}
+
+void
+gr_fll_band_edge_cc::print_taps()
+{
+  unsigned int i;
+  std::vector<gr_complex> taps_upper = d_filter_upper->get_taps();
+  std::vector<gr_complex> taps_lower = d_filter_lower->get_taps();
+
+  printf("Upper Band-edge: [");
+  for(i = 0; i < taps_upper.size(); i++) {
+    printf(" %.4e + %.4ej,", taps_upper[i].real(), taps_upper[i].imag());
+  }
+  printf("]\n\n");
+
+  printf("Lower Band-edge: [");
+  for(i = 0; i < taps_lower.size(); i++) {
+    printf(" %.4e + %.4ej,", taps_lower[i].real(), taps_lower[i].imag());
+  }
+  printf("]\n\n");
+}
+
+int
+gr_fll_band_edge_cc::work (int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+{
+  const gr_complex *in  = (const gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  float *frq, *phs;
+  gr_complex *err;
+  if(output_items.size() > 2) {
+    frq = (float *) output_items[1];
+    phs = (float *) output_items[2];
+    err = (gr_complex *) output_items[3];
+  }
+
+  if (d_updated) {
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int i;
+  gr_complex nco_out;
+  gr_complex out_upper, out_lower;
+  float error;
+  float avg_k = 0.1;
+  for(i = 0; i < noutput_items; i++) {
+    nco_out = gr_expj(d_phase);
+    out[i] = in[i] * nco_out;
+
+    out_upper = (d_filter_upper->filter(&out[i]));
+    out_lower = (d_filter_lower->filter(&out[i]));
+    error = -real((out_upper + out_lower) * conj(out_upper - out_lower));
+    d_error = avg_k*error + avg_k*d_error;  // average error
+
+    d_freq = d_freq + d_beta * d_error;
+    d_phase = d_phase + d_freq + d_alpha * d_error;
+
+    if(d_phase > M_PI)
+      d_phase -= M_TWOPI;
+    else if(d_phase < -M_PI)
+      d_phase += M_TWOPI;
+
+    if (d_freq > d_max_freq)
+      d_freq = d_max_freq;
+    else if (d_freq < d_min_freq)
+      d_freq = d_min_freq;
+
+    if(output_items.size() > 2) {
+      frq[i] = d_freq;
+      phs[i] = d_phase;
+      err[i] = d_error;
+    }
+  }
+
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h
new file mode 100644 (file)
index 0000000..db06079
--- /dev/null
@@ -0,0 +1,139 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+
+#ifndef INCLUDED_GR_FLL_BAND_EDGE_CC_H
+#define        INCLUDED_GR_FLL_BAND_EDGE_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_fll_band_edge_cc;
+typedef boost::shared_ptr<gr_fll_band_edge_cc> gr_fll_band_edge_cc_sptr;
+gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                                                  int filter_size, float alpha, float beta);
+
+class gr_fir_ccc;
+class gri_fft_complex;
+
+/*!
+ * \class gr_fll_band_edge_cc
+ * \brief Frequency Lock Loop using band-edge filters
+ *
+ * \ingroup general
+ *
+ * The frequency lock loop derives a band-edge filter that covers the upper and lower bandwidths
+ * of a digitally-modulated signal. The bandwidth range is determined by the excess bandwidth
+ * (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges
+ * is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth.
+ * The size of the filters should be fairly large so as to average over a number of symbols.
+ *
+ * The FLL works by filtering the upper and lower band edges into x_u(t) and x_l(t), respectively.
+ * These are combined to form cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining
+ * these to form the signal e(t) = Re{cc(t) \\times ss(t)^*} (where ^* is the complex conjugate)
+ * provides an error signal at the DC term that is directly proportional to the carrier frequency.
+ * We then make a second-order loop using the error signal that is the running average of e(t).
+ *
+ * In theory, the band-edge filter is the derivative of the matched filter in frequency, 
+ * (H_be(f) = \\frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point
+ * of the matched filter's rolloff (if it's a raised-cosine, the derivative of a cosine is a sine).
+ * Extend this sine by another quarter wave to make a half wave around the band-edges is equivalent
+ * in time to the sum of two sinc functions. The baseband filter fot the band edges is therefore
+ * derived from this sum of sincs. The band edge filters are then just the baseband signal
+ * modulated to the correct place in frequency. All of these calculations are done in the
+ * 'design_filter' function.
+ *
+ * Note: We use FIR filters here because the filters have to have a flat phase response over the
+ * entire frequency range to allow their comparisons to be valid.
+ */
+
+class gr_fll_band_edge_cc : public gr_sync_block
+{
+ private:
+  /*!
+   * Build the FLL
+   * \param samps_per_sym    (float) Number of samples per symbol of signal
+   * \param rolloff          (float) Rolloff factor of signal
+   * \param filter_size      (int)   Size (in taps) of the filter
+   * \param alpha            (float) Loop gain 1
+   * \param beta             (float) Loop gain 2
+   */
+  friend gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                                                           int filter_size, float alpha, float beta);
+
+  float                   d_alpha;
+  float                   d_beta;
+  float                   d_max_freq;
+  float                   d_min_freq;
+
+  gr_fir_ccc*             d_filter_upper;
+  gr_fir_ccc*             d_filter_lower;
+  bool                   d_updated;
+  float                   d_error;
+  float                   d_freq;
+  float                   d_phase;
+
+  /*!
+   * Build the FLL
+   * \param samps_per_sym (float) number of samples per symbol
+   * \param rolloff (float) Rolloff (excess bandwidth) of signal filter
+   * \param filter_size (int) number of filter taps to generate
+   * \param alpha (float) Alpha gain in the control loop
+   * \param beta  (float) Beta gain in the control loop
+   */
+  gr_fll_band_edge_cc(float samps_per_sym, float rolloff,
+                     int filter_size, float alpha, float beta);
+
+public:
+  ~gr_fll_band_edge_cc ();
+  
+  /*!
+   * Design the band-edge filter based on the number of samples per symbol,
+   * filter rolloff factor, and the filter size
+   * \param samps_per_sym    (float) Number of samples per symbol of signal
+   * \param rolloff          (float) Rolloff factor of signal
+   * \param filter_size      (int)   Size (in taps) of the filter
+   */
+  void design_filter(float samps_per_sym, float rolloff, int filter_size);
+
+  /*!
+   * Set the alpha gainvalue
+   * \param alpha    (float) new gain value
+   */
+  void set_alpha(float alpha);
+
+  /*!
+   * Set the beta gain value
+   * \param beta    (float) new gain value
+   */
+  void set_beta(float beta) { d_beta = beta; }
+
+  /*!
+   * Print the taps to screen.
+   */
+  void print_taps();
+   
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i
new file mode 100644 (file)
index 0000000..c9c792c
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fll_band_edge_cc);
+
+gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                                                  int filter_size, float alpha, float beta);
+
+class gr_fll_band_edge_cc : public gr_sync_block
+{
+ private:
+  gr_fll_band_edge_cc (float samps_per_sym, float rolloff,
+                      int filter_size, float alpha, float beta);
+
+ public:
+  ~gr_fll_band_edge_cc ();
+
+  void set_alpha (float alpha);
+  void set_beta (float beta);
+  void design_filter(float samps_per_sym, float rolloff, int filter_size);
+  void print_taps();
+};
index 172ef12797b704d0402e3c6563c450e087399cda..e2c7e7a7f9cb5588c28e6ceb0c7a0c8070972704 100644 (file)
@@ -45,12 +45,25 @@ gr_fmdet_cf::gr_fmdet_cf (float samplerate, float freq_low, float freq_high, flo
     d_S1(0.1),d_S2(0.1),
     d_S3(0.1),d_S4(0.1)
 {
+  const float h[]={0.003118678733, -0.012139843428,  0.027270898036, -0.051318579352,
+            0.090406910552, -0.162926865366,  0.361885392563, 0.000000000000,
+            -0.361885392563,  0.162926865366, -0.090406910552,  0.051318579352,
+            -0.027270898036,  0.012139843428, -0.003118678733};
+
+
+
+
   float delta;
+  std::vector<float> taps(15);
+  
   d_freqhi = freq_high;
   d_freqlo = freq_low;
   delta = (d_freqhi - d_freqlo);
   d_scl = scl;
   d_bias = 0.5*scl*(d_freqhi+d_freqlo)/delta;
+  for (int i=0;i<15;i++) taps[i] = h[i];
+  //  d_filter = gr_fir_util::create_gr_fir_ccf(taps);
+  
 }
 
 int
@@ -60,18 +73,19 @@ gr_fmdet_cf::work (int noutput_items,
 {
   const gr_complex *iptr = (gr_complex *) input_items[0];
   float *optr = (float *) output_items[0];
+  //  const gr_complex *scaleiptr = (gr_complex *) input_items[0];
 
   int  size = noutput_items;
 
   gr_complex Sdot,S0,S1=d_S1,S2=d_S2,S3=d_S3,S4=d_S4;
+  float d_8 = 8.0;
 
   while (size-- > 0) {
     S0=*iptr++;
 
-    Sdot = gr_complex(d_scl*
-                     (-S0.real() + 8.0*S1.real() - 8.0*S3.real() + S4.real()),
-                     d_scl*
-                     (-S0.imag() + 8.0*S1.imag() - 8.0*S3.imag() + S4.imag()));
+
+    Sdot = d_scl * (-S0+d_8*S1-d_8*S1+S4);
+
     d_freq = (S2.real()*Sdot.imag()-S2.imag()*Sdot.real())/
       (S2.real()*S2.real()+S2.imag()*S2.imag());
 
index 7e8be31b1d27c6cc30187493b56a1cc15ccdb337..792646bef225b6b605a7f3ac499d5fac0df866c1 100644 (file)
@@ -30,6 +30,9 @@ typedef boost::shared_ptr<gr_fmdet_cf> gr_fmdet_cf_sptr;
 
 gr_fmdet_cf_sptr gr_make_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
 
+class gr_fir_ccf;
+
+
 /*!
  * \brief Implements an IQ slope detector
  * 
@@ -47,6 +50,7 @@ class gr_fmdet_cf : public gr_sync_block
 
   gr_complex d_S1,d_S2,d_S3,d_S4;
   float d_freq,d_freqlo,d_freqhi,d_scl,d_bias;
+  gr_fir_ccf* d_filter;
   gr_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
 
   int work (int noutput_items,
index 94a00cc68df2bfc38f57d9278506201252521934..b52735c06eb39705ea08e78a68e6005474a5f035 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -27,7 +27,7 @@
 #include <gr_io_signature.h>
 #include <string.h>
 
-gr_head::gr_head (size_t sizeof_stream_item, int nitems)
+gr_head::gr_head (size_t sizeof_stream_item, unsigned long long nitems)
   : gr_sync_block ("head",
                   gr_make_io_signature (1, 1, sizeof_stream_item),
                   gr_make_io_signature (1, 1, sizeof_stream_item)),
@@ -35,10 +35,10 @@ gr_head::gr_head (size_t sizeof_stream_item, int nitems)
 {
 }
 
-gr_block_sptr
-gr_make_head (size_t sizeof_stream_item, int nitems)
+gr_head_sptr
+gr_make_head (size_t sizeof_stream_item, unsigned long long nitems)
 {
-  return gr_block_sptr (new gr_head (sizeof_stream_item, nitems));
+  return gnuradio::get_initial_sptr(new gr_head (sizeof_stream_item, nitems));
 }
 
 int
@@ -49,7 +49,7 @@ gr_head::work (int noutput_items,
   if (d_ncopied_items >= d_nitems)
     return -1;                         // Done!
 
-  unsigned n = std::min (d_nitems - d_ncopied_items, noutput_items);
+  unsigned n = std::min (d_nitems - d_ncopied_items, (unsigned long long) noutput_items);
   
   if (n == 0)
     return 0;
index cd97d63994c0333b958ce6515248449d45376936..f7eee10648e3f354455844272f8785ae9af6e571 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,6 +26,9 @@
 #include <gr_sync_block.h>
 #include <stddef.h>                    // size_t
 
+class gr_head;
+typedef boost::shared_ptr<gr_head> gr_head_sptr;
+
 /*!
  * \brief copies the first N items to the output then signals done
  * \ingroup slicedice_blk
 
 class gr_head : public gr_sync_block
 {
-  friend gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
-  gr_head (size_t sizeof_stream_item, int nitems);
+  friend gr_head_sptr gr_make_head (size_t sizeof_stream_item, unsigned long long nitems);
+  gr_head (size_t sizeof_stream_item, unsigned long long nitems);
 
-  int  d_nitems;
-  int  d_ncopied_items;
+  unsigned long long   d_nitems;
+  unsigned long long   d_ncopied_items;
 
  public:
   int work (int noutput_items,
                 gr_vector_const_void_star &input_items,
                 gr_vector_void_star &output_items);
+
+  void reset() { d_ncopied_items = 0; }
 };
 
-gr_block_sptr
-gr_make_head (size_t sizeof_stream_item, int nitems);
+gr_head_sptr
+gr_make_head (size_t sizeof_stream_item, unsigned long long nitems);
 
 
 #endif /* INCLUDED_GR_HEAD_H */
index 324bb08ecbd1b2e7f6b0bb072b336f1cbadda3df..3aece9601c16a039a8cee0acba922550ad350279 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
  * Boston, MA 02110-1301, USA.
  */
 
-%ignore gr_head;
+GR_SWIG_BLOCK_MAGIC(gr,head);
+
+gr_head_sptr gr_make_head(size_t sizeof_stream_item, unsigned long long nitems);
+
 class gr_head : public gr_block {
-  friend gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
-  gr_head (size_t sizeof_stream_item, int nitems);
+  gr_head();
+public:
+  void reset();
 };
 
-%rename(head) gr_make_head;
-gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
index 49bbb8d36048338d687339da480e0d116689fef1..1efa827035da7848338c24a982a46db2dcd61987 100644 (file)
@@ -265,8 +265,6 @@ gr_mpsk_receiver_cc::phase_error_tracking(gr_complex sample)
 
   // Make phase and frequency corrections based on sampled value
   phase_error = (*this.*d_phase_error_detector)(sample);
-
-  phase_error = gr_branchless_clip(phase_error, 1.0);
     
   d_freq += d_beta*phase_error;             // adjust frequency based on error
   d_phase += d_freq + d_alpha*phase_error;  // adjust phase based on error
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc
new file mode 100644 (file)
index 0000000..a01cf35
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_bpsk_demapper.h>
+#include <gr_io_signature.h>
+
+gr_ofdm_bpsk_demapper_sptr
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers)
+{
+  return gr_ofdm_bpsk_demapper_sptr (new gr_ofdm_bpsk_demapper (occupied_carriers));
+}
+
+gr_ofdm_bpsk_demapper::gr_ofdm_bpsk_demapper (unsigned occupied_carriers)
+  : gr_block ("ofdm_bpsk_demapper",
+             gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers),
+             gr_make_io_signature (1, 1, sizeof(unsigned char))),
+    d_occupied_carriers(occupied_carriers),
+    d_byte_offset(0), d_partial_byte(0)
+{
+}
+
+gr_ofdm_bpsk_demapper::~gr_ofdm_bpsk_demapper(void)
+{
+}
+
+unsigned char gr_ofdm_bpsk_demapper::slicer(gr_complex x)
+{
+  return (unsigned char)(x.real() > 0 ? 1 : 0);
+}
+
+void
+gr_ofdm_bpsk_demapper::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned ninputs = ninput_items_required.size ();
+  for (unsigned i = 0; i < ninputs; i++)
+    ninput_items_required[i] = 1;
+}
+
+int
+gr_ofdm_bpsk_demapper::general_work(int noutput_items,
+                                   gr_vector_int &ninput_items,
+                                   gr_vector_const_void_star &input_items,
+                                   gr_vector_void_star &output_items)
+{
+  const gr_complex *in = (const gr_complex *)input_items[0];
+  unsigned char *out = (unsigned char *) output_items[0];
+  
+  unsigned int i=0, bytes_produced=0;
+
+  while(i < d_occupied_carriers) {
+
+    while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+      //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag()); 
+      d_partial_byte |= slicer(in[i++]) << (d_byte_offset++);
+    }
+
+    if(d_byte_offset == 8) {
+      out[bytes_produced++] = d_partial_byte;
+      d_byte_offset = 0;
+      d_partial_byte = 0;
+    }
+  }
+
+#if 0
+printf("demod out: ");
+  for(i = 0; i < bytes_produced; i++) {
+    printf("%4x", out[i]);
+  }
+  printf(" \tlen: %d\n", i);
+#endif
+
+  consume_each(1);
+  return bytes_produced;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h
new file mode 100644 (file)
index 0000000..12ae6a8
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_GR_OFDM_BPSK_DEMAPPER_H
+#define INCLUDED_GR_OFDM_BPSK_DEMAPPER_H
+
+
+#include <gr_block.h>
+#include <vector>
+
+class gr_ofdm_bpsk_demapper;
+typedef boost::shared_ptr<gr_ofdm_bpsk_demapper> gr_ofdm_bpsk_demapper_sptr;
+
+gr_ofdm_bpsk_demapper_sptr 
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+
+/*!
+ * \brief take a vector of complex constellation points in from an FFT
+ * and demodulate to a stream of bits. Simple BPSK version.
+ * \ingroup ofdm_blk
+ */
+class gr_ofdm_bpsk_demapper : public gr_block
+{
+  friend gr_ofdm_bpsk_demapper_sptr
+    gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+  
+ protected:
+  gr_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+  
+ private:
+  unsigned char slicer(gr_complex x);
+
+  unsigned int d_occupied_carriers;
+  unsigned int d_byte_offset;
+  unsigned char d_partial_byte;
+  
+  void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+ public:
+  ~gr_ofdm_bpsk_demapper(void);
+  int general_work(int noutput_items,
+                  gr_vector_int &ninput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i
new file mode 100644 (file)
index 0000000..4ad5ed1
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#include <vector>
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_demapper)
+
+gr_ofdm_bpsk_demapper_sptr 
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+class gr_ofdm_bpsk_demapper : public gr_sync_decimator
+{
+ protected:
+  gr_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+ public:
+  int general_work(int noutput_items,
+                  gr_vector_int &ninput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+};
index 74bd65a50a688ddae32b3a761f968205664f0296..7f6b2b01c984a6d5064a9d91fbdb5005146989e7 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -45,6 +45,7 @@ gr_ofdm_sampler::gr_ofdm_sampler (unsigned int fft_length,
              gr_make_io_signature2 (2, 2, sizeof (gr_complex)*fft_length, sizeof(char)*fft_length)),
     d_state(STATE_NO_SIG), d_timeout_max(timeout), d_fft_length(fft_length), d_symbol_length(symbol_length)
 {
+  set_relative_rate(1.0/(double) fft_length);   // buffer allocator hint
 }
 
 void
index ca6df541b7d1d935ad29f9d73aeaa00dd8b41095..86c2901b5f10c8a91ecb6c8e792cf6b6a3f80cdc 100644 (file)
@@ -814,8 +814,10 @@ gr_remez (int order,
   if (arg_bands[0] < 0 || arg_bands[arg_bands.size () - 1] > 1)
     punt ("gr_remez: band edges must be in the range [0,1]");
 
+  // Divide by 2 to fit with the implementation that uses a
+  // sample rate of [0, 0.5] instead of [0, 1.0]
   for (int i = 0; i < 2 * numbands; i++)
-    bands[i] = arg_bands[i] / 2;               // FIXME why / 2?
+    bands[i] = arg_bands[i] / 2;
 
   LOCAL_BUFFER (double, response, numbands * 2);
   if (arg_response.size () != arg_bands.size ())
index 715da78a94d8fc0f0aff080a5c26b92bf09c93c0..f691e36ecbdaad23f7605ea5d2761a9d39708bc3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -86,6 +86,7 @@ class gri_lfsr
  private:
   uint32_t d_shift_register;
   uint32_t d_mask;
+  uint32_t d_seed;
   uint32_t d_shift_register_length;    // less than 32
 
   static uint32_t
@@ -99,7 +100,10 @@ class gri_lfsr
  public:
 
   gri_lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len)
-    : d_shift_register(seed), d_mask(mask), d_shift_register_length(reg_len)
+    : d_shift_register(seed), 
+      d_mask(mask), 
+      d_seed(seed),
+      d_shift_register_length(reg_len)
   {
     if (reg_len > 31)
       throw std::invalid_argument("reg_len must be <= 31");
@@ -126,6 +130,10 @@ class gri_lfsr
     return output;
   }
 
+  /*!
+   * Reset shift register to initial seed value
+   */
+  void reset() { d_shift_register = d_seed; }
 
   /*!
    * Rotate the register through x number of bits
diff --git a/gnuradio-core/src/lib/gengen/.gitignore b/gnuradio-core/src/lib/gengen/.gitignore
new file mode 100644 (file)
index 0000000..ecd4cb0
--- /dev/null
@@ -0,0 +1,418 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/generate-stamp
+/GrFIRfilterCCC.cc
+/GrFIRfilterCCC.h
+/GrFIRfilterCCF.cc
+/GrFIRfilterCCF.h
+/GrFIRfilterFCC.cc
+/GrFIRfilterFCC.h
+/GrFIRfilterFFF.cc
+/GrFIRfilterFFF.h
+/GrFIRfilterFSF.cc
+/GrFIRfilterFSF.h
+/GrFIRfilterSCC.cc
+/GrFIRfilterSCC.h
+/GrFIRfilterSIS.cc
+/GrFIRfilterSIS.h
+/GrFreqXlatingFIRfilterCCC.cc
+/GrFreqXlatingFIRfilterCCC.h
+/GrFreqXlatingFIRfilterCCF.cc
+/GrFreqXlatingFIRfilterCCF.h
+/GrFreqXlatingFIRfilterFCC.cc
+/GrFreqXlatingFIRfilterFCC.h
+/GrFreqXlatingFIRfilterFCF.cc
+/GrFreqXlatingFIRfilterFCF.h
+/GrFreqXlatingFIRfilterSCC.cc
+/GrFreqXlatingFIRfilterSCC.h
+/GrFreqXlatingFIRfilterSCF.cc
+/GrFreqXlatingFIRfilterSCF.h
+/gr_fir_CCC.cc
+/gr_fir_CCC.h
+/gr_fir_CCC_generic.cc
+/gr_fir_CCC_generic.h
+/gr_fir_CCF.cc
+/gr_fir_CCF.h
+/gr_fir_CCF_generic.cc
+/gr_fir_CCF_generic.h
+/gr_fir_FCC.cc
+/gr_fir_FCC.h
+/gr_fir_FCC_generic.cc
+/gr_fir_FCC_generic.h
+/gr_fir_FFF.cc
+/gr_fir_FFF.h
+/gr_fir_FFF_generic.cc
+/gr_fir_FFF_generic.h
+/gr_fir_FSF.cc
+/gr_fir_FSF.h
+/gr_fir_FSF_generic.cc
+/gr_fir_FSF_generic.h
+/gr_fir_SCC.cc
+/gr_fir_SCC.h
+/gr_fir_SCC_generic.cc
+/gr_fir_SCC_generic.h
+/gr_fir_SIS.cc
+/gr_fir_SIS.h
+/gr_fir_SIS_generic.cc
+/gr_fir_SIS_generic.h
+/gr_fir_sysconfig.cc
+/gr_fir_sysconfig.h
+/gr_fir_sysconfig_generic.cc
+/gr_fir_sysconfig_generic.h
+/gr_fir_util.cc
+/gr_fir_util.h
+/GrFIRfilterCCC.i
+/GrFIRfilterCCF.i
+/GrFIRfilterFCC.i
+/GrFIRfilterFFF.i
+/GrFIRfilterFSF.i
+/GrFIRfilterSCC.i
+/GrFIRfilterSIS.i
+/GrFreqXlatingFIRfilterCCC.i
+/GrFreqXlatingFIRfilterCCF.i
+/GrFreqXlatingFIRfilterFCC.i
+/GrFreqXlatingFIRfilterFCF.i
+/GrFreqXlatingFIRfilterSCC.i
+/GrFreqXlatingFIRfilterSCF.i
+/# --- generated files ---
+/gr_add_cc.cc
+/gr_add_cc.h
+/gr_add_cc.i
+/gr_add_const_c.cc
+/gr_add_const_cc.cc
+/gr_add_const_cc.h
+/gr_add_const_cc.i
+/gr_add_const_c.h
+/gr_add_const_c.i
+/gr_add_const_f.cc
+/gr_add_const_ff.cc
+/gr_add_const_ff.h
+/gr_add_const_ff.i
+/gr_add_const_f.h
+/gr_add_const_f.i
+/gr_add_const_i.cc
+/gr_add_const_i.h
+/gr_add_const_i.i
+/gr_add_const_ii.cc
+/gr_add_const_ii.h
+/gr_add_const_ii.i
+/gr_add_const_s.cc
+/gr_add_const_sf.cc
+/gr_add_const_sf.h
+/gr_add_const_sf.i
+/gr_add_const_s.h
+/gr_add_const_s.i
+/gr_add_const_ss.cc
+/gr_add_const_ss.h
+/gr_add_const_ss.i
+/gr_add_const_vcc.cc
+/gr_add_const_vcc.h
+/gr_add_const_vcc.i
+/gr_add_const_vff.cc
+/gr_add_const_vff.h
+/gr_add_const_vff.i
+/gr_add_const_vii.cc
+/gr_add_const_vii.h
+/gr_add_const_vii.i
+/gr_add_const_vss.cc
+/gr_add_const_vss.h
+/gr_add_const_vss.i
+/gr_add_ff.cc
+/gr_add_ff.h
+/gr_add_ff.i
+/gr_add_ii.cc
+/gr_add_ii.h
+/gr_add_ii.i
+/gr_add_ss.cc
+/gr_add_ss.h
+/gr_add_ss.i
+/gr_and_bb.cc
+/gr_and_bb.h
+/gr_and_bb.i
+/gr_and_ii.cc
+/gr_and_ii.h
+/gr_and_ii.i
+/gr_and_ss.cc
+/gr_and_ss.h
+/gr_and_ss.i
+/gr_argmax_fs.cc
+/gr_argmax_fs.h
+/gr_argmax_fs.i
+/gr_argmax_is.cc
+/gr_argmax_is.h
+/gr_argmax_is.i
+/gr_argmax_ss.cc
+/gr_argmax_ss.h
+/gr_argmax_ss.i
+/gr_chunks_to_symbols_bc.cc
+/gr_chunks_to_symbols_bc.h
+/gr_chunks_to_symbols_bc.i
+/gr_chunks_to_symbols_bf.cc
+/gr_chunks_to_symbols_bf.h
+/gr_chunks_to_symbols_bf.i
+/gr_chunks_to_symbols_ic.cc
+/gr_chunks_to_symbols_ic.h
+/gr_chunks_to_symbols_ic.i
+/gr_chunks_to_symbols_if.cc
+/gr_chunks_to_symbols_if.h
+/gr_chunks_to_symbols_if.i
+/gr_chunks_to_symbols_sc.cc
+/gr_chunks_to_symbols_sc.h
+/gr_chunks_to_symbols_sc.i
+/gr_chunks_to_symbols_sf.cc
+/gr_chunks_to_symbols_sf.h
+/gr_chunks_to_symbols_sf.i
+/gr_divide_cc.cc
+/gr_divide_cc.h
+/gr_divide_cc.i
+/gr_divide_ff.cc
+/gr_divide_ff.h
+/gr_divide_ff.i
+/gr_divide_ii.cc
+/gr_divide_ii.h
+/gr_divide_ii.i
+/gr_divide_ss.cc
+/gr_divide_ss.h
+/gr_divide_ss.i
+/gr_integrate_cc.cc
+/gr_integrate_cc.h
+/gr_integrate_cc.i
+/gr_integrate_ff.cc
+/gr_integrate_ff.h
+/gr_integrate_ff.i
+/gr_integrate_ii.cc
+/gr_integrate_ii.h
+/gr_integrate_ii.i
+/gr_integrate_ss.cc
+/gr_integrate_ss.h
+/gr_integrate_ss.i
+/gr_max_ff.cc
+/gr_max_ff.h
+/gr_max_ff.i
+/gr_max_ii.cc
+/gr_max_ii.h
+/gr_max_ii.i
+/gr_max_ss.cc
+/gr_max_ss.h
+/gr_max_ss.i
+/gr_multiply_cc.cc
+/gr_multiply_cc.h
+/gr_multiply_cc.i
+/gr_multiply_const_cc.cc
+/gr_multiply_const_cc.h
+/gr_multiply_const_cc.i
+/gr_multiply_const_ff.cc
+/gr_multiply_const_ff.h
+/gr_multiply_const_ff.i
+/gr_multiply_const_ii.cc
+/gr_multiply_const_ii.h
+/gr_multiply_const_ii.i
+/gr_multiply_const_ss.cc
+/gr_multiply_const_ss.h
+/gr_multiply_const_ss.i
+/gr_multiply_const_vcc.cc
+/gr_multiply_const_vcc.h
+/gr_multiply_const_vcc.i
+/gr_multiply_const_vff.cc
+/gr_multiply_const_vff.h
+/gr_multiply_const_vff.i
+/gr_multiply_const_vii.cc
+/gr_multiply_const_vii.h
+/gr_multiply_const_vii.i
+/gr_multiply_const_vss.cc
+/gr_multiply_const_vss.h
+/gr_multiply_const_vss.i
+/gr_multiply_ff.cc
+/gr_multiply_ff.h
+/gr_multiply_ff.i
+/gr_multiply_ii.cc
+/gr_multiply_ii.h
+/gr_multiply_ii.i
+/gr_multiply_ss.cc
+/gr_multiply_ss.h
+/gr_multiply_ss.i
+/gr_mute_cc.cc
+/gr_mute_cc.h
+/gr_mute_cc.i
+/gr_mute_ff.cc
+/gr_mute_ff.h
+/gr_mute_ff.i
+/gr_mute_ii.cc
+/gr_mute_ii.h
+/gr_mute_ii.i
+/gr_mute_ss.cc
+/gr_mute_ss.h
+/gr_mute_ss.i
+/gr_noise_source_c.cc
+/gr_noise_source_c.h
+/gr_noise_source_c.i
+/gr_noise_source_f.cc
+/gr_noise_source_f.h
+/gr_noise_source_f.i
+/gr_noise_source_i.cc
+/gr_noise_source_i.h
+/gr_noise_source_i.i
+/gr_noise_source_s.cc
+/gr_noise_source_s.h
+/gr_noise_source_s.i
+/gr_not_bb.cc
+/gr_not_bb.h
+/gr_not_bb.i
+/gr_not_ii.cc
+/gr_not_ii.h
+/gr_not_ii.i
+/gr_not_ss.cc
+/gr_not_ss.h
+/gr_not_ss.i
+/gr_or_bb.cc
+/gr_or_bb.h
+/gr_or_bb.i
+/gr_or_ii.cc
+/gr_or_ii.h
+/gr_or_ii.i
+/gr_or_ss.cc
+/gr_or_ss.h
+/gr_or_ss.i
+/gr_packed_to_unpacked_bb.cc
+/gr_packed_to_unpacked_bb.h
+/gr_packed_to_unpacked_bb.i
+/gr_packed_to_unpacked_ii.cc
+/gr_packed_to_unpacked_ii.h
+/gr_packed_to_unpacked_ii.i
+/gr_packed_to_unpacked_ss.cc
+/gr_packed_to_unpacked_ss.h
+/gr_packed_to_unpacked_ss.i
+/gr_peak_detector_fb.cc
+/gr_peak_detector_fb.h
+/gr_peak_detector_fb.i
+/gr_peak_detector_ff.cc
+/gr_peak_detector_ff.h
+/gr_peak_detector_ff.i
+/gr_peak_detector_ib.cc
+/gr_peak_detector_ib.h
+/gr_peak_detector_ib.i
+/gr_peak_detector_ii.cc
+/gr_peak_detector_ii.h
+/gr_peak_detector_ii.i
+/gr_peak_detector_sb.cc
+/gr_peak_detector_sb.h
+/gr_peak_detector_sb.i
+/gr_peak_detector_ss.cc
+/gr_peak_detector_ss.h
+/gr_peak_detector_ss.i
+/gr_prefix.cc
+/gr_sample_and_hold_bb.cc
+/gr_sample_and_hold_bb.h
+/gr_sample_and_hold_bb.i
+/gr_sample_and_hold_ff.cc
+/gr_sample_and_hold_ff.h
+/gr_sample_and_hold_ff.i
+/gr_sample_and_hold_ii.cc
+/gr_sample_and_hold_ii.h
+/gr_sample_and_hold_ii.i
+/gr_sample_and_hold_ss.cc
+/gr_sample_and_hold_ss.h
+/gr_sample_and_hold_ss.i
+/gr_sig_source_c.cc
+/gr_sig_source_c.h
+/gr_sig_source_c.i
+/gr_sig_source_f.cc
+/gr_sig_source_f.h
+/gr_sig_source_f.i
+/gr_sig_source_i.cc
+/gr_sig_source_i.h
+/gr_sig_source_i.i
+/gr_sig_source_s.cc
+/gr_sig_source_s.h
+/gr_sig_source_s.i
+/gr_sub_cc.cc
+/gr_sub_cc.h
+/gr_sub_cc.i
+/gr_sub_ff.cc
+/gr_sub_ff.h
+/gr_sub_ff.i
+/gr_sub_ii.cc
+/gr_sub_ii.h
+/gr_sub_ii.i
+/gr_sub_ss.cc
+/gr_sub_ss.h
+/gr_sub_ss.i
+/gr_unpacked_to_packed_bb.cc
+/gr_unpacked_to_packed_bb.h
+/gr_unpacked_to_packed_bb.i
+/gr_unpacked_to_packed_ii.cc
+/gr_unpacked_to_packed_ii.h
+/gr_unpacked_to_packed_ii.i
+/gr_unpacked_to_packed_ss.cc
+/gr_unpacked_to_packed_ss.h
+/gr_unpacked_to_packed_ss.i
+/gr_vector_sink_b.cc
+/gr_vector_sink_b.h
+/gr_vector_sink_b.i
+/gr_vector_sink_c.cc
+/gr_vector_sink_c.h
+/gr_vector_sink_c.i
+/gr_vector_sink_f.cc
+/gr_vector_sink_f.h
+/gr_vector_sink_f.i
+/gr_vector_sink_i.cc
+/gr_vector_sink_i.h
+/gr_vector_sink_i.i
+/gr_vector_sink_s.cc
+/gr_vector_sink_s.h
+/gr_vector_sink_s.i
+/gr_vector_source_b.cc
+/gr_vector_source_b.h
+/gr_vector_source_b.i
+/gr_vector_source_c.cc
+/gr_vector_source_c.h
+/gr_vector_source_c.i
+/gr_vector_source_f.cc
+/gr_vector_source_f.h
+/gr_vector_source_f.i
+/gr_vector_source_i.cc
+/gr_vector_source_i.h
+/gr_vector_source_i.i
+/gr_vector_source_s.cc
+/gr_vector_source_s.h
+/gr_vector_source_s.i
+/gr_xor_bb.cc
+/gr_xor_bb.h
+/gr_xor_bb.i
+/gr_xor_ii.cc
+/gr_xor_ii.h
+/gr_xor_ii.i
+/gr_xor_ss.cc
+/gr_xor_ss.h
+/gr_xor_ss.i
+/gr_moving_average_cc.cc
+/gr_moving_average_cc.h
+/gr_moving_average_cc.i
+/gr_moving_average_ff.cc
+/gr_moving_average_ff.h
+/gr_moving_average_ff.i
+/gr_moving_average_ss.cc
+/gr_moving_average_ss.h
+/gr_moving_average_ss.i
+/gr_moving_average_ii.cc
+/gr_moving_average_ii.h
+/gr_moving_average_ii.i
+/gr_and_const_bb.cc
+/gr_and_const_ss.h
+/gr_and_const_ss.i
+/gr_and_const_ii.cc
+/gr_and_const_bb.h
+/gr_and_const_ss.cc
+/gr_and_const_bb.i
+/gr_and_const_ii.h
+/gr_and_const_ii.i
+/# --- end generated files ---
+/stamp-*
+/gengen_generated.i
index db7bee02f2ab3ab3b1069b0d4b3a1734dac72c03..4978ad1c511325e2005a2752931a2ecad7d8e276 100644 (file)
@@ -135,11 +135,13 @@ grinclude_HEADERS =                       \
        gr_noise_type.h                 \
        gr_sig_source_waveform.h        
 
+if PYTHON
 swiginclude_HEADERS =                  \
        $(GENERATED_I)                  \
        gr_endianness.i                 \
        gengen.i                        \
        gengen_generated.i              
+endif
 
 # Do creation and inclusion of other Makefiles last
 
index b5fdf88fda24be741f5b59a2cd199f1da4831f44..7ba5ee9e93903fe04fce7d55136fb1696a79f7f2 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -50,7 +50,8 @@ class @NAME@ : public gr_sync_block {
                    gr_vector_const_void_star &input_items,
                    gr_vector_void_star &output_items);
 
-  void clear() {d_data.clear();}
+  void reset() {d_data.clear();}
+  void clear() {reset(); }             // deprecated
   std::vector<@TYPE@> data () const;
 };
 
index 22d6faa1aa73bb8789e1a9d131bb20b1002b9ff7..a49276a995662a1633531c5ce5e099834642b524 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -32,7 +32,8 @@ class @NAME@ : public gr_sync_block {
   @NAME@ (int vlen);
 
  public:
-  void clear() {d_data.clear();}
+  void clear();                        // deprecated
+  void reset();
   std::vector<@TYPE@> data () const;
 };
 
diff --git a/gnuradio-core/src/lib/gnuradio-config-info.cc b/gnuradio-core/src/lib/gnuradio-config-info.cc
new file mode 100644 (file)
index 0000000..6fa53b8
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_constants.h>
+#include <boost/program_options.hpp>
+#include <iostream>
+
+namespace po = boost::program_options;
+
+int
+main(int argc, char **argv)
+{
+  po::options_description desc("Program options: gnuradio [options]");
+  po::variables_map vm;
+
+  desc.add_options()
+    ("help,h", "print help message")
+    ("prefix", "print gnuradio installation prefix")
+    ("sysconfdir", "print gnuradio system configuration directory")
+    ("prefsdir", "print gnuradio preferences directory")
+    ("builddate", "print gnuradio build date (RFC2822 format)")
+    ("version,v", "print gnuradio version")
+    ;
+
+  po::store(po::parse_command_line(argc, argv, desc), vm);
+  po::notify(vm);
+
+  if (vm.size() == 0 || vm.count("help")) {
+    std::cout << desc << std::endl;
+    return 1;
+  }
+      
+  if (vm.count("prefix"))
+    std::cout << gr_prefix() << std::endl;
+
+  if (vm.count("sysconfdir"))
+    std::cout << gr_sysconfdir() << std::endl;
+
+  if (vm.count("prefsdir"))
+    std::cout << gr_prefsdir() << std::endl;
+
+  if (vm.count("builddate"))
+    std::cout << gr_build_date() << std::endl;
+
+  if (vm.count("version"))
+    std::cout << gr_version() << std::endl;
+
+  return 0;
+}
diff --git a/gnuradio-core/src/lib/hier/.gitignore b/gnuradio-core/src/lib/hier/.gitignore
new file mode 100644 (file)
index 0000000..89a768d
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
index b525d19b4f63c056c4c3289575125295204cf9fb..e2e7fe886ac6f4009bb00e6e0f9f119a672c40e9 100644 (file)
@@ -32,6 +32,8 @@ libhier_la_SOURCES = \
 grinclude_HEADERS = \
        gr_channel_model.h
 
+if PYTHON
 swiginclude_HEADERS = \
        hier.i \
        gr_channel_model.i
+endif
diff --git a/gnuradio-core/src/lib/io/.gitignore b/gnuradio-core/src/lib/io/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index 4583a033c88d9b4a7c0cb72316b9de0e19993865..c52554645779ef0d0f34398be28b7d86a4638ddb 100644 (file)
@@ -39,7 +39,6 @@ libio_la_SOURCES =                    \
        gr_oscope_guts.cc               \
        gr_oscope_sink_f.cc             \
        gr_oscope_sink_x.cc             \
-       gri_logger.cc                   \
        i2c.cc                          \
        i2c_bitbang.cc                  \
        i2c_bbio.cc                     \
@@ -72,7 +71,6 @@ grinclude_HEADERS =                   \
        gr_oscope_sink_f.h              \
        gr_oscope_sink_x.h              \
        gr_trigger_mode.h               \
-       gri_logger.h                    \
        i2c.h                           \
        i2c_bitbang.h                   \
        i2c_bbio.h                      \
@@ -93,9 +91,7 @@ grinclude_HEADERS =                   \
        gr_wavfile_sink.h               \
        gri_wavfile.h
 
-
-
-
+if PYTHON
 swiginclude_HEADERS =                  \
        io.i                            \
        gr_file_sink.i                  \
@@ -116,4 +112,4 @@ swiginclude_HEADERS =                       \
        gr_udp_source.i                 \
        gr_wavfile_source.i             \
        gr_wavfile_sink.i
-
+endif
index 29ac0dbb1dcb978dd1b433d12efa94ad822eab6f..5ddeeb4d5686fffc8aadfc0ca1e725ce95d03ffb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006,2007 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2007,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -31,6 +31,7 @@
 #include <fcntl.h>
 #include <stdexcept>
 #include <stdio.h>
+#include <gruel/thread.h>
 
 // win32 (mingw/msvc) specific
 #ifdef HAVE_IO_H
@@ -68,7 +69,7 @@ gr_file_sink_base::~gr_file_sink_base ()
 bool
 gr_file_sink_base::open(const char *filename)
 {
-  omni_mutex_lock      l(d_mutex);     // hold mutex for duration of this function
+  gruel::scoped_lock guard(d_mutex);   // hold mutex for duration of this function
 
   // we use the open system call to get access to the O_LARGEFILE flag.
   int fd;
@@ -96,7 +97,7 @@ gr_file_sink_base::open(const char *filename)
 void
 gr_file_sink_base::close()
 {
-  omni_mutex_lock      l(d_mutex);     // hold mutex for duration of this function
+  gruel::scoped_lock guard(d_mutex);   // hold mutex for duration of this function
 
   if (d_new_fp){
     fclose(d_new_fp);
@@ -109,7 +110,7 @@ void
 gr_file_sink_base::do_update()
 {
   if (d_updated){
-    omni_mutex_lock    l(d_mutex);     // hold mutex for duration of this block
+    gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block
     if (d_fp)
       fclose(d_fp);
     d_fp = d_new_fp;                   // install new file pointer
index f36f5ac978be203ec77d88f54aa1111b7239675d..0c028d7fd3adcf7413f688d68bf5e8aaca602321 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2007 Free Software Foundation, Inc.
+ * Copyright 2004,2007,2008 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #ifndef INCLUDED_GR_FILE_SINK_BASE_H
 #define INCLUDED_GR_FILE_SINK_BASE_H
 
-#include <gnuradio/omnithread.h>
+#include <boost/thread.hpp>
 #include <cstdio>
 
 /*!
@@ -36,7 +36,7 @@ class gr_file_sink_base
   FILE        *d_new_fp;       // new FILE pointer
   bool         d_updated;      // is there a new FILE pointer?
   bool         d_is_binary;
-  omni_mutex   d_mutex;
+  boost::mutex d_mutex;
 
  protected:
   gr_file_sink_base(const char *filename, bool is_binary);
index a923a7e45428529d11a0043ea425de6604249ba5..2885fe428a12575cfa04f4e59139b049885c763d 100644 (file)
@@ -53,7 +53,6 @@ gr_histo_sink_f::gr_histo_sink_f (gr_msg_queue_sptr msgq)
   : gr_sync_block ("histo_sink_f", gr_make_io_signature (1, 1, sizeof (float)), gr_make_io_signature (0, 0, 0)),
   d_msgq (msgq), d_num_bins(11), d_frame_size(1000), d_sample_count(0), d_bins(NULL), d_samps(NULL)
 {
-  pthread_mutex_init(&d_mutex, 0);
   //allocate arrays and clear
   set_num_bins(d_num_bins);
   set_frame_size(d_frame_size);
@@ -61,7 +60,6 @@ gr_histo_sink_f::gr_histo_sink_f (gr_msg_queue_sptr msgq)
 
 gr_histo_sink_f::~gr_histo_sink_f (void)
 {
-  pthread_mutex_destroy(&d_mutex);
   delete [] d_samps;
   delete [] d_bins;
 }
@@ -72,7 +70,7 @@ gr_histo_sink_f::work (int noutput_items,
   gr_vector_void_star &output_items)
 {
   const float *in = (const float *) input_items[0];
-  pthread_mutex_lock(&d_mutex);
+  gruel::scoped_lock guard(d_mutex);   // hold mutex for duration of this function
   for (unsigned int i = 0; i < (unsigned int)noutput_items; i++){
     d_samps[d_sample_count] = in[i];
     d_sample_count++;
@@ -82,7 +80,6 @@ gr_histo_sink_f::work (int noutput_items,
       clear();
     }
   }
-  pthread_mutex_unlock(&d_mutex);
   return noutput_items;
 }
 
@@ -148,22 +145,20 @@ gr_histo_sink_f::get_num_bins(void){
  **************************************************/
 void
 gr_histo_sink_f::set_frame_size(unsigned int frame_size){
-  pthread_mutex_lock(&d_mutex);
+  gruel::scoped_lock guard(d_mutex);   // hold mutex for duration of this function
   d_frame_size = frame_size;
   /* allocate a new sample array */
   delete [] d_samps;
   d_samps = new float[d_frame_size];
   clear();
-  pthread_mutex_unlock(&d_mutex);
 }
 
 void
 gr_histo_sink_f::set_num_bins(unsigned int num_bins){
-  pthread_mutex_lock(&d_mutex);
+  gruel::scoped_lock guard(d_mutex);   // hold mutex for duration of this function
   d_num_bins = num_bins;
   /* allocate a new bin array */
   delete [] d_bins;
   d_bins = new unsigned int[d_num_bins];
   clear();
-  pthread_mutex_unlock(&d_mutex);
 }
index 640398c60a4a1d960e132f42f436b16610b1c486..8ba45ec55cf5713856e8dd895c7bb37051b902b9 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <gr_sync_block.h>
 #include <gr_msg_queue.h>
-#include <pthread.h>
+#include <gruel/thread.h>
 
 class gr_histo_sink_f;
 typedef boost::shared_ptr<gr_histo_sink_f> gr_histo_sink_f_sptr;
@@ -45,7 +45,7 @@ private:
   unsigned int d_sample_count;
   unsigned int *d_bins;
   float *d_samps;
-  pthread_mutex_t d_mutex;
+  gruel::mutex d_mutex;
 
   friend gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
   gr_histo_sink_f (gr_msg_queue_sptr msgq);
index 3fbe3708eeb701519e285365af5486f5e1aec637..3efc5b3216c2eebf28c61bd5507abd57b6e1219a 100644 (file)
@@ -43,6 +43,13 @@ gr_make_message_source(size_t itemsize, int msgq_limit)
   return gr_message_source_sptr(new gr_message_source(itemsize, msgq_limit));
 }
 
+// public constructor that takes existing message queue
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq)
+{
+  return gr_message_source_sptr(new gr_message_source(itemsize, msgq));
+}
+
 gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
   : gr_sync_block("message_source",
                  gr_make_io_signature(0, 0, 0),
@@ -51,6 +58,14 @@ gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
 {
 }
 
+gr_message_source::gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq)
+  : gr_sync_block("message_source",
+                 gr_make_io_signature(0, 0, 0),
+                 gr_make_io_signature(1, 1, itemsize)),
+    d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false)
+{
+}
+
 gr_message_source::~gr_message_source()
 {
 }
index 5a5c6a5d863347f121660c59bca057f8752f80ff..46a808754c0f9830b551b0c43f4e97241f525fba 100644 (file)
@@ -31,6 +31,7 @@ class gr_message_source;
 typedef boost::shared_ptr<gr_message_source> gr_message_source_sptr;
 
 gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
 
 /*!
  * \brief Turn received messages into a stream
@@ -47,9 +48,12 @@ class gr_message_source : public gr_sync_block
 
   friend gr_message_source_sptr
   gr_make_message_source(size_t itemsize, int msgq_limit);
+  friend gr_message_source_sptr
+  gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq);
 
  protected:
   gr_message_source (size_t itemsize, int msgq_limit);
+  gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
 
  public:
   ~gr_message_source ();
index fdc74741e798755b3594b6a787987bb69e2425a5..8a9c762d0a0f4aaeb2a6838ae6e6a8373d96de2e 100644 (file)
 GR_SWIG_BLOCK_MAGIC(gr,message_source);
 
 gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
 
 class gr_message_source : public gr_sync_block
 {
  protected:
   gr_message_source (size_t itemsize, int msgq_limit);
+  gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
 
  public:
   ~gr_message_source ();
index 215eaf8d556c0a120f0ac49320617b860af8d806..3084a848be7a78c537af79e069703ca404533052 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_udp_sink.h>
 #include <gr_io_signature.h>
 #include <stdexcept>
-#if defined(HAVE_SOCKET)
-#include <netdb.h>
+#include <errno.h>
 #include <stdio.h>
+#include <string.h>
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>  //usually included by <netdb.h>?
+#endif
 typedef void* optval_t;
-#else
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
 #define SHUT_RDWR 2
-#define inet_aton(N,A) ( (A)->s_addr = inet_addr(N), ( (A)->s_addr != INADDR_NONE ) )
 typedef char* optval_t;
 #endif
 
+#include <gruel/thread.h>
+
 #define SNK_VERBOSE 0
 
-gr_udp_sink::gr_udp_sink (size_t itemsize, 
-                         const char *src, unsigned short port_src,
-                         const char *dst, unsigned short port_dst,
-                         int payload_size)
-  : gr_sync_block ("udp_sink",
-                  gr_make_io_signature (1, 1, itemsize),
-                  gr_make_io_signature (0, 0, 0)),
-    d_itemsize (itemsize), d_updated(false), d_payload_size(payload_size)
+static int is_error( int perr )
 {
-  int ret = 0;
-  
-  // Set up the address stucture for the source address and port numbers
-  // Get the source IP address from the host name
-  struct hostent *hsrc = gethostbyname(src);
-  if(hsrc) {   // if the source was provided as a host namex
-    d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0];    
+  // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+#define ECONNREFUSED 111
+  // All codes to be checked for must be defined below
+  int werr = WSAGetLastError();
+  switch( werr ) {
+  case WSAETIMEDOUT:
+    return( perr == EAGAIN );
+  case WSAENOPROTOOPT:
+    return( perr == ENOPROTOOPT );
+  case WSAECONNREFUSED:
+    return( perr == ECONNREFUSED );
+  default:
+    fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+    throw std::runtime_error("internal error");
   }
-  else { // assume it was specified as an IP address
-    if((ret=inet_aton(src, &d_ip_src)) == 0) {            // format IP address
-      perror("Not a valid source IP address or host name");
-      throw std::runtime_error("can't initialize source socket");
-    }
-  }
-
-  // Get the destination IP address from the host name
-  struct hostent *hdst = gethostbyname(dst);
-  if(hdst) {   // if the source was provided as a host namex
-    d_ip_dst = *(struct in_addr*)hdst->h_addr_list[0];    
-  }
-  else { // assume it was specified as an IP address
-    if((ret=inet_aton(dst, &d_ip_dst)) == 0) {            // format IP address
-      perror("Not a valid destination IP address or host name");
-      throw std::runtime_error("can't initialize destination socket");
-    }
-  }
-
-  d_port_src = htons(port_src);           // format port number
-  d_port_dst = htons(port_dst);           // format port number
-
-  d_sockaddr_src.sin_family = AF_INET;
-  d_sockaddr_src.sin_addr   = d_ip_src;
-  d_sockaddr_src.sin_port   = d_port_src;
-
-  d_sockaddr_dst.sin_family = AF_INET;
-  d_sockaddr_dst.sin_addr   = d_ip_dst;
-  d_sockaddr_dst.sin_port   = d_port_dst;
-  
-  open();
-}
-
-// public constructor that returns a shared_ptr
-
-gr_udp_sink_sptr
-gr_make_udp_sink (size_t itemsize, 
-                 const char *src, unsigned short port_src,
-                 const char *dst, unsigned short port_dst,
-                 int payload_size)
-{
-  return gr_udp_sink_sptr (new gr_udp_sink (itemsize, 
-                                           src, port_src,
-                                           dst, port_dst,
-                                           payload_size));
+  return 0;
+#else
+  return( perr == errno );
+#endif
 }
 
-gr_udp_sink::~gr_udp_sink ()
+static void report_error( const char *msg1, const char *msg2 )
 {
-  close();
+  // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+  int werr = WSAGetLastError();
+  fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+  perror(msg1);
+#endif
+  if( msg2 != NULL )
+    throw std::runtime_error(msg2);
+  return;
 }
 
-bool
-gr_udp_sink::open()
+gr_udp_sink::gr_udp_sink (size_t itemsize, 
+                         const char *host, unsigned short port,
+                         int payload_size, bool eof)
+  : gr_sync_block ("udp_sink",
+                  gr_make_io_signature (1, 1, itemsize),
+                  gr_make_io_signature (0, 0, 0)),
+    d_itemsize (itemsize), d_payload_size(payload_size), d_eof(eof),
+    d_socket(-1), d_connected(false)
 {
-  omni_mutex_lock l(d_mutex);  // hold mutex for duration of this function
-
-  // create socket
-  if((d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
-    perror("socket open");
-    throw std::runtime_error("can't open socket");
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+  // initialize winsock DLL
+  WSADATA wsaData;
+  int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+  if( iResult != NO_ERROR ) {
+    report_error( "gr_udp_source WSAStartup", "can't open socket" );
   }
+#endif
 
-  // Turn on reuse address
-  int opt_val = true;
-  if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) {
-    perror("SO_REUSEADDR");
-    throw std::runtime_error("can't set socket option SO_REUSEADDR");
+  // create socket
+  d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+  if(d_socket == -1) {
+    report_error("socket open","can't open socket");
   }
 
   // Don't wait when shutting down
@@ -130,36 +119,46 @@ gr_udp_sink::open()
   lngr.l_onoff  = 1;
   lngr.l_linger = 0;
   if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
-    perror("SO_LINGER");
-    throw std::runtime_error("can't set socket option SO_LINGER");
+    if( !is_error(ENOPROTOOPT) ) {  // no SO_LINGER for SOCK_DGRAM on Windows
+      report_error("SO_LINGER","can't set socket option SO_LINGER");
+    }
   }
 
-  // bind socket to an address and port number to listen on
-  if(bind (d_socket, (sockaddr*)&d_sockaddr_src, sizeof(struct sockaddr)) == -1) {
-    perror("socket bind");
-    throw std::runtime_error("can't bind socket");
-  }
+  // Get the destination address
+  connect(host, port);
+}
 
-  // Not sure if we should throw here or allow retries
-  if(connect(d_socket, (sockaddr*)&d_sockaddr_dst, sizeof(struct sockaddr)) == -1) {
-    perror("socket connect");
-    throw std::runtime_error("can't connect to socket");
-  }
+// public constructor that returns a shared_ptr
 
-  d_updated = true;
-  return d_socket != 0;
+gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize, 
+                 const char *host, unsigned short port,
+                 int payload_size, bool eof)
+{
+  return gr_udp_sink_sptr (new gr_udp_sink (itemsize, 
+                                           host, port,
+                                           payload_size, eof));
 }
 
-void
-gr_udp_sink::close()
+gr_udp_sink::~gr_udp_sink ()
 {
-  omni_mutex_lock l(d_mutex);  // hold mutex for duration of this function
+  if (d_connected)
+    disconnect();
 
-  if (d_socket){
+  if (d_socket != -1){
     shutdown(d_socket, SHUT_RDWR);
-    d_socket = 0;
+#if defined(USING_WINSOCK)
+    closesocket(d_socket);
+#else
+    ::close(d_socket);
+#endif
+    d_socket = -1;
   }
-  d_updated = true;
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+  // free winsock resources
+  WSACleanup();
+#endif
 }
 
 int 
@@ -172,21 +171,31 @@ gr_udp_sink::work (int noutput_items,
   ssize_t total_size = noutput_items*d_itemsize;
 
   #if SNK_VERBOSE
-  printf("Entered upd_sink\n");
+  printf("Entered udp_sink\n");
   #endif
 
+  gruel::scoped_lock guard(d_mutex);  // protect d_socket
+
   while(bytes_sent <  total_size) {
     bytes_to_send = std::min((ssize_t)d_payload_size, (total_size-bytes_sent));
   
-    r = send(d_socket, (in+bytes_sent), bytes_to_send, 0);
-    if(r == -1) {         // error on send command
-      perror("udp_sink"); // there should be no error case where this function 
-      return -1;          // should not exit immediately
+    if(d_connected) {
+      r = send(d_socket, (in+bytes_sent), bytes_to_send, 0);
+      if(r == -1) {         // error on send command
+       if( is_error(ECONNREFUSED) )
+         r = bytes_to_send;  // discard data until receiver is started
+       else {
+         report_error("udp_sink",NULL); // there should be no error case where
+         return -1;                  // this function should not exit immediately
+       }
+      }
     }
+    else
+      r = bytes_to_send;  // discarded for lack of connection
     bytes_sent += r;
     
     #if SNK_VERBOSE
-    printf("\tbyte sent: %d bytes\n", bytes);
+    printf("\tbyte sent: %d bytes\n", r);
     #endif
   }
 
@@ -196,3 +205,98 @@ gr_udp_sink::work (int noutput_items,
 
   return noutput_items;
 }
+
+void gr_udp_sink::connect( const char *host, unsigned short port )
+{
+  if(d_connected)
+    disconnect();
+
+  if(host != NULL ) {
+    // Get the destination address
+    struct addrinfo *ip_dst;
+    struct addrinfo hints;
+    memset( (void*)&hints, 0, sizeof(hints) );
+    hints.ai_family = AF_INET;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_protocol = IPPROTO_UDP;
+    char port_str[12];
+    sprintf( port_str, "%d", port );
+
+    // FIXME leaks if report_error throws below
+    int ret = getaddrinfo( host, port_str, &hints, &ip_dst );
+    if( ret != 0 )
+      report_error("gr_udp_source/getaddrinfo",
+                  "can't initialize destination socket" );
+
+    // don't need d_mutex lock when !d_connected
+    if(::connect(d_socket, ip_dst->ai_addr, ip_dst->ai_addrlen) == -1) {
+      report_error("socket connect","can't connect to socket");
+    }
+    d_connected = true;
+
+    freeaddrinfo(ip_dst);
+  }
+
+  return;
+}
+
+void gr_udp_sink::disconnect()
+{
+  if(!d_connected)
+    return;
+
+  #if SNK_VERBOSE
+  printf("gr_udp_sink disconnecting\n");
+  #endif
+
+  gruel::scoped_lock guard(d_mutex);  // protect d_socket from work()
+
+  // Send a few zero-length packets to signal receiver we are done
+  if(d_eof) {
+    int i;
+    for( i = 0; i < 3; i++ )
+      (void) send( d_socket, NULL, 0, 0 );  // ignore errors
+  }
+
+  // Sending EOF can produce ERRCONNREFUSED errors that won't show up
+  //  until the next send or recv, which might confuse us if it happens
+  //  on a new connection.  The following does a nonblocking recv to
+  //  clear any such errors.
+  timeval timeout;
+  timeout.tv_sec = 0;    // zero time for immediate return
+  timeout.tv_usec = 0;
+  fd_set readfds;
+  FD_ZERO(&readfds);
+  FD_SET(d_socket, &readfds);
+  int r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+  if(r < 0) {
+      #if SNK_VERBOSE
+      report_error("udp_sink/select",NULL);
+      #endif
+  }
+  else if(r > 0) {  // call recv() to get error return
+    r = recv(d_socket, (char*)&readfds, sizeof(readfds), 0);
+    if(r < 0) {
+       #if SNK_VERBOSE
+       report_error("udp_sink/recv",NULL);
+       #endif
+    }
+  }
+
+  // Since I can't find any way to disconnect a datagram socket in Cygwin,
+  // we just leave it connected but disable sending.
+#if 0
+  // zeroed address structure should reset connection
+  struct sockaddr addr;
+  memset( (void*)&addr, 0, sizeof(addr) );
+  // addr.sa_family = AF_UNSPEC;  // doesn't work on Cygwin
+  // addr.sa_family = AF_INET;  // doesn't work on Cygwin
+
+  if(::connect(d_socket, &addr, sizeof(addr)) == -1)
+    report_error("socket connect","can't connect to socket");
+#endif
+
+  d_connected = false;
+
+  return;
+}
index 13b2befc9efc08835d4c0bdaf9589d0482946be2..421d514a4db270872f218bddbc116cc8b293f054 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #define INCLUDED_GR_UDP_SINK_H
 
 #include <gr_sync_block.h>
-#include <gnuradio/omnithread.h>
-#if defined(HAVE_SOCKET)
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#elif defined(HAVE_WINDOWS_H)
-#include <winsock2.h>
-#include <windows.h>
-#endif
-#if defined(HAVE_NETINET_IN_H)
-#include <netinet/in.h>
-#endif
+#include <gruel/thread.h>
 
 class gr_udp_sink;
 typedef boost::shared_ptr<gr_udp_sink> gr_udp_sink_sptr;
 
 gr_udp_sink_sptr
 gr_make_udp_sink (size_t itemsize, 
-                 const char *src, unsigned short port_src,
-                 const char *dst, unsigned short port_dst,
-                 int payload_size=1472);
+                 const char *host, unsigned short port,
+                 int payload_size=1472, bool eof=true);
 
 /*!
  * \brief Write stream to an UDP socket.
  * \ingroup sink_blk
  * 
  * \param itemsize     The size (in bytes) of the item datatype
- * \param src          The source address as either the host name or the 'numbers-and-dots'
- *                     IP address
- * \param port_src     Destination port to bind to (0 allows socket to choose an appropriate port)
- * \param dst          The destination address as either the host name or the 'numbers-and-dots'
- *                     IP address
- * \param port_dst     Destination port to connect to
- * \param payload_size UDP payload size by default set to 
- *                     1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param host         The name or IP address of the receiving host; use
+ *                     NULL or None for no connection
+ * \param port         Destination port to connect to on receiving host
+ * \param payload_size UDP payload size by default set to 1472 =
+ *                     (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof          Send zero-length packet on disconnect
  */
 
 class gr_udp_sink : public gr_sync_block
 {
   friend gr_udp_sink_sptr gr_make_udp_sink (size_t itemsize, 
-                                           const char *src, unsigned short port_src,
-                                           const char *dst, unsigned short port_dst,
-                                           int payload_size);
+                                           const char *host,
+                                           unsigned short port,
+                                           int payload_size, bool eof);
  private:
   size_t       d_itemsize;
-  bool         d_updated;
-  omni_mutex   d_mutex;
 
-  int            d_payload_size;    // maximum transmission unit (packet length)
-  int            d_socket;          // handle to socket
-  int            d_socket_rcv;      // handle to socket retuned in the accept call
-  struct in_addr d_ip_src;          // store the source ip info
-  struct in_addr d_ip_dst;          // store the destination ip info
-  unsigned short d_port_src;        // the port number to open for connections to this service
-  unsigned short d_port_dst;        // port number of the remove system
-  struct sockaddr_in    d_sockaddr_src;    // store the source sockaddr data (formatted IP address and port number)
-  struct sockaddr_in    d_sockaddr_dst;    // store the destination sockaddr data (formatted IP address and port number)
+  int           d_payload_size;    // maximum transmission unit (packet length)
+  bool          d_eof;             // send zero-length packet on disconnect
+  int           d_socket;          // handle to socket
+  bool          d_connected;       // are we connected?
+  gruel::mutex  d_mutex;           // protects d_socket and d_connected
 
  protected:
   /*!
    * \brief UDP Sink Constructor
    * 
    * \param itemsize     The size (in bytes) of the item datatype
-   * \param src          The source address as either the host name or the 'numbers-and-dots'
-   *                     IP address
-   * \param port_src     Destination port to bind to (0 allows socket to choose an appropriate port)
-   * \param dst          The destination address as either the host name or the 'numbers-and-dots'
-   *                     IP address
-   * \param port_dst     Destination port to connect to
+   * \param host         The name or IP address of the receiving host; use
+   *                     NULL or None for no connection
+   * \param port         Destination port to connect to on receiving host
    * \param payload_size UDP payload size by default set to 
    *                     1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+   * \param eof          Send zero-length packet on disconnect
    */
   gr_udp_sink (size_t itemsize, 
-              const char *src, unsigned short port_src,
-              const char *dst, unsigned short port_dst,
-              int payload_size);
+              const char *host, unsigned short port,
+              int payload_size, bool eof);
 
  public:
   ~gr_udp_sink ();
 
-  /*!
-   * \brief open a socket specified by the port and ip address info
-   *
-   * Opens a socket, binds to the address, and makes connectionless association
-   * over UDP. If any of these fail, the fuction retuns the error and exits.
-   */
-  bool open();
+  /*! \brief return the PAYLOAD_SIZE of the socket */
+  int payload_size() { return d_payload_size; }
 
-  /*!
-   * \brief Close current socket.
+  /*! \brief Change the connection to a new destination
+   *
+   * \param host         The name or IP address of the receiving host; use
+   *                     NULL or None to break the connection without closing
+   * \param port         Destination port to connect to on receiving host
    *
-   * Shuts down read/write on the socket
+   * Calls disconnect() to terminate any current connection first.
    */
-  void close();
+  void connect( const char *host, unsigned short port );
 
-  /*! \brief return the PAYLOAD_SIZE of the socket */
-  int payload_size() { return d_payload_size; }
+  /*! \brief Send zero-length packet (if eof is requested) then stop sending
+   *
+   * Zero-byte packets can be interpreted as EOF by gr_udp_source.  Note that
+   * disconnect occurs automatically when the sink is destroyed, but not when
+   * its top_block stops.*/
+  void disconnect();
 
   // should we export anything else?
 
index 0f37b477b2c8f5a6b6512c67350a4d976bf4b53b..a71006ae03e9e47a200500f0339c0371d310c536 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -25,22 +25,22 @@ GR_SWIG_BLOCK_MAGIC(gr,udp_sink)
 
 gr_udp_sink_sptr 
 gr_make_udp_sink (size_t itemsize, 
-                 const char *src, unsigned short port_src,
-                 const char *dst, unsigned short port_dst,
-                 int payload_size=1472);
+                 const char *host, unsigned short port,
+                 int payload_size=1472, bool eof=true) throw (std::runtime_error);
 
 class gr_udp_sink : public gr_sync_block
 {
  protected:
   gr_udp_sink (size_t itemsize, 
-              const char *src, unsigned short port_src,
-              const char *dst, unsigned short port_dst,
-              int payload_size);
-
-  bool open();
-  void close();
-  int payload_size() { return d_payload_size; }
+              const char *host, unsigned short port,
+              int payload_size, bool eof) 
+    throw (std::runtime_error);
 
  public:
   ~gr_udp_sink ();
+
+  int payload_size() { return d_payload_size; }
+  void connect( const char *host, unsigned short port );
+  void disconnect();
+
 };
index 9b6ee6e7d8474a3580de629f1f57dabc735e52d4..fea9a26ba40083c3fb25768ed08badae5763fc1b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#if defined(HAVE_SOCKET)
+
+#if defined(HAVE_NETDB_H)
 #include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
 typedef void* optval_t;
-#else
+
+// ntohs() on FreeBSD may require both netinet/in.h and arpa/inet.h, in order
+#if defined(HAVE_NETINET_IN_H)
+#include <netinet/in.h>
+#endif
+#if defined(HAVE_ARPA_INET_H)
+#include <arpa/inet.h>
+#endif
+
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
 #define SHUT_RDWR 2
-#define inet_aton(N,A) ( (A)->s_addr = inet_addr(N), ( (A)->s_addr != INADDR_NONE ) )
 typedef char* optval_t;
 #endif
 
+#define USE_SELECT    1  // non-blocking receive on all platforms
+#define USE_RCV_TIMEO 0  // non-blocking receive on all but Cygwin
 #define SRC_VERBOSE 0
 
-gr_udp_source::gr_udp_source(size_t itemsize, const char *src, 
-                            unsigned short port_src, int payload_size)
+static int is_error( int perr )
+{
+  // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+  // All codes to be checked for must be defined below
+  int werr = WSAGetLastError();
+  switch( werr ) {
+  case WSAETIMEDOUT:
+    return( perr == EAGAIN );
+  case WSAENOPROTOOPT:
+    return( perr == ENOPROTOOPT );
+  default:
+    fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+    throw std::runtime_error("internal error");
+  }
+  return 0;
+#else
+  return( perr == errno );
+#endif
+}
+
+static void report_error( const char *msg1, const char *msg2 )
+{
+  // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+  int werr = WSAGetLastError();
+  fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+  perror(msg1);
+#endif
+  if( msg2 != NULL )
+    throw std::runtime_error(msg2);
+  return;
+}
+
+gr_udp_source::gr_udp_source(size_t itemsize, const char *host, 
+                            unsigned short port, int payload_size,
+                            bool eof, bool wait)
   : gr_sync_block ("udp_source",
                   gr_make_io_signature(0, 0, 0),
                   gr_make_io_signature(1, 1, itemsize)),
-    d_itemsize(itemsize), d_updated(false), d_payload_size(payload_size), d_residual(0), d_temp_offset(0)
+    d_itemsize(itemsize), d_payload_size(payload_size),
+    d_eof(eof), d_wait(wait), d_socket(-1), d_residual(0), d_temp_offset(0)
 {
   int ret = 0;
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+  // initialize winsock DLL
+  WSADATA wsaData;
+  int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+  if( iResult != NO_ERROR ) {
+    report_error( "gr_udp_source WSAStartup", "can't open socket" );
+  }
+#endif
   
   // Set up the address stucture for the source address and port numbers
   // Get the source IP address from the host name
-  struct hostent *hsrc = gethostbyname(src);
-  if(hsrc) {   // if the source was provided as a host namex
-    d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0];    
-  }
-  else { // assume it was specified as an IP address
-    if((ret=inet_aton(src, &d_ip_src)) == 0) {            // format IP address
-      perror("Not a valid source IP address or host name");
-      throw std::runtime_error("can't initialize source socket");
-    }
-  }
+  struct addrinfo *ip_src;      // store the source IP address to use
+  struct addrinfo hints;
+  memset( (void*)&hints, 0, sizeof(hints) );
+  hints.ai_family = AF_INET;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_protocol = IPPROTO_UDP;
+  hints.ai_flags = AI_PASSIVE;
+  char port_str[12];
+  sprintf( port_str, "%d", port );
 
-  d_port_src = htons(port_src);     // format port number
-  
-  d_sockaddr_src.sin_family = AF_INET;
-  d_sockaddr_src.sin_addr   = d_ip_src;
-  d_sockaddr_src.sin_port   = d_port_src;
+  // FIXME leaks if report_error throws below
+  ret = getaddrinfo( host, port_str, &hints, &ip_src );
+  if( ret != 0 )
+    report_error("gr_udp_source/getaddrinfo",
+                "can't initialize source socket" );
 
+  // FIXME leaks if report_error throws below
   d_temp_buff = new char[d_payload_size];   // allow it to hold up to payload_size bytes
-  
-  open();
-}
 
-gr_udp_source_sptr
-gr_make_udp_source (size_t itemsize, const char *ipaddr, 
-                   unsigned short port, int payload_size)
-{
-  return gr_udp_source_sptr (new gr_udp_source (itemsize, ipaddr, 
-                                               port, payload_size));
-}
-
-gr_udp_source::~gr_udp_source ()
-{
-  delete [] d_temp_buff;
-  close();
-}
-
-bool
-gr_udp_source::open()
-{
-  omni_mutex_lock l(d_mutex);  // hold mutex for duration of this function
   // create socket
-  d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+  d_socket = socket(ip_src->ai_family, ip_src->ai_socktype,
+                   ip_src->ai_protocol);
   if(d_socket == -1) {
-    perror("socket open");
-    throw std::runtime_error("can't open socket");
+    report_error("socket open","can't open socket");
   }
 
   // Turn on reuse address
   int opt_val = 1;
   if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) {
-    perror("SO_REUSEADDR");
-    throw std::runtime_error("can't set socket option SO_REUSEADDR");
+    report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR");
   }
 
   // Don't wait when shutting down
@@ -110,40 +156,61 @@ gr_udp_source::open()
   lngr.l_onoff  = 1;
   lngr.l_linger = 0;
   if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
-    perror("SO_LINGER");
-    throw std::runtime_error("can't set socket option SO_LINGER");
+    if( !is_error(ENOPROTOOPT) ) {  // no SO_LINGER for SOCK_DGRAM on Windows
+      report_error("SO_LINGER","can't set socket option SO_LINGER");
+    }
   }
 
+#if USE_RCV_TIMEO
   // Set a timeout on the receive function to not block indefinitely
   // This value can (and probably should) be changed
+  // Ignored on Cygwin
+#if defined(USING_WINSOCK)
+  DWORD timeout = 1000;  // milliseconds
+#else
   timeval timeout;
   timeout.tv_sec = 1;
   timeout.tv_usec = 0;
+#endif
   if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) {
-    perror("SO_RCVTIMEO");
-    throw std::runtime_error("can't set socket option SO_RCVTIMEO");
+    report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO");
   }
+#endif // USE_RCV_TIMEO
 
   // bind socket to an address and port number to listen on
-  if(bind (d_socket, (sockaddr*)&d_sockaddr_src, sizeof(struct sockaddr)) == -1) {
-    perror("socket bind");
-    throw std::runtime_error("can't bind socket");
+  if(bind (d_socket, ip_src->ai_addr, ip_src->ai_addrlen) == -1) {
+    report_error("socket bind","can't bind socket");
   }
-  
-  d_updated = true;
-  return d_socket != 0;
+  freeaddrinfo(ip_src);
+
 }
 
-void
-gr_udp_source::close()
+gr_udp_source_sptr
+gr_make_udp_source (size_t itemsize, const char *ipaddr, 
+                   unsigned short port, int payload_size, bool eof, bool wait)
 {
-  omni_mutex_lock l(d_mutex);  // hold mutex for duration of this function
+  return gr_udp_source_sptr (new gr_udp_source (itemsize, ipaddr, 
+                                               port, payload_size, eof, wait));
+}
+
+gr_udp_source::~gr_udp_source ()
+{
+  delete [] d_temp_buff;
 
-  if (d_socket){
+  if (d_socket != -1){
     shutdown(d_socket, SHUT_RDWR);
-    d_socket = 0;
+#if defined(USING_WINSOCK)
+    closesocket(d_socket);
+#else
+    ::close(d_socket);
+#endif
+    d_socket = -1;
   }
-  d_updated = true;
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+  // free winsock resources
+  WSACleanup();
+#endif
 }
 
 int 
@@ -175,29 +242,85 @@ gr_udp_source::work (int noutput_items,
     
     // Update indexing of amount of bytes left in the buffer
     d_residual -= nbytes;
-    d_temp_offset = d_temp_offset+d_residual;
+    d_temp_offset += nbytes;
+
+    // Return now with what we've got.
+    assert(nbytes % d_itemsize == 0);
+    return nbytes/d_itemsize;
   }
 
   while(1) {
     // get the data into our output buffer and record the number of bytes
+
+#if USE_SELECT
+    // RCV_TIMEO doesn't work on all systems (e.g., Cygwin)
+    // use select() instead of, or in addition to RCV_TIMEO
+    fd_set readfds;
+    timeval timeout;
+    timeout.tv_sec = 1;          // Init timeout each iteration.  Select can modify it.
+    timeout.tv_usec = 0;
+    FD_ZERO(&readfds);
+    FD_SET(d_socket, &readfds);
+    r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+    if(r < 0) {
+       report_error("udp_source/select",NULL);
+       return -1;
+    }
+    else if(r == 0 ) {  // timed out
+      if( d_wait ) {
+       // Allow boost thread interrupt, then try again
+       boost::this_thread::interruption_point();
+       continue;
+      }
+      else
+       return -1;
+    }
+#endif // USE_SELECT
+
     // This is a non-blocking call with a timeout set in the constructor
     r = recv(d_socket, d_temp_buff, d_payload_size, 0);  // get the entire payload or the what's available
 
+    // If r > 0, round it down to a multiple of d_itemsize 
+    // (If sender is broken, don't propagate problem)
+    if (r > 0)
+      r = (r/d_itemsize) * d_itemsize;
+
     // Check if there was a problem; forget it if the operation just timed out
     if(r == -1) {
-      if(errno == EAGAIN) {  // handle non-blocking call timeout
+      if( is_error(EAGAIN) ) {  // handle non-blocking call timeout
         #if SRC_VERBOSE
        printf("UDP receive timed out\n"); 
         #endif
 
-       // Break here to allow the rest of the flow graph time to run and so ctrl-C breaks
-       break;
+       if( d_wait ) {
+         // Allow boost thread interrupt, then try again
+         boost::this_thread::interruption_point();
+         continue;
+       }
+       else
+         return -1;
       }
       else {
-       perror("udp_source");
+       report_error("udp_source/recv",NULL);
        return -1;
       }
     }
+    else if(r==0) {
+      if(d_eof) {
+       // zero-length packet interpreted as EOF
+
+       #if SNK_VERBOSE
+       printf("\tzero-length packet received; returning EOF\n");
+       #endif
+
+       return -1;
+      }
+      else{
+       // do we need to allow boost thread interrupt?
+       boost::this_thread::interruption_point();
+       continue;
+      }
+    }
     else {
       // Calculate the number of bytes we can take from the buffer in this call
       nbytes = std::min(r, total_bytes-bytes_received);
@@ -235,3 +358,15 @@ gr_udp_source::work (int noutput_items,
   return bytes_received/d_itemsize;
 }
 
+// Return port number of d_socket
+int gr_udp_source::get_port(void)
+{
+  sockaddr_in name;
+  socklen_t len = sizeof(name);
+  int ret = getsockname( d_socket, (sockaddr*)&name, &len );
+  if( ret ) {
+    report_error("gr_udp_source/getsockname",NULL);
+    return -1;
+  }
+  return ntohs(name.sin_port);
+}
index afc41a45a23348a822e57aa0e70de02ff8b8afc6..5d30fad3045de4c7efc4189a5d6a1cab178e930a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #define INCLUDED_GR_UDP_SOURCE_H
 
 #include <gr_sync_block.h>
-#include <gnuradio/omnithread.h>
-#if defined(HAVE_SOCKET)
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#elif defined(HAVE_WINDOWS_H)
-#include <winsock2.h>
-#include <windows.h>
-#endif
-#if defined(HAVE_NETINET_IN_H)
-#include <netinet/in.h>
-#endif
+#include <gruel/thread.h>
 
 class gr_udp_source;
 typedef boost::shared_ptr<gr_udp_source> gr_udp_source_sptr;
 
-gr_udp_source_sptr gr_make_udp_source(size_t itemsize, const char *src, 
-                                     unsigned short port_src, int payload_size=1472);
+gr_udp_source_sptr gr_make_udp_source(size_t itemsize, const char *host, 
+                                     unsigned short port,
+                                     int payload_size=1472,
+                                     bool eof=true, bool wait=true);
 
 /*! 
  * \brief Read stream from an UDP socket.
  * \ingroup source_blk
  *
  * \param itemsize     The size (in bytes) of the item datatype
- * \param src          The source address as either the host name or the 'numbers-and-dots'
- *                     IP address
- * \param port_src     The port number on which the socket listens for data
- * \param payload_size UDP payload size by default set to 
- *                     1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param host         The name or IP address of the receiving host; can be
+ *                     NULL, None, or "0.0.0.0" to allow reading from any
+ *                     interface on the host
+ * \param port         The port number on which to receive data; use 0 to
+ *                     have the system assign an unused port number
+ * \param payload_size UDP payload size by default set to 1472 =
+ *                     (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof          Interpret zero-length packet as EOF (default: true)
+ * \param wait         Wait for data if not immediately available
+ *                     (default: true)
  *
 */
 
 class gr_udp_source : public gr_sync_block
 {
-  friend gr_udp_source_sptr gr_make_udp_source(size_t itemsize, const char *src, 
-                                              unsigned short port_src, int payload_size);
+  friend gr_udp_source_sptr gr_make_udp_source(size_t itemsize,
+                                              const char *host, 
+                                              unsigned short port,
+                                              int payload_size,
+                                              bool eof, bool wait);
 
  private:
   size_t       d_itemsize;
-  bool         d_updated;
-  omni_mutex   d_mutex;
-
-  int            d_payload_size;  // maximum transmission unit (packet length)
-  int            d_socket;        // handle to socket
-  int            d_socket_rcv;    // handle to socket retuned in the accept call
-  struct in_addr d_ip_src;        // store the source IP address to use
-  unsigned short d_port_src;      // the port number to open for connections to this service
-  struct sockaddr_in    d_sockaddr_src;  // store the source sockaddr data (formatted IP address and port number)
+  int           d_payload_size;  // maximum transmission unit (packet length)
+  bool          d_eof;           // zero-length packet is EOF
+  bool          d_wait;          // wait if data if not immediately available
+  int           d_socket;        // handle to socket
   char *d_temp_buff;    // hold buffer between calls
   ssize_t d_residual;   // hold information about number of bytes stored in the temp buffer
   size_t d_temp_offset; // point to temp buffer location offset
@@ -80,35 +75,29 @@ class gr_udp_source : public gr_sync_block
    * \brief UDP Source Constructor
    * 
    * \param itemsize     The size (in bytes) of the item datatype
-   * \param src          The source address as either the host name or the 'numbers-and-dots'
-   *                     IP address
-   * \param port_src     The port number on which the socket listens for data
-   * \param payload_size UDP payload size by default set to 
-   *                     1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+   * \param host         The name or IP address of the receiving host; can be
+   *                     NULL, None, or "0.0.0.0" to allow reading from any
+   *                     interface on the host
+   * \param port         The port number on which to receive data; use 0 to
+   *                     have the system assign an unused port number
+   * \param payload_size UDP payload size by default set to 1472 =
+   *                     (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+   * \param eof          Interpret zero-length packet as EOF (default: true)
+   * \param wait         Wait for data if not immediately available
+   *                     (default: true)
    */
-  gr_udp_source(size_t itemsize, const char *src, unsigned short port_src, int payload_size);
+  gr_udp_source(size_t itemsize, const char *host, unsigned short port,
+               int payload_size, bool eof, bool wait);
 
  public:
   ~gr_udp_source();
 
-  /*!
-   * \brief open a socket specified by the port and ip address info
-   *
-   * Opens a socket, binds to the address, and waits for a connection
-   * over UDP. If any of these fail, the fuction retuns the error and exits.
-   */
-  bool open();
-
-  /*!
-   * \brief Close current socket.
-   *
-   * Shuts down read/write on the socket
-   */
-  void close();
-
   /*! \brief return the PAYLOAD_SIZE of the socket */
   int payload_size() { return d_payload_size; }
 
+  /*! \brief return the port number of the socket */
+  int get_port();
+
   // should we export anything else?
 
   int work(int noutput_items,
index fb39dad68f509aed3635a445ea764c952db1c461..2001f33e9cc8ec3cd2cc2a22fe7af7acbd71e412 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 GR_SWIG_BLOCK_MAGIC(gr,udp_source)
 
 gr_udp_source_sptr 
-gr_make_udp_source (size_t itemsize, const char *src, 
-                   unsigned short port_src, int payload_size=1472);
+gr_make_udp_source (size_t itemsize, const char *host, 
+                   unsigned short port, int payload_size=1472,
+                   bool eof=true, bool wait=true) throw (std::runtime_error);
 
 class gr_udp_source : public gr_sync_block
 {
  protected:
-  gr_udp_source (size_t itemsize, const char *src
-                unsigned short port_src, int payload_size);
+  gr_udp_source (size_t itemsize, const char *host
+                unsigned short port, int payload_size, bool eof, bool wait) throw (std::runtime_error);
 
  public:
   ~gr_udp_source ();
 
-  bool open();
-  void close();
   int payload_size() { return d_payload_size; }
-
+  int get_port();
 };
index f06c33d5cd67e7135d4fd0a8874b02f60dd68b5a..72e4ef51e0721ccbd163e06ac577e3f5eaa91d30 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2007,2008,2009 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -32,6 +32,7 @@
 #include <cstring>
 #include <cmath>
 #include <fcntl.h>
+#include <gruel/thread.h>
 
 // win32 (mingw/msvc) specific
 #ifdef HAVE_IO_H
@@ -103,7 +104,7 @@ gr_wavfile_sink::gr_wavfile_sink(const char *filename,
 bool
 gr_wavfile_sink::open(const char* filename)
 {
-  omni_mutex_lock l(d_mutex);
+  gruel::scoped_lock guard(d_mutex);
   
   // we use the open system call to get access to the O_LARGEFILE flag.
   int fd;
@@ -141,7 +142,7 @@ gr_wavfile_sink::open(const char* filename)
 void
 gr_wavfile_sink::close()
 {
-  omni_mutex_lock l(d_mutex);
+  gruel::scoped_lock guard(d_mutex);
   
   if (!d_fp)
     return;
@@ -230,7 +231,7 @@ gr_wavfile_sink::convert_to_short(float sample)
 void
 gr_wavfile_sink::set_bits_per_sample(int bits_per_sample)
 {
-  omni_mutex_lock l(d_mutex);
+  gruel::scoped_lock guard(d_mutex);
   if (bits_per_sample == 8 || bits_per_sample == 16) {
     d_bytes_per_sample_new = bits_per_sample / 8;
   }
@@ -240,7 +241,7 @@ gr_wavfile_sink::set_bits_per_sample(int bits_per_sample)
 void
 gr_wavfile_sink::set_sample_rate(unsigned int sample_rate)
 {
-  omni_mutex_lock l(d_mutex);
+  gruel::scoped_lock guard(d_mutex);
   d_sample_rate = sample_rate;
 }
 
@@ -252,7 +253,7 @@ gr_wavfile_sink::do_update()
     return;
   }
   
-  omni_mutex_lock     l(d_mutex);     // hold mutex for duration of this block
+  gruel::scoped_lock guard(d_mutex);     // hold mutex for duration of this block
   if (d_fp) {
     close_wav();
   }
index fd1d0bf6f1c618c32edd9b000a8f1e674a364392..a1d6ed52713a9b42968afbd430b8037043564094 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -25,7 +25,7 @@
 
 #include <gr_sync_block.h>
 #include <gr_file_sink_base.h>
-#include <gnuradio/omnithread.h>
+#include <boost/thread.hpp>
 
 class gr_wavfile_sink;
 typedef boost::shared_ptr<gr_wavfile_sink> gr_wavfile_sink_sptr;
@@ -76,7 +76,7 @@ private:
   FILE *d_fp;
   FILE *d_new_fp;
   bool d_updated;
-  omni_mutex d_mutex;
+  boost::mutex d_mutex;
   
   /*!
    * \brief Convert a sample value within [-1;+1] to a corresponding
index c1a2b7c7373f497318d8ea370bb63f99b69a2d74..b8375edc20354bcd49576cb083a18edc17b60ae1 100644 (file)
@@ -32,8 +32,7 @@
 
 // WAV files are always little-endian, so we need some byte switching macros
 
-// FIXME: These need to be refactored into a separate endianess header file
-// as they duplicate routines defined in usrp/host/lib/legacy/usrp_bytesex.h
+// FIXME: Use libgruel versions
 
 #ifdef WORDS_BIGENDIAN
 
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board.i b/gnuradio-core/src/lib/io/microtune_eval_board.i
new file mode 100644 (file)
index 0000000..3ad7eb6
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+/*
+ * SWIG interface defs for Microtune 4937 and eval board with Eric's daughterboard
+ */
+
+/*!
+ * \brief abstract class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 {
+public:
+  microtune_4937 ();
+
+  virtual ~microtune_4937 ();
+
+  // returns actual freq or 0 if error (easier interface for SWIG)
+  double set_RF_freq (double freq);
+  
+  /*!
+   * \returns true iff PLL is locked
+   */
+  bool pll_locked_p ();
+  
+  /*!
+   * \returns the output frequency (IF center freq) of the tuner in Hz.
+   */
+  double get_output_freq ();
+
+
+ private:
+  //! \returns true iff successful
+  virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+  //! \returns number of bytes read or -1 if error
+  virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
+
+  int  d_reference_divider;
+  bool d_fast_tuning_p;        /* if set, higher charge pump current:
+                                  faster tuning, worse phase noise
+                                  for distance < 10kHz to the carrier */
+};
+
+/*!
+ * \brief concrete class for controlling microtune 4937 eval board attached to parallel port
+ */
+class microtune_eval_board : public microtune_4937 {
+public:
+  microtune_eval_board (int which_pp = 0);
+  ~microtune_eval_board ();
+
+  //! is the eval board present?
+  bool board_present_p ();
+
+  /*!
+   * \brief set RF and IF AGC control voltages ([0, 5] volts)
+   */
+  void set_RF_AGC_voltage (float volts);
+  void set_IF_AGC_voltage (float volts);
+
+  /*!
+   * \brief set RF and IF AGC levels together (scale [0, 1000])
+   *
+   * This provides a simple linear interface for adjusting both
+   * the RF and IF gain in consort.  This is the easy to use interface.
+   * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+   */
+  void set_AGC (float value_0_1000);
+
+private:
+  //! \returns true iff successful
+  virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
+
+  //! \returns number of bytes read or -1 if error
+  virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
+};
diff --git a/gnuradio-core/src/lib/missing/.gitignore b/gnuradio-core/src/lib/missing/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index 08e521cb362a04bff8d5ecb3e003a1ec1de49d9b..2383709101db330fa6f5cac5351b42a768b80372 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2003,2004,2008 Free Software Foundation, Inc.
+# Copyright 2003,2004,2008,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -33,6 +33,14 @@ EXTRA_DIST =                         \
 
 noinst_LTLIBRARIES = libmissing.la
 
-libmissing_la_SOURCES =        \
-       bug_work_around_8.cc    \
+libmissing_la_common_SOURCES = \
+       bug_work_around_8.cc
+
+powerpc_CODE = \
        posix_memalign.cc       
+
+if MD_CPU_powerpc
+libmissing_la_SOURCES = $(libmissing_la_common_SOURCES) $(powerpc_CODE)
+else
+libmissing_la_SOURCES = $(libmissing_la_common_SOURCES)
+endif
diff --git a/gnuradio-core/src/lib/reed-solomon/.gitignore b/gnuradio-core/src/lib/reed-solomon/.gitignore
new file mode 100644 (file)
index 0000000..f137f5c
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/rstest
diff --git a/gnuradio-core/src/lib/reed-solomon/Makefile.in.karn b/gnuradio-core/src/lib/reed-solomon/Makefile.in.karn
new file mode 100644 (file)
index 0000000..8550b41
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright 2002 Phil Karn, KA9Q
+# May be used under the terms of the GNU General Public License (GPL)
+# @configure_input@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix=@exec_prefix@
+VPATH = @srcdir@
+CC=@CC@
+
+CFLAGS=@CFLAGS@ @ARCH_OPTION@ -Wall
+
+LIB=   encode_rs_char.o encode_rs_int.o encode_rs_8.o \
+       decode_rs_char.o decode_rs_int.o decode_rs_8.o \
+       init_rs_char.o init_rs_int.o ccsds_tab.o \
+       encode_rs_ccsds.o decode_rs_ccsds.o ccsds_tal.o
+
+all: librs.a librs.so.@SO_VERSION@
+
+test: rstest
+       ./rstest
+
+rstest: rstest.o exercise_int.o exercise_char.o exercise_8.o exercise_ccsds.o \
+       librs.a
+       gcc -g -o $@ $^
+
+install: all
+       install -D -m 644 -p librs.a librs.so.@SO_VERSION@ @libdir@
+       (cd @libdir@;ln -f -s librs.so.@SO_VERSION@ librs.so)
+       ldconfig
+       install -m 644 -p rs.h @includedir@
+       install -m 644 rs.3 @mandir@/man3
+
+librs.a: $(LIB)
+       ar rv $@ $^
+
+librs.so.@SO_VERSION@: librs.a
+       gcc -shared -Xlinker -soname=librs.so.@SO_NAME@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive -lc
+
+encode_rs_char.o: encode_rs.c
+       gcc $(CFLAGS) -c -o $@ $^
+
+encode_rs_int.o: encode_rs.c
+       gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
+
+encode_rs_8.o: encode_rs.c
+       gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^
+
+decode_rs_char.o: decode_rs.c
+       gcc $(CFLAGS) -c -o $@ $^
+
+decode_rs_int.o: decode_rs.c
+       gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
+
+decode_rs_8.o: decode_rs.c
+       gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^
+
+init_rs_char.o: init_rs.c
+       gcc $(CFLAGS) -c -o $@ $^
+
+init_rs_int.o: init_rs.c
+       gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
+
+ccsds_tab.o: ccsds_tab.c
+
+ccsds_tab.c: gen_ccsds
+       ./gen_ccsds > ccsds_tab.c
+
+gen_ccsds: gen_ccsds.o init_rs_char.o
+       gcc -o $@ $^
+
+gen_ccsds.o: gen_ccsds.c
+       gcc  $(CFLAGS) -c -o $@ $^
+
+ccsds_tal.o: ccsds_tal.c
+
+ccsds_tal.c: gen_ccsds_tal
+       ./gen_ccsds_tal > ccsds_tal.c
+
+exercise_char.o: exercise.c
+       gcc $(CFLAGS) -c -o $@ $^
+
+exercise_int.o: exercise.c
+       gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
+
+exercise_8.o: exercise.c
+       gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^
+
+exercise_ccsds.o: exercise.c
+       gcc -DCCSDS=1 $(CFLAGS) -c -o $@ $^
+
+
+clean:
+       rm -f *.o *.a ccsds_tab.c ccsds_tal.c gen_ccsds gen_ccsds_tal \
+       rstest librs.so.@SO_VERSION@
+
+distclean: clean
+       rm -f config.log config.cache config.status config.h makefile
+
+
diff --git a/gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c b/gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c
new file mode 100644 (file)
index 0000000..2543d3a
--- /dev/null
@@ -0,0 +1,27 @@
+/* This function wraps around the fixed 8-bit decoder, performing the
+ * basis transformations necessary to meet the CCSDS standard
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define FIXED 1
+#include "fixed.h"
+#include "ccsds.h"
+
+int decode_rs_ccsds(unsigned char *data,int *eras_pos,int no_eras){
+  int i,r;
+  unsigned char cdata[NN];
+
+  /* Convert data from dual basis to conventional */
+  for(i=0;i<NN;i++)
+    cdata[i] = Tal1tab[data[i]];
+
+  r = decode_rs_8(cdata,eras_pos,no_eras);
+
+  if(r > 0){
+    /* Convert from conventional to dual basis */
+    for(i=0;i<NN;i++)
+      data[i] = Taltab[cdata[i]];
+  }
+  return r;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/encode_rs_ccsds.c b/gnuradio-core/src/lib/reed-solomon/encode_rs_ccsds.c
new file mode 100644 (file)
index 0000000..a748b34
--- /dev/null
@@ -0,0 +1,24 @@
+/* This function wraps around the fixed 8-bit encoder, performing the
+ * basis transformations necessary to meet the CCSDS standard
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define FIXED
+#include "fixed.h"
+#include "ccsds.h"
+
+void encode_rs_ccsds(unsigned char *data,unsigned char *parity){
+  int i;
+  unsigned char cdata[NN-NROOTS];
+
+  /* Convert data from dual basis to conventional */
+  for(i=0;i<NN-NROOTS;i++)
+    cdata[i] = Tal1tab[data[i]];
+
+  encode_rs_8(cdata,parity);
+
+  /* Convert parity from conventional to dual basis */
+  for(i=0;i<NN-NROOTS;i++)
+    parity[i] = Taltab[parity[i]];
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/gen_ccsds.c b/gnuradio-core/src/lib/reed-solomon/gen_ccsds.c
new file mode 100644 (file)
index 0000000..1e4e4f5
--- /dev/null
@@ -0,0 +1,34 @@
+/* Generate tables for CCSDS code
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <stdio.h>
+#include "char.h"
+
+int main(){
+  struct rs *rs;
+  int i;
+
+  rs = init_rs_char(8,0x187,112,11,32); /* CCSDS standard */
+  printf("unsigned char CCSDS_alpha_to[] = {");
+  for(i=0;i<256;i++){
+    if((i % 16) == 0)
+      printf("\n");
+    printf("0x%02x,",rs->alpha_to[i]);
+  }
+  printf("\n};\n\nunsigned char CCSDS_index_of[] = {");
+  for(i=0;i<256;i++){
+    if((i % 16) == 0)
+      printf("\n");
+    printf("%3d,",rs->index_of[i]);
+  }
+  printf("\n};\n\nunsigned char CCSDS_poly[] = {");
+  for(i=0;i<33;i++){
+    if((i % 16) == 0)
+      printf("\n");
+
+    printf("%3d,",rs->genpoly[i]);
+  }
+  printf("\n};\n");
+  exit(0);
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/gen_ccsds_tal.c b/gnuradio-core/src/lib/reed-solomon/gen_ccsds_tal.c
new file mode 100644 (file)
index 0000000..9dde189
--- /dev/null
@@ -0,0 +1,50 @@
+/* Conversion lookup tables from conventional alpha to Berlekamp's
+ * dual-basis representation. Used in the CCSDS version only.
+ * taltab[] -- convert conventional to dual basis
+ * tal1tab[] -- convert dual basis to conventional
+
+ * Note: the actual RS encoder/decoder works with the conventional basis.
+ * So data is converted from dual to conventional basis before either
+ * encoding or decoding and then converted back.
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <stdio.h>
+unsigned char Taltab[256],Tal1tab[256];
+
+static unsigned char tal[] = { 0x8d, 0xef, 0xec, 0x86, 0xfa, 0x99, 0xaf, 0x7b };
+
+/* Generate conversion lookup tables between conventional alpha representation
+ * (@**7, @**6, ...@**0)
+ *  and Berlekamp's dual basis representation
+ * (l0, l1, ...l7)
+ */
+int main(){
+  int i,j,k;
+
+  for(i=0;i<256;i++){/* For each value of input */
+    Taltab[i] = 0;
+    for(j=0;j<8;j++) /* for each column of matrix */
+      for(k=0;k<8;k++){ /* for each row of matrix */
+       if(i & (1<<k))
+          Taltab[i] ^= tal[7-k] & (1<<j);
+      }
+    Tal1tab[Taltab[i]] = i;
+  }
+  printf("unsigned char Taltab[] = {\n");
+  for(i=0;i<256;i++){
+    if((i % 16) == 0)
+      printf("\n");
+    printf("0x%02x,",Taltab[i]);
+  }
+  printf("\n};\n\nunsigned char Tal1tab[] = {");
+  for(i=0;i<256;i++){
+    if((i % 16) == 0)
+      printf("\n");
+    printf("0x%02x,",Tal1tab[i]);
+  }
+  printf("\n};\n");
+  exit(0);
+}
+
diff --git a/gnuradio-core/src/lib/reed-solomon/rs.3 b/gnuradio-core/src/lib/reed-solomon/rs.3
new file mode 100644 (file)
index 0000000..c3953ce
--- /dev/null
@@ -0,0 +1,170 @@
+.TH REED-SOLOMON 3
+.SH NAME
+init_rs_int, encode_rs_int, decode_rs_int, free_rs_int,
+init_rs_char, encode_rs_char, decode_rs_char, free_rs_char,
+encode_rs_8, decode_rs_8, encode_rs_ccsds, decode_rs_ccsds
+.SH SYNOPSIS
+.nf
+.ft B
+#include "rs.h"
+
+void *init_rs_int(unsigned int symsize,unsigned int gfpoly,unsigned fcr,
+unsigned prim,unsigned int nroots);
+void encode_rs_int(void *rs,int *data,int *parity);
+int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras);
+void free_rs_int(void *rs);
+
+void *init_rs_char(unsigned int symsize,unsigned int gfpoly,unsigned fcr,
+unsigned prim,unsigned int nroots);
+void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity);
+int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,int no_eras);
+void free_rs_char(void *rs);
+
+void encode_rs_8(unsigned char *data,unsigned char  *parity);
+int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras);
+
+void encode_rs_ccsds(unsigned char *data,unsigned char  *parity);
+int decode_rs_ccsds(unsigned char *data,int *eras_pos,int no_eras);
+
+unsigned char Taltab[256];
+unsigned char Tal1tab[256];
+
+.fi
+
+.SH DESCRIPTION
+These functions implement Reed-Solomon error control encoding and
+decoding. For optimal performance in a variety of applications, three
+sets of functions are supplied. To access these functions, add "-lrs"
+to your linker command line.
+
+The functions with names ending in "_int" handle data in integer arrays,
+permitting arbitrarily large codewords limited only by machine
+resources.
+
+The functions with names ending in "_char" take unsigned char arrays and can
+handle codes with symbols of 8 bits or less (i.e., with codewords of
+255 symbols or less).
+
+\fBencode_rs_8\fR and \fBdecode_rs_8\fR implement a specific
+(255,223) code with 8-bit symbols specified by the CCSDS:
+a field generator of 1 + X + X^2 + X^7 + X^8 and a code
+generator with first consecutive root = 112 and a primitive element of
+11. These functions use the conventional
+polynomial form, \fBnot\fR the dual-basis specified in
+the CCSDS standard, to represent symbols.
+
+For full CCSDS compatibility, \fBencode_rs_ccsds\fR and
+\fBdecode_rs_ccsds\fR are provided. These functions use two lookup
+tables, \fBTaltab\fR to convert from conventional to dual-basis, and
+\fBTal1tab\fR to perform the inverse mapping from dual-basis to
+conventional form, before and after calls to \fBencode_rs_8\fR
+and \fBdecode_rs_8\fR.
+
+The _8 and _ccsds functions do not require initialization.
+To use the general purpose RS encoder or decoder (i.e.,
+the _char or _int versions), the user must first
+call \fBinit_rs_int\fR or \fBinit_rs_char\fR as appropriate. The
+arguments are as follows:
+
+\fBsymsize\fR gives the symbol size in bits, up to 8 for \fBinit_rs_char\fR
+or 32 for \fBinit_rs_int\fR on a machine with 32-bit ints (though such a
+huge code would exhaust memory limits on a 32-bit machine). The resulting
+Reed-Solomon code word will have 2^\fBsymsize\fR - 1 symbols,
+each containing \fBsymsize\fR bits.
+
+\fBgfpoly\fR gives the extended Galois field generator polynomial coefficients,
+with the 0th coefficient in the low order bit. The polynomial
+\fImust\fR be primitive; if not, the call will fail and NULL will be
+returned.
+
+\fBfcr\fR gives, in index form, the first consecutive root of the
+Reed Solomon code generator polynomial.
+
+\fBprim\fR gives, in index form, the primitive element in the Galois field
+used to generate the Reed Solomon code generator polynomial.
+
+\fBnroots\fR gives the number of roots in the Reed Solomon code
+generator polynomial. This equals the number of parity symbols
+per code block.
+
+The resulting Reed-Solomon code has parameters (N,K), where
+N = 2^\fBsymsize\fR-1 and K = N-\fBnroots\fR.
+
+The \fBencode_rs_char\fR and \fBencode_rs_int\fR functions accept
+the pointer returned by \fBinit_rs_char\fR or
+\fBinit_rs_int\fR, respectively, to
+encode a block of data using the specified code.
+The input data array is expected to
+contain K symbols (of \fBsymsize\fR bits each, right justified
+in each char or int) and \fBnroots\fR parity symbols will be placed
+into the \fBparity\fR array, right justified.
+
+The \fBdecode_rs_char\fR and \fBdecode_rs_int\fR functions correct
+the errors in a Reed-Solomon codeword up to the capability of the code.
+An optional list of "erased" symbol indices may be given in the \fBeras_pos\fR
+array to assist the decoder; this parameter may be NULL if no erasures
+are given. The number of erased symbols must be given in the \fBno_eras\fR
+parameter.
+
+To maximize performance, the encode and decode functions perform no
+"sanity checking" of their inputs. Decoder failure may result if
+\fBeras_pos\fR contains duplicate entries, and both encoder and
+decoder will fail if an input symbol exceeds its allowable range.
+(Symbol range overflow cannot occur with the _8 or _ccsds functions,
+or with the _char functions when 8-bit symbols are specified.)
+
+The decoder corrects the symbols "in place", returning the number
+of symbols in error. If the codeword is uncorrectable, -1 is returned
+and the data block is unchanged. If \fBeras_pos\fR is non-null, it is
+used to return a list of corrected symbol positions, in no particular
+order.  This means that the
+array passed through this parameter \fImust\fR have at least \fBnroots\fR
+elements to prevent a possible buffer overflow.
+
+The \fBfree_rs_int\fR and \fBfree_rs_char\fR functions free the internal
+space allocated by the \fBinit_rs_int\fR and \fBinit_rs_char\fR functions,
+respecitively.
+
+The functions \fBencode_rs_8\fR and \fBdecode_rs_8\fR do not have
+corresponding \fBinit\fR and \fBfree\fR, nor do they take the
+\fBrs\fR argument accepted by the other functions as their parameters
+are statically compiled. These functions implement a code
+equivalent to calling
+
+\fBinit_rs_char\fR(8,0x187,112,11,32);
+
+and using the resulting pointer with \fBencode_rs_char\fR and
+\fBdecode_rs_char\fR.
+
+.SH RETURN VALUES
+\fBinit_rs_int\fR and \fBinit_rs_char\fR return a pointer to an internal
+control structure that must be passed to the corresponding encode, decode
+and free functions. These functions return NULL on error.
+
+The decode functions return a count of corrected
+symbols, or -1 if the block was uncorrectible.
+
+.SH AUTHOR
+Phil Karn, KA9Q (karn@ka9q.net), based heavily on earlier work by Robert
+Morelos-Zaragoza (rober@spectra.eng.hawaii.edu) and Hari Thirumoorthy
+(harit@spectra.eng.hawaii.edu).
+
+.SH COPYRIGHT
+Copyright 2002, Phil Karn, KA9Q. May be used under the terms of the
+GNU General Public License (GPL).
+
+.SH SEE ALSO
+CCSDS 101.0-B-5: Telemetry Channel Coding.
+http://www.ccsds.org/documents/pdf/CCSDS-101.0-B-5.pdf
+
+.SH NOTE
+CCSDS chose the "dual basis" symbol representation because it
+simplified the implementation of a Reed-Solomon encoder in dedicated
+hardware. However, this approach holds no advantages for a software
+implementation on a general purpose computer, so use of the dual basis
+is recommended only if compatibility with the CCSDS standard is needed,
+e.g., to decode data from an existing spacecraft using the CCSDS
+standard. If you just want a fast (255,223) RS codec without needing
+to interoperate with a CCSDS standard code, use \fBencode_rs_8\fR
+and \fBdecode_rs_8\fR.
+
diff --git a/gnuradio-core/src/lib/runtime/.gitignore b/gnuradio-core/src/lib/runtime/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index af5e4980d68ec91813d9bc6ddde7f251b06fe81a..b0e80427700c649efbb25bf0e674a96be839e775 100644 (file)
@@ -44,6 +44,7 @@ libruntime_la_SOURCES =                       \
        gr_io_signature.cc                      \
        gr_local_sighandler.cc                  \
        gr_message.cc                           \
+       gr_msg_accepter.cc                      \
        gr_msg_handler.cc                       \
        gr_msg_queue.cc                         \
        gr_pagesize.cc                          \
@@ -96,6 +97,7 @@ grinclude_HEADERS =                           \
        gr_io_signature.h                       \
        gr_local_sighandler.h                   \
        gr_message.h                            \
+       gr_msg_accepter.h                       \
        gr_msg_handler.h                        \
        gr_msg_queue.h                          \
        gr_pagesize.h                           \
@@ -135,6 +137,7 @@ noinst_HEADERS =                            \
        qa_gr_vmcircbuf.h                       \
        qa_runtime.h                            
 
+if PYTHON
 swiginclude_HEADERS =                  \
        gr_basic_block.i                \
        gr_block.i                      \
@@ -154,3 +157,4 @@ swiginclude_HEADERS =                       \
        gr_sync_interpolator.i          \
        gr_top_block.i                  \
        runtime.i
+endif
index e94e089e2fcdd7d49981c5cd0954974f2a086b92..2fa1066cb9b99f5045d48d5de7dbd4a059d0f582 100644 (file)
@@ -27,6 +27,8 @@
 #include <gr_basic_block.h>
 #include <stdexcept>
 
+using namespace pmt;
+
 static long s_next_id = 0;
 static long s_ncurrently_allocated = 0;
 
index faaba1c8313ed294ee9c0ca70e4256c1dd0ff2e9..b8797fdc678038d49075b0faf94cce8176ca5267 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006,2008 Free Software Foundation, Inc.
+ * Copyright 2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_runtime_types.h>
 #include <gr_sptr_magic.h>
 #include <boost/enable_shared_from_this.hpp>
+#include <gr_msg_accepter.h>
 #include <string>
 
 /*!
  * \brief The abstract base class for all signal processing blocks.
  * \ingroup internal
  *
- * Basic blocks are the bare abstraction of an entity that has a name
- * and a set of inputs and outputs.  These are never instantiated
+ * Basic blocks are the bare abstraction of an entity that has a name,
+ * a set of inputs and outputs, and a message queue.  These are never instantiated
  * directly; rather, this is the abstract parent class of both gr_hier_block,
  * which is a recursive container, and gr_block, which implements actual
  * signal processing functions.
  */
 
-class gr_basic_block : public boost::enable_shared_from_this<gr_basic_block>
+class gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block>
 {
 protected:
     friend class gr_flowgraph;
@@ -96,6 +97,17 @@ public:
      * and output gr_io_signatures.
      */
     virtual bool check_topology(int ninputs, int noutputs) { return true; }
+
+    /*!
+     * \brief Block message handler.
+     * 
+     * \param msg  Arbitrary message encapsulated as pmt::pmt_t
+     *
+     * This function is called by the runtime system whenever there are
+     * messages in its queue.  Blocks should override this to receive
+     * messages; the default behavior is to drop them on the floor.
+     */
+    virtual void handle_msg(pmt::pmt_t msg) { };
 };
 
 inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs)
index b8b1bd9c73ac9db1c5449f8e6792039d11337e21..8915f3360fb56c9a6c6459bd3565bee82ffaba7b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -99,6 +99,12 @@ gr_block::consume_each (int how_many_items)
   d_detail->consume_each (how_many_items);
 }
 
+void
+gr_block::produce (int which_output, int how_many_items)
+{
+  d_detail->produce (which_output, how_many_items);
+}
+
 int
 gr_block::fixed_rate_ninput_to_noutput(int ninput)
 {
index 354695c0b70bb9de3d6b27a7d66310e6f58c54d7..b6f724dde0a89bc79629602209b0baf710ef6a10 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2007 Free Software Foundation, Inc.
+ * Copyright 2004,2007,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -57,6 +57,12 @@ class gr_block : public gr_basic_block {
 
  public:
   
+  //! Magic return values from general_work
+  enum {
+    WORK_CALLED_PRODUCE = -2,
+    WORK_DONE = -1
+  };
+
   virtual ~gr_block ();
 
   /*!
@@ -70,7 +76,7 @@ class gr_block : public gr_basic_block {
   void  set_history (unsigned history) { d_history = history; }
   
   /*!
-   * \brief return true if this block has a fixed input to output rate
+   * \brief Return true if this block has a fixed input to output rate.
    *
    * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
    */
@@ -149,6 +155,13 @@ class gr_block : public gr_basic_block {
    */
   void consume_each (int how_many_items);
 
+  /*!
+   * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
+   *
+   * If the block's general_work method calls produce, \p general_work must return WORK_CALLED_PRODUCE.
+   */
+  void produce (int which_output, int how_many_items);
+
   /*!
    * \brief Set the approximate output rate / input rate
    *
@@ -191,7 +204,7 @@ class gr_block : public gr_basic_block {
 
   int                   d_output_multiple;
   double                d_relative_rate;       // approx output_rate / input_rate
-  gr_block_detail_sptr d_detail;                   // implementation details
+  gr_block_detail_sptr d_detail;               // implementation details
   unsigned              d_history;
   bool                  d_fixed_rate;
     
index ae1ea25628d63631df41dcd4924fa85cdfa1a8ed..38d4a13ca57cb48c03a33f364a03a9d8d192d700 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -36,7 +36,8 @@ gr_block_detail_ncurrently_allocated ()
 }
 
 gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
-  : d_ninputs (ninputs), d_noutputs (noutputs),
+  : d_produce_or(0),
+    d_ninputs (ninputs), d_noutputs (noutputs),
     d_input (ninputs), d_output (noutputs),
     d_done (false)
 {
@@ -99,10 +100,28 @@ gr_block_detail::consume_each (int how_many_items)
       d_input[i]->update_read_pointer (how_many_items);
 }
 
+void
+gr_block_detail::produce (int which_output, int how_many_items)
+{
+  if (how_many_items > 0){
+    d_output[which_output]->update_write_pointer (how_many_items);
+    d_produce_or |= how_many_items;
+  }
+}
+
 void
 gr_block_detail::produce_each (int how_many_items)
 {
-  if (how_many_items > 0)
+  if (how_many_items > 0){
     for (int i = 0; i < noutputs (); i++)
       d_output[i]->update_write_pointer (how_many_items);
+    d_produce_or |= how_many_items;
+  }
+}
+
+
+void
+gr_block_detail::_post(pmt::pmt_t msg)
+{
+  d_tpb.insert_tail(msg);
 }
index 2856c402c7a7925a5d8f762adc9d2eb7f5861633..c5787a5ad0fd56c72656be3ed69c5406369df227 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -73,13 +73,23 @@ class gr_block_detail {
    */
   void consume_each (int how_many_items);
 
+  /*!
+   * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
+   */
+  void produce (int which_output, int how_many_items);
+
   /*!
    * \brief Tell the scheduler \p how_many_items were produced on each output stream.
    */
   void produce_each (int how_many_items);
 
+  /*!
+   * Accept msg, place in queue, arrange for thread to be awakened if it's not already.
+   */
+  void _post(pmt::pmt_t msg);
 
   gr_tpb_detail                             d_tpb;     // used by thread-per-block scheduler
+  int                               d_produce_or;
 
   // ----------------------------------------------------------------------------
 
index fd3a916d4a03e954e9316b0668c3189a2550f007..2c21a0b0f26815b764bf5df89ca5789d1be671b3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -68,7 +68,7 @@ min_available_space (gr_block_detail *d, int output_multiple)
   int  min_space = std::numeric_limits<int>::max();
 
   for (int i = 0; i < d->noutputs (); i++){
-    gr_buffer::scoped_lock guard(*d->output(i)->mutex());
+    gruel::scoped_lock guard(*d->output(i)->mutex());
 #if 0
     int n = round_down(d->output(i)->space_available(), output_multiple);
 #else
@@ -163,7 +163,7 @@ gr_block_executor::run_one_iteration()
        /*
         * Acquire the mutex and grab local copies of items_available and done.
         */
-       gr_buffer::scoped_lock guard(*d->input(i)->mutex());
+       gruel::scoped_lock guard(*d->input(i)->mutex());
        d_ninput_items[i] = d->input(i)->items_available();
        d_input_done[i] = d->input(i)->done();
       }
@@ -205,7 +205,7 @@ gr_block_executor::run_one_iteration()
        /*
         * Acquire the mutex and grab local copies of items_available and done.
         */
-       gr_buffer::scoped_lock guard(*d->input(i)->mutex());
+       gruel::scoped_lock guard(*d->input(i)->mutex());
        d_ninput_items[i] = d->input(i)->items_available ();
        d_input_done[i] = d->input(i)->done();
       }
@@ -290,6 +290,7 @@ gr_block_executor::run_one_iteration()
 
   setup_call_to_work:
 
+    d->d_produce_or = 0;
     for (int i = 0; i < d->noutputs (); i++)
       d_output_items[i] = d->output(i)->write_pointer();
 
@@ -299,11 +300,13 @@ gr_block_executor::run_one_iteration()
     LOG(*d_log << "  general_work: noutput_items = " << noutput_items
        << " result = " << n << std::endl);
 
-    if (n == -1)               // block is done
+    if (n == gr_block::WORK_DONE)
       goto were_done;
 
-    d->produce_each (n);       // advance write pointers
-    if (n > 0)
+    if (n != gr_block::WORK_CALLED_PRODUCE)
+      d->produce_each (n);     // advance write pointers
+    
+    if (d->d_produce_or > 0)   // block produced something
       return READY;
 
     // We didn't produce any output even though we called general_work.
@@ -312,7 +315,7 @@ gr_block_executor::run_one_iteration()
     // If this is a source, it's broken.
     if (d->source_p()){
       std::cerr << "gr_block_executor: source " << m
-               << " returned 0 from work.  We're marking it DONE.\n";
+               << " produced no output.  We're marking it DONE.\n";
       // FIXME maybe we ought to raise an exception...
       goto were_done;
     }
index 31a471ea75273fd607388576775c66ab7be8d319..db2db5d6d7a4b6e3f2b7399f63d5f273c5815d25 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -175,14 +175,14 @@ gr_buffer::write_pointer ()
 void
 gr_buffer::update_write_pointer (int nitems)
 {
-  scoped_lock  guard(*mutex());
+  gruel::scoped_lock guard(*mutex());
   d_write_index = index_add (d_write_index, nitems);
 }
 
 void
 gr_buffer::set_done (bool done)
 {
-  scoped_lock  guard(*mutex());
+  gruel::scoped_lock guard(*mutex());
   d_done = done;
 }
 
@@ -251,7 +251,7 @@ gr_buffer_reader::read_pointer ()
 void
 gr_buffer_reader::update_read_pointer (int nitems)
 {
-  scoped_lock  guard(*mutex());
+  gruel::scoped_lock guard(*mutex());
   d_read_index = d_buffer->index_add (d_read_index, nitems);
 }
 
index cb593eea3453b7c8e6401922f050626acf9558aa..207bfe7c58954d588318d3b3be75292642038c6d 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -25,7 +25,7 @@
 
 #include <gr_runtime_types.h>
 #include <boost/weak_ptr.hpp>
-#include <boost/thread.hpp>
+#include <gruel/thread.h>
 
 class gr_vmcircbuf;
 
@@ -50,8 +50,6 @@ gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr lin
 class gr_buffer {
  public:
 
-  typedef boost::unique_lock<boost::mutex>  scoped_lock;
-
   virtual ~gr_buffer ();
 
   /*!
@@ -88,7 +86,7 @@ class gr_buffer {
   size_t nreaders() const { return d_readers.size(); }
   gr_buffer_reader* reader(size_t index) { return d_readers[index]; }
 
-  boost::mutex *mutex() { return &d_mutex; }
+  gruel::mutex *mutex() { return &d_mutex; }
 
   // -------------------------------------------------------------------------
 
@@ -110,7 +108,7 @@ class gr_buffer {
   //
   // The mutex protects d_write_index, d_done and the d_read_index's in the buffer readers.
   //
-  boost::mutex                         d_mutex;
+  gruel::mutex                         d_mutex;
   unsigned int                         d_write_index;  // in items [0,d_bufsize)
   bool                                 d_done;
   
@@ -185,8 +183,6 @@ long gr_buffer_ncurrently_allocated ();
 class gr_buffer_reader {
  public:
 
-  typedef gr_buffer::scoped_lock scoped_lock;
-
   ~gr_buffer_reader ();
 
   /*!
@@ -221,7 +217,7 @@ class gr_buffer_reader {
   void set_done (bool done)   { d_buffer->set_done (done); }
   bool done () const { return d_buffer->done (); }
 
-  boost::mutex *mutex() { return d_buffer->mutex(); }
+  gruel::mutex *mutex() { return d_buffer->mutex(); }
 
 
   /*!
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc
new file mode 100644 (file)
index 0000000..89876ae
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_msg_accepter.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_hier_block2.h>
+#include <stdexcept>
+
+using namespace pmt;
+
+gr_msg_accepter::gr_msg_accepter()
+{
+}
+
+gr_msg_accepter::~gr_msg_accepter()
+{
+  // NOP, required as virtual destructor
+}
+
+void
+gr_msg_accepter::post(pmt_t msg)
+{
+  // Notify derived class, handled case by case
+  gr_block *p = dynamic_cast<gr_block *>(this);
+  if (p) { 
+    p->detail()->_post(msg);
+    return;
+  }
+  gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this);
+  if (p2){
+    // FIXME do the right thing
+    return;
+  }
+
+  throw std::runtime_error("unknown derived class");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.h b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h
new file mode 100644 (file)
index 0000000..79a631f
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_MSG_ACCEPTER_H
+#define INCLUDED_GR_MSG_ACCEPTER_H
+
+#include <gruel/msg_accepter.h>
+#include <gruel/pmt.h>
+
+/*!
+ * \brief Accepts messages and inserts them into a message queue, then notifies
+ * subclass gr_basic_block there is a message pending.
+ */
+class gr_msg_accepter : public gruel::msg_accepter
+{
+public:
+  gr_msg_accepter();
+  ~gr_msg_accepter();
+
+  void post(pmt::pmt_t msg);
+
+};
+
+#endif /* INCLUDED_GR_MSG_ACCEPTER_H */
index 922eeda03cff5aa80a0e0c5d6f41c1be2c992ad1..3097acc9eecd96ccce1cf1ede1fd0e51112174bb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_msg_queue.h>
 #include <stdexcept>
 
-
 gr_msg_queue_sptr
 gr_make_msg_queue(unsigned int limit)
 {
   return gr_msg_queue_sptr (new gr_msg_queue(limit));
 }
 
-
 gr_msg_queue::gr_msg_queue(unsigned int limit)
-  : d_not_empty(&d_mutex), d_not_full(&d_mutex),
+  : d_not_empty(), d_not_full(),
     /*d_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
 {
 }
@@ -51,10 +49,10 @@ gr_msg_queue::insert_tail(gr_message_sptr msg)
   if (msg->d_next)
     throw std::invalid_argument("gr_msg_queue::insert_tail: msg already in queue");
 
-  omni_mutex_lock      l(d_mutex);
+  gruel::scoped_lock guard(d_mutex);
 
   while (full_p())
-    d_not_full.wait();
+    d_not_full.wait(guard);
 
   if (d_tail == 0){
     d_tail = d_head = msg;
@@ -68,17 +66,17 @@ gr_msg_queue::insert_tail(gr_message_sptr msg)
     msg->d_next.reset();
   }
   d_count++;
-  d_not_empty.signal();
+  d_not_empty.notify_one();
 }
 
 gr_message_sptr
 gr_msg_queue::delete_head()
 {
-  omni_mutex_lock      l(d_mutex);
-  gr_message_sptr      m;
+  gruel::scoped_lock guard(d_mutex);
+  gr_message_sptr m;
 
   while ((m = d_head) == 0)
-    d_not_empty.wait();
+    d_not_empty.wait(guard);
 
   d_head = m->d_next;
   if (d_head == 0){
@@ -89,15 +87,15 @@ gr_msg_queue::delete_head()
   d_count--;
   // m->d_next = 0;
   m->d_next.reset();
-  d_not_full.signal();
+  d_not_full.notify_one();
   return m;
 }
 
 gr_message_sptr
 gr_msg_queue::delete_head_nowait()
 {
-  omni_mutex_lock      l(d_mutex);
-  gr_message_sptr      m;
+  gruel::scoped_lock guard(d_mutex);
+  gr_message_sptr m;
 
   if ((m = d_head) == 0){
     //return 0;
@@ -113,7 +111,7 @@ gr_msg_queue::delete_head_nowait()
   d_count--;
   //m->d_next = 0;
   m->d_next.reset();
-  d_not_full.signal();
+  d_not_full.notify_one();
   return m;
 }
 
index f965887e16454d63709833e23e18c65c32a49400..477b1ddf1ba0588925b1db957a1635fd7e299a55 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #define INCLUDED_GR_MSG_QUEUE_H
 
 #include <gr_msg_handler.h>
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
 
 class gr_msg_queue;
 typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
@@ -35,13 +35,14 @@ gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0);
  * \ingroup misc
  */
 class gr_msg_queue : public gr_msg_handler {
-  omni_mutex           d_mutex;
-  omni_condition       d_not_empty;
-  omni_condition       d_not_full;
-  gr_message_sptr      d_head;
-  gr_message_sptr      d_tail;
-  unsigned int         d_count;    // # of messages in queue.
-  unsigned int         d_limit;    // max # of messages in queue.  0 -> unbounded
+
+  gruel::mutex             d_mutex;
+  gruel::condition_variable d_not_empty;
+  gruel::condition_variable d_not_full;
+  gr_message_sptr          d_head;
+  gr_message_sptr          d_tail;
+  unsigned int             d_count;    // # of messages in queue.
+  unsigned int             d_limit;    // max # of messages in queue.  0 -> unbounded
 
 public:
   gr_msg_queue(unsigned int limit);
index 254a7a940c2ea0b276dbd3efa8f81f4b80453587..9ca92b6ec8cded6c384b0b0c0543aafedd8939ef 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -32,12 +32,6 @@ gr_msg_queue_sptr gr_make_msg_queue(unsigned limit=0);
  */
 %ignore gr_msg_queue;
 class gr_msg_queue : public gr_msg_handler {
-  omni_mutex           d_mutex;
-  omni_condition       d_cond;
-  gr_message_sptr      d_head;
-  gr_message_sptr      d_tail;
-  int                  d_count;
-
 public:
   gr_msg_queue(unsigned int limit);
   ~gr_msg_queue();
index 3295f849e42a331553c2366d3371b9cfe91f05a1..96ffae85fe9a5bcef671b62919ff1652facdd33f 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <stdexcept>
 
 
-#if 0
-  #include <boost/thread.hpp>
-  typedef boost::mutex                 mutex;
-  typedef boost::mutex::scoped_lock    scoped_lock;
-#else
-  #include <gnuradio/omnithread.h>
-  typedef omni_mutex                   mutex;
-  typedef omni_mutex_lock              scoped_lock;
-#endif
+#include <gruel/thread.h>
 
 namespace gnuradio {
 
-  static mutex         s_mutex;
+  static gruel::mutex  s_mutex;
   typedef std::map<gr_basic_block*, gr_basic_block_sptr> sptr_map;
   static sptr_map      s_map;
 
@@ -47,7 +39,7 @@ namespace gnuradio {
   detail::sptr_magic::create_and_stash_initial_sptr(gr_hier_block2 *p)
   {
     gr_basic_block_sptr sptr(p);
-    scoped_lock        l();
+    gruel::scoped_lock guard();
     s_map.insert(sptr_map::value_type(static_cast<gr_basic_block *>(p), sptr));
   }
 
@@ -68,7 +60,7 @@ namespace gnuradio {
      * p is a subclass of gr_hier_block2, thus we've already created the shared pointer
      * and stashed it away.  Fish it out and return it.
      */
-    scoped_lock        l();
+    gruel::scoped_lock guard();
     sptr_map::iterator pos = s_map.find(static_cast<gr_basic_block *>(p));
     if (pos == s_map.end())
       throw std::invalid_argument("gr_sptr_magic: invalid pointer!");
@@ -78,4 +70,3 @@ namespace gnuradio {
     return sptr;
   }
 };
-
index 50d480d009e80875b02744740e84917837a33e0e..9cad687fb55f4f685fa4373564c072b5a265218f 100644 (file)
@@ -90,7 +90,7 @@ gr_top_block_impl::~gr_top_block_impl()
 void
 gr_top_block_impl::start()
 {
-  gr_lock_guard        l(d_mutex);
+  gruel::scoped_lock   l(d_mutex);
 
   if (d_state != IDLE)
     throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
@@ -131,14 +131,14 @@ gr_top_block_impl::wait()
 void
 gr_top_block_impl::lock()
 {
-  gr_lock_guard lock(d_mutex);
+  gruel::scoped_lock lock(d_mutex);
   d_lock_count++;
 }
 
 void
 gr_top_block_impl::unlock()
 {
-  gr_lock_guard lock(d_mutex);
+  gruel::scoped_lock lock(d_mutex);
 
   if (d_lock_count <= 0){
     d_lock_count = 0;          // fix it, then complain
index 35fb44ef92ba7110c4c052e3c96d8a89573fcb8d..ef28dd8292124803f1162b85515b2313d4da0475 100644 (file)
 #define INCLUDED_GR_TOP_BLOCK_IMPL_H
 
 #include <gr_scheduler.h>
-#include <boost/thread.hpp>
-
-typedef boost::mutex                   gr_mutex;       // FIXME move these elsewhere
-typedef boost::lock_guard<boost::mutex>        gr_lock_guard;
+#include <gruel/thread.h>
 
 /*!
  *\brief Abstract implementation details of gr_top_block
@@ -69,7 +66,7 @@ protected:
   gr_flat_flowgraph_sptr         d_ffg;
   gr_scheduler_sptr             d_scheduler;
 
-  gr_mutex                       d_mutex;      // protects d_state and d_lock_count
+  gruel::mutex                   d_mutex;      // protects d_state and d_lock_count
   tb_state                      d_state;
   int                            d_lock_count;
   
index 02e8deed88b90a8fda7326977ab6279c918995fe..c6311ccaa3efefd9ef62342231b0ad73aadab789 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -27,6 +27,8 @@
 #include <gr_block_detail.h>
 #include <gr_buffer.h>
 
+using namespace pmt;
+
 /*
  * We assume that no worker threads are ever running when the
  * graph structure is being manipulated, thus it's safe for us to poke
@@ -65,3 +67,44 @@ gr_tpb_detail::notify_neighbors(gr_block_detail *d)
   notify_downstream(d);
   notify_upstream(d);
 }
+
+void
+gr_tpb_detail::insert_tail(pmt::pmt_t msg)
+{
+  gruel::scoped_lock guard(mutex);
+
+  msg_queue.push_back(msg);
+
+  // wake up thread if BLKD_IN or BLKD_OUT
+  input_cond.notify_one();
+  output_cond.notify_one();
+}
+
+pmt_t 
+gr_tpb_detail::delete_head_nowait()
+{
+  gruel::scoped_lock guard(mutex);
+
+  if (empty_p())
+    return pmt_t();
+
+  pmt_t m(msg_queue.front());
+  msg_queue.pop_front();
+
+  return m;
+}
+
+/*
+ * Caller must already be holding the mutex
+ */
+pmt_t 
+gr_tpb_detail::delete_head_nowait_already_holding_mutex()
+{
+  if (empty_p())
+    return pmt_t();
+
+  pmt_t m(msg_queue.front());
+  msg_queue.pop_front();
+
+  return m;
+}
index 9566312dc82a126892ed19b5a440d47c941cd44a..acfa264c7c412d02a39ce3f6d1c7e32dd48f92dc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -21,7 +21,9 @@
 #ifndef INCLUDED_GR_TPB_DETAIL_H
 #define INCLUDED_GR_TPB_DETAIL_H
 
-#include <boost/thread.hpp>
+#include <gruel/thread.h>
+#include <deque>
+#include <gruel/pmt.h>
 
 class gr_block_detail;
 
@@ -29,17 +31,19 @@ class gr_block_detail;
  * \brief used by thread-per-block scheduler
  */
 struct gr_tpb_detail {
-  typedef boost::unique_lock<boost::mutex>  scoped_lock;
 
-  boost::mutex                 mutex;                  //< protects all vars
+  gruel::mutex                 mutex;                  //< protects all vars
   bool                         input_changed;
-  boost::condition_variable    input_cond;
+  gruel::condition_variable    input_cond;
   bool                         output_changed;
-  boost::condition_variable    output_cond;
+  gruel::condition_variable    output_cond;
 
-  gr_tpb_detail()
-    : input_changed(false), output_changed(false) {}
+private:
+  std::deque<pmt::pmt_t>       msg_queue;
 
+public:
+  gr_tpb_detail()
+    : input_changed(false), output_changed(false) { }
 
   //! Called by us to tell all our upstream blocks that their output may have changed.
   void notify_upstream(gr_block_detail *d);
@@ -53,17 +57,34 @@ struct gr_tpb_detail {
   //! Called by us
   void clear_changed()
   {
-    scoped_lock        guard(mutex);
+    gruel::scoped_lock guard(mutex);
     input_changed = false;
     output_changed = false;
   }
+  
+  //! is the queue empty?
+  bool empty_p() const { return msg_queue.empty(); }
+
+  //| Acquires and release the mutex   
+  void insert_tail(pmt::pmt_t msg);
+
+  /*!
+   * \returns returns pmt at head of queue or pmt_t() if empty.
+   */
+  pmt::pmt_t delete_head_nowait();
+
+  /*!
+   * \returns returns pmt at head of queue or pmt_t() if empty.
+   * Caller must already be holding the mutex
+   */
+  pmt::pmt_t delete_head_nowait_already_holding_mutex();
 
 private:
 
   //! Used by notify_downstream
   void set_input_changed()
   {
-    scoped_lock        guard(mutex);
+    gruel::scoped_lock guard(mutex);
     input_changed = true;
     input_cond.notify_one();
   }
@@ -71,7 +92,7 @@ private:
   //! Used by notify_upstream
   void set_output_changed()
   {
-    scoped_lock        guard(mutex);
+    gruel::scoped_lock guard(mutex);
     output_changed = true;
     output_cond.notify_one();
   }
index e3abf6d8446bc62b6257ea3169a27ac25227112c..03eef17d937f63927f4723bc623b0474af17357c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_tpb_thread_body.h>
 #include <iostream>
 #include <boost/thread.hpp>
+#include <gruel/pmt.h>
+
+using namespace pmt;
 
 gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
   : d_exec(block)
 {
   // std::cerr << "gr_tpb_thread_body: " << block << std::endl;
 
-  gr_block_detail      *d = block->detail().get();
+  gr_block_detail *d = block->detail().get();
   gr_block_executor::state s;
+  pmt_t msg;
+
 
   while (1){
     boost::this_thread::interruption_point();
+    // handle any queued up messages
+    while ((msg = d->d_tpb.delete_head_nowait()))
+      block->handle_msg(msg);
 
     d->d_tpb.clear_changed();
     s = d_exec.run_one_iteration();
@@ -54,17 +63,40 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
 
     case gr_block_executor::BLKD_IN:           // Wait for input.
       {
-       gr_tpb_detail::scoped_lock guard(d->d_tpb.mutex);
-       while(!d->d_tpb.input_changed)
-         d->d_tpb.input_cond.wait(guard);
+       gruel::scoped_lock guard(d->d_tpb.mutex);
+       while (!d->d_tpb.input_changed){
+         
+         // wait for input or message
+         while(!d->d_tpb.input_changed && d->d_tpb.empty_p())
+           d->d_tpb.input_cond.wait(guard);
+
+         // handle all pending messages
+         while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
+           guard.unlock();                     // release lock while processing msg
+           block->handle_msg(msg);
+           guard.lock();
+         }
+       }
       }
       break;
+
       
     case gr_block_executor::BLKD_OUT:          // Wait for output buffer space.
       {
-       gr_tpb_detail::scoped_lock guard(d->d_tpb.mutex);
-       while(!d->d_tpb.output_changed)
-         d->d_tpb.output_cond.wait(guard);
+       gruel::scoped_lock guard(d->d_tpb.mutex);
+       while (!d->d_tpb.output_changed){
+         
+         // wait for output room or message
+         while(!d->d_tpb.output_changed && d->d_tpb.empty_p())
+           d->d_tpb.output_cond.wait(guard);
+
+         // handle all pending messages
+         while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
+           guard.unlock();                     // release lock while processing msg
+           block->handle_msg(msg);
+           guard.lock();
+         }
+       }
       }
       break;
 
diff --git a/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc b/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc
new file mode 100644 (file)
index 0000000..e541c54
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#include <gr_shared_block_sptr.h>
+#include <gr_vector_source_i.h>
+
+gr_block_sptr 
+foo (gr_vector_source_i_sptr s)
+{
+  return gr_block_sptr (s);
+}
+
+typedef gr_shared_block_sptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+//typedef boost::shared_ptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+
+gr_vector_source_i_ptrX
+bar (gr_vector_source_i *s)
+{
+  return gr_vector_source_i_ptrX (s);
+}
+
+gr_block_sptr 
+baz_1 (gr_vector_source_i_ptrX s)
+{
+  return gr_block_sptr (s);
+}
+
+#if 0
+gr_block_sptr 
+baz_2 (gr_vector_source_i_ptrX s)
+{
+  return s.block_sptr ();
+}
+#endif
diff --git a/gnuradio-core/src/lib/swig/.gitignore b/gnuradio-core/src/lib/swig/.gitignore
new file mode 100644 (file)
index 0000000..9d7d010
--- /dev/null
@@ -0,0 +1,36 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/swigrun.py
+/swigrun_wrap.c
+/Makefile.swigdeps.new
+/gnuradio_swig_py_runtime.d
+/gnuradio_swig_py_general.d
+/gnuradio_swig_py_gengen.d
+/gnuradio_swig_py_filter.d
+/gnuradio_swig_py_io.d
+/gnuradio_swig_bug_workaround.h
+/gnuradio_swig_py_runtime.cc
+/gnuradio_swig_py_runtime.h
+/gnuradio_swig_py_runtime.py
+/gnuradio_swig_py_general.cc
+/gnuradio_swig_py_general.h
+/gnuradio_swig_py_general.py
+/gnuradio_swig_py_gengen.cc
+/gnuradio_swig_py_gengen.h
+/gnuradio_swig_py_gengen.py
+/gnuradio_swig_py_filter.cc
+/gnuradio_swig_py_filter.h
+/gnuradio_swig_py_filter.py
+/gnuradio_swig_py_io.cc
+/gnuradio_swig_py_io.h
+/gnuradio_swig_py_io.py
+/gnuradio_swig_py_hier.cc
+/gnuradio_swig_py_hier.h
+/gnuradio_swig_py_hier.py
index 75b152dc0b52109cf0be208eb161fc749282f880..242f27d9c0d7d9de79696ca4af39a3fc13f76ab2 100644 (file)
@@ -21,6 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
+if PYTHON
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) -I$(srcdir) \
         $(WITH_INCLUDES)
 
@@ -99,3 +100,4 @@ BUILT_SOURCES =                              \
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gnuradio-core/src/lib/viterbi/.gitignore b/gnuradio-core/src/lib/viterbi/.gitignore
new file mode 100644 (file)
index 0000000..85bb5cc
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/encode
+/decode
diff --git a/gnuradio-core/src/python/.gitignore b/gnuradio-core/src/python/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-core/src/python/bin/.gitignore b/gnuradio-core/src/python/bin/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-core/src/python/gnuradio/.gitignore b/gnuradio-core/src/python/gnuradio/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index 5cc0824b3aa5392ea96c48553cf836ff2d0ddc85..f0516f2fd9e808387f6b687e50556b7ccca12c0a 100644 (file)
@@ -21,6 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
+if PYTHON
 SUBDIRS = gr gru gruimpl blks2 blks2impl vocoder
 
 grpython_PYTHON =                      \
@@ -29,8 +30,11 @@ grpython_PYTHON =                    \
        eng_notation.py                 \
        eng_option.py                   \
        modulation_utils.py             \
+       modulation_utils2.py            \
        ofdm_packet_utils.py            \
        packet_utils.py                 \
        gr_unittest.py                  \
        optfir.py                       \
+       usrp_options.py         \
        window.py
+endif
diff --git a/gnuradio-core/src/python/gnuradio/blks2/.gitignore b/gnuradio-core/src/python/gnuradio/blks2/.gitignore
new file mode 100644 (file)
index 0000000..b695091
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pyc
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/.gitignore b/gnuradio-core/src/python/gnuradio/blks2impl/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index f07abd4c4b13d74b5ed4338839c6b41fd6d00b1e..7b24fb69d75bed59643c8af4296fc7385fd65d29 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2005,2007,2009 Free Software Foundation, Inc.
+# Copyright 2005,2007,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -31,11 +31,14 @@ grblkspython_PYTHON =               \
        am_demod.py             \
        channel_model.py        \
        dbpsk.py                \
+       dbpsk2.py               \
        dqpsk.py                \
+       dqpsk2.py               \
        d8psk.py                \
        filterbank.py           \
        fm_demod.py             \
        fm_emph.py              \
+       generic_usrp.py \
        gmsk.py                 \
        cpm.py                  \
        logpwrfft.py            \
@@ -47,6 +50,10 @@ grblkspython_PYTHON =                \
        ofdm_sync_pn.py         \
        ofdm_sync_pnac.py       \
        ofdm_sync_ml.py         \
+       pfb_arb_resampler.py    \
+       pfb_channelizer.py      \
+       pfb_decimator.py        \
+       pfb_interpolator.py     \
        pkt.py                  \
        psk.py                  \
        qam.py                  \
index 3147bfa2ab4f4f102b27121083368394063148c7..55e4890f309d274f3c5c5cb5f8194abb9e52cc20 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -233,10 +233,10 @@ class dbpsk_demod(gr.hier_block2):
         arity = pow(2,self.bits_per_symbol())
 
         # 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)
+        #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
         ntaps = 11 * samples_per_symbol
@@ -251,20 +251,20 @@ class dbpsk_demod(gr.hier_block2):
         # 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.1
-        fmax = 0.1
+        fmin = -0.25
+        fmax = 0.25
         
         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)
+            
         # Do differential decoding based on phase change of symbols
         self.diffdec = gr.diff_phasor_cc()
 
@@ -288,7 +288,7 @@ class dbpsk_demod(gr.hier_block2):
             self._setup_logging()
 
         # Connect and Initialize base class
-        self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver,
+        self.connect(self, self.agc, self.rrc_filter, self.receiver,
                      self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
 
     def samples_per_symbol(self):
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
new file mode 100644 (file)
index 0000000..d7bcf53
--- /dev/null
@@ -0,0 +1,369 @@
+#
+# Copyright 2009,2010 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 BPSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils2
+from math import pi, sqrt, ceil
+import psk
+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_freq_alpha = 0.010
+_def_phase_alpha = 0.1
+_def_timing_alpha = 0.100
+_def_timing_beta = 0.010
+_def_timing_max_dev = 1.5
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                             DBPSK modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class dbpsk2_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 differential BPSK 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 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 log: Log modulation data to files?
+        @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
+
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if self._samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % self._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(psk.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity])
+
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity])
+
+        # pulse shaping filter
+        nfilts = 32
+        ntaps = nfilts * 11 * int(self._samples_per_symbol)    # make nfilts filters of ntaps each
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            nfilts,          # gain
+            nfilts,          # sampling rate based on 32 filters in resampler
+            1.0,             # symbol rate
+            self._excess_bw, # excess bandwidth (roll-off factor)
+            ntaps)
+        self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps)
+
+       # 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
+
+    def bits_per_symbol(self=None):   # static method that's also callable on an instance
+        return 1
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static method.  RTFM
+
+    def add_options(parser):
+        """
+        Adds DBPSK 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]")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=True,
+                          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_utils2.extract_kwargs_from_options(dbpsk2_mod.__init__,
+                                                            ('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
+
+    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_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"))
+              
+
+# /////////////////////////////////////////////////////////////////////////////
+#                             DBPSK demodulator
+#
+#      Differentially coherent detection of differentially encoded BPSK
+# /////////////////////////////////////////////////////////////////////////////
+
+class dbpsk2_demod(gr.hier_block2):
+
+    def __init__(self,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 freq_alpha=_def_freq_alpha,
+                 phase_alpha=_def_phase_alpha,
+                 timing_alpha=_def_timing_alpha,
+                 timing_max_dev=_def_timing_max_dev,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log,
+                 sync_out=False):
+        """
+       Hierarchical block for RRC-filtered differential BPSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param freq_alpha: loop filter gain for frequency recovery
+        @type freq_alpha: float
+        @param phase_alpha: loop filter gain for phase/fine frequency recovery
+        @type phase_alpha: float
+        @param timing_alpha: loop alpha gain for timing recovery
+        @type timing_alpha: float
+        @param timing_max: timing loop maximum rate deviations
+        @type timing_max: 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 log: Print modualtion data to files?
+        @type log: bool
+        @param sync_out: Output a sync signal on :1?
+        @type sync_out: bool
+       """
+       if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex))
+       else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char)
+
+       gr.hier_block2.__init__(self, "dqpsk2_demod",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               io_sig_out)       # Output signature
+
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._freq_alpha = freq_alpha
+        self._freq_beta = 0.10*self._freq_alpha
+        self._phase_alpha = phase_alpha
+        self._timing_alpha = timing_alpha
+        self._timing_beta = _def_timing_beta
+        self._timing_max_dev=timing_max_dev
+        self._gray_code = gray_code
+        
+        if samples_per_symbol < 2:
+            raise TypeError, "samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,)
+
+        arity = pow(2,self.bits_per_symbol())
+
+        # Automatic gain control
+        self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
+        #self.agc = gr.feedforward_agc_cc(16, 1.0)
+
+        # Frequency correction
+        self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+                                              11*int(self._samples_per_symbol),
+                                              self._freq_alpha, self._freq_beta)
+
+        # symbol timing recovery with RRC data filter
+        nfilts = 32
+        ntaps = 11 * int(self._samples_per_symbol*nfilts)
+        taps = gr.firdes.root_raised_cosine(nfilts, nfilts,
+                                            1.0/float(self._samples_per_symbol),
+                                            self._excess_bw, ntaps)
+        self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
+                                                self._timing_alpha,
+                                                taps, nfilts, nfilts/2, self._timing_max_dev)
+        self.time_recov.set_beta(self._timing_beta)
+
+        # Perform phase / fine frequency correction
+        self._phase_beta  = 0.25 * self._phase_alpha * self._phase_alpha
+        # Allow a frequency swing of +/- half of the sample rate
+        fmin = -0.5
+        fmax = 0.5
+        
+        self.phase_recov = gr.costas_loop_cc(self._phase_alpha,
+                                             self._phase_beta,
+                                             fmax, fmin, arity)
+
+        # Do differential decoding based on phase change of symbols
+        self.diffdec = gr.diff_phasor_cc()
+
+        # find closest constellation point
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol())
+
+        if verbose:
+            self._print_verbage()
+
+        if log:
+            self._setup_logging()
+
+        # Connect
+        self.connect(self, self.agc,
+                     self.freq_recov, self.time_recov, self.phase_recov,
+                     self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
+        if sync_out: self.connect(self.time_recov, (self, 1))
+
+    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.  RTFM
+
+    def _print_verbage(self):
+        print "\nDemodulator:"
+        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 "FLL gain:            %.2e" % self._freq_alpha
+        print "Timing alpha gain:   %.2e" % self._timing_alpha
+        print "Timing beta gain:    %.2e" % self._timing_beta
+        print "Timing max dev:      %.2f" % self._timing_max_dev
+        print "Phase track alpha:   %.2e" % self._phase_alpha
+        print "Phase track beta:    %.2e" % self._phase_beta
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self.connect(self.agc,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
+        self.connect(self.freq_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat"))
+        self.connect(self.time_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat"))
+        self.connect(self.phase_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.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):
+        """
+        Adds DBPSK demodulation-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)")
+        parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
+                          help="set frequency lock loop alpha gain value [default=%default] (PSK)")
+        parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha,
+                          help="set phase tracking loop alpha value [default=%default] (PSK)")
+        parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha,
+                          help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)")
+        parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta,
+                          help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)")
+        parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev,
+                          help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/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_utils2.extract_kwargs_from_options(
+                 dbpsk2_demod.__init__, ('self',), options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+#
+# Add these to the mod/demod registry
+#
+modulation_utils2.add_type_1_mod('dbpsk2', dbpsk2_mod)
+modulation_utils2.add_type_1_demod('dbpsk2', dbpsk2_demod)
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 (file)
index 0000000..6ec6682
--- /dev/null
@@ -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)
index 8c15d2173427750bcee5062cf6d985ef4dc10c3e..42d534168579d2d308b8d0876d93f16c4e4c9081 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -255,8 +255,8 @@ class dqpsk_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.025
-        fmax = 0.025
+        fmin = -0.25
+        fmax = 0.25
         
         self.receiver=gr.mpsk_receiver_cc(arity, pi/4.0,
                                           self._costas_alpha, self._costas_beta,
@@ -264,7 +264,7 @@ class dqpsk_demod(gr.hier_block2):
                                           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()
         
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
new file mode 100644 (file)
index 0000000..e1e6277
--- /dev/null
@@ -0,0 +1,377 @@
+#
+# Copyright 2009,2010 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_utils2
+from math import pi, sqrt
+import psk
+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_freq_alpha = 0.010
+_def_phase_alpha = 0.01
+_def_timing_alpha = 0.100
+_def_timing_beta = 0.010
+_def_timing_max_dev = 1.5
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           DQPSK modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class dqpsk2_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, "dqpsk2_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 samples_per_symbol < 2:
+            raise TypeError, ("sbp must be >= 2, is %f" % 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(psk.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = .707 + .707j
+        rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
+        self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const)
+
+        # pulse shaping filter
+        nfilts = 32
+        ntaps = 11 * int(nfilts * self._samples_per_symbol)  # make nfilts filters of ntaps each
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            nfilts,          # gain
+            nfilts,          # sampling rate based on 32 filters in resampler
+            1.0,             # symbol rate
+            self._excess_bw, # excess bandwidth (roll-off factor)
+            ntaps)
+        self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps)
+
+        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
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on an instance
+        return 2
+    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 "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_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):
+        """
+        Adds QPSK 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_utils2.extract_kwargs_from_options(dqpsk2_mod.__init__,
+                                                            ('self',), options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           DQPSK demodulator
+#
+# Differentially coherent detection of differentially encoded qpsk
+# /////////////////////////////////////////////////////////////////////////////
+
+class dqpsk2_demod(gr.hier_block2):
+
+    def __init__(self, 
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 freq_alpha=_def_freq_alpha,
+                 phase_alpha=_def_phase_alpha,
+                 timing_alpha=_def_timing_alpha,
+                 timing_max_dev=_def_timing_max_dev,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log,
+                 sync_out=False):
+        """
+       Hierarchical block for RRC-filtered DQPSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param freq_alpha: loop filter gain for frequency recovery
+        @type freq_alpha: float
+        @param phase_alpha: loop filter gain
+        @type phase_alphas: float
+        @param timing_alpha: timing loop alpha gain
+        @type timing_alpha: float
+        @param timing_max: timing loop maximum rate deviations
+        @type timing_max: 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 log: Print modualtion data to files?
+        @type log: bool
+        @param sync_out: Output a sync signal on :1?
+        @type sync_out: bool
+       """
+       if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex))
+       else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char)
+
+       gr.hier_block2.__init__(self, "dqpsk2_demod",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               io_sig_out)       # Output signature
+
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._freq_alpha = freq_alpha
+        self._freq_beta = 0.25*self._freq_alpha**2
+        self._phase_alpha = phase_alpha
+        self._timing_alpha = timing_alpha
+        self._timing_beta = _def_timing_beta
+        self._timing_max_dev=timing_max_dev
+        self._gray_code = gray_code
+
+        if samples_per_symbol < 2:
+            raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol
+
+        arity = pow(2,self.bits_per_symbol())
+        # Automatic gain control
+        self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
+        #self.agc = gr.feedforward_agc_cc(16, 2.0)
+
+        # Frequency correction
+        self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+                                              11*int(self._samples_per_symbol),
+                                              self._freq_alpha, self._freq_beta)
+
+
+        # symbol timing recovery with RRC data filter
+        nfilts = 32
+        ntaps = 11 * int(samples_per_symbol*nfilts)
+        taps = gr.firdes.root_raised_cosine(nfilts, nfilts,
+                                            1.0/float(self._samples_per_symbol),
+                                            self._excess_bw, ntaps)
+        self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
+                                                self._timing_alpha,
+                                                taps, nfilts, nfilts/2, self._timing_max_dev)
+        self.time_recov.set_beta(self._timing_beta)
+        
+
+        # Perform phase / fine frequency correction
+        self._phase_beta  = 0.25 * self._phase_alpha * self._phase_alpha
+        # Allow a frequency swing of +/- half of the sample rate
+        fmin = -0.5
+        fmax = 0.5
+
+        self.phase_recov = gr.costas_loop_cc(self._phase_alpha,
+                                             self._phase_beta,
+                                             fmax, fmin, arity)
+
+
+        # 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])
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol())
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+        # Connect
+        self.connect(self, self.agc, 
+                     self.freq_recov, self.time_recov, self.phase_recov,
+                     self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
+        if sync_out: self.connect(self.time_recov, (self, 1))
+
+    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 2
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static method.  RTFM
+
+    def _print_verbage(self):
+        print "\nDemodulator:"
+        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 "FLL gain:            %.2f" % self._freq_alpha
+        print "Timing alpha gain:   %.2f" % self._timing_alpha
+        print "Timing beta gain:    %.2f" % self._timing_beta
+        print "Timing max dev:      %.2f" % self._timing_max_dev
+        print "Phase track alpha:   %.2e" % self._phase_alpha
+        print "Phase track beta:    %.2e" % self._phase_beta
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self.connect(self.agc,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
+        self.connect(self.freq_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat"))
+        self.connect(self.time_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat"))
+        self.connect(self.phase_recov,
+                     gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.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):
+        """
+        Adds DQPSK demodulation-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)")
+        parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
+                          help="set frequency lock loop alpha gain value [default=%default] (PSK)")
+        parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha,
+                          help="set phase tracking loop alpha value [default=%default] (PSK)")
+        parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha,
+                          help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)")
+        parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta,
+                          help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)")
+        parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev,
+                          help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/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_utils2.extract_kwargs_from_options(
+            dqpsk2_demod.__init__, ('self',), options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils2.add_type_1_mod('dqpsk2', dqpsk2_mod)
+modulation_utils2.add_type_1_demod('dqpsk2', dqpsk2_demod)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py b/gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py
new file mode 100644 (file)
index 0000000..82d1eca
--- /dev/null
@@ -0,0 +1,238 @@
+#
+# Copyright 2009 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.
+#
+
+USRP1_TYPE = 'usrp1'
+USRP2_TYPE = 'usrp2'
+DUMMY_TYPE = 'dummy'
+#usrp2 rates common for decim and interp
+_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
+#dummy common rates
+_DUMMY_XRATES = range(4, 512, 2)
+_DUMMY_CONVERTER_RATE = 100e6
+#dummy freq result
+class _dummy_freq_result(object):
+    def __init__(self, target_freq):
+        self.baseband_freq = target_freq
+        self.dxc_freq = 0
+        self.residual_freq = 0
+from gnuradio import gr
+
+########################################################################
+# generic usrp common stuff
+########################################################################
+class _generic_usrp_base(object):
+
+    def __init__(self, which=0, subdev_spec=None, interface="", mac_addr="",
+        fusb_block_size=0, fusb_nblocks=0, usrpx=None, lo_offset=None, gain=None):
+        self._lo_offset = lo_offset
+        #usrp options
+        self._which = which
+        self._subdev_spec = subdev_spec
+        #usrp2 options
+        self._interface = interface
+        self._mac_addr = mac_addr
+        #fusb options
+        self._fusb_block_size = fusb_block_size
+        self._fusb_nblocks = fusb_nblocks
+        #pick which usrp model
+        if usrpx == '0': self._setup_usrpx(DUMMY_TYPE)
+        elif usrpx == '1' or self._subdev_spec: self._setup_usrpx(USRP1_TYPE)
+        elif usrpx == '2' or self._mac_addr: self._setup_usrpx(USRP2_TYPE)
+        else: #automatic
+            try: self._setup_usrpx(USRP2_TYPE)
+            except:
+                try: self._setup_usrpx(USRP1_TYPE)
+                except: raise Exception, 'Failed to automatically setup a usrp device.'
+        #post usrp setup
+        if self._lo_offset is not None:
+            self.set_lo_offset(self._lo_offset)
+        self.set_gain(gain)
+        self.set_auto_tr(True)
+
+    def _setup_usrpx(self, type):
+        """
+        Call the appropriate setup method.
+        @param type the usrp type constant
+        """
+        self._type = type
+        if self._type == USRP1_TYPE: self._setup_usrp1()
+        elif self._type == USRP2_TYPE: self._setup_usrp2()
+        elif self._type == DUMMY_TYPE: self._setup_dummy()
+
+    def __str__(self):
+        if self._type == USRP1_TYPE: return self._subdev.side_and_name()
+        elif self._type == USRP2_TYPE:
+            return 'Interface: %s    MAC Address: %s    D-Board ID: 0x%.2x'%(
+                self._u.interface_name(), self._u.mac_addr(), self._u.daughterboard_id())
+        elif self._type == DUMMY_TYPE: return 'Dummy USRP Device'
+
+    def gain(self): return self._gain
+
+    def set_gain(self, gain=None):
+        #automatic gain calculation
+        r = self.gain_range()
+        if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
+        #set gain for usrp
+        self._gain = gain
+        if self._type == USRP1_TYPE: return self._subdev.set_gain(gain)
+        elif self._type == USRP2_TYPE: return self._u.set_gain(gain)
+        elif self._type == DUMMY_TYPE: return True
+
+    def gain_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.gain_range()
+        elif self._type == USRP2_TYPE: return self._u.gain_range()
+        elif self._type == DUMMY_TYPE: return (0, 0, 0)
+
+    def set_center_freq(self, target_freq):
+        if self._type == USRP1_TYPE:
+            return self._u.tune(self._dxc, self._subdev, target_freq)
+        elif self._type == USRP2_TYPE:
+            return self._u.set_center_freq(target_freq)
+        elif self._type == DUMMY_TYPE: return _dummy_freq_result(target_freq)
+
+    def freq_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.freq_range()
+        elif self._type == USRP2_TYPE: return self._u.freq_range()
+        elif self._type == DUMMY_TYPE: return (-10e9, 10e9, 100e3)
+
+    def set_lo_offset(self, lo_offset):
+        if self._type == USRP1_TYPE: return self._subdev.set_lo_offset(lo_offset)
+        elif self._type == USRP2_TYPE: return self._u.set_lo_offset(lo_offset)
+        elif self._type == DUMMY_TYPE: return True
+
+    def set_auto_tr(self, enable):
+        if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
+
+########################################################################
+# generic usrp source
+########################################################################
+class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp source that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_source",
+            gr.io_signature(0, 0, 0), # Input signature
+            gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        self.connect(self._u, self)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_decim(self, decim):
+        if decim not in self.get_decim_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
+        elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_decim_rates(self):
+        if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def adc_rate(self):
+        if self._type == USRP1_TYPE: return self._u.adc_rate()
+        if self._type == USRP2_TYPE: return self._u.adc_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        from gnuradio import usrp
+        self._u = usrp.source_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
+        self._dxc = 0
+
+    def _setup_usrp2(self):
+        from gnuradio import usrp2
+        self._u = usrp2.source_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
+
+########################################################################
+# generic usrp sink
+########################################################################
+class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp sink that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_sink",
+            gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+            gr.io_signature(0, 0, 0)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
+            self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
+        else: self.connect(self, self._u)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_interp(self, interp):
+        if interp not in self.get_interp_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
+        elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_interp_rates(self):
+        if self._type == USRP1_TYPE: return range(16, 512+1, 4)
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def dac_rate(self):
+        if self._type == USRP1_TYPE: return self._u.dac_rate()
+        if self._type == USRP2_TYPE: return self._u.dac_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        from gnuradio import usrp
+        self._u = usrp.sink_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_tx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
+        self._dxc = self._subdev.which()
+
+    def _setup_usrp2(self):
+        from gnuradio import usrp2
+        self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)
index cf8eb1be78597fae71ed617307ddf4e707e0e7f4..200c4cfbe86a6b8c8c38c2bd366329df650b7c8a 100644 (file)
@@ -28,7 +28,7 @@ class _logpwrfft_base(gr.hier_block2):
     Create a log10(abs(fft)) stream chain, with real or complex input.
     """
 
-    def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average):
+    def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None):
         """
         Create an log10(abs(fft)) stream chain.
         Provide access to the setting the filter and sample rate.
@@ -38,6 +38,7 @@ class _logpwrfft_base(gr.hier_block2):
         @param frame_rate        Output frame rate
         @param avg_alpha        FFT averaging (over time) constant [0.0-1.0]
         @param average                Whether to average [True, False]
+        @param win              the window taps generation function
         """
         gr.hier_block2.__init__(self, self._name,
                                 gr.io_signature(1, 1, self._item_size),          # Input signature
@@ -48,16 +49,17 @@ class _logpwrfft_base(gr.hier_block2):
                                               vec_rate=frame_rate,
                                               vec_len=fft_size)
 
-        fft_window = window.blackmanharris(fft_size)
+        if win is None: win = window.blackmanharris
+        fft_window = win(fft_size)
         fft = self._fft_block[0](fft_size, True, fft_window)
         window_power = sum(map(lambda x: x*x, fft_window))
 
         c2mag = gr.complex_to_mag(fft_size)
         self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
         self._log = gr.nlog10_ff(20, fft_size,
-                                 -10*math.log10(fft_size)              # Adjust for number of bins
+                                 -20*math.log10(fft_size)              # Adjust for number of bins
                                  -10*math.log10(window_power/fft_size) # Adjust for windowing loss
-                                 -20*math.log10(ref_scale/2))          # Adjust for reference scale
+                                 -20*math.log10(ref_scale/2)+3.0)      # Adjust for reference scale
         self.connect(self, self._sd, fft, c2mag, self._avg, self._log, self)
 
         self._average = average
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
new file mode 100644 (file)
index 0000000..e40d963
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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 pfb_arb_resampler_ccf(gr.hier_block2):
+    '''
+    Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+    The block takes a single complex stream in and outputs a single complex
+    stream out. As such, it requires no extra glue to handle the input/output
+    streams. This block is provided to be consistent with the interface to the
+    other PFB block.
+    '''
+    def __init__(self, rate, taps, flt_size=32):
+       gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+        
+        self._rate = rate
+        self._taps = taps
+        self._size = flt_size
+
+        self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size)
+
+        self.connect(self, self.pfb)
+        self.connect(self.pfb, self)
+        
+    def set_taps(self, taps):
+        self.pfb.set_taps(taps)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py
new file mode 100644 (file)
index 0000000..a479ed4
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2010 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 pfb_channelizer_ccf(gr.hier_block2):
+    '''
+    Make a Polyphase Filter channelizer (complex in, complex out, floating-point taps)
+
+    This simplifies the interface by allowing a single input stream to connect to this block.
+    It will then output a stream for each channel.
+    '''
+    def __init__(self, numchans, taps, oversample_rate=1):
+       gr.hier_block2.__init__(self, "pfb_channelizer_ccf",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) # Output signature
+
+        self._numchans = numchans
+        self._taps = taps
+        self._oversample_rate = oversample_rate
+
+        self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._numchans)
+        self.pfb = gr.pfb_channelizer_ccf(self._numchans, self._taps,
+                                          self._oversample_rate)
+        self.v2s = gr.vector_to_streams(gr.sizeof_gr_complex, self._numchans)
+
+        self.connect(self, self.s2ss)
+
+        for i in xrange(self._numchans):
+            self.connect((self.s2ss,i), (self.pfb,i))
+
+        # Get independent streams from the filterbank and send them out
+        self.connect(self.pfb, self.v2s)
+
+        for i in xrange(self._numchans):
+            self.connect((self.v2s,i), (self,i))
+
+        
+        
+        
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py
new file mode 100644 (file)
index 0000000..176d047
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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 pfb_decimator_ccf(gr.hier_block2):
+    '''
+    Make a Polyphase Filter decimator (complex in, complex out, floating-point taps)
+
+    This simplifies the interface by allowing a single input stream to connect to this block.
+    It will then output a stream that is the decimated output stream.
+    '''
+    def __init__(self, decim, taps, channel=0):
+       gr.hier_block2.__init__(self, "pfb_decimator_ccf",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+        self._decim = decim
+        self._taps = taps
+        self._channel = channel
+
+        self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._decim)
+        self.pfb = gr.pfb_decimator_ccf(self._decim, self._taps, self._channel)
+
+        self.connect(self, self.s2ss)
+
+        for i in xrange(self._decim):
+            self.connect((self.s2ss,i), (self.pfb,i))
+
+        self.connect(self.pfb, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py
new file mode 100644 (file)
index 0000000..db29440
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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 pfb_interpolator_ccf(gr.hier_block2):
+    '''
+    Make a Polyphase Filter interpolator (complex in, complex out, floating-point taps)
+
+    The block takes a single complex stream in and outputs a single complex
+    stream out. As such, it requires no extra glue to handle the input/output
+    streams. This block is provided to be consistent with the interface to the
+    other PFB block.
+    '''
+    def __init__(self, interp, taps):
+       gr.hier_block2.__init__(self, "pfb_interpolator_ccf",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+        self._interp = interp
+        self._taps = taps
+
+        self.pfb = gr.pfb_interpolator_ccf(self._interp, self._taps)
+
+        self.connect(self, self.pfb)
+        self.connect(self.pfb, self)
+        
+        
+        
+        
index 39c8b5050259cc0a94256d80e063a240cc879cb3..8f75729c91c24a3c0e032e53b40d3863e1f23519 100644 (file)
@@ -72,8 +72,7 @@ class stream_to_vector_decimator(gr.hier_block2):
         self.one_in_n.set_n(self._decim)
 
     def _update_decimator(self):
-        self._decim = max(1, int(round(self._sample_rate/self._vec_len/self._vec_rate)))
-        self.one_in_n.set_n(self._decim)
+        self.set_decimation(self._sample_rate/self._vec_len/self._vec_rate)
 
     def decimation(self):
         """
index 09c3e1d87771a0a5a26ea2ce0f52b2f62a8def06..e10235f143958329b3ccfbdb70f6e08f4d91eb33 100644 (file)
 
 from copy import copy
 from optparse import Option, OptionValueError
-
-scale_factor = {}
-scale_factor['E'] = 1e18
-scale_factor['P'] = 1e15
-scale_factor['T'] = 1e12
-scale_factor['G'] = 1e9
-scale_factor['M'] = 1e6
-scale_factor['k'] = 1e3
-scale_factor['m'] = 1e-3
-scale_factor['u'] = 1e-6
-scale_factor['n'] = 1e-9
-scale_factor['p'] = 1e-12
-scale_factor['f'] = 1e-15
-scale_factor['a'] = 1e-18
-
+import eng_notation
 
 def check_eng_float (option, opt, value):
     try:
-        scale = 1.0
-        suffix = value[-1]
-        if scale_factor.has_key (suffix):
-            return float (value[0:-1]) * scale_factor[suffix]
-        return float (value)
+        return eng_notation.str_to_num(value)
     except:
         raise OptionValueError (
             "option %s: invalid engineering notation value: %r" % (opt, value))
diff --git a/gnuradio-core/src/python/gnuradio/gr/.gitignore b/gnuradio-core/src/python/gnuradio/gr/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
index 41ef52240968013c2ad75d16df6896977e4b696d..341f58812c962bdc6106bdcfbc1266d967904d7b 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004,2005,2006,2008 Free Software Foundation, Inc.
+# Copyright 2004,2005,2006,2008,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -54,6 +54,7 @@ noinst_PYTHON =                       \
        qa_cma_equalizer.py             \
        qa_complex_to_xxx.py            \
        qa_constellation_decoder_cb.py  \
+       qa_copy.py                      \
        qa_correlate_access_code.py     \
        qa_delay.py                     \
        qa_diff_encoder.py              \
@@ -96,4 +97,5 @@ noinst_PYTHON =                       \
        qa_unpack_k_bits.py             \
        qa_repeat.py                    \
        qa_scrambler.py                 \
+       qa_udp_sink_source.py           \
        qa_vector_sink_source.py        
index 52f1ff64a6637b2b55014b251f9e68fe4b65e40f..9b31b772b3f4fb72c05905326a8078662180c2b8 100644 (file)
@@ -33,7 +33,7 @@ def _user_prefs_filename():
     return os.path.expanduser('~/.gnuradio/config.conf')
         
 def _sys_prefs_dirname():
-    return os.path.join(gsp.prefix(), 'etc/gnuradio/conf.d')
+    return gsp.prefsdir()
 
 def _bool(x):
     """
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py b/gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py
new file mode 100755 (executable)
index 0000000..ee9bae6
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def help_ss (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_s (s[1])
+            self.tb.connect (src, (op, s[0]))
+        dst = gr.vector_sink_s ()
+        self.tb.connect (op, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_bb (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_b (s[1])
+            self.tb.connect (src, (op, s[0]))
+        dst = gr.vector_sink_b ()
+        self.tb.connect (op, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_ii (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_i (s[1])
+            self.tb.connect (src, (op, s[0]))
+        dst = gr.vector_sink_i ()
+        self.tb.connect (op, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+        
+    def test_xor_ss (self):
+        src1_data =       (1,  2,  3,  0x5004,   0x1150)
+        src2_data =       (8,  2,  1 , 0x0508,   0x1105)
+        expected_result = (9,  0,  2,  0x550C,   0x0055)
+        op = gr.xor_ss ()
+        self.help_ss ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_xor_bb (self):
+        src1_data =       (1,  2,  3,  4,   0x50)
+        src2_data =       (8,  2,  1 , 8,   0x05)
+        expected_result = (9,  0,  2,  0xC, 0x55)
+        op = gr.xor_bb ()
+        self.help_bb ((src1_data, src2_data),
+                      expected_result, op)
+
+
+    def test_xor_ii (self):
+        src1_data =       (1,  2,  3,  0x5000004,   0x11000050)
+        src2_data =       (8,  2,  1 , 0x0500008,   0x11000005)
+        expected_result = (9,  0,  2,  0x550000C,   0x00000055)
+        op = gr.xor_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_and_ss (self):
+        src1_data =       (1,  2,  3,  0x5004,   0x1150)
+        src2_data =       (8,  2,  1 , 0x0508,   0x1105)
+        expected_result = (0,  2,  1,  0x0000,   0x1100)
+        op = gr.and_ss ()
+        self.help_ss ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_and_bb (self):
+        src1_data =       (1,  2, 2,  3,  0x04,   0x50)
+        src2_data =       (8,  2, 2,  1,  0x08,   0x05)
+        src3_data =       (8,  2, 1,  1,  0x08,   0x05)
+        expected_result = (0,  2, 0,  1,  0x00,   0x00)
+        op = gr.and_bb ()
+        self.help_bb ((src1_data, src2_data, src3_data),
+                      expected_result, op)
+
+    def test_and_ii (self):
+        src1_data =       (1,  2,  3,  0x50005004,   0x11001150)
+        src2_data =       (8,  2,  1 , 0x05000508,   0x11001105)
+        expected_result = (0,  2,  1,  0x00000000,   0x11001100)
+        op = gr.and_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_or_ss (self):
+        src1_data =       (1,  2,  3,  0x5004,   0x1150)
+        src2_data =       (8,  2,  1 , 0x0508,   0x1105)
+        expected_result = (9,  2,  3,  0x550C,   0x1155)
+        op = gr.or_ss ()
+        self.help_ss ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_or_bb (self):
+        src1_data =       (1,  2, 2,  3,  0x04,   0x50)
+        src2_data =       (8,  2, 2,  1 , 0x08,   0x05)
+        src3_data =       (8,  2, 1,  1 , 0x08,   0x05)
+        expected_result = (9,  2, 3,  3,  0x0C,   0x55)
+        op = gr.or_bb ()
+        self.help_bb ((src1_data, src2_data, src3_data),
+                      expected_result, op)
+
+    def test_or_ii (self):
+        src1_data =       (1,  2,  3,  0x50005004,   0x11001150)
+        src2_data =       (8,  2,  1 , 0x05000508,   0x11001105)
+        expected_result = (9,  2,  3,  0x5500550C,   0x11001155)
+        op = gr.or_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_not_ss (self):
+        src1_data =       (1,      2,      3,       0x5004,   0x1150)
+        expected_result = (~1,     ~2,      ~3,       ~0x5004,   ~0x1150)
+        op = gr.not_ss ()
+        self.help_ss ((((src1_data),)),
+                      expected_result, op)
+
+    def test_not_bb (self):
+        src1_data =       (1,     2,    2,     3,     0x04,   0x50)
+        expected_result = (0xFE,  0xFD, 0xFD,  0xFC,  0xFB,   0xAF)
+        op = gr.not_bb ()
+        self.help_bb (((src1_data), ),
+                      expected_result, op)
+
+    def test_not_ii (self):
+        src1_data =       (1,    2,  3,  0x50005004,   0x11001150)
+        expected_result = (~1 , ~2, ~3, ~0x50005004,  ~0x11001150)
+        op = gr.not_ii ()
+        self.help_ii (((src1_data),),
+                      expected_result, op)
+
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_copy.py b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py
new file mode 100755 (executable)
index 0000000..7f9f72a
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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, gr_unittest
+
+class test_copy(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_copy (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        src = gr.vector_source_b(src_data)
+        op = gr.copy(gr.sizeof_char)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+    
+    def test_copy_drop (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = ()
+        src = gr.vector_source_b(src_data)
+        op = gr.copy(gr.sizeof_char)
+       op.set_enabled(False)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+    
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_integrate.py b/gnuradio-core/src/python/gnuradio/gr/qa_integrate.py
new file mode 100755 (executable)
index 0000000..fbd601e
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_integrate (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_000_ss(self):
+       src_data = (1, 2, 3, 4, 5, 6)
+       dst_data = (6, 15)
+       src = gr.vector_source_s(src_data)
+       itg = gr.integrate_ss(3)
+       dst = gr.vector_sink_s()
+       self.tb.connect(src, itg, dst)
+       self.tb.run()
+       self.assertEqual(dst_data, dst.data())
+       
+    def test_001_ii(self):
+       src_data = (1, 2, 3, 4, 5, 6)
+       dst_data = (6, 15)
+       src = gr.vector_source_i(src_data)
+       itg = gr.integrate_ii(3)
+       dst = gr.vector_sink_i()
+       self.tb.connect(src, itg, dst)
+       self.tb.run()
+       self.assertEqual(dst_data, dst.data())
+       
+    def test_002_ff(self):
+       src_data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
+       dst_data = [6.0, 15.0]
+       src = gr.vector_source_f(src_data)
+       itg = gr.integrate_ff(3)
+       dst = gr.vector_sink_f()
+       self.tb.connect(src, itg, dst)
+       self.tb.run()
+       self.assertFloatTuplesAlmostEqual(dst_data, dst.data(), 6)      
+
+    def test_003_cc(self):
+       src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, 6.0+6.0j]
+       dst_data = [6.0+6.0j, 15.0+15.0j]
+       src = gr.vector_source_c(src_data)
+       itg = gr.integrate_cc(3)
+       dst = gr.vector_sink_c()
+       self.tb.connect(src, itg, dst)
+       self.tb.run()
+       self.assertComplexTuplesAlmostEqual(dst_data, dst.data(), 6)    
+
+if __name__ == '__main__':
+    gr_unittest.main ()
index 6e85083bd76103e14f59d265edd2e94615a4eda8..cb6c4c33c8fc3ac9835bbbbcf74ca8683e8d7364 100755 (executable)
@@ -99,6 +99,7 @@ class test_message (gr_unittest.TestCase):
         self.assertEquals(input_data, dst.data())
 
     def test_301(self):
+        # Use itemsize, limit constructor
         src = gr.message_source(gr.sizeof_char)
         dst = gr.vector_sink_b()
        tb = gr.top_block()
@@ -111,6 +112,20 @@ class test_message (gr_unittest.TestCase):
         tb.run()
         self.assertEquals(tuple(map(ord, '0123456789')), dst.data())
         
+    def test_302(self):
+        # Use itemsize, msgq constructor
+        msgq = gr.msg_queue()
+        src = gr.message_source(gr.sizeof_char, msgq)
+        dst = gr.vector_sink_b()
+       tb = gr.top_block()
+        tb.connect(src, dst)
+        src.msgq().insert_tail(gr.message_from_string('01234'))
+        src.msgq().insert_tail(gr.message_from_string('5'))
+        src.msgq().insert_tail(gr.message_from_string(''))
+        src.msgq().insert_tail(gr.message_from_string('6789'))
+        src.msgq().insert_tail(gr.message(1))                  # send EOF
+        tb.run()
+        self.assertEquals(tuple(map(ord, '0123456789')), dst.data())
 
 if __name__ == '__main__':
     gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py b/gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py
new file mode 100755 (executable)
index 0000000..64e7511
--- /dev/null
@@ -0,0 +1,90 @@
+#!/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, gr_unittest
+import math
+
+class test_sig_source (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_regen1 (self):
+        tb = self.tb
+        
+        data = [0, 0, 0,
+                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+
+        expected_result = (0, 0, 0,
+                           1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+                           1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
+
+        src = gr.vector_source_b(data, False)
+        regen = gr.regenerate_bb(5, 2)
+        dst = gr.vector_sink_b()
+
+        tb.connect (src, regen)
+        tb.connect (regen, dst)
+        tb.run ()
+
+        dst_data = dst.data ()
+        
+        self.assertEqual (expected_result, dst_data)
+
+    def test_regen2 (self):
+        tb = self.tb
+        
+        data = 200*[0,]
+        data[9] = 1
+        data[99] = 1
+
+        expected_result = 200*[0,]
+        expected_result[9]   = 1
+        expected_result[19]  = 1
+        expected_result[29]  = 1
+        expected_result[39]  = 1
+        
+        expected_result[99]  = 1
+        expected_result[109]  = 1
+        expected_result[119]  = 1
+        expected_result[129]  = 1
+
+        src = gr.vector_source_b(data, False)
+        regen = gr.regenerate_bb(10, 3)
+        dst = gr.vector_sink_b()
+
+        tb.connect (src, regen)
+        tb.connect (regen, dst)
+        tb.run ()
+
+        dst_data = dst.data ()
+        
+        self.assertEqual (tuple(expected_result), dst_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
index 76b0e62fa4c70029afab72147ea86319353b90a3..aecf492933993e2836d4f4246f77be83b9d9f8da 100755 (executable)
@@ -40,5 +40,25 @@ class test_scrambler(gr_unittest.TestCase):
         self.tb.run()
         self.assertEqual(tuple(src_data[:-8]), dst.data()[8:]) # skip garbage during synchronization
 
+    def test_additive_scrambler(self):
+        src_data = (1,)*1000
+        src = gr.vector_source_b(src_data, False)
+        scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
+        descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, scrambler, descrambler, dst)
+        self.tb.run()
+        self.assertEqual(src_data, dst.data())                            
+
+    def test_additive_scrambler_reset(self):
+        src_data = (1,)*1000
+        src = gr.vector_source_b(src_data, False)
+        scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+        descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, scrambler, descrambler, dst)
+        self.tb.run()
+        self.assertEqual(src_data, dst.data())                            
+
 if __name__ == '__main__':
     gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py b/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py
new file mode 100755 (executable)
index 0000000..8a76f81
--- /dev/null
@@ -0,0 +1,168 @@
+#!/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, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def help_stream_2ff(self, N, stream_sizes):
+        v0 = gr.vector_source_f(N*[1,], False)
+        v1 = gr.vector_source_f(N*[2,], False)
+        
+        mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+        dst = gr.vector_sink_f ()
+
+        self.tb.connect (v0, (mux,0))
+        self.tb.connect (v1, (mux,1))
+        self.tb.connect (mux, dst)
+        self.tb.run ()
+
+        return dst.data ()
+        
+    def help_stream_ramp_2ff(self, N, stream_sizes):
+        r1 = range(N)
+        r2 = range(N)
+        r2.reverse()
+
+        v0 = gr.vector_source_f(r1, False)
+        v1 = gr.vector_source_f(r2, False)
+        
+        mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+        dst = gr.vector_sink_f ()
+
+        self.tb.connect (v0, (mux,0))
+        self.tb.connect (v1, (mux,1))
+        self.tb.connect (mux, dst)
+        self.tb.run ()
+
+        return dst.data ()
+        
+    def test_stream_2NN_ff(self):
+        N = 40
+        stream_sizes = [10, 10]
+        result_data = self.help_stream_2ff(N, stream_sizes)
+
+        exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0)
+        self.assertEqual (exp_data, result_data)
+
+    def test_stream_ramp_2NN_ff(self):
+        N = 40
+        stream_sizes = [10, 10]
+        result_data = self.help_stream_ramp_2ff(N, stream_sizes)
+
+        exp_data = ( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,  9.0,
+                    39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 32.0, 31.0, 30.0,
+                    10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
+                    29.0, 28.0, 27.0, 26.0, 25.0, 24.0, 23.0, 22.0, 21.0, 20.0,
+                    20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
+                    19.0, 18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 11.0, 10.0,
+                    30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
+                     9.0,  8.0,  7.0,  6.0,  5.0,  4.0,  3.0,  2.0,  1.0,  0.0)
+        self.assertEqual (exp_data, result_data)
+
+    def test_stream_2NM_ff(self):
+        N = 40
+        stream_sizes = [7, 9]
+        self.help_stream_2ff(N, stream_sizes)
+
+        result_data = self.help_stream_2ff(N, stream_sizes)
+
+        exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0)
+                
+        self.assertEqual (exp_data, result_data)
+
+
+    def test_stream_2MN_ff(self):
+        N = 37
+        stream_sizes = [7, 9]
+        self.help_stream_2ff(N, stream_sizes)
+
+        result_data = self.help_stream_2ff(N, stream_sizes)
+
+        exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    2.0)
+
+        self.assertEqual (exp_data, result_data)
+
+    def test_stream_2N0_ff(self):
+        N = 30
+        stream_sizes = [7, 0]
+        self.help_stream_2ff(N, stream_sizes)
+
+        result_data = self.help_stream_2ff(N, stream_sizes)
+
+        exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
+                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+                    1.0, 1.0)
+      
+        self.assertEqual (exp_data, result_data)
+
+    def test_stream_20N_ff(self):
+        N = 30
+        stream_sizes = [0, 9]
+        self.help_stream_2ff(N, stream_sizes)
+
+        result_data = self.help_stream_2ff(N, stream_sizes)
+
+        exp_data = (2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+                    2.0, 2.0, 2.0)
+      
+        self.assertEqual (exp_data, result_data)
+
+if __name__ == '__main__':
+    gr_unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py
new file mode 100755 (executable)
index 0000000..b00b26b
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 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, gr_unittest
+from threading import Timer
+
+class test_sink_source(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb_snd = gr.top_block()
+        self.tb_rcv = gr.top_block()
+
+    def tearDown(self):
+        self.tb_rcv = None
+        self.tb_snd = None
+        
+    def test_001(self):
+        port = 65500
+
+        n_data = 16
+        src_data = [float(x) for x in range(n_data)]
+        expected_result = tuple(src_data)
+        src = gr.vector_source_f(src_data)
+        udp_snd = gr.udp_sink( gr.sizeof_float, 'localhost', port )
+        self.tb_snd.connect( src, udp_snd )
+
+        udp_rcv = gr.udp_source( gr.sizeof_float, 'localhost', port )
+        dst = gr.vector_sink_f()
+        self.tb_rcv.connect( udp_rcv, dst )
+
+        self.tb_rcv.start()
+        self.tb_snd.run()
+        udp_snd.disconnect()
+        self.timeout = False
+        q = Timer(3.0,self.stop_rcv)
+        q.start()
+        self.tb_rcv.wait()
+        q.cancel()
+
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+        self.assert_(not self.timeout)
+        
+    def test_002(self):
+        udp_rcv = gr.udp_source( gr.sizeof_float, '0.0.0.0', 0, eof=False )
+        rcv_port = udp_rcv.get_port()
+
+        udp_snd = gr.udp_sink( gr.sizeof_float, '127.0.0.1', 65500 )
+        udp_snd.connect( 'localhost', rcv_port )
+
+        n_data = 16
+        src_data = [float(x) for x in range(n_data)]
+        expected_result = tuple(src_data)
+        src = gr.vector_source_f(src_data)
+        dst = gr.vector_sink_f()
+
+        self.tb_snd.connect( src, udp_snd )
+        self.tb_rcv.connect( udp_rcv, dst )
+
+        self.tb_rcv.start()
+        self.tb_snd.run()
+        udp_snd.disconnect()
+        self.timeout = False
+        q = Timer(3.0,self.stop_rcv)
+        q.start()
+        self.tb_rcv.wait()
+        q.cancel()
+
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+        self.assert_(self.timeout)  # source ignores EOF?
+
+    def stop_rcv(self):
+        self.timeout = True
+        self.tb_rcv.stop()
+        #print "tb_rcv stopped by Timer"
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
+    
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py b/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py
new file mode 100755 (executable)
index 0000000..3ba5dfb
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+
+import os
+from os.path import getsize
+
+g_in_file = os.path.join (os.getenv ("srcdir"), "test_16bit_1chunk.wav")
+
+class qa_wavefile(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_checkwavread (self):
+       wf = gr.wavfile_source(g_in_file)
+       self.assertEqual(wf.sample_rate(), 8000)
+
+    def test_002_checkwavcopy (self):
+       infile  = g_in_file
+       outfile = "test_out.wav"
+
+       wf_in  = gr.wavfile_source(infile)
+       wf_out = gr.wavfile_sink(outfile,
+                                wf_in.channels(),
+                                wf_in.sample_rate(),
+                                wf_in.bits_per_sample())
+       self.tb.connect(wf_in, wf_out)
+       self.tb.run()
+       wf_out.close()
+
+       self.assertEqual(getsize(infile), getsize(outfile))
+
+       in_f  = file(infile,  'rb')
+       out_f = file(outfile, 'rb')
+
+       in_data  = in_f.read()
+       out_data = out_f.read()
+        out_f.close()
+       os.remove(outfile)
+       
+       self.assertEqual(in_data, out_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gru/.gitignore b/gnuradio-core/src/python/gnuradio/gru/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/.gitignore b/gnuradio-core/src/python/gnuradio/gruimpl/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index 8d46e8192f90924ab72368c45f5611047f5d6388..f2808c44890a3188029edc352f32ca8b7e05df5b 100644 (file)
@@ -30,3 +30,15 @@ def hexint(mask):
   if mask >= 2**31:
      return int(mask-2**32)
   return mask
+
+def hexshort(mask):
+  """
+  Convert unsigned masks into signed shorts.
+
+  This allows us to use hex constants like 0x8000 when talking to
+  our hardware and not get screwed by them getting treated as python
+  longs.
+  """
+  if mask >= 2**15:
+    return int(mask-2**16)
+  return mask
diff --git a/gnuradio-core/src/python/gnuradio/modulation_utils2.py b/gnuradio-core/src/python/gnuradio/modulation_utils2.py
new file mode 100644 (file)
index 0000000..c5dba3e
--- /dev/null
@@ -0,0 +1,81 @@
+#
+# Copyright 2010 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+Miscellaneous utilities for managing mods and demods, as well as other items
+useful in dealing with generalized handling of different modulations and demods.
+"""
+
+import inspect
+
+
+# Type 1 modulators accept a stream of bytes on their input and produce complex baseband output
+_type_1_modulators = {}
+
+def type_1_mods():
+    return _type_1_modulators
+
+def add_type_1_mod(name, mod_class):
+    _type_1_modulators[name] = mod_class
+
+
+# Type 1 demodulators accept complex baseband input and produce a stream of bits, packed
+# 1 bit / byte as their output.  Their output is completely unambiguous.  There is no need
+# to resolve phase or polarity ambiguities.
+_type_1_demodulators = {}
+
+def type_1_demods():
+    return _type_1_demodulators
+
+def add_type_1_demod(name, demod_class):
+    _type_1_demodulators[name] = demod_class
+
+
+def extract_kwargs_from_options(function, excluded_args, options):
+    """
+    Given a function, a list of excluded arguments and the result of
+    parsing command line options, create a dictionary of key word
+    arguments suitable for passing to the function.  The dictionary
+    will be populated with key/value pairs where the keys are those
+    that are common to the function's argument list (minus the
+    excluded_args) and the attributes in options.  The values are the
+    corresponding values from options unless that value is None.
+    In that case, the corresponding dictionary entry is not populated.
+
+    (This allows different modulations that have the same parameter
+    names, but different default values to coexist.  The downside is
+    that --help in the option parser will list the default as None,
+    but in that case the default provided in the __init__ argument
+    list will be used since there is no kwargs entry.)
+
+    @param function: the function whose parameter list will be examined
+    @param excluded_args: function arguments that are NOT to be added to the dictionary
+    @type excluded_args: sequence of strings
+    @param options: result of command argument parsing
+    @type options: optparse.Values
+    """
+    # Try this in C++ ;)
+    args, varargs, varkw, defaults = inspect.getargspec(function)
+    d = {}
+    for kw in [a for a in args if a not in excluded_args]:
+        if hasattr(options, kw):
+            if getattr(options, kw) is not None:
+                d[kw] = getattr(options, kw)
+    return d
index bd43fcc9744bc64fbd187456c74d34042782e99f..aee1d2a0c19ac819aa7d6b2b632c2284d1915761 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004,2005 Free Software Foundation, Inc.
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -27,32 +27,131 @@ For a great intro to how all this stuff works, see section 6.6 of
 and Barrie W. Jervis, Adison-Wesley, 1993.  ISBN 0-201-54413-X.
 '''
 
-import math
+import math, cmath
 from gnuradio import gr
 
 remez = gr.remez
 
 # ----------------------------------------------------------------
 
+##  Builds a low pass filter.
+#   @param gain  Filter gain in the passband (linear)
+#   @param Fs    Sampling rate (sps)
+#   @param freq1 End of pass band (in Hz)
+#   @param freq2 Start of stop band (in Hz)
+#   @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+#   @param stopband_atten_db  Stop band attenuation in dB (should be large, >= 60)
+#   @param nextra_taps  Extra taps to use in the filter (default=2)
 def low_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
-              nextra_taps=0):
+              nextra_taps=2):
     passband_dev = passband_ripple_to_dev (passband_ripple_db)
     stopband_dev = stopband_atten_to_dev (stopband_atten_db)
     desired_ampls = (gain, 0)
     (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
                                [passband_dev, stopband_dev], Fs)
+    # The remezord typically under-estimates the filter order, so add 2 taps by default
     taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
     return taps
 
-# FIXME high_passs is broken...
-def high_pass (Fs, freq1, freq2, stopband_atten_db, passband_ripple_db, 
-               nextra_taps=0):
-    """FIXME: broken"""
+##  Builds a band pass filter.
+#   @param gain  Filter gain in the passband (linear)
+#   @param Fs    Sampling rate (sps)
+#   @param freq_sb1 End of stop band (in Hz)
+#   @param freq_pb1 Start of pass band (in Hz)
+#   @param freq_pb2 End of pass band (in Hz)
+#   @param freq_sb2 Start of stop band (in Hz)
+#   @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+#   @param stopband_atten_db  Stop band attenuation in dB (should be large, >= 60)
+#   @param nextra_taps  Extra taps to use in the filter (default=2)
+def band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+               passband_ripple_db, stopband_atten_db,
+               nextra_taps=2):
+    passband_dev = passband_ripple_to_dev (passband_ripple_db)
+    stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+    desired_ampls = (0, gain, 0)
+    desired_freqs = [freq_sb1, freq_pb1, freq_pb2, freq_sb2]
+    desired_ripple = [stopband_dev, passband_dev, stopband_dev]
+    (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+                               desired_ripple, Fs)
+    # The remezord typically under-estimates the filter order, so add 2 taps by default
+    taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+    return taps
+
+
+##  Builds a band pass filter with complex taps by making an LPF and
+#   spinning it up to the right center frequency
+#   @param gain  Filter gain in the passband (linear)
+#   @param Fs    Sampling rate (sps)
+#   @param freq_sb1 End of stop band (in Hz)
+#   @param freq_pb1 Start of pass band (in Hz)
+#   @param freq_pb2 End of pass band (in Hz)
+#   @param freq_sb2 Start of stop band (in Hz)
+#   @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+#   @param stopband_atten_db  Stop band attenuation in dB (should be large, >= 60)
+#   @param nextra_taps  Extra taps to use in the filter (default=2)
+def complex_band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+                       passband_ripple_db, stopband_atten_db,
+                       nextra_taps=2):
+    center_freq = (freq_pb2 + freq_pb1) / 2.0
+    lp_pb = (freq_pb2 - center_freq)/1.0
+    lp_sb = freq_sb2 - center_freq
+    lptaps = low_pass(gain, Fs, lp_pb, lp_sb, passband_ripple_db,
+                      stopband_atten_db, nextra_taps)
+    spinner = [cmath.exp(2j*cmath.pi*center_freq/Fs*i) for i in xrange(len(lptaps))]
+    taps = [s*t for s,t in zip(spinner, lptaps)]
+    return taps
+
+
+##  Builds a band reject filter
+#   spinning it up to the right center frequency
+#   @param gain  Filter gain in the passband (linear)
+#   @param Fs    Sampling rate (sps)
+#   @param freq_pb1 End of pass band (in Hz)
+#   @param freq_sb1 Start of stop band (in Hz)
+#   @param freq_sb2 End of stop band (in Hz)
+#   @param freq_pb2 Start of pass band (in Hz)
+#   @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+#   @param stopband_atten_db  Stop band attenuation in dB (should be large, >= 60)
+#   @param nextra_taps  Extra taps to use in the filter (default=2)
+def band_reject (gain, Fs, freq_pb1, freq_sb1, freq_sb2, freq_pb2,
+                 passband_ripple_db, stopband_atten_db,
+                 nextra_taps=2):
+    passband_dev = passband_ripple_to_dev (passband_ripple_db)
+    stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+    desired_ampls = (gain, 0, gain)
+    desired_freqs = [freq_pb1, freq_sb1, freq_sb2, freq_pb2]
+    desired_ripple = [passband_dev, stopband_dev, passband_dev]
+    (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+                               desired_ripple, Fs)
+    # Make sure we use an odd number of taps
+    if((n+nextra_taps)%2 == 1):
+        n += 1
+    # The remezord typically under-estimates the filter order, so add 2 taps by default
+    taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+    return taps
+
+
+##  Builds a high pass filter.
+#   @param gain  Filter gain in the passband (linear)
+#   @param Fs    Sampling rate (sps)
+#   @param freq1 End of stop band (in Hz)
+#   @param freq2 Start of pass band (in Hz)
+#   @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+#   @param stopband_atten_db  Stop band attenuation in dB (should be large, >= 60)
+#   @param nextra_taps  Extra taps to use in the filter (default=2)
+def high_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+               nextra_taps=2):
     passband_dev = passband_ripple_to_dev (passband_ripple_db)
     stopband_dev = stopband_atten_to_dev (stopband_atten_db)
     desired_ampls = (0, 1)
     (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
                                [stopband_dev, passband_dev], Fs)
+    # For a HPF, we need to use an odd number of taps
+    # In gr.remez, ntaps = n+1, so n must be even
+    if((n+nextra_taps)%2 == 1):
+        n += 1
+        
+    # The remezord typically under-estimates the filter order, so add 2 taps by default
     taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
     return taps
 
index 1417c17fa5b1d731a70bd07571040b66b710d5ed..e36b05413e1137b0a814eedd8dae635210d9336c 100644 (file)
@@ -143,7 +143,7 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
                        (payload_with_crc), '\x55'))
 
     if pad_for_usrp:
-        pkt = pkt + (_npadding_bytes(len(pkt), samples_per_symbol, bits_per_symbol) * '\x55')
+        pkt = pkt + (_npadding_bytes(len(pkt), int(samples_per_symbol), bits_per_symbol) * '\x55')
 
     #print "make_packet: len(pkt) =", len(pkt)
     return pkt
diff --git a/gnuradio-core/src/python/gnuradio/usrp_options.py b/gnuradio-core/src/python/gnuradio/usrp_options.py
new file mode 100644 (file)
index 0000000..86dba2f
--- /dev/null
@@ -0,0 +1,123 @@
+#
+# Copyright 2009 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.
+#
+
+_parser_to_groups_dict = dict()
+class _parser_groups(object):
+    def __init__(self, parser):
+        self.usrpx_grp = parser.add_option_group("General USRP Options")
+        self.usrp1_grp = parser.add_option_group("USRP1 Specific Options")
+        self.usrp1exp_grp = parser.add_option_group("USRP1 Expert Options")
+        self.usrp2_grp = parser.add_option_group("USRP2 Specific Options")
+
+from gnuradio import blks2
+
+def _add_options(parser):
+    """
+    Add options to manually choose between usrp or usrp2.
+    Add options for usb. Add options common to source and sink.
+    @param parser: instance of OptionParser
+    @return the parser group
+    """
+    #cache groups so they dont get added twice on tranceiver apps
+    if not _parser_to_groups_dict.has_key(parser): _parser_to_groups_dict[parser] = _parser_groups(parser)
+    pg = _parser_to_groups_dict[parser]
+    #pick usrp or usrp2
+    pg.usrpx_grp.add_option("-u", "--usrpx", type="string", default=None,
+                      help="specify which usrp model: 1 for USRP, 2 for USRP2 [default=auto]")
+    #fast usb options
+    pg.usrp1exp_grp.add_option("-B", "--fusb-block-size", type="int", default=0,
+                      help="specify fast usb block size [default=%default]")
+    pg.usrp1exp_grp.add_option("-N", "--fusb-nblocks", type="int", default=0,
+                      help="specify number of fast usb blocks [default=%default]")
+    #lo offset
+    pg.usrpx_grp.add_option("--lo-offset", type="eng_float", default=None,
+                      help="set LO Offset in Hz [default=automatic].")
+    #usrp options
+    pg.usrp1_grp.add_option("-w", "--which", type="int", default=0,
+                      help="select USRP board [default=%default]")
+    #usrp2 options
+    pg.usrp2_grp.add_option("-e", "--interface", type="string", default="eth0",
+                      help="Use USRP2 at specified Ethernet interface [default=%default]")
+    pg.usrp2_grp.add_option("-a", "--mac-addr", type="string", default="",
+                      help="Use USRP2 at specified MAC address [default=None]")
+    return pg
+
+def add_rx_options(parser):
+    """
+    Add receive specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.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")
+    pg.usrpx_grp.add_option("--show-rx-gain-range", action="store_true", default=False, 
+                      help="print min and max Rx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decimation rate to DECIM [default=%default]")
+
+def create_usrp_source(options):
+    u = blks2.generic_usrp_source_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.rx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.rx_gain,
+    )
+    if options.show_rx_gain_range:
+        print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
+
+def add_tx_options(parser):
+    """
+    Add transmit specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.add_option("--tx-gain", type="eng_float", default=None, metavar="GAIN",
+                      help="set transmitter gain in dB [default=midpoint].  See also --show-tx-gain-range")
+    pg.usrpx_grp.add_option("--show-tx-gain-range", action="store_true", default=False, 
+                      help="print min and max Tx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+
+def create_usrp_sink(options):
+    u = blks2.generic_usrp_sink_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.tx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.tx_gain,
+    )
+    if options.show_tx_gain_range:
+        print "Tx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
diff --git a/gnuradio-core/src/python/gnuradio/vocoder/.gitignore b/gnuradio-core/src/python/gnuradio/vocoder/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index fb4a10675be587c1371d1d4156d7ce3fc3e6554e..e109a98920300a14df862e5fede79fd21cd27b93 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004,2005 Free Software Foundation, Inc.
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -153,32 +153,6 @@ def riemann(fft_size):
         j -= 1
     return window
 
-def blackmanharris(fft_size):
-    a0 = 0.35875
-    a1 = 0.48829
-    a2 = 0.14128
-    a3 = 0.01168
-    window = [0 for i in range(fft_size)]
-    for index in xrange(fft_size):
-        window[index] = a0 
-        window[index] -= a1*math.cos(2.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] += a2*math.cos(4.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] -= a3*math.cos(6.0*math.pi*(index+0.5)/(fft_size - 1))
-    return window
-
-def nuttall(fft_size):
-    a0 = 0.3635819
-    a1 = 0.4891775
-    a2 = 0.1365995
-    a3 = 0.0106411
-    window = [0 for i in range(fft_size)]
-    for index in xrange(fft_size):
-        window[index] = a0 
-        window[index] -= a1*math.cos(2.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] += a2*math.cos(4.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] -= a3*math.cos(6.0*math.pi*(index+0.5)/(fft_size - 1))
-    return window
-
 def kaiser(fft_size,beta):
     ibeta = 1.0/izero(beta)
     inm1 = 1.0/(fft_size)
@@ -187,4 +161,20 @@ def kaiser(fft_size,beta):
         window[index] = izero(beta*math.sqrt(1.0 - (index * inm1)*(index * inm1))) * ibeta
     return window
 
-    
+# Closure to generate functions to create cos windows
+
+def coswindow(coeffs):
+    def closure(fft_size):
+        window = [0] * fft_size
+        #print list(enumerate(coeffs))
+        for w_index in range(fft_size):
+            for (c_index, coeff) in enumerate(coeffs):
+                window[w_index] += (-1)**c_index * coeff * math.cos(2.0*c_index*math.pi*(w_index+0.5)/(fft_size-1))
+        return window
+    return closure
+
+blackmanharris = coswindow((0.35875,0.48829,0.14128,0.01168))
+nuttall = coswindow((0.3635819,0.4891775,0.1365995,0.0106411))  # Wikipedia calls this Blackman-Nuttall
+nuttall_cfd = coswindow((0.355768,0.487396,0.144232,0.012604)) # Wikipedia calls this Nuttall, continuous first deriv
+flattop = coswindow((1.0,1.93,1.29,0.388,0.032)) # Flat top window, coeffs from Wikipedia
+rectangular = lambda fft_size: [1]*fft_size
diff --git a/gnuradio-core/src/tests/.gitignore b/gnuradio-core/src/tests/.gitignore
new file mode 100644 (file)
index 0000000..8687003
--- /dev/null
@@ -0,0 +1,28 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/t1
+/test_dtv
+/check_dups
+/test_gr
+/test_all
+/exercise_correlator
+/test_grbase
+/test_vmcircbuf
+/test_atsc
+/test_general
+/test_runtime
+/test_filter
+/benchmark_dotprod_fff
+/benchmark_dotprod_ccc
+/benchmark_dotprod_fcc
+/benchmark_dotprod_scc
+/benchmark_nco
+/benchmark_dotprod_ccf
+/benchmark_dotprod_fsf
+/benchmark_vco
diff --git a/gnuradio-core/src/tests/nco_results b/gnuradio-core/src/tests/nco_results
new file mode 100644 (file)
index 0000000..5bdf5dd
--- /dev/null
@@ -0,0 +1,48 @@
+================================================================
+These are on a 1.4 GHz Pentium M using g++ 3.4.1
+================================================================
+
+Default compiler options -O2
+
+        nop loop:  cpu:  0.015  steps/sec:  6.668e+08
+     native sine:  cpu:  0.900  steps/sec:  1.111e+07
+       fxpt sine:  cpu:  0.281  steps/sec:  3.559e+07
+  native sin/cos:  cpu:  1.138  steps/sec:  8.789e+06
+    fxpt sin/cos:  cpu:  0.550  steps/sec:  1.818e+07
+
+-O2 -march=pentium-m -fomit-frame-pointer
+
+        nop loop:  cpu:  0.015  steps/sec:  6.668e+08
+     native sine:  cpu:  0.903  steps/sec:  1.108e+07
+       fxpt sine:  cpu:  0.271  steps/sec:  3.691e+07
+  native sin/cos:  cpu:  1.092  steps/sec:  9.159e+06
+    fxpt sin/cos:  cpu:  0.542  steps/sec:  1.845e+07
+
+Inlined fxpt::sin & cos
+-O2 -march=pentium-m -fomit-frame-pointer
+
+        nop loop:  cpu:  0.015  steps/sec:  6.668e+08
+     native sine:  cpu:  0.904  steps/sec:  1.106e+07
+       fxpt sine:  cpu:  0.187  steps/sec:  5.348e+07
+  native sin/cos:  cpu:  1.091  steps/sec:  9.167e+06
+    fxpt sin/cos:  cpu:  0.373  steps/sec:  2.681e+07
+
+================================================================
+These are on a 1.5 GHz Athon MP 1800+
+================================================================
+
+Default compiler options: -O2
+
+        nop loop:  cpu:  0.013  steps/sec:  7.693e+08
+     native sine:  cpu:  0.733  steps/sec:  1.364e+07
+       fxpt sine:  cpu:  0.210  steps/sec:  4.763e+07
+  native sin/cos:  cpu:  1.183  steps/sec:  8.454e+06
+    fxpt sin/cos:  cpu:  0.420  steps/sec:  2.381e+07
+
+-O2 -fomit-frame-pointer -march=athlon-mp
+
+        nop loop:  cpu:  0.013  steps/sec:  7.693e+08
+     native sine:  cpu:  0.679  steps/sec:  1.473e+07
+       fxpt sine:  cpu:  0.200  steps/sec:  5.001e+07
+  native sin/cos:  cpu:  1.147  steps/sec:  8.720e+06
+    fxpt sin/cos:  cpu:  0.444  steps/sec:  2.253e+07
diff --git a/gnuradio-core/src/tests/test_atsc.cc b/gnuradio-core/src/tests/test_atsc.cc
new file mode 100644 (file)
index 0000000..f744d76
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_atsc.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_atsc::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gnuradio-core/src/utils/.gitignore b/gnuradio-core/src/utils/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gnuradio-core/src/utils/cool.m b/gnuradio-core/src/utils/cool.m
new file mode 100644 (file)
index 0000000..e996a3a
--- /dev/null
@@ -0,0 +1,50 @@
+%% Copyright (C) 1999,2000  Kai Habel
+%%
+%% This program 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 of the License, or
+%% (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program; if not, write to the Free Software
+%% Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
+
+%% -*- texinfo -*-
+%% @deftypefn {Function File} {} cool (@var{n})
+%% Create color colormap. 
+%% (cyan to magenta)
+%% The argument @var{n} should be a scalar.  If it
+%% is omitted, the length of the current colormap or 64 is assumed.
+%% @end deftypefn
+%% @seealso{colormap}
+
+%% Author:  Kai Habel <kai.habel@gmx.de>
+
+function map = cool (number)
+
+  if (nargin == 0)
+    number = rows (colormap);
+  elseif (nargin == 1)
+    if (! is_scalar (number))
+      error ("cool: argument must be a scalar");
+    end
+  else
+    usage ("cool (number)");
+  end
+
+  if (number == 1)
+    map = [0, 1, 1];  
+  elseif (number > 1)
+    r = (0:number - 1)' ./ (number - 1);
+    g = 1 - r;
+    b = ones (number, 1);
+    map = [r, g, b];
+  else
+    map = [];
+  end
+
diff --git a/gnuradio-core/src/utils/is_complex.m b/gnuradio-core/src/utils/is_complex.m
new file mode 100644 (file)
index 0000000..ce9a701
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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.
+# 
+
+function p = is_complex (x)
+  p = any (imag (x) != 0);
+endfunction;
diff --git a/gnuradio-core/src/utils/lp_to_bp.m b/gnuradio-core/src/utils/lp_to_bp.m
new file mode 100644 (file)
index 0000000..e4ef317
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Copyright 2002 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.
+# 
+
+## transform low pass coefficients into bandpass coefficients
+
+function bp_taps = lp_to_bp (lp_taps, center_freq, sampling_freq)
+  arg = 2 * pi * center_freq / sampling_freq;
+  bp_taps = lp_taps .* exp (j*arg*(0:length(lp_taps)-1)');
+endfunction
diff --git a/gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm b/gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm
new file mode 100644 (file)
index 0000000..598f79d
--- /dev/null
@@ -0,0 +1,68 @@
+;; Estimate the total work (ntaps * sampling rate) for two cascaded
+;; decimating low pass filters.
+;;
+;; The basic assumption is that the number of taps required in any 
+;; section is inversely proportional to the normalized transition width
+;; for that section.
+;;
+;; FS is the input sampling frequency
+;; F1 is the cutoff frequency
+;; F2 is the far edge of the transition band
+;; DEC1 is the decimation factor for the first filter
+;; DEC2 is the decimation factor for the 2nd filter
+;;
+;; The total decimation factor is DEC1 * DEC2.  Therefore,
+;; the output rate of the filter is FS / (DEC1 * DEC2)
+
+(require 'common-list-functions)
+(require 'factor)
+
+
+
+(define (work2 fs f1 f2 dec1 dec2)
+  (+ (work1 fs f1 (/ fs (* 2 dec1)) dec1)
+     (work1 (/ fs dec1) f1 f2 dec2)))
+
+
+;; work for a single section
+
+(define (work1 fs f1 f2 dec)
+  (/ (* fs (/ fs (- f2 f1))) dec))
+
+
+;; return the max integer dec such that fs/(2*dec) >= f2
+
+(define (max-dec fs f2)
+  (inexact->exact (floor (/ fs (* 2 f2)))))
+
+
+;; `adjoin' returns the adjoint of the element OBJ and the list LST.
+;;  That is, if OBJ is in LST, `adjoin' returns LST, otherwise, it returns
+;;  `(cons OBJ LST)'.
+
+(define (adjoin-equal obj lst)
+  (if (member obj lst) lst (cons obj lst)))
+
+
+;;; not quite right
+
+(define (permute lst)
+  (let ((result '()))
+    (define (aux set head)
+      (if (null? set)
+         (set! result (cons head result))
+         (for-each (lambda (x)
+                     (aux (set-difference set (list x))
+                          (cons x head)))
+                   set)))
+    (aux lst '())
+    result))
+
+;; `extract-nth' returns the Nth element of LST consed on to the
+;; list resulting from splicing out the Nth element of LST.
+;; Indexing is 0 based.
+
+(define (extract-nth n lst)
+  lst)
+
+  
\ No newline at end of file
diff --git a/gnuradio-core/src/utils/permute.scm b/gnuradio-core/src/utils/permute.scm
new file mode 100644 (file)
index 0000000..23ddfc9
--- /dev/null
@@ -0,0 +1,27 @@
+(require 'common-list-functions)
+
+
+(define (permute lst)
+  (define (aux set head)
+    (cond ((null? set) head)
+         (else
+          (map (lambda (x)
+                 (aux (set-difference set (list x))
+                      (cons x head)))
+               set))))
+  (aux lst '()))
+
+(define (permute-2 lst)
+  (let ((result '()))
+    (define (aux set head)
+      (if (null? set)
+         (set! result (cons head result))
+         (for-each (lambda (x)
+                     (aux (set-difference set (list x))
+                          (cons x head)))
+                   set)))
+    (aux lst '())
+    result))
+
+
+
diff --git a/gnuradio-core/src/utils/plot_cic_decimator_response.m b/gnuradio-core/src/utils/plot_cic_decimator_response.m
new file mode 100644 (file)
index 0000000..50d85e4
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# 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.
+# 
+
+function plot_cic_decimator_response (R, N, M)
+  ## R = decimation rate
+  ## N = number of stages (4)
+  ## M = 1
+  gain = (R*M)^N
+  npoints = 1024;
+  w = 0:1/npoints:1-1/npoints;
+  w = w * 1 * pi;
+  ## w = w * R;
+  length(w);
+  num = sin (w*R*M/2);
+  length (num);
+  ## H = sin (w*R*M/2) ./ sin (w/2)
+  denom = sin(w/2);
+  length (denom);
+  H = (num ./ denom) .^ N;
+  H(1) = gain;
+  H = H ./ gain;
+  plot (R*w/(2*pi), 10 * log10 (H));
+  ## plot (R*w/(2*pi), H);
+endfunction
+
+
+  
\ No newline at end of file
diff --git a/gnuradio-core/src/utils/rainbow.m b/gnuradio-core/src/utils/rainbow.m
new file mode 100644 (file)
index 0000000..9b16aab
--- /dev/null
@@ -0,0 +1,53 @@
+## Copyright (C) 1999,2000  Kai Habel
+##
+## This program 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 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rainbow (@var{n})
+## Create color colormap. 
+## (red through yellow, green, cyan,blue,magenta to red)
+## The argument @var{n} should be a scalar.  If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @end deftypefn
+## @seealso{colormap}
+
+## Author:  Kai Habel <kai.habel@gmx.de>
+
+## 2001-09-13 Paul Kienzle <pkienzle@users.sf.net>
+## * renamed to rainbow for use with tk_octave
+## * remove reference to __current_color_map__
+
+function map = rainbow (number)
+
+  if (nargin == 0)
+    number = length(colormap);
+  elseif (nargin == 1)
+    if (! is_scalar (number))
+      error ("rainbow: argument must be a scalar");
+    endif
+  else
+    usage ("rainbow (number)");
+  endif
+
+  if (number == 1)
+    map = [1, 0, 0];  
+  elseif (number > 1)
+    h = linspace (0, 1, number)';
+    map = hsv2rgb ([h, ones(number, 1), ones(number, 1)]);
+  else
+    map = [];
+  endif
+
+endfunction
diff --git a/gnuradio-core/src/utils/read_xambi.m b/gnuradio-core/src/utils/read_xambi.m
new file mode 100644 (file)
index 0000000..ac5bf38
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Copyright 2001,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.
+# 
+
+function v = read_xambi (filename)
+
+  ## usage: read_xambi (filename)
+  ##
+  ## read binary cross-ambiguity data from radar tools.
+  ## The file has an 8 float header, the first word of which specifies
+  ## the number of doppler bins.
+  ## returns a matrix
+
+  if ((m = nargchk (1,1,nargin)))
+    usage (m);
+  endif;
+
+  f = fopen (filename, "rb");
+  if (f < 0)
+    v = 0;
+  else
+    header = fread(f, 8, "float");
+    ndoppler_bins = header(1)
+    min_doppler = header(2)
+    max_doppler = header(3)
+    v = fread (f, [ndoppler_bins, Inf], "float");
+    fclose (f);
+  endif;
+endfunction;
diff --git a/gnuradio-core/src/utils/runsum.m b/gnuradio-core/src/utils/runsum.m
new file mode 100644 (file)
index 0000000..0f530b0
--- /dev/null
@@ -0,0 +1,9 @@
+function r = runsum(x)
+  len = length(x);
+  r = zeros (1, len);
+  r(1) = x(1);
+  for i = 2:len;
+    r(i) = r(i-1) + x(i);
+  endfor;
+endfunction;
+
diff --git a/gnuradio-core/src/utils/split_vect.m b/gnuradio-core/src/utils/split_vect.m
new file mode 100644 (file)
index 0000000..c492581
--- /dev/null
@@ -0,0 +1,15 @@
+% split vector into packets
+
+function y = split_vect(vect,N)
+  Z = floor(max(size(vect))/N);
+  y = [];
+  if(size(vect)(1)>size(vect)(2)) 
+    v = vect';
+  else
+    v = vect;
+  end
+  for i=1:Z
+    y(i,1:N) = v((i-1)*N+1:i*N);
+  end
+end
+
diff --git a/gnuradio-examples/.gitignore b/gnuradio-examples/.gitignore
new file mode 100644 (file)
index 0000000..29ec71e
--- /dev/null
@@ -0,0 +1,25 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/gnuradio.pc
index 41e9ee4d6101d337953547d5c2a5f314dbfd7caf..9ea890c120261389eb6a40d6d798324ff1efdec2 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004,2007 Free Software Foundation, Inc.
+# Copyright 2004,2007,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -21,4 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = python c++
+SUBDIRS = c++
+if PYTHON
+SUBDIRS += python grc
+endif
diff --git a/gnuradio-examples/c++/.gitignore b/gnuradio-examples/c++/.gitignore
new file mode 100644 (file)
index 0000000..19dd0e0
--- /dev/null
@@ -0,0 +1,5 @@
+/.deps
+/.libs
+/Makefile
+/Makefile.in
+/dialtone
diff --git a/gnuradio-examples/c++/dial_tone/.gitignore b/gnuradio-examples/c++/dial_tone/.gitignore
new file mode 100644 (file)
index 0000000..c5e3458
--- /dev/null
@@ -0,0 +1,5 @@
+/.deps
+/.libs
+/Makefile
+/Makefile.in
+/dial_tone
diff --git a/gnuradio-examples/c++/dial_tone/Makefile.am b/gnuradio-examples/c++/dial_tone/Makefile.am
new file mode 100644 (file)
index 0000000..ea34bee
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright 2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# For compiling within the GNU Radio build tree
+AM_CPPFLAGS=$(STD_DEFINES_AND_INCLUDES) \
+         -I$(top_srcdir)/gr-audio-alsa/src \
+        $(WITH_INCLUDES)
+
+GR_AUDIO_ALSA_LA=$(top_builddir)/gr-audio-alsa/src/libgnuradio-audio-alsa.la
+
+# For compiling outside the tree, these will get fished out by pkgconfig
+
+noinst_PROGRAMS = dial_tone
+
+noinst_HEADERS = \
+    dial_tone.h
+
+dial_tone_SOURCES = \
+    dial_tone.cc          \
+    main.cc
+
+dial_tone_LDADD = \
+    $(GNURADIO_CORE_LA) \
+    $(GR_AUDIO_ALSA_LA)
diff --git a/gnuradio-examples/c++/dial_tone/README b/gnuradio-examples/c++/dial_tone/README
new file mode 100644 (file)
index 0000000..6d5ed50
--- /dev/null
@@ -0,0 +1,16 @@
+This example requires that gr-audio-alsa be built in the main tree in order
+to compile successfully.  It is not built automatically.
+
+To build this example, you must make two modifications to the build system:
+
+1) Add the following line inside config/grc_gnuradio_examples.m4:
+
+   gnuradio-examples/c++/dial_tone/Makefile
+   
+   ...to the list of Makefiles already in there.
+   
+2) In gnuradio-examples/c++/Makefile.am, uncomment the SUBDIRS line
+
+# SUBDIRS = dial_tone
+
+Then, from the top-level directory, re-run ./bootstrap and ./configure.
\ No newline at end of file
diff --git a/gnuradio-examples/c++/dial_tone/dial_tone.cc b/gnuradio-examples/c++/dial_tone/dial_tone.cc
new file mode 100644 (file)
index 0000000..9a2772a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006,2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <dial_tone.h>
+#include <gr_io_signature.h>
+#include <gr_sig_source_f.h>
+#include <audio_alsa_sink.h>
+
+// Shared pointer constructor
+dial_tone_sptr make_dial_tone()
+{
+  return gnuradio::get_initial_sptr(new dial_tone());
+}
+
+// Hierarchical block constructor, with no inputs or outputs
+dial_tone::dial_tone() : 
+    gr_top_block("dial_tone")
+{
+    gr_sig_source_f_sptr src0 = gr_make_sig_source_f(48000, GR_SIN_WAVE, 350, 0.1);
+    gr_sig_source_f_sptr src1 = gr_make_sig_source_f(48000, GR_SIN_WAVE, 440, 0.1);
+    audio_alsa_sink_sptr sink = audio_alsa_make_sink(48000);
+
+    connect(src0, 0, sink, 0);
+    connect(src1, 0, sink, 1);
+}
diff --git a/gnuradio-examples/c++/dial_tone/dial_tone.h b/gnuradio-examples/c++/dial_tone/dial_tone.h
new file mode 100644 (file)
index 0000000..c645439
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include <gr_top_block.h>
+
+class dial_tone;
+typedef boost::shared_ptr<dial_tone> dial_tone_sptr;
+dial_tone_sptr make_dial_tone();
+
+class dial_tone : public gr_top_block
+{
+private:
+    dial_tone();
+    friend dial_tone_sptr make_dial_tone();
+};
diff --git a/gnuradio-examples/c++/dial_tone/main.cc b/gnuradio-examples/c++/dial_tone/main.cc
new file mode 100644 (file)
index 0000000..a09bd82
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+// GNU Radio C++ application
+//
+// Instantiate a top block
+// Instantiate a runtime, passing it the top block
+// Tell the runtime to go...
+
+#include <dial_tone.h>
+
+int main()
+{
+    dial_tone_sptr top_block = make_dial_tone();
+    top_block->run();   
+    return 0;
+}
diff --git a/gnuradio-examples/grc/.gitignore b/gnuradio-examples/grc/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gnuradio-examples/grc/Makefile.am b/gnuradio-examples/grc/Makefile.am
new file mode 100644 (file)
index 0000000..118ecd5
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+grc_examples_prefix = $(exampledir)/grc
+
+audiodatadir = $(grc_examples_prefix)/audio
+dist_audiodata_DATA = \
+       audio/dial_tone.grc \
+       audio/cvsd_sweep.grc
+
+demoddatadir = $(grc_examples_prefix)/demod
+dist_demoddata_DATA = \
+       demod/mpsk_demod.grc \
+       demod/pam_timing.grc \
+       demod/pam_sync.grc \
+       demod/digital_freq_lock.grc
+
+simpledatadir = $(grc_examples_prefix)/simple
+dist_simpledata_DATA = \
+       simple/ber_simulation.grc \
+       simple/dpsk_loopback.grc \
+       simple/variable_config.grc \
+       simple/var_sink_taps.grc
+
+trellisdatadir = $(grc_examples_prefix)/trellis
+dist_trellisdata_DATA = \
+       trellis/readme.txt \
+       trellis/interference_cancellation.grc
+
+usrpdatadir = $(grc_examples_prefix)/usrp
+dist_usrpdata_DATA = \
+       usrp/usrp2_const_wave.grc \
+       usrp/usrp2_dpsk_mod.grc \
+       usrp/usrp_rx_dpsk.grc \
+       usrp/usrp_tx_dpsk.grc \
+       usrp/usrp2_fft.grc \
+       usrp/usrp_two_tone_loopback.grc \
+       usrp/usrp_wbfm_receive.grc
+
+xmlrpcdatadir = $(grc_examples_prefix)/xmlrpc
+dist_xmlrpcdata_DATA = \
+       xmlrpc/readme.txt \
+       xmlrpc/xmlrpc_client.grc \
+       xmlrpc/xmlrpc_client_script.py\
+       xmlrpc/xmlrpc_server.grc
diff --git a/gnuradio-examples/grc/audio/cvsd_sweep.grc b/gnuradio-examples/grc/audio/cvsd_sweep.grc
new file mode 100644 (file)
index 0000000..8d0b385
--- /dev/null
@@ -0,0 +1,918 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sat Sep 19 20:30:08 2009</timestamp>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(157, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_cvsd_decode</key>
+    <param>
+      <key>id</key>
+      <value>blks2_cvsd_decode_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>resample</key>
+      <value>resample</value>
+    </param>
+    <param>
+      <key>bw</key>
+      <value>bw</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(887, 340)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>tri_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_TRI_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>0.05</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(44, 316)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(238, 348)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_vco_f</key>
+    <param>
+      <key>id</key>
+      <value>vco</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>sensitivity</key>
+      <value>audio_rate*2*math.pi</value>
+    </param>
+    <param>
+      <key>amplitude</key>
+      <value>0.9</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(427, 332)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_cvsd_encode</key>
+    <param>
+      <key>id</key>
+      <value>enc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>resample</key>
+      <value>resample</value>
+    </param>
+    <param>
+      <key>bw</key>
+      <value>bw</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(655, 340)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_packed_to_unpacked_xx</key>
+    <param>
+      <key>id</key>
+      <value>p2u</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>bits_per_chunk</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>endianness</key>
+      <value>gr.GR_MSB_FIRST</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(648, 415)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_char_to_float</key>
+    <param>
+      <key>id</key>
+      <value>c2f</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(676, 483)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>audio_sink</key>
+    <param>
+      <key>id</key>
+      <value>audio_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>device_name</key>
+      <value>plughw:0,0</value>
+    </param>
+    <param>
+      <key>ok_to_block</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1127, 340)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>8000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(251, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>resample</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(344, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>bw</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(431, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Original','Encoded','Decoded']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>orig_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Original Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(415, 97)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>orig_scope</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Original Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(414, 425)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>enc_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Encoded Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate*resample</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(610, 551)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>enc_scope</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Encoded Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate*resample</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/(audio_rate*resample)</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(858, 591)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>dec_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Decoded Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(891, 98)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>dec_scope</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Decoded Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>audio_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(889, 422)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>cvsd_sweep</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>CVSD Vocoder Test</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>vco</source_block_id>
+    <sink_block_id>orig_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>tri_source</source_block_id>
+    <sink_block_id>throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>throttle</source_block_id>
+    <sink_block_id>vco</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>vco</source_block_id>
+    <sink_block_id>enc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>enc</source_block_id>
+    <sink_block_id>blks2_cvsd_decode_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>vco</source_block_id>
+    <sink_block_id>orig_scope</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_cvsd_decode_0</source_block_id>
+    <sink_block_id>dec_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_cvsd_decode_0</source_block_id>
+    <sink_block_id>dec_scope</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_cvsd_decode_0</source_block_id>
+    <sink_block_id>audio_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>enc</source_block_id>
+    <sink_block_id>p2u</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>p2u</source_block_id>
+    <sink_block_id>c2f</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>c2f</source_block_id>
+    <sink_block_id>enc_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>c2f</source_block_id>
+    <sink_block_id>enc_scope</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/audio/dial_tone.grc b/gnuradio-examples/grc/audio/dial_tone.grc
new file mode 100644 (file)
index 0000000..ac8cbef
--- /dev/null
@@ -0,0 +1,375 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Jul 24 14:27:48 2008</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>dial_tone</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Dial Tone</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>example flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>3</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(513, 277)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>audio_sink</key>
+    <param>
+      <key>id</key>
+      <value>audio_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>device_name</key>
+      <value/>
+    </param>
+    <param>
+      <key>ok_to_block</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(699, 112)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_noise_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_noise_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>noise_type</key>
+      <value>gr.GR_GAUSSIAN</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(238, 380)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>440</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(240, 208)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>350</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(240, 38)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Volume</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.4</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(634, 413)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Noise</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.005</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(443, 412)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 171)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_sig_source_x0</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sig_source_x</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_noise_source_x</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>2</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx</source_block_id>
+    <sink_block_id>audio_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/demod/digital_freq_lock.grc b/gnuradio-examples/grc/demod/digital_freq_lock.grc
new file mode 100644 (file)
index 0000000..36037fe
--- /dev/null
@@ -0,0 +1,1321 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sat Mar  6 17:17:12 2010</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>top_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(217, 108)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(216, 273)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-0.5</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(293, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 80)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 245)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(213, 197)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(200, 360)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(440, 167)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(430, 330)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>nfilts</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(435, 686)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Channel Noise</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(168, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>spb_gen</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(119, 841)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(223, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4.1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(32, 842)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_float_to_complex</key>
+    <param>
+      <key>id</key>
+      <value>gr_float_to_complex_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(590, 184)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(788, 197)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>notebook_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Freq', 'Time']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(216, 845)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Signal into Receiver</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1123, 392)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Signal into Receiver</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1122, 473)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Frequency Corrected Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1122, 680)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Frequency Corrected Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1121, 762)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(128, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sig_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(315, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rolloff</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(398, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rrctaps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.root_raised_cosine(nfilts,1.0,1.0/(spb*nfilts), .35, int(11*spb*nfilts))</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(826, 61)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>root_raised_cosine_filter</key>
+    <param>
+      <key>id</key>
+      <value>root_raised_cosine_filter_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>interp_fir_filter_ccf</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>interp</key>
+      <value>spb_gen</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>2*spb_gen</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>sym_rate</key>
+      <value>1./spb_gen</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>rolloff</value>
+    </param>
+    <param>
+      <key>ntaps</key>
+      <value>44</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(978, 157)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_fll_band_edge_cc</key>
+    <param>
+      <key>id</key>
+      <value>gr_fll_band_edge_cc_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>cc</value>
+    </param>
+    <param>
+      <key>samps_per_sym</key>
+      <value>spb_gen</value>
+    </param>
+    <param>
+      <key>rolloff</key>
+      <value>rolloff</value>
+    </param>
+    <param>
+      <key>filter_size</key>
+      <value>44</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>beta</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(874, 664)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_channel_model</key>
+    <param>
+      <key>id</key>
+      <value>gr_channel_model_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>noise_voltage</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>freq_offset</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>epsilon</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(618, 376)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>beta</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq Beta</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(668, 5)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(552, 4)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0_1</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_float_to_complex_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>root_raised_cosine_filter_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>root_raised_cosine_filter_0</source_block_id>
+    <sink_block_id>gr_channel_model_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>gr_fll_band_edge_cc_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_fll_band_edge_cc_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_fll_band_edge_cc_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/demod/mpsk_demod.grc b/gnuradio-examples/grc/demod/mpsk_demod.grc
new file mode 100644 (file)
index 0000000..08108dc
--- /dev/null
@@ -0,0 +1,586 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Mon Oct  5 18:34:52 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>mpsk_demod</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>MPSK Demod Demo</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2**8</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(155, 160)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk_mod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk_mod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dqpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>log</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(391, 54)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(654, 142)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(7, 89)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_channel_model</key>
+    <param>
+      <key>id</key>
+      <value>gr_channel_model_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>noise_voltage</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>freq_offset</key>
+      <value>freq_off</value>
+    </param>
+    <param>
+      <key>epsilon</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(487, 282)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Noise</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(259, 353)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_off</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-.5</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(126, 345)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>notebook</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Constellation', 'Spectrum']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(520, 407)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_constellationsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_constellationsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Constellation Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>frame_rate</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>const_size</key>
+      <value>2048</value>
+    </param>
+    <param>
+      <key>M</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>theta</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>fmax</key>
+      <value>0.06</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>symbol_rate</key>
+      <value>samp_rate/4.</value>
+    </param>
+    <param>
+      <key>omega_limit</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(824, 212)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(847, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>blks2_dxpsk_mod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>wxgui_constellationsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk_mod_0</source_block_id>
+    <sink_block_id>gr_channel_model_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/demod/pam_sync.grc b/gnuradio-examples/grc/demod/pam_sync.grc
new file mode 100644 (file)
index 0000000..8571995
--- /dev/null
@@ -0,0 +1,1744 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sat Mar  6 17:17:22 2010</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>top_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(217, 108)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(216, 273)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(128, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-0.5</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(293, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 80)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 245)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(213, 197)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(200, 360)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(440, 167)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(430, 330)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>nfilts</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(435, 686)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Channel Noise</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(168, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>interpratio</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1.00</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.99</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.01</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(40, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(223, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sig_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(315, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rolloff</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(253, 575)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>time_beta</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Beta</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(606, 8)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>time_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(490, 8)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>phase_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Phase Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(953, 8)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>phase_beta</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Phase Beta</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1066, 8)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_costas_loop_cc</key>
+    <param>
+      <key>id</key>
+      <value>gr_costas_loop_cc_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>phase_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>phase_beta</value>
+    </param>
+    <param>
+      <key>max_freq</key>
+      <value>0.2</value>
+    </param>
+    <param>
+      <key>min_freq</key>
+      <value>-0.2</value>
+    </param>
+    <param>
+      <key>order</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(915, 560)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Input Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1116, 559)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rrctaps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.root_raised_cosine(nfilts,1.0,1.0/(spb*nfilts), rolloff, int(11*spb*nfilts))</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(436, 755)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>notebook_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Output Signal', 'Input Signal']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(203, 823)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Input Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(975, 312)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Input Frequency</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1116, 355)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_source</key>
+    <param>
+      <key>id</key>
+      <value>virtual_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>input_signal_probe</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(801, 453)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_sink</key>
+    <param>
+      <key>id</key>
+      <value>virtual_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>input_signal_probe</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(280, 475)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Output Frequency</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(663, 687)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_pfb_clock_sync_xxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_pfb_clock_sync_xxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ccf</value>
+    </param>
+    <param>
+      <key>sps</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>time_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>time_beta</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>rrctaps</value>
+    </param>
+    <param>
+      <key>filter_size</key>
+      <value>nfilts</value>
+    </param>
+    <param>
+      <key>init_phase</key>
+      <value>16</value>
+    </param>
+    <param>
+      <key>max_dev</key>
+      <value>1.5</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(662, 527)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_float_to_complex</key>
+    <param>
+      <key>id</key>
+      <value>gr_float_to_complex_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(592, 184)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_channel_model</key>
+    <param>
+      <key>id</key>
+      <value>gr_channel_model_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>noise_voltage</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>freq_offset</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>epsilon</key>
+      <value>interpratio</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(60, 443)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>sig_amp</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(670, 322)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_pfb_arb_resampler_ccf</key>
+    <param>
+      <key>id</key>
+      <value>blks2_pfb_arb_resampler_ccf_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>firdes.root_raised_cosine(32, 32, 1.0, 0.35, 44*32)</value>
+    </param>
+    <param>
+      <key>size</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(778, 180)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_fll_band_edge_cc</key>
+    <param>
+      <key>id</key>
+      <value>gr_fll_band_edge_cc_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>cc</value>
+    </param>
+    <param>
+      <key>samps_per_sym</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>rolloff</key>
+      <value>rolloff</value>
+    </param>
+    <param>
+      <key>filter_size</key>
+      <value>44</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>freq_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>freq_beta</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(429, 528)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(40, 829)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(734, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_beta</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq Beta</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(836, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0_1</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>gr_fll_band_edge_cc_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_fll_band_edge_cc_0</source_block_id>
+    <sink_block_id>gr_pfb_clock_sync_xxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id>
+    <sink_block_id>gr_costas_loop_cc_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_costas_loop_cc_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_fll_band_edge_cc_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>virtual_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_float_to_complex_0</source_block_id>
+    <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>gr_channel_model_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/demod/pam_timing.grc b/gnuradio-examples/grc/demod/pam_timing.grc
new file mode 100644 (file)
index 0000000..02130f4
--- /dev/null
@@ -0,0 +1,1388 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Mon Feb  1 18:54:46 2010</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>top_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(217, 108)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_uchar_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_uchar_to_float_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(216, 273)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(128, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-0.5</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(293, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 80)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 245)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(213, 197)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-0.5*(pam_amp-1)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(200, 360)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>notebook_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['error', 'phase', 'freq', 'Resampled Signal']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(729, 769)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(440, 167)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(430, 330)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>nfilts</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(435, 686)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Channel Noise</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(168, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>interpratio</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1.00</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.99</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.01</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(40, 684)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>beta</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Beta</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(668, 5)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(552, 4)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>pam_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(223, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sig_amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(315, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1116, 500)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(290, 575)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Error</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>3</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1110, 651)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>9</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1112, 881)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rrctaps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.root_raised_cosine(nfilts,1.0,1.0/(spb*nfilts), .35, int(11*spb*nfilts))</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(513, 679)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_pfb_clock_sync_xxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_pfb_clock_sync_xxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ccf</value>
+    </param>
+    <param>
+      <key>sps</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>beta</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>rrctaps</value>
+    </param>
+    <param>
+      <key>filter_size</key>
+      <value>nfilts</value>
+    </param>
+    <param>
+      <key>init_phase</key>
+      <value>16</value>
+    </param>
+    <param>
+      <key>max_dev</key>
+      <value>1.5</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(512, 527)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>1.25</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1111, 767)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Error</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>notebook_0,3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1115, 358)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_float_to_complex</key>
+    <param>
+      <key>id</key>
+      <value>gr_float_to_complex_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(590, 184)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_pfb_arb_resampler_ccf</key>
+    <param>
+      <key>id</key>
+      <value>blks2_pfb_arb_resampler_ccf_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>firdes.root_raised_cosine(32, 32, 1.0, 0.35, 44*32)</value>
+    </param>
+    <param>
+      <key>size</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(816, 181)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_channel_model</key>
+    <param>
+      <key>id</key>
+      <value>gr_channel_model_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>noise_voltage</key>
+      <value>noise_amp</value>
+    </param>
+    <param>
+      <key>freq_offset</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>epsilon</key>
+      <value>interpratio</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(59, 543)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>sig_amp</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(714, 382)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>spb</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4.2563</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(42, 840)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_uchar_to_float_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>const_source_x_0_0</source_block_id>
+    <sink_block_id>gr_add_xx_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0_0</source_block_id>
+    <sink_block_id>gr_uchar_to_float_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_channel_model_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0_1</source_block_id>
+    <sink_block_id>gr_float_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>gr_pfb_clock_sync_xxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0</sink_block_id>
+    <source_key>1</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id>
+    <source_key>3</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_0_0</sink_block_id>
+    <source_key>2</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_float_to_complex_0</source_block_id>
+    <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>gr_channel_model_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/simple/ber_simulation.grc b/gnuradio-examples/grc/simple/ber_simulation.grc
new file mode 100644 (file)
index 0000000..618add2
--- /dev/null
@@ -0,0 +1,564 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Mar 19 11:08:59 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>ber_sim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER Simulation</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>Adjust the noise and constellation... see what happens!</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(16, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_noise_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_noise_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>noise_type</key>
+      <value>gr.GR_GAUSSIAN</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(235, 379)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_chunks_to_symbols_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_chunks_to_symbols_xx</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>in_type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>symbol_table</key>
+      <value>const</value>
+    </param>
+    <param>
+      <key>dimension</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(360, 237)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_numbersink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_numbersink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER</value>
+    </param>
+    <param>
+      <key>units</key>
+      <value>%</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>base_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>min_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max_value</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>factor</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>decimal_places</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>number_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>show_gauge</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1062, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 27)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_error_rate</key>
+    <param>
+      <key>id</key>
+      <value>blks2_error_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>'BER'</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value>1000000</value>
+    </param>
+    <param>
+      <key>bits_per_symbol</key>
+      <value>int(math.log(len(const))/math.log(2))</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(670, 41)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_constellation_decoder_cb</key>
+    <param>
+      <key>id</key>
+      <value>gr_constellation_decoder_cb</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>sym_position</key>
+      <value>const</value>
+    </param>
+    <param>
+      <key>sym_value_out</key>
+      <value>range(len(const))</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(708, 224)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>len(const)</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>1000000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 244)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>noise</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.25</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(18, 386)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>const</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1+1j, 1-1j, -1-1j, -1+1j</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(16, 461)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>50e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(20, 168)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(138, 168)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(652, 395)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>"Constellation: "+str(const)</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(828, 368)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>blks2_error_rate</source_block_id>
+    <sink_block_id>wxgui_numbersink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle</source_block_id>
+    <sink_block_id>blks2_error_rate</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_constellation_decoder_cb</source_block_id>
+    <sink_block_id>blks2_error_rate</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx</source_block_id>
+    <sink_block_id>gr_constellation_decoder_cb</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_chunks_to_symbols_xx</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_noise_source_x</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x</source_block_id>
+    <sink_block_id>gr_throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x</source_block_id>
+    <sink_block_id>gr_chunks_to_symbols_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/simple/dpsk_loopback.grc b/gnuradio-examples/grc/simple/dpsk_loopback.grc
new file mode 100644 (file)
index 0000000..6a507c9
--- /dev/null
@@ -0,0 +1,450 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Tue Mar 17 12:53:37 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>dpsk_loopback</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>DPSK Loopback</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>gnuradio flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk_mod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk_mod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dbpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(426, 295)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>10000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>500</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_length</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 257)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_packet_encoder</key>
+    <param>
+      <key>id</key>
+      <value>blks2_packet_encoder_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>bits_per_symbol</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>access_code</key>
+      <value></value>
+    </param>
+    <param>
+      <key>pad_for_usrp</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>payload_length</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(216, 260)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(225, 174)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(203, 8)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_packet_decoder</key>
+    <param>
+      <key>id</key>
+      <value>blks2_packet_decoder_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>access_code</key>
+      <value></value>
+    </param>
+    <param>
+      <key>threshold</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(551, 65)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>frame_decim</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>1./freq</value>
+    </param>
+    <param>
+      <key>marker</key>
+      <value>set_format_line</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(769, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk_demod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk_demod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dbpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>costas_alpha</key>
+      <value>0.175</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>0.175</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(691, 219)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>blks2_dxpsk_mod_0</source_block_id>
+    <sink_block_id>blks2_dxpsk_demod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk_demod_0</source_block_id>
+    <sink_block_id>blks2_packet_decoder_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_packet_encoder_0</source_block_id>
+    <sink_block_id>blks2_dxpsk_mod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sig_source_x_0</source_block_id>
+    <sink_block_id>gr_throttle_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0_0</source_block_id>
+    <sink_block_id>blks2_packet_encoder_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_packet_decoder_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/simple/var_sink_taps.grc b/gnuradio-examples/grc/simple/var_sink_taps.grc
new file mode 100644 (file)
index 0000000..0720785
--- /dev/null
@@ -0,0 +1,488 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Tue May 19 16:45:51 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>var_sink_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Variable Sink + Taps</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>gnuradio flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_noise_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_noise_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>noise_type</key>
+      <value>gr.GR_GAUSSIAN</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(619, 36)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_fir_filter_xxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_fir_filter_xxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ccc</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>dest_taps</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(831, 47)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(999, 198)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>270</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(629, 184)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>from gnuradio.gr import firdes</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(330, 120)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>dest_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>[0]</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(836, 223)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(831, 130)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>source_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.low_pass(1, samp_rate, 4000, 2000)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 191)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>taps_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(268, 189)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_vector_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_vector_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>vector</key>
+      <value>source_taps</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>len(source_taps)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(205, 33)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>note</key>
+    <param>
+      <key>id</key>
+      <value>note_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>note</key>
+      <value>Pass the FIR taps via a variable sink.</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(14, 141)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>taps_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>len(source_taps)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(440, 41)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_variable_sink_x</key>
+    <param>
+      <key>id</key>
+      <value>blks2_variable_sink_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>variable</key>
+      <value>dest_taps</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>len(source_taps)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(305, 283)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_noise_source_x_0</source_block_id>
+    <sink_block_id>gr_fir_filter_xxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_fir_filter_xxx_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_vector_source_x_0</source_block_id>
+    <sink_block_id>gr_throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle</source_block_id>
+    <sink_block_id>blks2_variable_sink_x_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/simple/variable_config.grc b/gnuradio-examples/grc/simple/variable_config.grc
new file mode 100644 (file)
index 0000000..95c287c
--- /dev/null
@@ -0,0 +1,329 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Jun 25 10:56:04 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>variable_config_demo</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Variable Config Block Demonstration</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>Save/Load freq from a config file.</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>autostart</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>freq_init</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config.conf</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>main</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(255, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>freq_init</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-samp_rate/2</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(429, 24)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(392, 233)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(148, 233)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(671, 233)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_sig_source_x_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/trellis/interference_cancellation.grc b/gnuradio-examples/grc/trellis/interference_cancellation.grc
new file mode 100644 (file)
index 0000000..e93babd
--- /dev/null
@@ -0,0 +1,2072 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Mar 19 11:22:40 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>int_cancellation</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Superposition Coding</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>AA</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>gnuradio flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>2048, 2048</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>P1/P</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.6</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_length</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(243, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>snr_db</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>P/sigma^2 (dB)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>16</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_length</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(447, 14)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>noisevar</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>10**(-snr_db/10)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(637, 13)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(21, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_chunks_to_symbols_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_chunks_to_symbols_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>in_type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>symbol_table</key>
+      <value>1,1j,-1j,-1</value>
+    </param>
+    <param>
+      <key>dimension</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(665, 187)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>alpha**0.5</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(988, 196)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(25, 291)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_chunks_to_symbols_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_chunks_to_symbols_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>in_type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>symbol_table</key>
+      <value>1,1j,-1j,-1</value>
+    </param>
+    <param>
+      <key>dimension</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(660, 311)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>(1-alpha)**0.5</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(994, 319)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1224, 244)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_noise_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_noise_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>noise_type</key>
+      <value>gr.GR_GAUSSIAN</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>noisevar</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1146, 369)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(536, 529)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(771, 525)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_short_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_short_to_float_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(994, 545)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_3</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(535, 792)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(785, 779)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_short_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_short_to_float_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1005, 798)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_chunks_to_symbols_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_chunks_to_symbols_xx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>in_type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>symbol_table</key>
+      <value>1,1j,-1j,-1</value>
+    </param>
+    <param>
+      <key>dimension</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(405, 998)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>alpha**0.5</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(710, 1008)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(944, 978)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(540, 1141)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_xx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(796, 1136)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_short_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_short_to_float_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1009, 1156)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_chunks_to_symbols_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_chunks_to_symbols_xx_2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>in_type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>symbol_table</key>
+      <value>1,1j,-1j,-1</value>
+    </param>
+    <param>
+      <key>dimension</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(420, 1368)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>(1-alpha)**0.5</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(733, 1374)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(975, 1342)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sub_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_sub_xx_1_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(559, 1536)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_xx_2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(771, 1530)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_short_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_short_to_float_1_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1010, 1551)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_numbersink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_numbersink2_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER 2 (raw)</value>
+    </param>
+    <param>
+      <key>units</key>
+      <value>BER</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>base_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>min_value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max_value</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>factor</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>decimal_places</key>
+      <value>6</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>number_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.001</value>
+    </param>
+    <param>
+      <key>show_gauge</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0,1,1,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1260, 659)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_numbersink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_numbersink2_3</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER 2 (after cancelling user 1)</value>
+    </param>
+    <param>
+      <key>units</key>
+      <value>BER</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>base_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>min_value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max_value</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>factor</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>decimal_places</key>
+      <value>6</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>number_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.001</value>
+    </param>
+    <param>
+      <key>show_gauge</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1,1,1,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1262, 1020)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_numbersink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_numbersink2_3_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER 1 (after cancelling user 2)</value>
+    </param>
+    <param>
+      <key>units</key>
+      <value>BER</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>base_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>min_value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max_value</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>factor</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>decimal_places</key>
+      <value>6</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>number_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.001</value>
+    </param>
+    <param>
+      <key>show_gauge</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1,0,1,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1269, 1417)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>10e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(748, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_encoder_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_encoder_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ss</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(334, 190)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_encoder_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_encoder_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ss</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(336, 311)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_viterbi_combined_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_viterbi_combined_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>c</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>block_size</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>final_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>dim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>table</key>
+      <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
+    </param>
+    <param>
+      <key>metric_type</key>
+      <value>trellis.TRELLIS_EUCLIDEAN</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(79, 501)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_viterbi_combined_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_viterbi_combined_xx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>c</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>block_size</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>final_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>dim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>table</key>
+      <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
+    </param>
+    <param>
+      <key>metric_type</key>
+      <value>trellis.TRELLIS_EUCLIDEAN</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(82, 766)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_encoder_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_encoder_xx_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ss</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(89, 998)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_viterbi_combined_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_viterbi_combined_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>c</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>block_size</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>final_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>dim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>table</key>
+      <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value>
+    </param>
+    <param>
+      <key>metric_type</key>
+      <value>trellis.TRELLIS_EUCLIDEAN</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(83, 1111)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_encoder_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_encoder_xx_2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ss</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(105, 1367)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>trellis_viterbi_combined_xx</key>
+    <param>
+      <key>id</key>
+      <value>trellis_viterbi_combined_xx_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>c</value>
+    </param>
+    <param>
+      <key>out_type</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>fsm_args</key>
+      <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value>
+    </param>
+    <param>
+      <key>block_size</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>init_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>final_state</key>
+      <value>-1</value>
+    </param>
+    <param>
+      <key>dim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>table</key>
+      <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value>
+    </param>
+    <param>
+      <key>metric_type</key>
+      <value>trellis.TRELLIS_EUCLIDEAN</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(75, 1495)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>prefix</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>"../../../"</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(871, 14)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1400, 262)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_numbersink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_numbersink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>BER 1 (raw)</value>
+    </param>
+    <param>
+      <key>units</key>
+      <value>BER</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>base_value</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>min_value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max_value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>factor</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>decimal_places</key>
+      <value>6</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>number_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.001</value>
+    </param>
+    <param>
+      <key>show_gauge</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0,0,1,1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1267, 410)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>R</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1533, 149)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_1</source_block_id>
+    <sink_block_id>trellis_encoder_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_encoder_xx_0</source_block_id>
+    <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_encoder_xx_1</source_block_id>
+    <sink_block_id>gr_chunks_to_symbols_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_chunks_to_symbols_xx_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_0</source_block_id>
+    <sink_block_id>gr_add_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_noise_source_x_0</source_block_id>
+    <sink_block_id>gr_add_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_chunks_to_symbols_xx_1</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_1</source_block_id>
+    <sink_block_id>gr_add_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_0</source_block_id>
+    <sink_block_id>gr_multiply_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_0</source_block_id>
+    <sink_block_id>gr_multiply_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_xx_0</source_block_id>
+    <sink_block_id>gr_short_to_float_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_short_to_float_0</source_block_id>
+    <sink_block_id>wxgui_numbersink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_xx_2</source_block_id>
+    <sink_block_id>gr_short_to_float_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>trellis_encoder_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_1</source_block_id>
+    <sink_block_id>trellis_viterbi_combined_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>gr_sub_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
+    <sink_block_id>gr_sub_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_0</source_block_id>
+    <sink_block_id>gr_sub_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_1</source_block_id>
+    <sink_block_id>gr_sub_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_1</source_block_id>
+    <sink_block_id>gr_multiply_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_1</source_block_id>
+    <sink_block_id>gr_multiply_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_2</source_block_id>
+    <sink_block_id>trellis_viterbi_combined_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_1</source_block_id>
+    <sink_block_id>gr_sub_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_encoder_xx_2</source_block_id>
+    <sink_block_id>gr_chunks_to_symbols_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_chunks_to_symbols_xx_2</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_2</source_block_id>
+    <sink_block_id>gr_sub_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_1</source_block_id>
+    <sink_block_id>trellis_encoder_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_xx_1</source_block_id>
+    <sink_block_id>gr_short_to_float_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_short_to_float_2</source_block_id>
+    <sink_block_id>wxgui_numbersink2_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
+    <sink_block_id>gr_sub_xx_3</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_3</source_block_id>
+    <sink_block_id>gr_multiply_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_3</source_block_id>
+    <sink_block_id>gr_multiply_xx_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_1</source_block_id>
+    <sink_block_id>trellis_viterbi_combined_xx_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_1</source_block_id>
+    <sink_block_id>gr_sub_xx_3</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_short_to_float_1</source_block_id>
+    <sink_block_id>wxgui_numbersink2_3</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_encoder_xx_2_0</source_block_id>
+    <sink_block_id>gr_chunks_to_symbols_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_chunks_to_symbols_xx_2_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_2</source_block_id>
+    <sink_block_id>trellis_encoder_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_xx_2_0</source_block_id>
+    <sink_block_id>gr_short_to_float_1_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>trellis_viterbi_combined_xx_0_0</source_block_id>
+    <sink_block_id>gr_sub_xx_1_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_1_0</source_block_id>
+    <sink_block_id>gr_multiply_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_1_0</source_block_id>
+    <sink_block_id>gr_multiply_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sub_xx_2_0</source_block_id>
+    <sink_block_id>trellis_viterbi_combined_xx_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_short_to_float_1_0</source_block_id>
+    <sink_block_id>wxgui_numbersink2_3_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_1</source_block_id>
+    <sink_block_id>gr_sub_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>gr_sub_xx_1_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_2_0</source_block_id>
+    <sink_block_id>gr_sub_xx_2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx_1</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/trellis/readme.txt b/gnuradio-examples/grc/trellis/readme.txt
new file mode 100644 (file)
index 0000000..d620fd6
--- /dev/null
@@ -0,0 +1,16 @@
+This is an example of using gr-trellis in grc.
+
+Two users are transmitting simultaneously using convolutionally encoded QPSK, each with power P1=alpha*P and P2=(1-alpha)*P.
+The combined signal is observed in noise and four different receivers are considered:
+1) A viterbi decoder decoding user 1 assuming user 2 is noise
+2) A viterbi decoder decoding user 2 assuming user 1 is noise
+3) A viterbi decoder decoding user 1 first 
+   and then reencoding this signal, subtracting it from the observation 
+   and then running a Viterbi decoder decoding user 2
+4) A viterbi decoder decoding user 2 first 
+   and then reencoding this signal, subtracting it from the observation 
+   and then running a Viterbi decoder decoding user 1
+
+You can change the signal to noise ratio P/sigma^2 and the allocation of power to the two users, alpha.
+
+Enjoy.
diff --git a/gnuradio-examples/grc/usrp/usrp2_const_wave.grc b/gnuradio-examples/grc/usrp/usrp2_const_wave.grc
new file mode 100644 (file)
index 0000000..fdbd7c1
--- /dev/null
@@ -0,0 +1,252 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Apr 15 11:22:56 2009</timestamp>
+  <block>
+    <key>const_source_x</key>
+    <param>
+      <key>id</key>
+      <value>const_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(284, 154)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_sink_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_sink_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value></value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>interpolation</key>
+      <value>interp</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(493, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>interp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>16</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(16, 255)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>USRP2 Freq (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.45e9</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>2.4e9</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2.5e9</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_length</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(30, 376)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Amplitude</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_length</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(204, 376)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_const_wave</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP2 Constant Wave</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>Tune USRP2</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>const_source_x_0</source_block_id>
+    <sink_block_id>usrp2_sink_xxxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp2_dpsk_mod.grc b/gnuradio-examples/grc/usrp/usrp2_dpsk_mod.grc
new file mode 100644 (file)
index 0000000..e9f9b41
--- /dev/null
@@ -0,0 +1,693 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Apr 15 17:31:00 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_dpsk_mod</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP2 DPSK Modulation</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>Generate a DPSK signal</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e6/interp</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(52, 166)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_sink_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_sink_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value></value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>interpolation</key>
+      <value>interp</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1059, 56)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(679, 58)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk_mod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk_mod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dqpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(468, 55)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>interp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(31, 256)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(126, 250)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>256</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(255, 39)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Amplitude</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(246, 372)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>rx_freq_off</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>RX Freq Offset (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>-20e3</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-50e3</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>+50e3</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(247, 508)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>USRP2 Freq (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.45e9</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>2.4e9</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2.5e9</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(49, 341)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_constellationsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_constellationsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Constellation Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>frame_rate</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>const_size</key>
+      <value>2048</value>
+    </param>
+    <param>
+      <key>M</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>theta</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>fmax</key>
+      <value>0.06</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>symbol_rate</key>
+      <value>samp_rate/samps_per_sym</value>
+    </param>
+    <param>
+      <key>omega_limit</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(920, 202)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(691, 155)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(515, 272)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_source_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_source_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value>eth1</value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>interp</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq + rx_freq_off</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(270, 200)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>blks2_dxpsk_mod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk_mod_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>usrp2_sink_xxxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>wxgui_constellationsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp2_fft.grc b/gnuradio-examples/grc/usrp/usrp2_fft.grc
new file mode 100644 (file)
index 0000000..134bd46
--- /dev/null
@@ -0,0 +1,264 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Apr 15 17:30:20 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP2 FFT Plotter</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>FFT waveform plot</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>16</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(24, 267)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>USRP2 Freq (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.45e9</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>2.4e9</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2.5e9</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(32, 365)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(466, 100)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_source_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_source_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value></value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(211, 200)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp_rx_dpsk.grc b/gnuradio-examples/grc/usrp/usrp_rx_dpsk.grc
new file mode 100644 (file)
index 0000000..9843ee6
--- /dev/null
@@ -0,0 +1,727 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Dec  2 11:03:20 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_rx_dpsk</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP RX DPSK</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(14, 79)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.45e9</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(18, 151)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>p2p</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 314)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>timing_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Timing Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(759, 365)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_null_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_null_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(815, 80)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Costas Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.175</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(598, 367)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Receive Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-40</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>p2p</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(383, 321)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1e6/4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(20, 234)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Gain</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>70</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(152, 378)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_source_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_source_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value></value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>int(100e6/samp_rate)</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(158, 51)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>int(64e6/samp_rate)</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>B</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>TX/RX</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(154, 218)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk2_demod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk2_demod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dqpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>costas_alpha</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>timing_alpha</key>
+      <value>timing_alpha</value>
+    </param>
+    <param>
+      <key>timing_max_dev</key>
+      <value>1.5</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>log</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>sync_out</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(487, 64)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Recovered DQPSK Constellation</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate/4/20</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(760, 239)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_keep_one_in_n</key>
+    <param>
+      <key>id</key>
+      <value>gr_keep_one_in_n_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>n</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(873, 151)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp2_source_xxxx_0</source_block_id>
+    <sink_block_id>blks2_dxpsk2_demod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk2_demod_0</source_block_id>
+    <sink_block_id>gr_null_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk2_demod_0</source_block_id>
+    <sink_block_id>gr_keep_one_in_n_0</sink_block_id>
+    <source_key>1</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_keep_one_in_n_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp_two_tone_loopback.grc b/gnuradio-examples/grc/usrp/usrp_two_tone_loopback.grc
new file mode 100644 (file)
index 0000000..3df9770
--- /dev/null
@@ -0,0 +1,749 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Fri Apr 17 18:23:35 2009</timestamp>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/200</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(9, 166)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(100e6)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(116, 166)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>tone1</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>tone_ampl</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(258, 20)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>tone2</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>tone_ampl</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(255, 179)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_add_xx</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>3</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(528, 78)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>tx_side</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>A</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(688, 384)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_sink_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_sink_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>interpolation</key>
+      <value>400</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>tx_side</value>
+    </param>
+    <param>
+      <key>transmit</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(835, 5)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>tun_freq</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>rx_side</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>rx_ant</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(479, 224)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>rx_ant</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>RXA</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(802, 384)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>512*2</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 2, 2, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(746, 133)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>rx_side</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>A</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(568, 382)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_noise_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_noise_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>noise_type</key>
+      <value>gr.GR_GAUSSIAN</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>noise_ampl</value>
+    </param>
+    <param>
+      <key>seed</key>
+      <value>42</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(276, 312)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>noise_ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Noise Ampl</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2000</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>5000</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_VERTICAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 1, 2, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(20, 243)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tone_ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Tone Ampl</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>5000</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>10e3</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_VERTICAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 2, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(28, 437)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tone1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Tone 1</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>50e3</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-samp_rate/2</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(190, 436)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tone2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Tone 2</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>75e3</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-samp_rate/2</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 4, 1, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(367, 439)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_two_tone_loopback</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP Loopback - 2 Tone</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>Loopback test with basic rx and basic tx</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_sig_source_x</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_sig_source_x0</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>1</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_noise_source_x</source_block_id>
+    <sink_block_id>gr_add_xx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>2</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_simple_source_x</source_block_id>
+    <sink_block_id>wxgui_fftsink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_add_xx</source_block_id>
+    <sink_block_id>usrp_simple_sink_x</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp_tx_dpsk.grc b/gnuradio-examples/grc/usrp/usrp_tx_dpsk.grc
new file mode 100644 (file)
index 0000000..90ec5e9
--- /dev/null
@@ -0,0 +1,583 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Dec  3 11:42:41 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_tx_dpsk</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP TX DPSK</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 76)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>random_source_x</key>
+    <param>
+      <key>id</key>
+      <value>random_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2**8</value>
+    </param>
+    <param>
+      <key>num_samps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(23, 319)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_dxpsk2_mod</key>
+    <param>
+      <key>id</key>
+      <value>blks2_dxpsk2_mod_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>dqpsk</value>
+    </param>
+    <param>
+      <key>samples_per_symbol</key>
+      <value>samps_per_sym</value>
+    </param>
+    <param>
+      <key>excess_bw</key>
+      <value>0.35</value>
+    </param>
+    <param>
+      <key>gray_code</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>log</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(234, 151)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_sink_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_sink_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>interpolation</key>
+      <value>int(128e6/samp_rate)</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>A</value>
+    </param>
+    <param>
+      <key>transmit</key>
+      <value>auto_tr</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(516, 203)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp2_sink_xxxx</key>
+    <param>
+      <key>id</key>
+      <value>usrp2_sink_xxxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>interface</key>
+      <value></value>
+    </param>
+    <param>
+      <key>mac_addr</key>
+      <value></value>
+    </param>
+    <param>
+      <key>interpolation</key>
+      <value>int(100e6/samp_rate)</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(498, 51)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>tx_ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>TX Amplitude</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>.2</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(277, 491)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2.45e9+freq_off</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(14, 141)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq_off</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-samp_rate/2</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(63, 483)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>p2p</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2**15</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(179, 37)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>tx_ampl*p2p/2.</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(306, 355)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Transmit Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>bb_freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>p2p</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(576, 410)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1e6/4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 207)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>random_source_x_0</source_block_id>
+    <sink_block_id>blks2_dxpsk2_mod_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_dxpsk2_mod_0</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>usrp_simple_sink_x_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/usrp/usrp_wbfm_receive.grc b/gnuradio-examples/grc/usrp/usrp_wbfm_receive.grc
new file mode 100644 (file)
index 0000000..8f53475
--- /dev/null
@@ -0,0 +1,466 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Fri Apr 17 19:06:07 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_wbfm_receive</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP WBFM Receive</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>WBFM Receive with Basic RX or TV RX</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>200</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(14, 173)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>volume</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Volume</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(991, 40)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>(freq+fine)*1e6</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>A</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(277, 29)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>(freq+fine)*1e6</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>512</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 2, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(512, 191)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency (MHz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>87.5</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>108.0</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(104, 243)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>fine</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Fine Freq (MHz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-.1</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>.1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 2, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(275, 246)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_wfm_rcv</key>
+    <param>
+      <key>id</key>
+      <value>blks2_wfm_rcv</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>quad_rate</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>audio_decimation</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(510, 37)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_multiply_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_multiply_const_vxx</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>volume</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(764, 55)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>audio_sink</key>
+    <param>
+      <key>id</key>
+      <value>audio_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>device_name</key>
+      <value></value>
+    </param>
+    <param>
+      <key>ok_to_block</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(703, 241)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>usrp_simple_source_x</source_block_id>
+    <sink_block_id>blks2_wfm_rcv</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_simple_source_x</source_block_id>
+    <sink_block_id>wxgui_fftsink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blks2_wfm_rcv</source_block_id>
+    <sink_block_id>gr_multiply_const_vxx</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_multiply_const_vxx</source_block_id>
+    <sink_block_id>audio_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/grc/xmlrpc/readme.txt b/gnuradio-examples/grc/xmlrpc/readme.txt
new file mode 100644 (file)
index 0000000..c1f87c1
--- /dev/null
@@ -0,0 +1,18 @@
+##################################################
+# XMLRPC example
+##################################################
+
+XMLRPC allows software to make remote function calls over http. 
+In the case of GRC, one can use XMLRPC to modify variables in a running flow graph.
+See http://www.xmlrpc.com/
+
+--- Server Example ---
+Place an "XMLRPC Server" block inside of any flow graph. 
+The server will provide set functions for every variable in the flow graph.
+If a variable is called "freq", the server will provide a function set_freq(new_freq).
+Run the server example and experiment with the example client script.
+
+-- Client Example --
+The "XMLRPC Client" block will give a variable control over one remove function.
+In the example client, there is one client block and gui control per variable.
+This technique can be used to remotely control a flow graph, perhaps running on a non-gui machine.
diff --git a/gnuradio-examples/grc/xmlrpc/xmlrpc_client.grc b/gnuradio-examples/grc/xmlrpc/xmlrpc_client.grc
new file mode 100644 (file)
index 0000000..3bb4e7e
--- /dev/null
@@ -0,0 +1,312 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Jul 24 14:27:44 2008</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>client_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>XMLRPC Client</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>example flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>xmlrpc_client</key>
+    <param>
+      <key>id</key>
+      <value>xmlrpc_client0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>addr</key>
+      <value>localhost</value>
+    </param>
+    <param>
+      <key>port</key>
+      <value>1234</value>
+    </param>
+    <param>
+      <key>callback</key>
+      <value>set_ampl</value>
+    </param>
+    <param>
+      <key>variable</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(409, 35)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>xmlrpc_client</key>
+    <param>
+      <key>id</key>
+      <value>xmlrpc_client</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>addr</key>
+      <value>localhost</value>
+    </param>
+    <param>
+      <key>port</key>
+      <value>1234</value>
+    </param>
+    <param>
+      <key>callback</key>
+      <value>set_freq</value>
+    </param>
+    <param>
+      <key>variable</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(222, 34)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency (Hz)</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>5000</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(207, 162)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Amplitude</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>slider_type</key>
+      <value>horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 167)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_chooser</key>
+    <param>
+      <key>id</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Offset</value>
+    </param>
+    <param>
+      <key>value_index</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>choices</key>
+      <value>[-1, 0, 1]</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>["neg", "zero", "pos"]</value>
+    </param>
+    <param>
+      <key>chooser_type</key>
+      <value>radio_buttons_horizontal</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(596, 177)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>xmlrpc_client</key>
+    <param>
+      <key>id</key>
+      <value>xmlrpc_client1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>addr</key>
+      <value>localhost</value>
+    </param>
+    <param>
+      <key>port</key>
+      <value>1234</value>
+    </param>
+    <param>
+      <key>callback</key>
+      <value>set_offset</value>
+    </param>
+    <param>
+      <key>variable</key>
+      <value>offset*ampl</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(608, 39)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 172)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+</flow_graph>
\ No newline at end of file
diff --git a/gnuradio-examples/grc/xmlrpc/xmlrpc_client_script.py b/gnuradio-examples/grc/xmlrpc/xmlrpc_client_script.py
new file mode 100644 (file)
index 0000000..956fa07
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+import time
+import random
+import xmlrpclib
+
+#create server object
+s = xmlrpclib.Server("http://localhost:1234")
+
+#randomly change parameters of the sinusoid
+for i in range(10):
+       #generate random values
+       new_freq = random.uniform(0, 5000)
+       new_ampl = random.uniform(0, 2)
+       new_offset = random.uniform(-1, 1)
+       #set new values 
+       time.sleep(1)
+       s.set_freq(new_freq)
+       time.sleep(1)
+       s.set_ampl(new_ampl)
+       time.sleep(1)
+       s.set_offset(new_offset)
+
diff --git a/gnuradio-examples/grc/xmlrpc/xmlrpc_server.grc b/gnuradio-examples/grc/xmlrpc/xmlrpc_server.grc
new file mode 100644 (file)
index 0000000..dc539ef
--- /dev/null
@@ -0,0 +1,384 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Jul 24 14:27:42 2008</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>server_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>XMLRPC Server</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value>Example</value>
+    </param>
+    <param>
+      <key>description</key>
+      <value>example flow graph</value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>gr_sig_source_x</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(162, 200)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 390)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>xmlrpc_server</key>
+    <param>
+      <key>id</key>
+      <value>xmlrpc_server</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>addr</key>
+      <value>localhost</value>
+    </param>
+    <param>
+      <key>port</key>
+      <value>1234</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(395, 240)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(386, 93)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>frame_decim</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>.001</value>
+    </param>
+    <param>
+      <key>marker</key>
+      <value>set_format_line</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 2, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(623, 28)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>512</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 2, 4</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(630, 233)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 160)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 237)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>ampl</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 315)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_sig_source_x</source_block_id>
+    <sink_block_id>gr_throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle</source_block_id>
+    <sink_block_id>wxgui_scopesink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle</source_block_id>
+    <sink_block_id>wxgui_fftsink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
\ No newline at end of file
diff --git a/gnuradio-examples/python/.gitignore b/gnuradio-examples/python/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index 3a1acf51da21d46368a5d52edfaac999a33196f6..ea03b438f035c328177a6be12290e846aec48f19 100644 (file)
@@ -32,5 +32,6 @@ SUBDIRS = \
        multi_usrp \
        network \
        ofdm \
+       pfb \
        usrp \
        usrp2
diff --git a/gnuradio-examples/python/apps/.gitignore b/gnuradio-examples/python/apps/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gnuradio-examples/python/apps/hf_explorer/.gitignore b/gnuradio-examples/python/apps/hf_explorer/.gitignore
new file mode 100644 (file)
index 0000000..b695091
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pyc
diff --git a/gnuradio-examples/python/apps/hf_radio/.gitignore b/gnuradio-examples/python/apps/hf_radio/.gitignore
new file mode 100644 (file)
index 0000000..b695091
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pyc
index a7c8712878515648f7df9eb0fb71ab49ae79779c..5984d8254ec5656301aff1694e1b2c910e3fc213 100644 (file)
@@ -18,7 +18,12 @@ class input:
         self.src = usrp.source_c( )
         self.subdev = usrp.pick_subdev( self.src,
                                         (usrp_dbid.BASIC_RX,
-                                         usrp_dbid.TV_RX))
+                                         usrp_dbid.TV_RX,
+                                         usrp_dbid.TV_RX_REV_2,
+                                         usrp_dbid.TV_RX_REV_3,
+                                         usrp_dbid.TV_RX_MIMO,
+                                         usrp_dbid.TV_RX_REV_2_MIMO,
+                                         usrp_dbid.TV_RX_REV_3_MIMO))
 
         print self.subdev
 
diff --git a/gnuradio-examples/python/audio/.gitignore b/gnuradio-examples/python/audio/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-examples/python/digital-bert/.gitignore b/gnuradio-examples/python/digital-bert/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gnuradio-examples/python/digital/.gitignore b/gnuradio-examples/python/digital/.gitignore
new file mode 100644 (file)
index 0000000..ff40c06
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/*.dat
index 64ce4ec46625e0d9c6dc51a8ec472bbadad0294c..e32180cd493dd8a7caef30810a944dfd22de90c3 100644 (file)
@@ -25,7 +25,6 @@ ourdatadir = $(exampledir)/digital
 
 dist_ourdata_DATA =            \
        README                  \
-       generic_usrp.py         \
        pick_bitrate.py         \
        qt_digital_window.ui    \
        qt_digital_window.py    \
@@ -33,7 +32,6 @@ dist_ourdata_DATA =           \
        qt_rx_window.py         \
        receive_path.py         \
        transmit_path.py        \
-       usrp_options.py \
        usrp_receive_path.py \
        usrp_transmit_path.py
 
index 4cc4a7bee3698f1a14ae36706ce9c37307dd6ef7..47e4f20288a91e23ba5b57fbf7638b2dc217bc0f 100755 (executable)
@@ -44,6 +44,11 @@ class my_top_block(gr.top_block):
         noise_power = power_in_signal/SNR
         noise_voltage = math.sqrt(noise_power)
 
+        # With new interface, sps does not get set by default, but
+        # in the loopback, we don't recalculate it; so just force it here
+        if(options.samples_per_symbol == None):
+            options.samples_per_symbol = 2
+
         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)
index cd77f0748bf64e173babbe48f5d2d225cffd82c8..0ae0e4e51a1634f02f0bf963d887ca5ca47df752 100755 (executable)
@@ -52,7 +52,7 @@ class dialog_box(QtGui.QMainWindow):
         self.set_frequency(self.fg.frequency_offset())
         self.set_time_offset(self.fg.timing_offset())
 
-        self.set_gain_mu(self.fg.rx_gain_mu())
+        self.set_gain_mu(self.fg.rx_timing_gain_alpha())
         self.set_alpha(self.fg.rx_alpha())
 
         # Add the qtsnk widgets to the hlayout box
@@ -158,7 +158,7 @@ class dialog_box(QtGui.QMainWindow):
     def gainMuEditText(self):
         try:
             gain = self.gui.gainMuEdit.text().toDouble()[0]
-            self.fg.set_rx_gain_mu(gain)
+            self.fg.set_rx_timing_gain_alpha(gain)
         except RuntimeError:
             pass
 
@@ -167,7 +167,10 @@ class dialog_box(QtGui.QMainWindow):
         # Pull these globals in from the main thread
         global n_rcvd, n_right, pktno
 
-        per = float(n_rcvd - n_right)/float(pktno)
+        if(pktno > 0):
+            per = float(n_rcvd - n_right)/float(pktno)
+        else:
+            per = 0
         self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd))
         self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right))
         self.gui.perEdit.setText(QtCore.QString("%1").arg(per))
@@ -186,6 +189,9 @@ class my_top_block(gr.top_block):
 
         self._sample_rate = options.sample_rate
 
+        if(options.samples_per_symbol is None):
+            options.samples_per_symbol = 2
+
         channelon = True;
 
         self.gui_on = options.gui
@@ -202,7 +208,7 @@ class my_top_block(gr.top_block):
         self.rxpath = receive_path(demod_class, rx_callback, options)
 
         # FIXME: do better exposure to lower issues for control
-        self._gain_mu = self.rxpath.packet_receiver._demodulator._mm_gain_mu
+        self._timing_gain_alpha = self.rxpath.packet_receiver._demodulator._mm_gain_mu
         self._alpha = self.rxpath.packet_receiver._demodulator._costas_alpha
 
         if channelon:
@@ -229,10 +235,10 @@ class my_top_block(gr.top_block):
                 fftsize = 2048
 
                 self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
-                                           0, 1,
+                                           0, self._sample_rate,
                                            "Tx", True, True, False, True, True)
                 self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
-                                           0, 1,
+                                           0, self._sample_rate,
                                            "Rx", True, True, False, True, True)
 
                 self.snk_tx.set_frequency_axis(-80, 0)
@@ -241,15 +247,17 @@ class my_top_block(gr.top_block):
                 # Connect to the QT sinks
                 # FIXME: make better exposure to receiver from rxpath
                 self.receiver = self.rxpath.packet_receiver._demodulator.receiver
+                self.receiver.set_alpha(2)
+                self.receiver.set_beta(0.02)
                 self.connect(self.channel, self.snk_tx)
                 self.connect(self.receiver, self.snk_rx)
 
                 pyTxQt  = self.snk_tx.pyqwidget()
                 pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
-                
+                 
                 pyRxQt  = self.snk_rx.pyqwidget()
                 pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
-                
+
                 self.main_box = dialog_box(pyTx, pyRx, self)
                 self.main_box.show()
                 
@@ -279,7 +287,7 @@ class my_top_block(gr.top_block):
     def get_noise_voltage(self, SNR):
         snr = 10.0**(SNR/10.0)        
         power_in_signal = abs(self._tx_amplitude)**2
-        noise_power = power_in_signal/SNR
+        noise_power = power_in_signal/snr
         noise_voltage = math.sqrt(noise_power)
         return noise_voltage
 
@@ -299,17 +307,15 @@ class my_top_block(gr.top_block):
 
 
     # Receiver Parameters
-    def rx_gain_mu(self):
-        return self._gain_mu
+    def rx_timing_gain_alpha(self):
+        return self._timing_gain_alpha
 
-    def rx_gain_omega(self):
-        return self.gain_omega
+    def rx_timing_gain_beta(self):
+        return self._timing_gain_beta
     
-    def set_rx_gain_mu(self, gain):
-        self._gain_mu = gain
-        self.gain_omega = .25 * self._gain_mu * self._gain_mu
-        self.receiver.set_gain_mu(self._gain_mu)
-        self.receiver.set_gain_omega(self.gain_omega)
+    def set_rx_timing_gain_alpha(self, gain):
+        self._timing_gain_alpha = gain
+        self.receiver.set_gain_mu(self._timing_gain_alpha)
 
     def rx_alpha(self):
         return self._alpha
diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py
new file mode 100755 (executable)
index 0000000..02ae4b2
--- /dev/null
@@ -0,0 +1,536 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 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_utils2
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import random, time, struct, sys, os, math
+
+from threading import Thread
+
+# from current dir
+from transmit_path import transmit_path
+from receive_path import receive_path
+
+try:
+    from gnuradio.qtgui import qtgui
+    from PyQt4 import QtGui, QtCore
+    import sip
+except ImportError:
+    print "Please install gr-qtgui."
+    sys.exit(1)
+    
+try:
+    from qt_digital_window2 import Ui_DigitalWindow
+except ImportError:
+    print "Error: could not find qt_digital_window2.py:"
+    print "\t\"pyuic4 qt_digital_window2.ui -o qt_digital_window2.py\""
+    sys.exit(1)
+
+
+#print os.getpid()
+#raw_input()
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the QT Interface and Control Dialog
+# ////////////////////////////////////////////////////////////////////
+
+
+class dialog_box(QtGui.QMainWindow):
+    def __init__(self, snkTx, snkRx, fg, parent=None):
+
+        QtGui.QWidget.__init__(self, parent)
+        self.gui = Ui_DigitalWindow()
+        self.gui.setupUi(self)
+
+        self.fg = fg
+
+        self.set_sample_rate(self.fg.sample_rate())
+
+        self.set_snr(self.fg.snr())
+        self.set_frequency(self.fg.frequency_offset())
+        self.set_time_offset(self.fg.timing_offset())
+
+        self.set_gain_clock(self.fg.rx_gain_clock())
+        self.set_gain_phase(self.fg.rx_gain_phase())
+        self.set_gain_freq(self.fg.rx_gain_freq())
+
+        # Add the qtsnk widgets to the hlayout box
+        self.gui.sinkLayout.addWidget(snkTx)
+        self.gui.sinkLayout.addWidget(snkRx)
+
+
+        # Connect up some signals
+        self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
+                     self.pauseFg)
+
+        self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.sampleRateEditText)
+
+        self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.snrEditText)
+        self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.freqEditText)
+        self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.timeEditText)
+
+        self.connect(self.gui.gainClockEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainClockEditText)
+        self.connect(self.gui.gainPhaseEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainPhaseEditText)
+        self.connect(self.gui.gainFreqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainFreqEditText)
+
+        # Build a timer to update the packet number and PER fields
+        self.update_delay = 250  # time between updating packet rate fields
+        self.pkt_timer = QtCore.QTimer(self)
+        self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"),
+                     self.updatePacketInfo)
+        self.pkt_timer.start(self.update_delay)
+
+    def pauseFg(self):
+        if(self.gui.pauseButton.text() == "Pause"):
+            self.fg.stop()
+            self.fg.wait()
+            self.gui.pauseButton.setText("Unpause")
+        else:
+            self.fg.start()
+            self.gui.pauseButton.setText("Pause")
+
+    # Accessor functions for Gui to manipulate system parameters
+    def set_sample_rate(self, sr):
+        ssr = eng_notation.num_to_str(sr)
+        self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr))
+
+    def sampleRateEditText(self):
+        try:
+            rate = self.gui.sampleRateEdit.text().toAscii()
+            srate = eng_notation.str_to_num(rate)
+            #self.fg.set_sample_rate(srate)
+        except RuntimeError:
+            pass
+
+
+    # Accessor functions for Gui to manipulate channel model
+    def set_snr(self, snr):
+        self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr))
+
+    def set_frequency(self, fo):
+        self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
+
+    def set_time_offset(self, to):
+        self.gui.timeEdit.setText(QtCore.QString("%1").arg(to))
+
+    def snrEditText(self):
+        try:
+            snr = self.gui.snrEdit.text().toDouble()[0]
+            self.fg.set_snr(snr)
+        except RuntimeError:
+            pass
+
+    def freqEditText(self):
+        try:
+            freq = self.gui.freqEdit.text().toDouble()[0]
+            self.fg.set_frequency_offset(freq)
+        except RuntimeError:
+            pass
+
+    def timeEditText(self):
+        try:
+            to = self.gui.timeEdit.text().toDouble()[0]
+            self.fg.set_timing_offset(to)
+        except RuntimeError:
+            pass
+
+
+    # Accessor functions for Gui to manipulate receiver parameters
+    def set_gain_clock(self, gain):
+        self.gui.gainClockEdit.setText(QtCore.QString("%1").arg(gain))
+
+    def set_gain_phase(self, gain_phase):
+        self.gui.gainPhaseEdit.setText(QtCore.QString("%1").arg(gain_phase))
+
+    def set_gain_freq(self, gain_freq):
+        self.gui.gainFreqEdit.setText(QtCore.QString("%1").arg(gain_freq))
+        
+
+    def set_alpha_time(self, alpha):
+        self.gui.alphaTimeEdit.setText(QtCore.QString("%1").arg(alpha))
+
+    def set_beta_time(self, beta):
+        self.gui.betaTimeEdit.setText(QtCore.QString("%1").arg(beta))
+
+    def set_alpha_phase(self, alpha):
+        self.gui.alphaPhaseEdit.setText(QtCore.QString("%1").arg(alpha))
+
+    def gainPhaseEditText(self):
+        try:
+            gain_phase = self.gui.gainPhaseEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_phase(gain_phase)
+        except RuntimeError:
+            pass
+
+    def gainClockEditText(self):
+        try:
+            gain = self.gui.gainClockEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_clock(gain)
+        except RuntimeError:
+            pass
+
+    def gainFreqEditText(self):
+        try:
+            gain = self.gui.gainFreqEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_freq(gain)
+        except RuntimeError:
+            pass
+
+    # Accessor functions for packet error reporting
+    def updatePacketInfo(self):
+        # Pull these globals in from the main thread
+        global n_rcvd, n_right, pktno
+
+        if(pktno > 0):
+            per = float(n_rcvd - n_right)/float(pktno)
+        else:
+            per = 0
+        self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd))
+        self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right))
+        self.gui.perEdit.setText(QtCore.QString("%1").arg(float(per), 0, 'e', 4))
+
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the GNU Radio Top Block
+# ////////////////////////////////////////////////////////////////////
+
+
+
+class my_top_block(gr.top_block):
+    def __init__(self, mod_class, demod_class, rx_callback, options):
+        gr.top_block.__init__(self)
+
+        self._sample_rate = options.sample_rate
+
+        channelon = True;
+
+        self.gui_on = options.gui
+
+        self._frequency_offset = options.frequency_offset
+        self._timing_offset = options.timing_offset
+        self._tx_amplitude = options.tx_amplitude
+        self._snr_dB = options.snr
+
+        self._noise_voltage = self.get_noise_voltage(self._snr_dB)
+
+        # With new interface, sps does not get set by default, but
+        # in the loopback, we don't recalculate it; so just force it here
+        if(options.samples_per_symbol == None):
+            options.samples_per_symbol = 2
+
+        self.txpath = transmit_path(mod_class, options)
+        self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate())
+        self.rxpath = receive_path(demod_class, rx_callback, options)
+
+        # FIXME: do better exposure to lower issues for control
+        self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha
+        self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha
+        self._gain_freq  = self.rxpath.packet_receiver._demodulator._freq_alpha
+
+        if channelon:
+            self.channel = gr.channel_model(self._noise_voltage,
+                                            self.frequency_offset(),
+                                            self.timing_offset())
+            
+            if options.discontinuous:
+                z = 20000*[0,]
+                self.zeros = gr.vector_source_c(z, True)
+                packet_size = 5*((4+8+4+1500+4) * 8)
+                self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)])
+
+                # Connect components
+                self.connect(self.txpath, self.throttle, (self.mux,0))
+                self.connect(self.zeros, (self.mux,1))
+                self.connect(self.mux, self.channel, self.rxpath)
+
+            else:
+                self.connect(self.txpath, self.throttle, self.channel, self.rxpath)
+
+            if self.gui_on:
+                self.qapp = QtGui.QApplication(sys.argv)
+                fftsize = 2048
+
+                self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                           0, 1,
+                                           "Tx", True, True, False, True, True)
+                self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                           0, 1,
+                                           "Rx", True, True, False, True, True)
+
+                self.snk_tx.set_frequency_axis(-80, 0)
+                self.snk_rx.set_frequency_axis(-60, 20)
+
+                self.freq_recov = self.rxpath.packet_receiver._demodulator.freq_recov
+                self.phase_recov = self.rxpath.packet_receiver._demodulator.phase_recov
+                self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov
+                self.freq_recov.set_alpha(self._gain_freq)
+                self.freq_recov.set_beta(self._gain_freq/10.0)
+                self.phase_recov.set_alpha(self._gain_phase)
+                self.phase_recov.set_beta(0.25*self._gain_phase*self._gain_phase)
+                self.time_recov.set_alpha(self._gain_clock)
+                self.time_recov.set_beta(0.25*self._gain_clock*self._gain_clock)
+
+                # Connect to the QT sinks
+                # FIXME: make better exposure to receiver from rxpath
+                self.connect(self.channel, self.snk_tx)
+                self.connect(self.phase_recov, self.snk_rx)
+                #self.connect(self.freq_recov, self.snk_rx)
+
+                pyTxQt  = self.snk_tx.pyqwidget()
+                pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
+                 
+                pyRxQt  = self.snk_rx.pyqwidget()
+                pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
+
+                self.main_box = dialog_box(pyTx, pyRx, self)
+                self.main_box.show()
+                
+        else:
+            # Connect components
+            self.connect(self.txpath, self.throttle, self.rxpath)
+
+
+
+    # System Parameters
+    def sample_rate(self):
+        return self._sample_rate
+    
+    def set_sample_rate(self, sr):
+        self._sample_rate = sr
+        #self.throttle.set_samples_per_second(self._sample_rate)
+
+    # Channel Model Parameters
+    def snr(self):
+        return self._snr_dB
+    
+    def set_snr(self, snr):
+        self._snr_dB = snr
+        self._noise_voltage = self.get_noise_voltage(self._snr_dB)
+        self.channel.set_noise_voltage(self._noise_voltage)
+
+    def get_noise_voltage(self, SNR):
+        snr = 10.0**(SNR/10.0)        
+        power_in_signal = abs(self._tx_amplitude)**2
+        noise_power = power_in_signal/snr
+        noise_voltage = math.sqrt(noise_power)
+        return noise_voltage
+
+    def frequency_offset(self):
+        return self._frequency_offset * self.sample_rate()
+
+    def set_frequency_offset(self, fo):
+        self._frequency_offset = fo / self.sample_rate()
+        self.channel.set_frequency_offset(self._frequency_offset)
+
+    def timing_offset(self):
+        return self._timing_offset
+    
+    def set_timing_offset(self, to):
+        self._timing_offset = to
+        self.channel.set_timing_offset(self._timing_offset)
+
+
+    # Receiver Parameters
+    def rx_gain_clock(self):
+        return self._gain_clock
+
+    def rx_gain_clock_beta(self):
+        return self._gain_clock_beta
+
+    def set_rx_gain_clock(self, gain):
+        self._gain_clock = gain
+        self._gain_clock_beta = .25 * self._gain_clock * self._gain_clock
+        self.rxpath.packet_receiver._demodulator.time_recov.set_alpha(self._gain_clock)
+        self.rxpath.packet_receiver._demodulator.time_recov.set_beta(self._gain_clock_beta)
+
+    def rx_gain_phase(self):
+        return self._gain_phase
+
+    def rx_gain_phase_beta(self):
+        return self._gain_phase_beta
+    
+    def set_rx_gain_phase(self, gain_phase):
+        self._gain_phase = gain_phase
+        self._gain_phase_beta = .25 * self._gain_phase * self._gain_phase
+        self.rxpath.packet_receiver._demodulator.phase_recov.set_alpha(self._gain_phase)
+        self.rxpath.packet_receiver._demodulator.phase_recov.set_beta(self._gain_phase_beta)
+
+
+    def rx_gain_freq(self):
+        return self._gain_freq
+
+    def set_rx_gain_freq(self, gain_freq):
+        self._gain_freq = gain_freq
+        #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq
+        self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq)
+        self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0)
+        #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#       Thread to handle the packet sending procedure
+#          Operates in parallel with qApp.exec_()       
+# /////////////////////////////////////////////////////////////////////////////
+
+
+
+class th_send(Thread):
+    def __init__(self, send_fnc, megs, sz):
+        Thread.__init__(self)
+        self.send = send_fnc
+        self.nbytes = int(1e6 * megs)
+        self.pkt_size = int(sz)
+
+    def run(self):
+        # generate and send packets
+        n = 0
+        pktno = 0
+        
+        while n < self.nbytes:
+            self.send(struct.pack('!H', pktno & 0xffff) +
+                      (self.pkt_size - 2) * chr(pktno & 0xff))
+            n += self.pkt_size
+            pktno += 1
+            
+        self.send(eof=True)
+
+    def stop(self):
+        self.nbytes = 0
+
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+
+
+def main():
+
+    global n_rcvd, n_right, pktno
+
+    n_rcvd = 0
+    n_right = 0
+    pktno = 0
+    
+    def rx_callback(ok, payload):
+        global n_rcvd, n_right, pktno
+        (pktno,) = struct.unpack('!H', payload[0:2])
+        n_rcvd += 1
+        if ok:
+            n_right += 1
+
+        if not options.gui:
+            print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
+                ok, pktno, n_rcvd, n_right)
+        
+
+    def send_pkt(payload='', eof=False):
+        return tb.txpath.send_pkt(payload, eof)
+
+    mods = modulation_utils2.type_1_mods()
+    demods = modulation_utils2.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='dbpsk2',
+                      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)")
+    parser.add_option("-G", "--gui", action="store_true", default=False,
+                      help="Turn on the GUI [default=%default]")
+
+    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("", "--timing-offset", type="eng_float", default=1.0,
+                           help="set timing 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
+    tb = my_top_block(mods[options.modulation],
+                      demods[options.modulation],
+                      rx_callback, options)
+    tb.start()
+
+    packet_sender = th_send(send_pkt, options.megabytes, options.size)
+    packet_sender.start()
+
+    if(options.gui):
+        tb.qapp.exec_()
+        packet_sender.stop()
+    else:
+        # Process until done; hack in to the join to stop on an interrupt
+        while(packet_sender.isAlive()):
+            try:
+                packet_sender.join(1)
+            except KeyboardInterrupt:
+                packet_sender.stop()
+        
+    
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
index 33cf94a5c5a9235d2a24b04a5d15b797da7d8c0c..0cbb68d23ee5cbde40c086ddb96b96a5b7cd317d 100755 (executable)
@@ -25,6 +25,7 @@ from gnuradio import usrp
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
+from gnuradio import usrp_options
 
 import random
 import struct
@@ -33,7 +34,6 @@ import sys
 # from current dir
 from receive_path import receive_path
 from pick_bitrate import pick_rx_bitrate
-import usrp_options
 
 try:
     from gnuradio.qtgui import qtgui
diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx2.py b/gnuradio-examples/python/digital/benchmark_qt_rx2.py
new file mode 100755 (executable)
index 0000000..0c37f4c
--- /dev/null
@@ -0,0 +1,475 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 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_utils2
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from gnuradio import usrp_options
+
+import random
+import struct
+import sys
+
+# from current dir
+from receive_path import receive_path
+from pick_bitrate2 import pick_rx_bitrate
+
+try:
+    from gnuradio.qtgui import qtgui
+    from PyQt4 import QtGui, QtCore
+    import sip
+except ImportError:
+    print "Please install gr-qtgui."
+    sys.exit(1)
+    
+try:
+    from qt_rx_window2 import Ui_DigitalWindow
+except ImportError:
+    print "Error: could not find qt_rx_window2.py:"
+    print "\tYou must first build this from qt_rx_window2.ui with the following command:"
+    print "\t\"pyuic4 qt_rx_window2.ui -o qt_rx_window2.py\""
+    sys.exit(1)
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter: ')
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the QT Interface and Control Dialog
+# ////////////////////////////////////////////////////////////////////
+
+
+class dialog_box(QtGui.QMainWindow):
+    def __init__(self, snkRxIn, snkRx, fg, parent=None):
+
+        QtGui.QWidget.__init__(self, parent)
+        self.gui = Ui_DigitalWindow()
+        self.gui.setupUi(self)
+
+        self.fg = fg
+
+        self.set_frequency(self.fg.frequency())
+        self.set_gain(self.fg.gain())
+        self.set_decim(self.fg.decim())
+        self.set_gain_clock(self.fg.rx_gain_clock())
+        self.set_gain_phase(self.fg.rx_gain_phase())
+        self.set_gain_freq(self.fg.rx_gain_freq())
+
+        # Add the qtsnk widgets to the hlayout box
+        self.gui.sinkLayout.addWidget(snkRxIn)
+        self.gui.sinkLayout.addWidget(snkRx)
+
+
+        # Connect up some signals
+        self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.freqEditText)
+        self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainEditText)
+        self.connect(self.gui.decimEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.decimEditText)
+        self.connect(self.gui.gainClockEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainClockEditText)
+        self.connect(self.gui.gainPhaseEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainPhaseEditText)
+        self.connect(self.gui.gainFreqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainFreqEditText)
+
+        # Build a timer to update the packet number and PER fields
+        self.update_delay = 250  # time between updating packet rate fields
+        self.pkt_timer = QtCore.QTimer(self)
+        self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"),
+                     self.updatePacketInfo)
+        self.pkt_timer.start(self.update_delay)
+
+
+    # Accessor functions for Gui to manipulate receiver parameters
+    def set_frequency(self, fo):
+        self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
+
+    def set_gain(self, gain):
+        self.gui.gainEdit.setText(QtCore.QString("%1").arg(gain))
+
+    def set_decim(self, decim):
+        self.gui.decimEdit.setText(QtCore.QString("%1").arg(decim))
+
+    def set_gain_clock(self, gain):
+        self.gui.gainClockEdit.setText(QtCore.QString("%1").arg(gain))
+
+    def set_gain_phase(self, gain_phase):
+        self.gui.gainPhaseEdit.setText(QtCore.QString("%1").arg(gain_phase))
+
+    def set_gain_freq(self, gain_freq):
+        self.gui.gainFreqEdit.setText(QtCore.QString("%1").arg(gain_freq))
+        
+    def freqEditText(self):
+        try:
+            freq = self.gui.freqEdit.text().toDouble()[0]
+            self.fg.set_freq(freq)
+        except RuntimeError:
+            pass
+
+    def gainEditText(self):
+        try:
+            gain = self.gui.gainEdit.text().toDouble()[0]
+            self.fg.set_gain(gain)
+        except RuntimeError:
+            pass
+
+    def decimEditText(self):
+        try:
+            decim = self.gui.decimEdit.text().toInt()[0]
+            self.fg.set_decim(decim)
+        except RuntimeError:
+            pass
+
+    def gainPhaseEditText(self):
+        try:
+            gain_phase = self.gui.gainPhaseEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_phase(gain_phase)
+        except RuntimeError:
+            pass
+
+    def gainClockEditText(self):
+        try:
+            gain = self.gui.gainClockEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_clock(gain)
+        except RuntimeError:
+            pass
+
+    def gainFreqEditText(self):
+        try:
+            gain = self.gui.gainFreqEdit.text().toDouble()[0]
+            self.fg.set_rx_gain_freq(gain)
+        except RuntimeError:
+            pass
+
+
+    # Accessor function for packet error reporting
+    def updatePacketInfo(self):
+        # Pull these globals in from the main thread
+        global n_rcvd, n_right, pktno
+
+        per = float(n_rcvd - n_right)/float(pktno)
+        self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd))
+        self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right))
+        self.gui.perEdit.setText(QtCore.QString("%1").arg(per, 0, 'e', 4))
+
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the GNU Radio Top Block
+# ////////////////////////////////////////////////////////////////////
+
+
+class my_top_block(gr.top_block):
+    def __init__(self, demodulator, rx_callback, options):
+        gr.top_block.__init__(self)
+
+        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._decim              = options.decim           # Decimating rate for the USRP (prelim)
+        self._bitrate            = options.bitrate
+        self._samples_per_symbol = options.samples_per_symbol
+        self._demod_class        = demodulator
+        self.gui_on              = options.gui
+        
+        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
+        self._setup_usrp_source(options)
+
+        # 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
+
+        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)
+
+        self.set_gain(options.rx_gain)
+
+        # Set up receive path
+        self.rxpath = receive_path(demodulator, rx_callback, options) 
+
+        # FIXME: do better exposure to lower issues for control
+        self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha
+        self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha
+        self._gain_freq  = self.rxpath.packet_receiver._demodulator._freq_alpha
+
+        self.connect(self.u, self.rxpath)
+
+        if self.gui_on:
+            self.qapp = QtGui.QApplication(sys.argv)
+            fftsize = 2048
+
+            bw_in = self.u.adc_rate() / self.decim()
+            self.snk_rxin = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                         self._rx_freq, bw_in,
+                                         "Received", True, True, False, True, True, False)
+            self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                       0, self._bitrate,
+                                       "Post-Synchronizer", True, True, False, True, True, False)
+
+            self.snk_rxin.set_frequency_axis(-140, 20)
+            self.snk_rx.set_frequency_axis(-80, 20)
+            self.snk_rxin.set_time_domain_axis(-2000,2000)
+            
+            # Connect to the QT sinks
+            # FIXME: make better exposure to receiver from rxpath
+            self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov
+            #self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov
+            self.connect(self.u, self.snk_rxin)
+            self.connect(self.receiver, self.snk_rx)
+            
+            pyRxInQt  = self.snk_rxin.pyqwidget()
+            pyRxIn = sip.wrapinstance(pyRxInQt, QtGui.QWidget)
+            
+            pyRxQt  = self.snk_rx.pyqwidget()
+            pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
+
+            self.snk_freq = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                         0, self._bitrate,
+                                         "FLL", True, False, False, True, False, False)
+            
+            self.main_box = dialog_box(pyRxIn, pyRx, self)
+            self.main_box.show()
+
+    def _setup_usrp_source(self, options):
+        self.u = usrp_options.create_usrp_source(options)
+        adc_rate = self.u.adc_rate()
+
+        self.u.set_decim(self._decim)
+
+        (self._bitrate, self._samples_per_symbol, self._decim) = \
+                        pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
+                                        options.samples_per_symbol, options.decim, \
+                                        adc_rate, self.u.get_decim_rates())
+
+        self.u.set_decim(self._decim)
+        self.set_auto_tr(True)                 # enable Auto Transmit/Receive switching
+
+    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.
+        """
+        return self.u.set_center_freq(target_freq)
+
+    def set_gain(self, gain):
+        """
+        Sets the analog gain in the USRP
+        """
+        if gain is None:
+            r = self.u.gain_range()
+            gain = (r[0] + r[1])/2               # set gain to midpoint
+        self._rx_gain = gain
+        ret = self.u.set_gain(self._rx_gain)
+        return ret
+
+    def set_auto_tr(self, enable):
+        return self.u.set_auto_tr(enable)
+
+    def set_decim(self, decim):
+        self._decim = decim
+        self.u.set_decim(self._decim)
+
+        if(self.gui_on):
+            bw_in = self.u.adc_rate() / self._decim
+            self._bitrate = bw_in / self._samples_per_symbol
+            self.snk_rxin.set_frequency_range(0, bw_in)
+            self.snk_rx.set_frequency_range(0, self._bitrate)
+
+    def frequency(self):
+        return self._rx_freq
+
+    def gain(self):
+        return self._rx_gain
+
+    def decim(self):
+        return self._decim
+
+    def rx_gain_clock(self):
+        return self._gain_clock
+
+    def rx_gain_clock_beta(self):
+        return self._gain_clock_beta
+
+    def set_rx_gain_clock(self, gain):
+        self._gain_clock = gain
+        self._gain_clock_beta = .25 * self._gain_clock * self._gain_clock
+        self.rxpath.packet_receiver._demodulator.time_recov.set_alpha(self._gain_clock)
+        self.rxpath.packet_receiver._demodulator.time_recov.set_beta(self._gain_clock_beta)
+
+    def rx_gain_phase(self):
+        return self._gain_phase
+
+    def rx_gain_phase_beta(self):
+        return self._gain_phase_beta
+    
+    def set_rx_gain_phase(self, gain_phase):
+        self._gain_phase = gain_phase
+        self._gain_phase_beta = .25 * self._gain_phase * self._gain_phase
+        self.rxpath.packet_receiver._demodulator.phase_recov.set_alpha(self._gain_phase)
+        self.rxpath.packet_receiver._demodulator.phase_recov.set_beta(self._gain_phase_beta)
+
+
+    def rx_gain_freq(self):
+        return self._gain_freq
+
+    def set_rx_gain_freq(self, gain_freq):
+        self._gain_freq = gain_freq
+        #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq
+        self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq)
+        self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0)
+        #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta)
+
+
+    def add_options(normal, expert):
+        """
+        Adds usrp-specific options to the Options Parser
+        """
+        add_freq_option(normal)
+        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)
+        normal.add_option("-G", "--gui", action="store_true", default=False,
+                          help="Turn on the GUI [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=128,
+                          help="set fpga decimation rate to DECIM [default=%default]")
+        expert.add_option("", "--snr", type="eng_float", default=30,
+                          help="set the SNR of the channel in dB [default=%default]")
+   
+
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+
+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")
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+global n_rcvd, n_right
+
+def main():
+    global n_rcvd, n_right, pktno
+
+    n_rcvd = 0
+    n_right = 0
+    pktno = 1
+    
+    def rx_callback(ok, payload):
+        global n_rcvd, n_right, pktno
+        (pktno,) = struct.unpack('!H', payload[0:2])
+        n_rcvd += 1
+        if ok:
+            n_right += 1
+
+        if not options.gui:
+            print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
+                ok, pktno, n_rcvd, n_right)
+
+
+    demods = modulation_utils2.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='dbpsk2',
+                      help="Select modulation from: %s [default=%%default]"
+                            % (', '.join(demods.keys()),))
+
+    my_top_block.add_options(parser, expert_grp)
+    receive_path.add_options(parser, expert_grp)
+    usrp_options.add_rx_options(parser)
+
+    for mod in demods.values():
+        mod.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)
+
+
+    # build the graph
+    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."
+
+    tb.start()        # start flow graph
+
+    if(options.gui):
+        tb.qapp.exec_()
+    else:
+        tb.wait()         # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/digital/benchmark_rx2.py b/gnuradio-examples/python/digital/benchmark_rx2.py
new file mode 100755 (executable)
index 0000000..fe422be
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 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_utils2
+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
+import usrp_receive_path2
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter: ')
+
+class my_top_block(gr.top_block):
+    def __init__(self, demodulator, rx_callback, options):
+        gr.top_block.__init__(self)
+
+        # Set up receive path
+        self.rxpath = usrp_receive_path2.usrp_receive_path(demodulator, rx_callback, options) 
+
+        self.connect(self.rxpath)
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   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_utils2.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='dbpsk2',
+                      help="Select modulation from: %s [default=%%default]"
+                            % (', '.join(demods.keys()),))
+
+    usrp_receive_path2.add_options(parser, expert_grp)
+
+    for mod in demods.values():
+        mod.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)
+
+
+    # build the graph
+    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."
+
+    tb.start()        # start flow graph
+    tb.wait()         # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/digital/benchmark_tx2.py b/gnuradio-examples/python/digital/benchmark_tx2.py
new file mode 100755 (executable)
index 0000000..6093dba
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 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_utils2
+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
+import usrp_transmit_path2
+
+#import os 
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+class my_top_block(gr.top_block):
+    def __init__(self, modulator, options):
+        gr.top_block.__init__(self)
+
+        self.txpath = usrp_transmit_path2.usrp_transmit_path(modulator, options)
+
+        self.connect(self.txpath)
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+    def send_pkt(payload='', eof=False):
+        return tb.txpath.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        print "ok = %r, payload = '%s'" % (ok, payload)
+
+    mods = modulation_utils2.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='dbpsk2',
+                      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)")
+    parser.add_option("","--from-file", default=None,
+                      help="use file for packet contents")
+
+    usrp_transmit_path2.add_options(parser, expert_grp)
+
+    for mod in mods.values():
+        mod.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)
+
+    if options.from_file is not None:
+        source_file = open(options.from_file, 'r')
+
+    # build the graph
+    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"
+
+    tb.start()                       # start flow graph
+        
+    # generate and send packets
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+    pkt_size = int(options.size)
+
+    while n < nbytes:
+        if options.from_file is None:
+            data = (pkt_size - 2) * chr(pktno & 0xff) 
+        else:
+            data = source_file.read(pkt_size - 2)
+            if data == '':
+                break;
+
+        payload = struct.pack('!H', pktno & 0xffff) + data
+        send_pkt(payload)
+        n += len(payload)
+        sys.stderr.write('.')
+        if options.discontinuous and pktno % 5 == 4:
+            time.sleep(1)
+        pktno += 1
+        
+    send_pkt(eof=True)
+
+    tb.wait()                       # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/digital/pick_bitrate2.py b/gnuradio-examples/python/digital/pick_bitrate2.py
new file mode 100644 (file)
index 0000000..9253956
--- /dev/null
@@ -0,0 +1,154 @@
+#
+# Copyright 2010 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 eng_notation
+
+_default_bitrate = 500e3
+_sps_min = 2
+_sps_max = 100
+
+def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                  xrate, converter_rate, xrates):
+    """
+    @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"
+
+    converter_rate = float(converter_rate)
+    bits_per_symbol = float(bits_per_symbol)
+
+    # completely determined; if bitrate is specified, this overwrites it
+    if (samples_per_symbol is not None) and (xrate is not None):
+        bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+    # If only SPS is given
+    if (bitrate is None) and (samples_per_symbol is not None) and (xrate is None):
+        xrate = max(xrates)
+        bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+        
+    # If only xrate is given, just set SPS to 2 and calculate bitrate
+    if (bitrate is None) and (samples_per_symbol is None) and (xrate is not None):
+        samples_per_symbol = 2.0
+        bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+    # If no parameters are give, use the default bit rate
+    if (bitrate is None) and (samples_per_symbol is None) and (xrate is None):
+        bitrate = _default_bitrate
+
+    # If only bitrate is specified, return max xrate and appropriate
+    # samples per symbol (minimum of 2.0) to reach bit rate
+    if (samples_per_symbol is None) and (xrate is None):
+        xrates.sort()
+        for i in xrange(len(xrates)):
+            if((converter_rate / bits_per_symbol / xrates[i]) >= 2*bitrate):
+                rate = xrates[i]
+            else:
+                break
+
+        try:
+            xrate = rate
+        except UnboundLocalError:
+            raise ValueError("Requested bitrate out of bounds")
+            
+        samples_per_symbol = converter_rate / bits_per_symbol / rate / bitrate
+        bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+    # If bitrate and xrate are specified
+    if(samples_per_symbol is None):
+        samples_per_symbol = converter_rate / xrate / bits_per_symbol / bitrate
+
+    # If bitrate and SPS are specified
+    if(xrate is None):
+        xrate = converter_rate / samples_per_symbol / bits_per_symbol / bitrate
+        if((xrate in xrates) == False):
+            # Find the closest avaiable rate larger than the calculated one
+            xrates.sort()
+            for x in xrates:
+                if(x > xrate):
+                    xrate = x
+                    break
+            if(xrate > max(xrates)):
+                xrate = max(xrates)
+            
+            bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+            print "Could not find suitable rate for specified SPS and Bitrate"
+            print "Using rate = %d for bitrate of %sbps" % \
+                  (xrate, (eng_notation.num_to_str(bitrate)))
+
+    if((xrate in xrates) == False):
+        raise ValueError(("Invalid rate (rate = %d)" % xrate))
+    if((samples_per_symbol < _sps_min) or (samples_per_symbol > _sps_max)):
+        raise ValueError(("Invalid samples per symbol (sps = %.2f). Must be in [%.0f, %.0f]." \
+                          % (samples_per_symbol, _sps_min, _sps_max)))
+        
+    return (bitrate, samples_per_symbol, int(xrate))
+
+
+def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                    interp_rate, converter_rate, possible_interps):
+    """
+    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
+    @param possible_interps: a list of possible rates
+    @type possible_interps: a list of integers
+
+    @returns tuple (bitrate, samples_per_symbol, interp_rate)
+    """
+
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                         interp_rate, converter_rate, possible_interps)
+
+
+def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                    decim_rate, converter_rate, possible_decims):
+    """
+    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
+    @param possible_decims: a list of possible rates
+    @type possible_decims: a list of integers
+
+    @returns tuple (bitrate, samples_per_symbol, decim_rate)
+    """
+
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                         decim_rate, converter_rate, possible_decims)
index e3feb57c932e26834c849f0c0b8d2dc8bb5f0d49..b47ed0c2b57f483eadb13e064e9e2cae5aa4f643 100644 (file)
@@ -2,8 +2,8 @@
 
 # Form implementation generated from reading ui file 'qt_digital_window.ui'
 #
-# Created: Fri Jul  3 10:03:54 2009
-#      by: PyQt4 UI code generator 4.4.3
+# Created: Tue May 11 20:58:35 2010
+#      by: PyQt4 UI code generator 4.6.1
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -12,11 +12,16 @@ from PyQt4 import QtCore, QtGui
 class Ui_DigitalWindow(object):
     def setupUi(self, DigitalWindow):
         DigitalWindow.setObjectName("DigitalWindow")
-        DigitalWindow.resize(1050, 752)
+        DigitalWindow.resize(1059, 754)
         self.centralwidget = QtGui.QWidget(DigitalWindow)
         self.centralwidget.setObjectName("centralwidget")
-        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
-        self.gridLayout.setObjectName("gridLayout")
+        self.verticalLayout_4 = QtGui.QVBoxLayout(self.centralwidget)
+        self.verticalLayout_4.setObjectName("verticalLayout_4")
+        self.sinkLayout = QtGui.QHBoxLayout()
+        self.sinkLayout.setObjectName("sinkLayout")
+        self.verticalLayout_4.addLayout(self.sinkLayout)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
         self.verticalLayout_2 = QtGui.QVBoxLayout()
         self.verticalLayout_2.setObjectName("verticalLayout_2")
         self.sysBox = QtGui.QGroupBox(self.centralwidget)
@@ -29,7 +34,7 @@ class Ui_DigitalWindow(object):
         self.sysBox.setMaximumSize(QtCore.QSize(240, 16777215))
         self.sysBox.setObjectName("sysBox")
         self.formLayoutWidget = QtGui.QWidget(self.sysBox)
-        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 221, 31))
+        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 211, 31))
         self.formLayoutWidget.setObjectName("formLayoutWidget")
         self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
         self.formLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
@@ -41,8 +46,8 @@ class Ui_DigitalWindow(object):
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.sampleRateEdit.sizePolicy().hasHeightForWidth())
         self.sampleRateEdit.setSizePolicy(sizePolicy)
-        self.sampleRateEdit.setMinimumSize(QtCore.QSize(100, 26))
-        self.sampleRateEdit.setMaximumSize(QtCore.QSize(100, 26))
+        self.sampleRateEdit.setMinimumSize(QtCore.QSize(60, 26))
+        self.sampleRateEdit.setMaximumSize(QtCore.QSize(80, 26))
         self.sampleRateEdit.setObjectName("sampleRateEdit")
         self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit)
         self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget)
@@ -58,7 +63,7 @@ class Ui_DigitalWindow(object):
         self.verticalLayout_2.addWidget(self.sysBox)
         spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
         self.verticalLayout_2.addItem(spacerItem)
-        self.gridLayout.addLayout(self.verticalLayout_2, 2, 0, 1, 1)
+        self.horizontalLayout.addLayout(self.verticalLayout_2)
         self.channelModeBox = QtGui.QGroupBox(self.centralwidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
@@ -69,7 +74,7 @@ class Ui_DigitalWindow(object):
         self.channelModeBox.setMaximumSize(QtCore.QSize(245, 16777215))
         self.channelModeBox.setObjectName("channelModeBox")
         self.formLayoutWidget_2 = QtGui.QWidget(self.channelModeBox)
-        self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 231, 98))
+        self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 221, 98))
         self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")
         self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_2)
         self.formLayout_2.setSizeConstraint(QtGui.QLayout.SetFixedSize)
@@ -79,59 +84,38 @@ class Ui_DigitalWindow(object):
         self.snrLabel.setObjectName("snrLabel")
         self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.snrLabel)
         self.snrEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
-        self.snrEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.snrEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.snrEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.snrEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.snrEdit.setObjectName("snrEdit")
         self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.snrEdit)
         self.freqLabel = QtGui.QLabel(self.formLayoutWidget_2)
         self.freqLabel.setObjectName("freqLabel")
         self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.freqLabel)
         self.freqEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
-        self.freqEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.freqEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.freqEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.freqEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.freqEdit.setObjectName("freqEdit")
         self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.freqEdit)
         self.timeLabel = QtGui.QLabel(self.formLayoutWidget_2)
         self.timeLabel.setObjectName("timeLabel")
         self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.timeLabel)
         self.timeEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
-        self.timeEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.timeEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.timeEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.timeEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.timeEdit.setObjectName("timeEdit")
         self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit)
-        self.gridLayout.addWidget(self.channelModeBox, 2, 1, 1, 1)
-        self.verticalLayout_5 = QtGui.QVBoxLayout()
-        self.verticalLayout_5.setObjectName("verticalLayout_5")
-        self.sinkFrame = QtGui.QFrame(self.centralwidget)
-        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
-        sizePolicy.setHorizontalStretch(0)
-        sizePolicy.setVerticalStretch(0)
-        sizePolicy.setHeightForWidth(self.sinkFrame.sizePolicy().hasHeightForWidth())
-        self.sinkFrame.setSizePolicy(sizePolicy)
-        self.sinkFrame.setMinimumSize(QtCore.QSize(1000, 550))
-        self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel)
-        self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised)
-        self.sinkFrame.setObjectName("sinkFrame")
-        self.gridLayout_2 = QtGui.QGridLayout(self.sinkFrame)
-        self.gridLayout_2.setObjectName("gridLayout_2")
-        self.sinkLayout = QtGui.QHBoxLayout()
-        self.sinkLayout.setObjectName("sinkLayout")
-        self.gridLayout_2.addLayout(self.sinkLayout, 1, 0, 1, 1)
-        self.verticalLayout_5.addWidget(self.sinkFrame)
-        self.gridLayout.addLayout(self.verticalLayout_5, 0, 0, 1, 6)
-        self.verticalLayout_3 = QtGui.QVBoxLayout()
-        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.horizontalLayout.addWidget(self.channelModeBox)
         self.rxBox = QtGui.QGroupBox(self.centralwidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth())
         self.rxBox.setSizePolicy(sizePolicy)
-        self.rxBox.setMinimumSize(QtCore.QSize(180, 90))
+        self.rxBox.setMinimumSize(QtCore.QSize(220, 130))
         self.rxBox.setMaximumSize(QtCore.QSize(180, 16777215))
         self.rxBox.setObjectName("rxBox")
         self.formLayoutWidget_3 = QtGui.QWidget(self.rxBox)
-        self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 161, 61))
+        self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 101))
         self.formLayoutWidget_3.setObjectName("formLayoutWidget_3")
         self.formLayout_3 = QtGui.QFormLayout(self.formLayoutWidget_3)
         self.formLayout_3.setSizeConstraint(QtGui.QLayout.SetFixedSize)
@@ -143,19 +127,16 @@ class Ui_DigitalWindow(object):
         self.alphaLabel.setObjectName("alphaLabel")
         self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.alphaLabel)
         self.gainMuEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
-        self.gainMuEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.gainMuEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.gainMuEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.gainMuEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.gainMuEdit.setObjectName("gainMuEdit")
         self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.gainMuEdit)
         self.alphaEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
-        self.alphaEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.alphaEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.alphaEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.alphaEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.alphaEdit.setObjectName("alphaEdit")
         self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.alphaEdit)
-        self.verticalLayout_3.addWidget(self.rxBox)
-        spacerItem1 = QtGui.QSpacerItem(20, 30, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
-        self.verticalLayout_3.addItem(spacerItem1)
-        self.gridLayout.addLayout(self.verticalLayout_3, 2, 2, 1, 1)
+        self.horizontalLayout.addWidget(self.rxBox)
         self.rxBox_2 = QtGui.QGroupBox(self.centralwidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
@@ -166,7 +147,7 @@ class Ui_DigitalWindow(object):
         self.rxBox_2.setMaximumSize(QtCore.QSize(265, 125))
         self.rxBox_2.setObjectName("rxBox_2")
         self.formLayoutWidget_4 = QtGui.QWidget(self.rxBox_2)
-        self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 201, 92))
+        self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 201, 91))
         self.formLayoutWidget_4.setObjectName("formLayoutWidget_4")
         self.formLayout_4 = QtGui.QFormLayout(self.formLayoutWidget_4)
         self.formLayout_4.setSizeConstraint(QtGui.QLayout.SetFixedSize)
@@ -181,23 +162,23 @@ class Ui_DigitalWindow(object):
         self.perLabel.setObjectName("perLabel")
         self.formLayout_4.setWidget(2, QtGui.QFormLayout.LabelRole, self.perLabel)
         self.pktsRcvdEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
-        self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.pktsRcvdEdit.setObjectName("pktsRcvdEdit")
         self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.pktsRcvdEdit)
         self.pktsCorrectEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
-        self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.pktsCorrectEdit.setObjectName("pktsCorrectEdit")
         self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.pktsCorrectEdit)
         self.perEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
-        self.perEdit.setMinimumSize(QtCore.QSize(100, 0))
-        self.perEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.perEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.perEdit.setMaximumSize(QtCore.QSize(80, 16777215))
         self.perEdit.setObjectName("perEdit")
         self.formLayout_4.setWidget(2, QtGui.QFormLayout.FieldRole, self.perEdit)
-        self.gridLayout.addWidget(self.rxBox_2, 2, 3, 1, 1)
-        spacerItem2 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.gridLayout.addItem(spacerItem2, 2, 4, 1, 1)
+        self.horizontalLayout.addWidget(self.rxBox_2)
+        spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem1)
         self.verticalLayout = QtGui.QVBoxLayout()
         self.verticalLayout.setObjectName("verticalLayout")
         self.pauseButton = QtGui.QPushButton(self.centralwidget)
@@ -205,17 +186,18 @@ class Ui_DigitalWindow(object):
         self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215))
         self.pauseButton.setObjectName("pauseButton")
         self.verticalLayout.addWidget(self.pauseButton)
-        spacerItem3 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
-        self.verticalLayout.addItem(spacerItem3)
+        spacerItem2 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout.addItem(spacerItem2)
         self.closeButton = QtGui.QPushButton(self.centralwidget)
         self.closeButton.setMinimumSize(QtCore.QSize(80, 0))
         self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215))
         self.closeButton.setObjectName("closeButton")
         self.verticalLayout.addWidget(self.closeButton)
-        self.gridLayout.addLayout(self.verticalLayout, 2, 5, 1, 1)
+        self.horizontalLayout.addLayout(self.verticalLayout)
+        self.verticalLayout_4.addLayout(self.horizontalLayout)
         DigitalWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(DigitalWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 1050, 24))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1059, 23))
         self.menubar.setObjectName("menubar")
         self.menuFile = QtGui.QMenu(self.menubar)
         self.menuFile.setObjectName("menuFile")
index 413801ec7108324b4ab8c19454b45322305dcbee..4b3857d87e21f0fe77a0890aba0bef8fe23f7770 100644 (file)
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>DigitalWindow</class>
- <widget class="QMainWindow" name="DigitalWindow" >
-  <property name="geometry" >
+ <widget class="QMainWindow" name="DigitalWindow">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1050</width>
-    <height>752</height>
+    <width>1059</width>
+    <height>754</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QWidget" name="centralwidget" >
-   <layout class="QGridLayout" name="gridLayout" >
-    <item row="2" column="0" >
-     <layout class="QVBoxLayout" name="verticalLayout_2" >
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QVBoxLayout" name="verticalLayout_4">
+    <item>
+     <layout class="QHBoxLayout" name="sinkLayout"/>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
-       <widget class="QGroupBox" name="sysBox" >
-        <property name="sizePolicy" >
-         <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="QGroupBox" name="sysBox">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>240</width>
+            <height>60</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>240</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="title">
+           <string>System Parameters</string>
+          </property>
+          <widget class="QWidget" name="formLayoutWidget">
+           <property name="geometry">
+            <rect>
+             <x>10</x>
+             <y>20</y>
+             <width>211</width>
+             <height>31</height>
+            </rect>
+           </property>
+           <layout class="QFormLayout" name="formLayout">
+            <property name="sizeConstraint">
+             <enum>QLayout::SetFixedSize</enum>
+            </property>
+            <property name="verticalSpacing">
+             <number>20</number>
+            </property>
+            <item row="0" column="1">
+             <widget class="QLineEdit" name="sampleRateEdit">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>26</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>80</width>
+                <height>26</height>
+               </size>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="0">
+             <widget class="QLabel" name="sampleRateLabel">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>16777215</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Sample Rate (sps)</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </widget>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>60</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="channelModeBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
-        <property name="minimumSize" >
+        <property name="minimumSize">
          <size>
-          <width>240</width>
-          <height>60</height>
+          <width>245</width>
+          <height>130</height>
          </size>
         </property>
-        <property name="maximumSize" >
+        <property name="maximumSize">
          <size>
-          <width>240</width>
+          <width>245</width>
           <height>16777215</height>
          </size>
         </property>
-        <property name="title" >
-         <string>System Parameters</string>
+        <property name="title">
+         <string>Channel Model Parameters</string>
         </property>
-        <widget class="QWidget" name="formLayoutWidget>
-         <property name="geometry" >
+        <widget class="QWidget" name="formLayoutWidget_2">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>20</y>
            <width>221</width>
-           <height>31</height>
+           <height>98</height>
           </rect>
          </property>
-         <layout class="QFormLayout" name="formLayout>
-          <property name="sizeConstraint" >
+         <layout class="QFormLayout" name="formLayout_2">
+          <property name="sizeConstraint">
            <enum>QLayout::SetFixedSize</enum>
           </property>
-          <property name="verticalSpacing" >
-           <number>20</number>
+          <property name="fieldGrowthPolicy">
+           <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
           </property>
-          <item row="0" column="1" >
-           <widget class="QLineEdit" name="sampleRateEdit" >
-            <property name="sizePolicy" >
-             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
+          <item row="0" column="0">
+           <widget class="QLabel" name="snrLabel">
+            <property name="text">
+             <string>SNR (dB)</string>
             </property>
-            <property name="minimumSize" >
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="snrEdit">
+            <property name="minimumSize">
              <size>
-              <width>100</width>
-              <height>26</height>
+              <width>60</width>
+              <height>0</height>
              </size>
             </property>
-            <property name="maximumSize" >
+            <property name="maximumSize">
              <size>
-              <width>100</width>
-              <height>26</height>
+              <width>80</width>
+              <height>16777215</height>
              </size>
             </property>
            </widget>
           </item>
-          <item row="0" column="0" >
-           <widget class="QLabel" name="sampleRateLabel" >
-            <property name="sizePolicy" >
-             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
+          <item row="1" column="0">
+           <widget class="QLabel" name="freqLabel">
+            <property name="text">
+             <string>Frequency Offset (Hz)</string>
             </property>
-            <property name="minimumSize" >
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="freqEdit">
+            <property name="minimumSize">
              <size>
-              <width>0</width>
-              <height>20</height>
+              <width>60</width>
+              <height>0</height>
              </size>
             </property>
-            <property name="maximumSize" >
+            <property name="maximumSize">
              <size>
-              <width>16777215</width>
-              <height>20</height>
+              <width>80</width>
+              <height>16777215</height>
              </size>
             </property>
-            <property name="text" >
-             <string>Sample Rate (sps)</string>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="timeLabel">
+            <property name="text">
+             <string>Timing Offset</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="timeEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
+        <zorder>formLayoutWidget_2</zorder>
+        <zorder>sysBox</zorder>
        </widget>
       </item>
       <item>
-       <spacer name="verticalSpacer_2" >
-        <property name="orientation" >
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeType" >
-         <enum>QSizePolicy::Fixed</enum>
-        </property>
-        <property name="sizeHint" stdset="0" >
-         <size>
-          <width>20</width>
-          <height>60</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-     </layout>
-    </item>
-    <item row="2" column="1" >
-     <widget class="QGroupBox" name="channelModeBox" >
-      <property name="sizePolicy" >
-       <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="minimumSize" >
-       <size>
-        <width>245</width>
-        <height>130</height>
-       </size>
-      </property>
-      <property name="maximumSize" >
-       <size>
-        <width>245</width>
-        <height>16777215</height>
-       </size>
-      </property>
-      <property name="title" >
-       <string>Channel Model Parameters</string>
-      </property>
-      <widget class="QWidget" name="formLayoutWidget_2" >
-       <property name="geometry" >
-        <rect>
-         <x>10</x>
-         <y>20</y>
-         <width>231</width>
-         <height>98</height>
-        </rect>
-       </property>
-       <layout class="QFormLayout" name="formLayout_2" >
-        <property name="sizeConstraint" >
-         <enum>QLayout::SetFixedSize</enum>
-        </property>
-        <property name="fieldGrowthPolicy" >
-         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
-        </property>
-        <item row="0" column="0" >
-         <widget class="QLabel" name="snrLabel" >
-          <property name="text" >
-           <string>SNR (dB)</string>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1" >
-         <widget class="QLineEdit" name="snrEdit" >
-          <property name="minimumSize" >
-           <size>
-            <width>100</width>
-            <height>0</height>
-           </size>
-          </property>
-          <property name="maximumSize" >
-           <size>
-            <width>100</width>
-            <height>16777215</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="0" >
-         <widget class="QLabel" name="freqLabel" >
-          <property name="text" >
-           <string>Frequency Offset (Hz)</string>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1" >
-         <widget class="QLineEdit" name="freqEdit" >
-          <property name="minimumSize" >
-           <size>
-            <width>100</width>
-            <height>0</height>
-           </size>
-          </property>
-          <property name="maximumSize" >
-           <size>
-            <width>100</width>
-            <height>16777215</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="0" >
-         <widget class="QLabel" name="timeLabel" >
-          <property name="text" >
-           <string>Timing Offset</string>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1" >
-         <widget class="QLineEdit" name="timeEdit" >
-          <property name="minimumSize" >
-           <size>
-            <width>100</width>
-            <height>0</height>
-           </size>
-          </property>
-          <property name="maximumSize" >
-           <size>
-            <width>100</width>
-            <height>16777215</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-     </widget>
-    </item>
-    <item row="0" column="0" colspan="6" >
-     <layout class="QVBoxLayout" name="verticalLayout_5" >
-      <item>
-       <widget class="QFrame" name="sinkFrame" >
-        <property name="sizePolicy" >
-         <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+       <widget class="QGroupBox" name="rxBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
-        <property name="minimumSize" >
+        <property name="minimumSize">
          <size>
-          <width>1000</width>
-          <height>550</height>
+          <width>220</width>
+          <height>130</height>
          </size>
         </property>
-        <property name="frameShape" >
-         <enum>QFrame::StyledPanel</enum>
+        <property name="maximumSize">
+         <size>
+          <width>180</width>
+          <height>16777215</height>
+         </size>
         </property>
-        <property name="frameShadow" >
-         <enum>QFrame::Raised</enum>
+        <property name="title">
+         <string>Receiver Parameters</string>
         </property>
-        <layout class="QGridLayout" name="gridLayout_2" >
-         <item row="1" column="0" >
-          <layout class="QHBoxLayout" name="sinkLayout" />
-         </item>
-        </layout>
-        <zorder>verticalLayoutWidget</zorder>
-        <zorder>verticalLayoutWidget</zorder>
+        <widget class="QWidget" name="formLayoutWidget_3">
+         <property name="geometry">
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>201</width>
+           <height>101</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout_3">
+          <property name="sizeConstraint">
+           <enum>QLayout::SetFixedSize</enum>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="gainMuLabel">
+            <property name="text">
+             <string>Gain mu</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="alphaLabel">
+            <property name="text">
+             <string>Alpha</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="gainMuEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="alphaEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
        </widget>
       </item>
-     </layout>
-    </item>
-    <item row="2" column="2" >
-     <layout class="QVBoxLayout" name="verticalLayout_3" >
       <item>
-       <widget class="QGroupBox" name="rxBox>
-        <property name="sizePolicy" >
-         <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+       <widget class="QGroupBox" name="rxBox_2">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
-        <property name="minimumSize" >
+        <property name="minimumSize">
          <size>
-          <width>180</width>
-          <height>90</height>
+          <width>220</width>
+          <height>125</height>
          </size>
         </property>
-        <property name="maximumSize" >
+        <property name="maximumSize">
          <size>
-          <width>180</width>
-          <height>16777215</height>
+          <width>265</width>
+          <height>125</height>
          </size>
         </property>
-        <property name="title" >
-         <string>Receiver Parameters</string>
+        <property name="title">
+         <string>Received Packet Info</string>
         </property>
-        <widget class="QWidget" name="formLayoutWidget_3" >
-         <property name="geometry" >
+        <widget class="QWidget" name="formLayoutWidget_4">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>20</y>
-           <width>161</width>
-           <height>61</height>
+           <width>201</width>
+           <height>91</height>
           </rect>
          </property>
-         <layout class="QFormLayout" name="formLayout_3" >
-          <property name="sizeConstraint" >
+         <layout class="QFormLayout" name="formLayout_4">
+          <property name="sizeConstraint">
            <enum>QLayout::SetFixedSize</enum>
           </property>
-          <item row="0" column="0" >
-           <widget class="QLabel" name="gainMuLabel" >
-            <property name="text" >
-             <string>Gain mu</string>
+          <item row="0" column="0">
+           <widget class="QLabel" name="pktsRcvdLabel">
+            <property name="text">
+             <string>Packets Rcvd.</string>
             </property>
            </widget>
           </item>
-          <item row="1" column="0" >
-           <widget class="QLabel" name="alphaLabel" >
-            <property name="text" >
-             <string>Alpha</string>
+          <item row="1" column="0">
+           <widget class="QLabel" name="pktsCorrectLabel">
+            <property name="text">
+             <string>Packets Correct</string>
             </property>
            </widget>
           </item>
-          <item row="0" column="1" >
-           <widget class="QLineEdit" name="gainMuEdit" >
-            <property name="minimumSize" >
+          <item row="2" column="0">
+           <widget class="QLabel" name="perLabel">
+            <property name="text">
+             <string>PER</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="pktsRcvdEdit">
+            <property name="minimumSize">
              <size>
-              <width>100</width>
+              <width>60</width>
               <height>0</height>
              </size>
             </property>
-            <property name="maximumSize" >
+            <property name="maximumSize">
              <size>
-              <width>100</width>
+              <width>80</width>
               <height>16777215</height>
              </size>
             </property>
            </widget>
           </item>
-          <item row="1" column="1" >
-           <widget class="QLineEdit" name="alphaEdit" >
-            <property name="minimumSize" >
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="pktsCorrectEdit">
+            <property name="minimumSize">
              <size>
-              <width>100</width>
+              <width>60</width>
               <height>0</height>
              </size>
             </property>
-            <property name="maximumSize" >
+            <property name="maximumSize">
              <size>
-              <width>100</width>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="perEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
               <height>16777215</height>
              </size>
             </property>
        </widget>
       </item>
       <item>
-       <spacer name="verticalSpacer_4" >
-        <property name="orientation" >
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeType" >
-         <enum>QSizePolicy::Fixed</enum>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
-          <height>30</height>
+          <height>20</height>
          </size>
         </property>
        </spacer>
       </item>
-     </layout>
-    </item>
-    <item row="2" column="3" >
-     <widget class="QGroupBox" name="rxBox_2" >
-      <property name="sizePolicy" >
-       <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="minimumSize" >
-       <size>
-        <width>220</width>
-        <height>125</height>
-       </size>
-      </property>
-      <property name="maximumSize" >
-       <size>
-        <width>265</width>
-        <height>125</height>
-       </size>
-      </property>
-      <property name="title" >
-       <string>Received Packet Info</string>
-      </property>
-      <widget class="QWidget" name="formLayoutWidget_4" >
-       <property name="geometry" >
-        <rect>
-         <x>10</x>
-         <y>20</y>
-         <width>201</width>
-         <height>92</height>
-        </rect>
-       </property>
-       <layout class="QFormLayout" name="formLayout_4" >
-        <property name="sizeConstraint" >
-         <enum>QLayout::SetFixedSize</enum>
-        </property>
-        <item row="0" column="0" >
-         <widget class="QLabel" name="pktsRcvdLabel" >
-          <property name="text" >
-           <string>Packets Rcvd.</string>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="0" >
-         <widget class="QLabel" name="pktsCorrectLabel" >
-          <property name="text" >
-           <string>Packets Correct</string>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="0" >
-         <widget class="QLabel" name="perLabel" >
-          <property name="text" >
-           <string>PER</string>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1" >
-         <widget class="QLineEdit" name="pktsRcvdEdit" >
-          <property name="minimumSize" >
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QPushButton" name="pauseButton">
+          <property name="minimumSize">
            <size>
-            <width>100</width>
+            <width>80</width>
             <height>0</height>
            </size>
           </property>
-          <property name="maximumSize" >
+          <property name="maximumSize">
            <size>
-            <width>100</width>
+            <width>80</width>
             <height>16777215</height>
            </size>
           </property>
+          <property name="text">
+           <string>Pause</string>
+          </property>
          </widget>
         </item>
-        <item row="1" column="1" >
-         <widget class="QLineEdit" name="pktsCorrectEdit" >
-          <property name="minimumSize" >
-           <size>
-            <width>100</width>
-            <height>0</height>
-           </size>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
           </property>
-          <property name="maximumSize" >
+          <property name="sizeHint" stdset="0">
            <size>
-            <width>100</width>
-            <height>16777215</height>
+            <width>20</width>
+            <height>60</height>
            </size>
           </property>
-         </widget>
+         </spacer>
         </item>
-        <item row="2" column="1" >
-         <widget class="QLineEdit" name="perEdit" >
-          <property name="minimumSize" >
+        <item>
+         <widget class="QPushButton" name="closeButton">
+          <property name="minimumSize">
            <size>
-            <width>100</width>
+            <width>80</width>
             <height>0</height>
            </size>
           </property>
-          <property name="maximumSize" >
+          <property name="maximumSize">
            <size>
-            <width>100</width>
+            <width>80</width>
             <height>16777215</height>
            </size>
           </property>
+          <property name="text">
+           <string>Close</string>
+          </property>
          </widget>
         </item>
        </layout>
-      </widget>
-     </widget>
-    </item>
-    <item row="2" column="4" >
-     <spacer name="horizontalSpacer" >
-      <property name="orientation" >
-       <enum>Qt::Horizontal</enum>
-      </property>
-      <property name="sizeHint" stdset="0" >
-       <size>
-        <width>20</width>
-        <height>20</height>
-       </size>
-      </property>
-     </spacer>
-    </item>
-    <item row="2" column="5" >
-     <layout class="QVBoxLayout" name="verticalLayout" >
-      <item>
-       <widget class="QPushButton" name="pauseButton" >
-        <property name="minimumSize" >
-         <size>
-          <width>80</width>
-          <height>0</height>
-         </size>
-        </property>
-        <property name="maximumSize" >
-         <size>
-          <width>80</width>
-          <height>16777215</height>
-         </size>
-        </property>
-        <property name="text" >
-         <string>Pause</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer name="verticalSpacer" >
-        <property name="orientation" >
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeType" >
-         <enum>QSizePolicy::Fixed</enum>
-        </property>
-        <property name="sizeHint" stdset="0" >
-         <size>
-          <width>20</width>
-          <height>60</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item>
-       <widget class="QPushButton" name="closeButton" >
-        <property name="minimumSize" >
-         <size>
-          <width>80</width>
-          <height>0</height>
-         </size>
-        </property>
-        <property name="maximumSize" >
-         <size>
-          <width>80</width>
-          <height>16777215</height>
-         </size>
-        </property>
-        <property name="text" >
-         <string>Close</string>
-        </property>
-       </widget>
       </item>
      </layout>
     </item>
    </layout>
-   <zorder>sinkFrame</zorder>
-   <zorder>channelModeBox</zorder>
-   <zorder>verticalLayoutWidget</zorder>
-   <zorder>verticalLayoutWidget</zorder>
-   <zorder>rxBox</zorder>
-   <zorder></zorder>
-   <zorder>rxBox_2</zorder>
-   <zorder>horizontalSpacer</zorder>
-   <zorder></zorder>
   </widget>
-  <widget class="QMenuBar" name="menubar" >
-   <property name="geometry" >
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>1050</width>
-     <height>24</height>
+     <width>1059</width>
+     <height>23</height>
     </rect>
    </property>
-   <widget class="QMenu" name="menuFile" >
-    <property name="title" >
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
      <string>&amp;File</string>
     </property>
-    <addaction name="actionExit" />
+    <addaction name="actionExit"/>
    </widget>
-   <addaction name="menuFile" />
+   <addaction name="menuFile"/>
   </widget>
-  <widget class="QStatusBar" name="statusbar" />
-  <action name="actionExit" >
-   <property name="text" >
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionExit">
+   <property name="text">
     <string>E&amp;xit</string>
    </property>
   </action>
    <receiver>DigitalWindow</receiver>
    <slot>close()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>322</x>
      <y>623</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>66</x>
      <y>561</y>
     </hint>
    <receiver>DigitalWindow</receiver>
    <slot>close()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>-1</x>
      <y>-1</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>617</x>
      <y>327</y>
     </hint>
diff --git a/gnuradio-examples/python/digital/qt_digital_window2.py b/gnuradio-examples/python/digital/qt_digital_window2.py
new file mode 100644 (file)
index 0000000..2d10e3a
--- /dev/null
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'qt_digital_window2.ui'
+#
+# Created: Tue May 11 20:55:10 2010
+#      by: PyQt4 UI code generator 4.6.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_DigitalWindow(object):
+    def setupUi(self, DigitalWindow):
+        DigitalWindow.setObjectName("DigitalWindow")
+        DigitalWindow.resize(1059, 751)
+        self.centralwidget = QtGui.QWidget(DigitalWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.verticalLayout_3 = QtGui.QVBoxLayout(self.centralwidget)
+        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.sinkLayout = QtGui.QHBoxLayout()
+        self.sinkLayout.setObjectName("sinkLayout")
+        self.verticalLayout_3.addLayout(self.sinkLayout)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.verticalLayout_2 = QtGui.QVBoxLayout()
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        self.sysBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sysBox.sizePolicy().hasHeightForWidth())
+        self.sysBox.setSizePolicy(sizePolicy)
+        self.sysBox.setMinimumSize(QtCore.QSize(240, 60))
+        self.sysBox.setMaximumSize(QtCore.QSize(240, 16777215))
+        self.sysBox.setObjectName("sysBox")
+        self.formLayoutWidget = QtGui.QWidget(self.sysBox)
+        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 211, 31))
+        self.formLayoutWidget.setObjectName("formLayoutWidget")
+        self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
+        self.formLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout.setVerticalSpacing(20)
+        self.formLayout.setObjectName("formLayout")
+        self.sampleRateEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sampleRateEdit.sizePolicy().hasHeightForWidth())
+        self.sampleRateEdit.setSizePolicy(sizePolicy)
+        self.sampleRateEdit.setMinimumSize(QtCore.QSize(60, 26))
+        self.sampleRateEdit.setMaximumSize(QtCore.QSize(80, 26))
+        self.sampleRateEdit.setObjectName("sampleRateEdit")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit)
+        self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sampleRateLabel.sizePolicy().hasHeightForWidth())
+        self.sampleRateLabel.setSizePolicy(sizePolicy)
+        self.sampleRateLabel.setMinimumSize(QtCore.QSize(0, 20))
+        self.sampleRateLabel.setMaximumSize(QtCore.QSize(16777215, 20))
+        self.sampleRateLabel.setObjectName("sampleRateLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel)
+        self.verticalLayout_2.addWidget(self.sysBox)
+        spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout_2.addItem(spacerItem)
+        self.horizontalLayout.addLayout(self.verticalLayout_2)
+        self.channelModeBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.channelModeBox.sizePolicy().hasHeightForWidth())
+        self.channelModeBox.setSizePolicy(sizePolicy)
+        self.channelModeBox.setMinimumSize(QtCore.QSize(245, 130))
+        self.channelModeBox.setMaximumSize(QtCore.QSize(245, 16777215))
+        self.channelModeBox.setObjectName("channelModeBox")
+        self.formLayoutWidget_2 = QtGui.QWidget(self.channelModeBox)
+        self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 221, 98))
+        self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")
+        self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_2)
+        self.formLayout_2.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_2.setObjectName("formLayout_2")
+        self.snrLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.snrLabel.setObjectName("snrLabel")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.snrLabel)
+        self.snrEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.snrEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.snrEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.snrEdit.setObjectName("snrEdit")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.snrEdit)
+        self.freqLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.freqLabel.setObjectName("freqLabel")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.freqLabel)
+        self.freqEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.freqEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.freqEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.freqEdit.setObjectName("freqEdit")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.freqEdit)
+        self.timeLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.timeLabel.setObjectName("timeLabel")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.timeLabel)
+        self.timeEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.timeEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.timeEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.timeEdit.setObjectName("timeEdit")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit)
+        self.horizontalLayout.addWidget(self.channelModeBox)
+        self.rxBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth())
+        self.rxBox.setSizePolicy(sizePolicy)
+        self.rxBox.setMinimumSize(QtCore.QSize(220, 130))
+        self.rxBox.setMaximumSize(QtCore.QSize(180, 16777215))
+        self.rxBox.setObjectName("rxBox")
+        self.formLayoutWidget_3 = QtGui.QWidget(self.rxBox)
+        self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 101))
+        self.formLayoutWidget_3.setObjectName("formLayoutWidget_3")
+        self.formLayout_3 = QtGui.QFormLayout(self.formLayoutWidget_3)
+        self.formLayout_3.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_3.setObjectName("formLayout_3")
+        self.gainClockLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.gainClockLabel.setObjectName("gainClockLabel")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.gainClockLabel)
+        self.gainPhaseLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.gainPhaseLabel.setObjectName("gainPhaseLabel")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel)
+        self.gainClockEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.gainClockEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.gainClockEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.gainClockEdit.setObjectName("gainClockEdit")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.gainClockEdit)
+        self.gainFreqEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.gainFreqEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.gainFreqEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.gainFreqEdit.setObjectName("gainFreqEdit")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.gainFreqEdit)
+        self.gainPhaseEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.gainPhaseEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.gainPhaseEdit.setObjectName("gainPhaseEdit")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.gainPhaseEdit)
+        self.gainPhaseLabel_2 = QtGui.QLabel(self.formLayoutWidget_3)
+        self.gainPhaseLabel_2.setObjectName("gainPhaseLabel_2")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel_2)
+        self.horizontalLayout.addWidget(self.rxBox)
+        self.rxBox_2 = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxBox_2.sizePolicy().hasHeightForWidth())
+        self.rxBox_2.setSizePolicy(sizePolicy)
+        self.rxBox_2.setMinimumSize(QtCore.QSize(220, 125))
+        self.rxBox_2.setMaximumSize(QtCore.QSize(265, 125))
+        self.rxBox_2.setObjectName("rxBox_2")
+        self.formLayoutWidget_4 = QtGui.QWidget(self.rxBox_2)
+        self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 201, 91))
+        self.formLayoutWidget_4.setObjectName("formLayoutWidget_4")
+        self.formLayout_4 = QtGui.QFormLayout(self.formLayoutWidget_4)
+        self.formLayout_4.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_4.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_4.setObjectName("formLayout_4")
+        self.pktsRcvdLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.pktsRcvdLabel.setObjectName("pktsRcvdLabel")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.LabelRole, self.pktsRcvdLabel)
+        self.pktsRcvdEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pktsRcvdEdit.setObjectName("pktsRcvdEdit")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.pktsRcvdEdit)
+        self.pktsCorrectLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.pktsCorrectLabel.setObjectName("pktsCorrectLabel")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.LabelRole, self.pktsCorrectLabel)
+        self.pktsCorrectEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pktsCorrectEdit.setObjectName("pktsCorrectEdit")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.pktsCorrectEdit)
+        self.perLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.perLabel.setObjectName("perLabel")
+        self.formLayout_4.setWidget(2, QtGui.QFormLayout.LabelRole, self.perLabel)
+        self.perEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.perEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.perEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.perEdit.setObjectName("perEdit")
+        self.formLayout_4.setWidget(2, QtGui.QFormLayout.FieldRole, self.perEdit)
+        self.horizontalLayout.addWidget(self.rxBox_2)
+        spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem1)
+        self.verticalLayout = QtGui.QVBoxLayout()
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.pauseButton = QtGui.QPushButton(self.centralwidget)
+        self.pauseButton.setMinimumSize(QtCore.QSize(80, 0))
+        self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pauseButton.setObjectName("pauseButton")
+        self.verticalLayout.addWidget(self.pauseButton)
+        spacerItem2 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout.addItem(spacerItem2)
+        self.closeButton = QtGui.QPushButton(self.centralwidget)
+        self.closeButton.setMinimumSize(QtCore.QSize(80, 0))
+        self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout.addWidget(self.closeButton)
+        self.horizontalLayout.addLayout(self.verticalLayout)
+        self.verticalLayout_3.addLayout(self.horizontalLayout)
+        DigitalWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(DigitalWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1059, 23))
+        self.menubar.setObjectName("menubar")
+        self.menuFile = QtGui.QMenu(self.menubar)
+        self.menuFile.setObjectName("menuFile")
+        DigitalWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(DigitalWindow)
+        self.statusbar.setObjectName("statusbar")
+        DigitalWindow.setStatusBar(self.statusbar)
+        self.actionExit = QtGui.QAction(DigitalWindow)
+        self.actionExit.setObjectName("actionExit")
+        self.menuFile.addAction(self.actionExit)
+        self.menubar.addAction(self.menuFile.menuAction())
+
+        self.retranslateUi(DigitalWindow)
+        QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close)
+        QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(DigitalWindow)
+        DigitalWindow.setTabOrder(self.snrEdit, self.freqEdit)
+        DigitalWindow.setTabOrder(self.freqEdit, self.timeEdit)
+
+    def retranslateUi(self, DigitalWindow):
+        DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.channelModeBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Channel Model Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.snrLabel.setText(QtGui.QApplication.translate("DigitalWindow", "SNR (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency Offset (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainClockLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Clock Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainPhaseLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Freq. Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainPhaseLabel_2.setText(QtGui.QApplication.translate("DigitalWindow", "Phase Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox_2.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8))
+        self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8))
+        self.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8))
+        self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+
diff --git a/gnuradio-examples/python/digital/qt_digital_window2.ui b/gnuradio-examples/python/digital/qt_digital_window2.ui
new file mode 100644 (file)
index 0000000..5447046
--- /dev/null
@@ -0,0 +1,605 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DigitalWindow</class>
+ <widget class="QMainWindow" name="DigitalWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1059</width>
+    <height>751</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QVBoxLayout" name="verticalLayout_3">
+    <item>
+     <layout class="QHBoxLayout" name="sinkLayout"/>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="QGroupBox" name="sysBox">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>240</width>
+            <height>60</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>240</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="title">
+           <string>System Parameters</string>
+          </property>
+          <widget class="QWidget" name="formLayoutWidget">
+           <property name="geometry">
+            <rect>
+             <x>10</x>
+             <y>20</y>
+             <width>211</width>
+             <height>31</height>
+            </rect>
+           </property>
+           <layout class="QFormLayout" name="formLayout">
+            <property name="sizeConstraint">
+             <enum>QLayout::SetFixedSize</enum>
+            </property>
+            <property name="verticalSpacing">
+             <number>20</number>
+            </property>
+            <item row="0" column="1">
+             <widget class="QLineEdit" name="sampleRateEdit">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>26</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>80</width>
+                <height>26</height>
+               </size>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="0">
+             <widget class="QLabel" name="sampleRateLabel">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>16777215</width>
+                <height>20</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Sample Rate (sps)</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </widget>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>60</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="channelModeBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>245</width>
+          <height>130</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>245</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Channel Model Parameters</string>
+        </property>
+        <widget class="QWidget" name="formLayoutWidget_2">
+         <property name="geometry">
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>221</width>
+           <height>98</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout_2">
+          <property name="sizeConstraint">
+           <enum>QLayout::SetFixedSize</enum>
+          </property>
+          <property name="fieldGrowthPolicy">
+           <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="snrLabel">
+            <property name="text">
+             <string>SNR (dB)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="snrEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="freqLabel">
+            <property name="text">
+             <string>Frequency Offset (Hz)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="freqEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="timeLabel">
+            <property name="text">
+             <string>Timing Offset</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="timeEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="rxBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>220</width>
+          <height>130</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>180</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Receiver Parameters</string>
+        </property>
+        <widget class="QWidget" name="formLayoutWidget_3">
+         <property name="geometry">
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>201</width>
+           <height>101</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout_3">
+          <property name="sizeConstraint">
+           <enum>QLayout::SetFixedSize</enum>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="gainClockLabel">
+            <property name="text">
+             <string>Clock Loop Gain</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="gainPhaseLabel">
+            <property name="text">
+             <string>Freq. Loop Gain</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="gainClockEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="gainFreqEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="gainPhaseEdit">
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="gainPhaseLabel_2">
+            <property name="text">
+             <string>Phase Loop Gain</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="rxBox_2">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>220</width>
+          <height>125</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>265</width>
+          <height>125</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Received Packet Info</string>
+        </property>
+        <widget class="QWidget" name="formLayoutWidget_4">
+         <property name="geometry">
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>201</width>
+           <height>91</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout_4">
+          <property name="sizeConstraint">
+           <enum>QLayout::SetFixedSize</enum>
+          </property>
+          <property name="fieldGrowthPolicy">
+           <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="pktsRcvdLabel">
+            <property name="text">
+             <string>Packets Rcvd.</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLineEdit" name="pktsRcvdEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="pktsCorrectLabel">
+            <property name="text">
+             <string>Packets Correct</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="pktsCorrectEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="perLabel">
+            <property name="text">
+             <string>PER</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="perEdit">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>80</width>
+              <height>16777215</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+         </layout>
+         <zorder>pktsRcvdLabel</zorder>
+         <zorder>pktsCorrectLabel</zorder>
+         <zorder>perLabel</zorder>
+         <zorder>pktsRcvdEdit</zorder>
+         <zorder>pktsCorrectEdit</zorder>
+         <zorder>perEdit</zorder>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QPushButton" name="pauseButton">
+          <property name="minimumSize">
+           <size>
+            <width>80</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Pause</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>60</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="closeButton">
+          <property name="minimumSize">
+           <size>
+            <width>80</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Close</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1059</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>&amp;File</string>
+    </property>
+    <addaction name="actionExit"/>
+   </widget>
+   <addaction name="menuFile"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionExit">
+   <property name="text">
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+ </widget>
+ <tabstops>
+  <tabstop>snrEdit</tabstop>
+  <tabstop>freqEdit</tabstop>
+  <tabstop>timeEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>closeButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>322</x>
+     <y>623</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>66</x>
+     <y>561</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>actionExit</sender>
+   <signal>triggered()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>617</x>
+     <y>327</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index 60e1a6e3790339bc2dfc656bc3f5ab29af267540..e2488eb3d3e456dcb3d21ca5e37310803f40ce1f 100644 (file)
@@ -2,8 +2,8 @@
 
 # Form implementation generated from reading ui file 'qt_rx_window.ui'
 #
-# Created: Fri Jul  3 01:03:19 2009
-#      by: PyQt4 UI code generator 4.4.3
+# Created: Tue May 11 21:03:07 2010
+#      by: PyQt4 UI code generator 4.6.1
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -12,29 +12,14 @@ from PyQt4 import QtCore, QtGui
 class Ui_DigitalWindow(object):
     def setupUi(self, DigitalWindow):
         DigitalWindow.setObjectName("DigitalWindow")
-        DigitalWindow.resize(1000, 816)
+        DigitalWindow.resize(999, 519)
         self.centralwidget = QtGui.QWidget(DigitalWindow)
         self.centralwidget.setObjectName("centralwidget")
-        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
-        self.gridLayout.setObjectName("gridLayout")
-        self.sinkFrame = QtGui.QFrame(self.centralwidget)
-        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
-        sizePolicy.setHorizontalStretch(0)
-        sizePolicy.setVerticalStretch(1)
-        sizePolicy.setHeightForWidth(self.sinkFrame.sizePolicy().hasHeightForWidth())
-        self.sinkFrame.setSizePolicy(sizePolicy)
-        self.sinkFrame.setMinimumSize(QtCore.QSize(800, 500))
-        self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel)
-        self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised)
-        self.sinkFrame.setObjectName("sinkFrame")
-        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.sinkFrame)
-        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
+        self.verticalLayout.setObjectName("verticalLayout")
         self.sinkLayout = QtGui.QHBoxLayout()
         self.sinkLayout.setObjectName("sinkLayout")
-        self.horizontalLayout_2.addLayout(self.sinkLayout)
-        self.gridLayout.addWidget(self.sinkFrame, 0, 0, 1, 1)
-        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
-        self.gridLayout.addItem(spacerItem, 1, 0, 1, 1)
+        self.verticalLayout.addLayout(self.sinkLayout)
         self.horizontalLayout = QtGui.QHBoxLayout()
         self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
         self.horizontalLayout.setObjectName("horizontalLayout")
@@ -113,15 +98,15 @@ class Ui_DigitalWindow(object):
         self.perEdit.setGeometry(QtCore.QRect(120, 90, 113, 23))
         self.perEdit.setObjectName("perEdit")
         self.verticalLayout_3.addWidget(self.rxPacketBox)
-        spacerItem1 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
-        self.verticalLayout_3.addItem(spacerItem1)
+        spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout_3.addItem(spacerItem)
         self.horizontalLayout.addLayout(self.verticalLayout_3)
-        spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.horizontalLayout.addItem(spacerItem2)
+        spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem1)
         self.verticalLayout_5 = QtGui.QVBoxLayout()
         self.verticalLayout_5.setObjectName("verticalLayout_5")
-        spacerItem3 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_5.addItem(spacerItem3)
+        spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.verticalLayout_5.addItem(spacerItem2)
         self.closeButton = QtGui.QPushButton(self.centralwidget)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
@@ -133,10 +118,10 @@ class Ui_DigitalWindow(object):
         self.closeButton.setObjectName("closeButton")
         self.verticalLayout_5.addWidget(self.closeButton)
         self.horizontalLayout.addLayout(self.verticalLayout_5)
-        self.gridLayout.addLayout(self.horizontalLayout, 2, 0, 1, 1)
+        self.verticalLayout.addLayout(self.horizontalLayout)
         DigitalWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(DigitalWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 24))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 999, 23))
         self.menubar.setObjectName("menubar")
         self.menuFile = QtGui.QMenu(self.menubar)
         self.menuFile.setObjectName("menuFile")
index 4631b77827c7ec7ceb35b482ea90019239c4d408..f5a074876dd17825c3a9228ecd98e121dfa94996 100644 (file)
@@ -1,92 +1,53 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>DigitalWindow</class>
- <widget class="QMainWindow" name="DigitalWindow" >
-  <property name="geometry" >
+ <widget class="QMainWindow" name="DigitalWindow">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1000</width>
-    <height>816</height>
+    <width>999</width>
+    <height>519</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QWidget" name="centralwidget" >
-   <layout class="QGridLayout" name="gridLayout" >
-    <item row="0" column="0" >
-     <widget class="QFrame" name="sinkFrame" >
-      <property name="sizePolicy" >
-       <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
-        <horstretch>0</horstretch>
-        <verstretch>1</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="minimumSize" >
-       <size>
-        <width>800</width>
-        <height>500</height>
-       </size>
-      </property>
-      <property name="frameShape" >
-       <enum>QFrame::StyledPanel</enum>
-      </property>
-      <property name="frameShadow" >
-       <enum>QFrame::Raised</enum>
-      </property>
-      <layout class="QHBoxLayout" name="horizontalLayout_2" >
-       <item>
-        <layout class="QHBoxLayout" name="sinkLayout" />
-       </item>
-      </layout>
-     </widget>
-    </item>
-    <item row="1" column="0" >
-     <spacer name="verticalSpacer" >
-      <property name="orientation" >
-       <enum>Qt::Vertical</enum>
-      </property>
-      <property name="sizeType" >
-       <enum>QSizePolicy::Fixed</enum>
-      </property>
-      <property name="sizeHint" stdset="0" >
-       <size>
-        <width>20</width>
-        <height>40</height>
-       </size>
-      </property>
-     </spacer>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QHBoxLayout" name="sinkLayout"/>
     </item>
-    <item row="2" column="0" >
-     <layout class="QHBoxLayout" name="horizontalLayout" >
-      <property name="sizeConstraint" >
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="sizeConstraint">
        <enum>QLayout::SetFixedSize</enum>
       </property>
       <item>
-       <widget class="QGroupBox" name="rxBox" >
-        <property name="sizePolicy" >
-         <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+       <widget class="QGroupBox" name="rxBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
-        <property name="minimumSize" >
+        <property name="minimumSize">
          <size>
           <width>250</width>
           <height>190</height>
          </size>
         </property>
-        <property name="maximumSize" >
+        <property name="maximumSize">
          <size>
           <width>250</width>
           <height>190</height>
          </size>
         </property>
-        <property name="title" >
+        <property name="title">
          <string>Receiver Parameters</string>
         </property>
-        <widget class="QLineEdit" name="gainMuEdit" >
-         <property name="geometry" >
+        <widget class="QLineEdit" name="gainMuEdit">
+         <property name="geometry">
           <rect>
            <x>120</x>
            <y>120</y>
@@ -95,8 +56,8 @@
           </rect>
          </property>
         </widget>
-        <widget class="QLabel" name="gainMuLabel" >
-         <property name="geometry" >
+        <widget class="QLabel" name="gainMuLabel">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>120</y>
            <height>20</height>
           </rect>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>mu's gain</string>
          </property>
         </widget>
-        <widget class="QLineEdit" name="alphaEdit" >
-         <property name="geometry" >
+        <widget class="QLineEdit" name="alphaEdit">
+         <property name="geometry">
           <rect>
            <x>120</x>
            <y>150</y>
           </rect>
          </property>
         </widget>
-        <widget class="QLabel" name="alphaLabel" >
-         <property name="geometry" >
+        <widget class="QLabel" name="alphaLabel">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>150</y>
            <height>20</height>
           </rect>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Alpha</string>
          </property>
         </widget>
-        <widget class="QLabel" name="gainLabel" >
-         <property name="geometry" >
+        <widget class="QLabel" name="gainLabel">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>60</y>
            <height>17</height>
           </rect>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Gain (dB)</string>
          </property>
         </widget>
-        <widget class="QLineEdit" name="freqEdit" >
-         <property name="geometry" >
+        <widget class="QLineEdit" name="freqEdit">
+         <property name="geometry">
           <rect>
            <x>120</x>
            <y>30</y>
           </rect>
          </property>
         </widget>
-        <widget class="QLabel" name="freqLabel" >
-         <property name="geometry" >
+        <widget class="QLabel" name="freqLabel">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>30</y>
            <height>17</height>
           </rect>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Frequency (Hz)</string>
          </property>
         </widget>
-        <widget class="QLineEdit" name="gainEdit" >
-         <property name="geometry" >
+        <widget class="QLineEdit" name="gainEdit">
+         <property name="geometry">
           <rect>
            <x>120</x>
            <y>60</y>
           </rect>
          </property>
         </widget>
-        <widget class="QLabel" name="decimLabel" >
-         <property name="geometry" >
+        <widget class="QLabel" name="decimLabel">
+         <property name="geometry">
           <rect>
            <x>10</x>
            <y>90</y>
            <height>17</height>
           </rect>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Decimation</string>
          </property>
         </widget>
-        <widget class="QLineEdit" name="decimEdit" >
-         <property name="geometry" >
+        <widget class="QLineEdit" name="decimEdit">
+         <property name="geometry">
           <rect>
            <x>120</x>
            <y>90</y>
        </widget>
       </item>
       <item>
-       <layout class="QVBoxLayout" name="verticalLayout_3" >
+       <layout class="QVBoxLayout" name="verticalLayout_3">
         <item>
-         <widget class="QGroupBox" name="rxPacketBox" >
-          <property name="enabled" >
+         <widget class="QGroupBox" name="rxPacketBox">
+          <property name="enabled">
            <bool>true</bool>
           </property>
-          <property name="sizePolicy" >
-           <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
-          <property name="minimumSize" >
+          <property name="minimumSize">
            <size>
             <width>250</width>
             <height>130</height>
            </size>
           </property>
-          <property name="maximumSize" >
+          <property name="maximumSize">
            <size>
             <width>250</width>
             <height>130</height>
            </size>
           </property>
-          <property name="font" >
+          <property name="font">
            <font>
             <weight>50</weight>
             <bold>false</bold>
            </font>
           </property>
-          <property name="title" >
+          <property name="title">
            <string>Received Packet Info</string>
           </property>
-          <widget class="QLineEdit" name="pktsRcvdEdit" >
-           <property name="geometry" >
+          <widget class="QLineEdit" name="pktsRcvdEdit">
+           <property name="geometry">
             <rect>
              <x>120</x>
              <y>30</y>
             </rect>
            </property>
           </widget>
-          <widget class="QLabel" name="pktsRcvdLabel" >
-           <property name="geometry" >
+          <widget class="QLabel" name="pktsRcvdLabel">
+           <property name="geometry">
             <rect>
              <x>10</x>
              <y>30</y>
              <height>20</height>
             </rect>
            </property>
-           <property name="text" >
+           <property name="text">
             <string>Packets Rcvd.</string>
            </property>
           </widget>
-          <widget class="QLineEdit" name="pktsCorrectEdit" >
-           <property name="geometry" >
+          <widget class="QLineEdit" name="pktsCorrectEdit">
+           <property name="geometry">
             <rect>
              <x>120</x>
              <y>60</y>
             </rect>
            </property>
           </widget>
-          <widget class="QLabel" name="pktsCorrectLabel" >
-           <property name="geometry" >
+          <widget class="QLabel" name="pktsCorrectLabel">
+           <property name="geometry">
             <rect>
              <x>10</x>
              <y>60</y>
              <height>20</height>
             </rect>
            </property>
-           <property name="text" >
+           <property name="text">
             <string>Packets Correct</string>
            </property>
           </widget>
-          <widget class="QLabel" name="perLabel" >
-           <property name="geometry" >
+          <widget class="QLabel" name="perLabel">
+           <property name="geometry">
             <rect>
              <x>10</x>
              <y>90</y>
              <height>20</height>
             </rect>
            </property>
-           <property name="text" >
+           <property name="text">
             <string>PER</string>
            </property>
           </widget>
-          <widget class="QLineEdit" name="perEdit" >
-           <property name="geometry" >
+          <widget class="QLineEdit" name="perEdit">
+           <property name="geometry">
             <rect>
              <x>120</x>
              <y>90</y>
             </rect>
            </property>
           </widget>
-          <zorder>pktsRcvdEdit</zorder>
-          <zorder>pktsRcvdLabel</zorder>
-          <zorder>pktsCorrectEdit</zorder>
-          <zorder>pktsCorrectLabel</zorder>
-          <zorder>perLabel</zorder>
-          <zorder>perEdit</zorder>
-          <zorder>rxBox</zorder>
-          <zorder>verticalLayoutWidget</zorder>
          </widget>
         </item>
         <item>
-         <spacer name="verticalSpacer_2" >
-          <property name="orientation" >
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
-          <property name="sizeType" >
+          <property name="sizeType">
            <enum>QSizePolicy::Fixed</enum>
           </property>
-          <property name="sizeHint" stdset="0" >
+          <property name="sizeHint" stdset="0">
            <size>
             <width>20</width>
             <height>60</height>
        </layout>
       </item>
       <item>
-       <spacer name="horizontalSpacer" >
-        <property name="orientation" >
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>40</width>
           <height>20</height>
        </spacer>
       </item>
       <item>
-       <layout class="QVBoxLayout" name="verticalLayout_5" >
+       <layout class="QVBoxLayout" name="verticalLayout_5">
         <item>
-         <spacer name="verticalSpacer_3" >
-          <property name="orientation" >
+         <spacer name="verticalSpacer_3">
+          <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
-          <property name="sizeHint" stdset="0" >
+          <property name="sizeHint" stdset="0">
            <size>
             <width>20</width>
             <height>40</height>
          </spacer>
         </item>
         <item>
-         <widget class="QPushButton" name="closeButton" >
-          <property name="sizePolicy" >
-           <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+         <widget class="QPushButton" name="closeButton">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
-          <property name="minimumSize" >
+          <property name="minimumSize">
            <size>
             <width>80</width>
             <height>30</height>
            </size>
           </property>
-          <property name="maximumSize" >
+          <property name="maximumSize">
            <size>
             <width>80</width>
             <height>30</height>
            </size>
           </property>
-          <property name="text" >
+          <property name="text">
            <string>Close</string>
           </property>
          </widget>
      </layout>
     </item>
    </layout>
-   <zorder>closeButton</zorder>
-   <zorder>sinkFrame</zorder>
-   <zorder>rxBox</zorder>
-   <zorder>rxPacketBox</zorder>
-   <zorder>verticalLayoutWidget</zorder>
-   <zorder>verticalSpacer</zorder>
-   <zorder>horizontalLayoutWidget_2</zorder>
   </widget>
-  <widget class="QMenuBar" name="menubar" >
-   <property name="geometry" >
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>1000</width>
-     <height>24</height>
+     <width>999</width>
+     <height>23</height>
     </rect>
    </property>
-   <widget class="QMenu" name="menuFile" >
-    <property name="title" >
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
      <string>&amp;File</string>
     </property>
-    <addaction name="actionExit" />
+    <addaction name="actionExit"/>
    </widget>
-   <addaction name="menuFile" />
+   <addaction name="menuFile"/>
   </widget>
-  <widget class="QStatusBar" name="statusbar" />
-  <action name="actionExit" >
-   <property name="text" >
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionExit">
+   <property name="text">
     <string>E&amp;xit</string>
    </property>
   </action>
    <receiver>DigitalWindow</receiver>
    <slot>close()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>-1</x>
      <y>-1</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>617</x>
      <y>327</y>
     </hint>
    <receiver>DigitalWindow</receiver>
    <slot>close()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>960</x>
      <y>694</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>66</x>
      <y>561</y>
     </hint>
diff --git a/gnuradio-examples/python/digital/qt_rx_window2.py b/gnuradio-examples/python/digital/qt_rx_window2.py
new file mode 100644 (file)
index 0000000..2fd719c
--- /dev/null
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'qt_rx_window2.ui'
+#
+# Created: Tue May 11 21:01:39 2010
+#      by: PyQt4 UI code generator 4.6.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_DigitalWindow(object):
+    def setupUi(self, DigitalWindow):
+        DigitalWindow.setObjectName("DigitalWindow")
+        DigitalWindow.resize(1000, 523)
+        self.centralwidget = QtGui.QWidget(DigitalWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.sinkLayout = QtGui.QHBoxLayout()
+        self.sinkLayout.setObjectName("sinkLayout")
+        self.verticalLayout.addLayout(self.sinkLayout)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.rxBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth())
+        self.rxBox.setSizePolicy(sizePolicy)
+        self.rxBox.setMinimumSize(QtCore.QSize(250, 190))
+        self.rxBox.setMaximumSize(QtCore.QSize(250, 250))
+        self.rxBox.setObjectName("rxBox")
+        self.formLayout = QtGui.QFormLayout(self.rxBox)
+        self.formLayout.setObjectName("formLayout")
+        self.freqLabel = QtGui.QLabel(self.rxBox)
+        self.freqLabel.setObjectName("freqLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.freqLabel)
+        self.freqEdit = QtGui.QLineEdit(self.rxBox)
+        self.freqEdit.setObjectName("freqEdit")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.freqEdit)
+        self.gainLabel = QtGui.QLabel(self.rxBox)
+        self.gainLabel.setObjectName("gainLabel")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.gainLabel)
+        self.gainEdit = QtGui.QLineEdit(self.rxBox)
+        self.gainEdit.setObjectName("gainEdit")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.gainEdit)
+        self.decimLabel = QtGui.QLabel(self.rxBox)
+        self.decimLabel.setObjectName("decimLabel")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.decimLabel)
+        self.decimEdit = QtGui.QLineEdit(self.rxBox)
+        self.decimEdit.setObjectName("decimEdit")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.decimEdit)
+        self.gainClockLabel = QtGui.QLabel(self.rxBox)
+        self.gainClockLabel.setObjectName("gainClockLabel")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.gainClockLabel)
+        self.gainClockEdit = QtGui.QLineEdit(self.rxBox)
+        self.gainClockEdit.setObjectName("gainClockEdit")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.gainClockEdit)
+        self.gainPhaseLabel = QtGui.QLabel(self.rxBox)
+        self.gainPhaseLabel.setObjectName("gainPhaseLabel")
+        self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel)
+        self.gainPhaseEdit = QtGui.QLineEdit(self.rxBox)
+        self.gainPhaseEdit.setObjectName("gainPhaseEdit")
+        self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.gainPhaseEdit)
+        self.gainFreqEdit = QtGui.QLineEdit(self.rxBox)
+        self.gainFreqEdit.setObjectName("gainFreqEdit")
+        self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.gainFreqEdit)
+        self.gainFreqLabel = QtGui.QLabel(self.rxBox)
+        self.gainFreqLabel.setObjectName("gainFreqLabel")
+        self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.gainFreqLabel)
+        self.horizontalLayout.addWidget(self.rxBox)
+        self.verticalLayout_3 = QtGui.QVBoxLayout()
+        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.rxPacketBox = QtGui.QGroupBox(self.centralwidget)
+        self.rxPacketBox.setEnabled(True)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxPacketBox.sizePolicy().hasHeightForWidth())
+        self.rxPacketBox.setSizePolicy(sizePolicy)
+        self.rxPacketBox.setMinimumSize(QtCore.QSize(250, 130))
+        self.rxPacketBox.setMaximumSize(QtCore.QSize(250, 130))
+        font = QtGui.QFont()
+        font.setWeight(50)
+        font.setBold(False)
+        self.rxPacketBox.setFont(font)
+        self.rxPacketBox.setObjectName("rxPacketBox")
+        self.pktsRcvdEdit = QtGui.QLineEdit(self.rxPacketBox)
+        self.pktsRcvdEdit.setGeometry(QtCore.QRect(120, 30, 113, 23))
+        self.pktsRcvdEdit.setObjectName("pktsRcvdEdit")
+        self.pktsRcvdLabel = QtGui.QLabel(self.rxPacketBox)
+        self.pktsRcvdLabel.setGeometry(QtCore.QRect(10, 30, 111, 20))
+        self.pktsRcvdLabel.setObjectName("pktsRcvdLabel")
+        self.pktsCorrectEdit = QtGui.QLineEdit(self.rxPacketBox)
+        self.pktsCorrectEdit.setGeometry(QtCore.QRect(120, 60, 113, 23))
+        self.pktsCorrectEdit.setObjectName("pktsCorrectEdit")
+        self.pktsCorrectLabel = QtGui.QLabel(self.rxPacketBox)
+        self.pktsCorrectLabel.setGeometry(QtCore.QRect(10, 60, 111, 20))
+        self.pktsCorrectLabel.setObjectName("pktsCorrectLabel")
+        self.perLabel = QtGui.QLabel(self.rxPacketBox)
+        self.perLabel.setGeometry(QtCore.QRect(10, 90, 111, 20))
+        self.perLabel.setObjectName("perLabel")
+        self.perEdit = QtGui.QLineEdit(self.rxPacketBox)
+        self.perEdit.setGeometry(QtCore.QRect(120, 90, 113, 23))
+        self.perEdit.setObjectName("perEdit")
+        self.verticalLayout_3.addWidget(self.rxPacketBox)
+        spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout_3.addItem(spacerItem)
+        self.horizontalLayout.addLayout(self.verticalLayout_3)
+        spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem1)
+        self.verticalLayout_5 = QtGui.QVBoxLayout()
+        self.verticalLayout_5.setObjectName("verticalLayout_5")
+        spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.verticalLayout_5.addItem(spacerItem2)
+        self.closeButton = QtGui.QPushButton(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.closeButton.sizePolicy().hasHeightForWidth())
+        self.closeButton.setSizePolicy(sizePolicy)
+        self.closeButton.setMinimumSize(QtCore.QSize(80, 30))
+        self.closeButton.setMaximumSize(QtCore.QSize(80, 30))
+        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout_5.addWidget(self.closeButton)
+        self.horizontalLayout.addLayout(self.verticalLayout_5)
+        self.verticalLayout.addLayout(self.horizontalLayout)
+        DigitalWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(DigitalWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 23))
+        self.menubar.setObjectName("menubar")
+        self.menuFile = QtGui.QMenu(self.menubar)
+        self.menuFile.setObjectName("menuFile")
+        DigitalWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(DigitalWindow)
+        self.statusbar.setObjectName("statusbar")
+        DigitalWindow.setStatusBar(self.statusbar)
+        self.actionExit = QtGui.QAction(DigitalWindow)
+        self.actionExit.setObjectName("actionExit")
+        self.menuFile.addAction(self.actionExit)
+        self.menubar.addAction(self.menuFile.menuAction())
+
+        self.retranslateUi(DigitalWindow)
+        QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close)
+        QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(DigitalWindow)
+
+    def retranslateUi(self, DigitalWindow):
+        DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.decimLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Decimation", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainClockLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Clock Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainPhaseLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Phase Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainFreqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Freq. Loop Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxPacketBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8))
+        self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8))
+        self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+
diff --git a/gnuradio-examples/python/digital/qt_rx_window2.ui b/gnuradio-examples/python/digital/qt_rx_window2.ui
new file mode 100644 (file)
index 0000000..745af8f
--- /dev/null
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DigitalWindow</class>
+ <widget class="QMainWindow" name="DigitalWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1000</width>
+    <height>523</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QHBoxLayout" name="sinkLayout"/>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="sizeConstraint">
+       <enum>QLayout::SetFixedSize</enum>
+      </property>
+      <item>
+       <widget class="QGroupBox" name="rxBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>250</width>
+          <height>190</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>250</width>
+          <height>250</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Receiver Parameters</string>
+        </property>
+        <layout class="QFormLayout" name="formLayout">
+         <item row="0" column="0">
+          <widget class="QLabel" name="freqLabel">
+           <property name="text">
+            <string>Frequency (Hz)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLineEdit" name="freqEdit"/>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="gainLabel">
+           <property name="text">
+            <string>Gain (dB)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="gainEdit"/>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="decimLabel">
+           <property name="text">
+            <string>Decimation</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="decimEdit"/>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="gainClockLabel">
+           <property name="text">
+            <string>Clock Loop Gain</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLineEdit" name="gainClockEdit"/>
+         </item>
+         <item row="4" column="0">
+          <widget class="QLabel" name="gainPhaseLabel">
+           <property name="text">
+            <string>Phase Loop Gain</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1">
+          <widget class="QLineEdit" name="gainPhaseEdit"/>
+         </item>
+         <item row="5" column="1">
+          <widget class="QLineEdit" name="gainFreqEdit"/>
+         </item>
+         <item row="5" column="0">
+          <widget class="QLabel" name="gainFreqLabel">
+           <property name="text">
+            <string>Freq. Loop Gain</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <widget class="QGroupBox" name="rxPacketBox">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>250</width>
+            <height>130</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>250</width>
+            <height>130</height>
+           </size>
+          </property>
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="title">
+           <string>Received Packet Info</string>
+          </property>
+          <widget class="QLineEdit" name="pktsRcvdEdit">
+           <property name="geometry">
+            <rect>
+             <x>120</x>
+             <y>30</y>
+             <width>113</width>
+             <height>23</height>
+            </rect>
+           </property>
+          </widget>
+          <widget class="QLabel" name="pktsRcvdLabel">
+           <property name="geometry">
+            <rect>
+             <x>10</x>
+             <y>30</y>
+             <width>111</width>
+             <height>20</height>
+            </rect>
+           </property>
+           <property name="text">
+            <string>Packets Rcvd.</string>
+           </property>
+          </widget>
+          <widget class="QLineEdit" name="pktsCorrectEdit">
+           <property name="geometry">
+            <rect>
+             <x>120</x>
+             <y>60</y>
+             <width>113</width>
+             <height>23</height>
+            </rect>
+           </property>
+          </widget>
+          <widget class="QLabel" name="pktsCorrectLabel">
+           <property name="geometry">
+            <rect>
+             <x>10</x>
+             <y>60</y>
+             <width>111</width>
+             <height>20</height>
+            </rect>
+           </property>
+           <property name="text">
+            <string>Packets Correct</string>
+           </property>
+          </widget>
+          <widget class="QLabel" name="perLabel">
+           <property name="geometry">
+            <rect>
+             <x>10</x>
+             <y>90</y>
+             <width>111</width>
+             <height>20</height>
+            </rect>
+           </property>
+           <property name="text">
+            <string>PER</string>
+           </property>
+          </widget>
+          <widget class="QLineEdit" name="perEdit">
+           <property name="geometry">
+            <rect>
+             <x>120</x>
+             <y>90</y>
+             <width>113</width>
+             <height>23</height>
+            </rect>
+           </property>
+          </widget>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>60</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout_5">
+        <item>
+         <spacer name="verticalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="closeButton">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>80</width>
+            <height>30</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>80</width>
+            <height>30</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Close</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1000</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>&amp;File</string>
+    </property>
+    <addaction name="actionExit"/>
+   </widget>
+   <addaction name="menuFile"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionExit">
+   <property name="text">
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>actionExit</sender>
+   <signal>triggered()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>617</x>
+     <y>327</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>closeButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>960</x>
+     <y>694</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>66</x>
+     <y>561</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index c229aa9e4784c9f6d848d893b0d42c520d52d87c..0024d6941f714778d61c43b040a2aeb575c95816 100644 (file)
@@ -119,7 +119,7 @@ class receive_path(gr.hier_block2):
             normal.add_option("-r", "--bitrate", type="eng_float", default=100e3,
                               help="specify bitrate [default=%default].")
         normal.add_option("-v", "--verbose", action="store_true", default=False)
-        expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+        expert.add_option("-S", "--samples-per-symbol", type="float", default=None,
                           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)")
@@ -135,4 +135,4 @@ class receive_path(gr.hier_block2):
         print "\nReceive 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)
+        print "samples/symbol:  %.4f"   % (self._samples_per_symbol)
index 0567701b10a61bfb2189f58abbaa931332f82c5a..b3770479635af2cd8e31fe97cf9394433f494755 100644 (file)
@@ -100,7 +100,7 @@ class transmit_path(gr.hier_block2):
                           help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]")
         normal.add_option("-v", "--verbose", action="store_true", default=False)
 
-        expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+        expert.add_option("-S", "--samples-per-symbol", type="float", default=None,
                           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)")
@@ -115,5 +115,5 @@ class transmit_path(gr.hier_block2):
         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 "samples/symbol:  %.4f"    % (self._samples_per_symbol)
         
index fd47c2725daee854e14475006cbccae440aa64e4..a8f16e28a9f5b884369f5c1731778c5a0abb2d42 100644 (file)
@@ -20,7 +20,7 @@
 # 
 
 from gnuradio import gr
-import usrp_options
+from gnuradio import usrp_options
 import receive_path
 from pick_bitrate import pick_rx_bitrate
 from gnuradio import eng_notation
@@ -59,26 +59,36 @@ class usrp_receive_path(gr.hier_block2):
         if options.rx_freq is None:
             sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
             raise SystemExit
+
+        #setup usrp
+        self._demod_class = demod_class
+        self._setup_usrp_source(options)
+
         rx_path = receive_path.receive_path(demod_class, rx_callback, options)
         for attr in dir(rx_path): #forward the methods
             if not attr.startswith('_') and not hasattr(self, attr):
                 setattr(self, attr, getattr(rx_path, attr))
-        #setup usrp
-        self._demod_class = demod_class
-        self._setup_usrp_source(options)
+
         #connect
         self.connect(self.u, rx_path)
 
     def _setup_usrp_source(self, options):
         self.u = usrp_options.create_usrp_source(options)
         adc_rate = self.u.adc_rate()
-        if options.verbose:
-            print 'USRP Source:', self.u
+        self.rs_rate = options.bitrate
+
         (self._bitrate, self._samples_per_symbol, self._decim) = \
                         pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
-                                        options.samples_per_symbol, options.decim, adc_rate,  \
-                                        self.u.get_decim_rates())
+                                        options.samples_per_symbol, options.decim,
+                                        adc_rate, self.u.get_decim_rates())
+
+        if options.verbose:
+            print 'USRP Source:', self.u
+            print 'Decimation: ', self._decim
 
+        options.samples_per_symbol = self._samples_per_symbol
+        options.decim = self._decim
+        
         self.u.set_decim(self._decim)
 
         if not self.u.set_center_freq(options.rx_freq):
diff --git a/gnuradio-examples/python/digital/usrp_receive_path2.py b/gnuradio-examples/python/digital/usrp_receive_path2.py
new file mode 100644 (file)
index 0000000..d200172
--- /dev/null
@@ -0,0 +1,96 @@
+#
+# Copyright 2010 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 usrp_options
+import receive_path
+from pick_bitrate2 import pick_rx_bitrate
+from gnuradio import eng_notation
+
+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")
+
+def add_options(parser, expert):
+    add_freq_option(parser)
+    usrp_options.add_rx_options(parser)
+    receive_path.receive_path.add_options(parser, expert)
+    expert.add_option("", "--rx-freq", type="eng_float", default=None,
+                          help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_receive_path(gr.hier_block2):
+
+    def __init__(self, demod_class, rx_callback, options):
+        '''
+        See below for what options should hold
+        '''
+        gr.hier_block2.__init__(self, "usrp_receive_path",
+                gr.io_signature(0, 0, 0),                    # Input signature
+                gr.io_signature(0, 0, 0)) # Output signature
+        if options.rx_freq is None:
+            sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
+            raise SystemExit
+
+        #setup usrp
+        self._demod_class = demod_class
+        self._setup_usrp_source(options)
+
+        rx_path = receive_path.receive_path(demod_class, rx_callback, options)
+        for attr in dir(rx_path): #forward the methods
+            if not attr.startswith('_') and not hasattr(self, attr):
+                setattr(self, attr, getattr(rx_path, attr))
+
+        #connect
+        self.connect(self.u, rx_path)
+
+    def _setup_usrp_source(self, options):
+        self.u = usrp_options.create_usrp_source(options)
+        adc_rate = self.u.adc_rate()
+        self.rs_rate = options.bitrate
+
+        (self._bitrate, self._samples_per_symbol, self._decim) = \
+                        pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
+                                        options.samples_per_symbol, options.decim,
+                                        adc_rate, self.u.get_decim_rates())
+
+        if options.verbose:
+            print 'USRP Source:', self.u
+            print 'Decimation: ', self._decim
+
+        options.samples_per_symbol = self._samples_per_symbol
+        options.decim = self._decim
+        
+        self.u.set_decim(self._decim)
+
+        if not self.u.set_center_freq(options.rx_freq):
+            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq))
+            raise ValueError, eng_notation.num_to_str(options.rx_freq)
index ed2603fa3e632a35580e4559b07440801b06adaa..f0f467599a6f6e78b0d4dfce46cce6d1facda01d 100644 (file)
@@ -20,7 +20,7 @@
 # 
 
 from gnuradio import gr
-import usrp_options
+from gnuradio import usrp_options
 import transmit_path
 from pick_bitrate import pick_tx_bitrate
 from gnuradio import eng_notation
@@ -58,16 +58,19 @@ class usrp_transmit_path(gr.hier_block2):
         if options.tx_freq is None:
             sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
             raise SystemExit
+
+        #setup usrp
+        self._modulator_class = modulator_class
+        self._setup_usrp_sink(options)
+
         tx_path = transmit_path.transmit_path(modulator_class, options)
         for attr in dir(tx_path): #forward the methods
             if not attr.startswith('_') and not hasattr(self, attr):
                 setattr(self, attr, getattr(tx_path, attr))
-        #setup usrp
-        self._modulator_class = modulator_class
-        self._setup_usrp_sink(options)
+
         #connect
         self.connect(tx_path, self.u)
-
+        
     def _setup_usrp_sink(self, options):
         """
         Creates a USRP sink, determines the settings for best bitrate,
@@ -75,13 +78,21 @@ class usrp_transmit_path(gr.hier_block2):
         """
         self.u = usrp_options.create_usrp_sink(options)
         dac_rate = self.u.dac_rate()
-        if options.verbose:
-            print 'USRP Sink:', self.u
+        self.rs_rate = options.bitrate    # Store requested bit rate
+            
         (self._bitrate, self._samples_per_symbol, self._interp) = \
-                        pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), \
-                                        options.samples_per_symbol, options.interp, dac_rate, \
-                                        self.u.get_interp_rates())
+                        pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(),
+                                        options.samples_per_symbol, options.interp,
+                                        dac_rate, self.u.get_interp_rates())
 
+        options.interp = self._interp
+        options.samples_per_symbol = self._samples_per_symbol
+        options.bitrate = self._bitrate
+
+        if options.verbose:
+            print 'USRP Sink:', self.u
+            print "Interpolation Rate: ", self._interp
+        
         self.u.set_interp(self._interp)
         self.u.set_auto_tr(True)
 
diff --git a/gnuradio-examples/python/digital/usrp_transmit_path2.py b/gnuradio-examples/python/digital/usrp_transmit_path2.py
new file mode 100644 (file)
index 0000000..54930e5
--- /dev/null
@@ -0,0 +1,101 @@
+#
+# Copyright 2010 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 usrp_options
+import transmit_path
+from pick_bitrate2 import pick_tx_bitrate
+from gnuradio import eng_notation
+
+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")
+
+def add_options(parser, expert):
+    add_freq_option(parser)
+    usrp_options.add_tx_options(parser)
+    transmit_path.transmit_path.add_options(parser, expert)
+    expert.add_option("", "--tx-freq", type="eng_float", default=None,
+                          help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_transmit_path(gr.hier_block2):
+    def __init__(self, modulator_class, options):
+        '''
+        See below for what options should hold
+        '''
+        gr.hier_block2.__init__(self, "usrp_transmit_path",
+                gr.io_signature(0, 0, 0),                    # Input signature
+                gr.io_signature(0, 0, 0)) # Output signature
+        if options.tx_freq is None:
+            sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
+            raise SystemExit
+
+        #setup usrp
+        self._modulator_class = modulator_class
+        self._setup_usrp_sink(options)
+
+        tx_path = transmit_path.transmit_path(modulator_class, options)
+        for attr in dir(tx_path): #forward the methods
+            if not attr.startswith('_') and not hasattr(self, attr):
+                setattr(self, attr, getattr(tx_path, attr))
+
+        #connect
+        self.connect(tx_path, self.u)
+        
+    def _setup_usrp_sink(self, options):
+        """
+        Creates a USRP sink, determines the settings for best bitrate,
+        and attaches to the transmitter's subdevice.
+        """
+        self.u = usrp_options.create_usrp_sink(options)
+        dac_rate = self.u.dac_rate()
+        self.rs_rate = options.bitrate    # Store requested bit rate
+            
+        (self._bitrate, self._samples_per_symbol, self._interp) = \
+                        pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(),
+                                        options.samples_per_symbol, options.interp,
+                                        dac_rate, self.u.get_interp_rates())
+
+        options.interp = self._interp
+        options.samples_per_symbol = self._samples_per_symbol
+        options.bitrate = self._bitrate
+
+        if options.verbose:
+            print 'USRP Sink:', self.u
+            print "Interpolation Rate: ", self._interp
+        
+        self.u.set_interp(self._interp)
+        self.u.set_auto_tr(True)
+
+        if not self.u.set_center_freq(options.tx_freq):
+            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq))
+            raise ValueError, eng_notation.num_to_str(options.tx_freq)
diff --git a/gnuradio-examples/python/digital_voice/.gitignore b/gnuradio-examples/python/digital_voice/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-examples/python/mp-sched/.gitignore b/gnuradio-examples/python/mp-sched/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-examples/python/mp-sched/perf-data/core-duo.dat b/gnuradio-examples/python/mp-sched/perf-data/core-duo.dat
new file mode 100644 (file)
index 0000000..064d1e1
--- /dev/null
@@ -0,0 +1,65 @@
+#D Core Duo 1.83 GHz (T2400)
+  1   1 5.273e+07  10.010  10.160   0.060   1.021 2.700000e+10 2.697e+09
+  1   2 5.273e+07  10.410  20.180   0.150   1.953 5.400000e+10 5.187e+09
+  1   3 3.516e+07  10.360  20.030   0.150   1.948 5.400000e+10 5.212e+09
+  1   4 2.637e+07  10.100  20.030   0.100   1.993 5.400000e+10 5.347e+09
+  1   5 2.109e+07  10.140  19.980   0.110   1.981 5.400000e+10 5.325e+09
+  1   6 1.758e+07  10.110  20.030   0.110   1.992 5.400000e+10 5.341e+09
+  1   7 1.507e+07  10.120  20.030   0.110   1.990 5.400000e+10 5.336e+09
+  1   8 1.318e+07  10.060  19.980   0.090   1.995 5.400000e+10 5.368e+09
+  2   1 5.273e+07  10.210  20.130   0.260   1.997 5.400000e+10 5.289e+09
+  2   2 2.637e+07  10.110  20.030   0.140   1.995 5.400000e+10 5.341e+09
+  2   3 1.758e+07  10.120  20.010   0.150   1.992 5.400000e+10 5.336e+09
+  2   4 1.318e+07  10.080  19.990   0.110   1.994 5.400000e+10 5.357e+09
+  2   5 1.055e+07  10.050  19.990   0.090   1.998 5.400000e+10 5.373e+09
+  2   6 8.789e+06  10.050  19.980   0.080   1.996 5.400000e+10 5.373e+09
+  2   7 7.533e+06  10.050  19.970   0.090   1.996 5.400000e+10 5.373e+09
+  2   8 6.592e+06  10.040  19.970   0.090   1.998 5.399999e+10 5.378e+09
+  3   1 3.516e+07  10.630  20.130   0.230   1.915 5.400000e+10 5.080e+09
+  3   2 1.758e+07  10.120  20.020   0.170   1.995 5.400000e+10 5.336e+09
+  3   3 1.172e+07  10.140  20.050   0.130   1.990 5.400000e+10 5.325e+09
+  3   4 8.789e+06  10.070  20.010   0.100   1.997 5.400000e+10 5.362e+09
+  3   5 7.031e+06  10.060  19.980   0.100   1.996 5.400000e+10 5.368e+09
+  3   6 5.859e+06  10.060  20.000   0.100   1.998 5.400000e+10 5.368e+09
+  3   7 5.022e+06  10.050  20.010   0.070   1.998 5.400000e+10 5.373e+09
+  3   8 4.395e+06  10.050  19.990   0.070   1.996 5.400000e+10 5.373e+09
+  4   1 2.637e+07  10.180  20.080   0.240   1.996 5.400000e+10 5.305e+09
+  4   2 1.318e+07  10.140  20.000   0.180   1.990 5.400000e+10 5.325e+09
+  4   3 8.789e+06  10.110  20.020   0.120   1.992 5.400000e+10 5.341e+09
+  4   4 6.592e+06  10.080  20.020   0.090   1.995 5.399999e+10 5.357e+09
+  4   5 5.273e+06  10.050  19.990   0.090   1.998 5.399999e+10 5.373e+09
+  4   6 4.395e+06  10.080  20.010   0.080   1.993 5.400000e+10 5.357e+09
+  4   7 3.767e+06  10.070  20.000   0.080   1.994 5.400000e+10 5.362e+09
+  4   8 3.296e+06  10.050  20.000   0.080   1.998 5.399999e+10 5.373e+09
+  5   1 2.109e+07  11.240  20.080   0.260   1.810 5.400000e+10 4.804e+09
+  5   2 1.055e+07  10.130  19.990   0.150   1.988 5.400000e+10 5.331e+09
+  5   3 7.031e+06  10.100  20.020   0.120   1.994 5.400000e+10 5.347e+09
+  5   4 5.273e+06  10.070  20.000   0.090   1.995 5.399999e+10 5.362e+09
+  5   5 4.219e+06  10.100  20.040   0.090   1.993 5.400000e+10 5.347e+09
+  5   6 3.516e+06  10.080  20.000   0.090   1.993 5.400000e+10 5.357e+09
+  5   7 3.013e+06  10.070  20.000   0.100   1.996 5.399998e+10 5.362e+09
+  5   8 2.637e+06  10.070  20.000   0.090   1.995 5.399998e+10 5.362e+09
+  6   1 1.758e+07  10.220  20.100   0.290   1.995 5.400000e+10 5.284e+09
+  6   2 8.789e+06  10.080  20.010   0.130   1.998 5.400000e+10 5.357e+09
+  6   3 5.859e+06  10.090  20.030   0.120   1.997 5.400000e+10 5.352e+09
+  6   4 4.395e+06  10.100  20.030   0.080   1.991 5.400000e+10 5.347e+09
+  6   5 3.516e+06  10.060  20.020   0.080   1.998 5.400000e+10 5.368e+09
+  6   6 2.930e+06  10.070  20.030   0.090   1.998 5.399999e+10 5.362e+09
+  6   7 2.511e+06  10.070  20.030   0.080   1.997 5.399998e+10 5.362e+09
+  6   8 2.197e+06  10.070  20.010   0.090   1.996 5.399998e+10 5.362e+09
+  7   1 1.507e+07  10.420  20.030   0.260   1.947 5.400000e+10 5.182e+09
+  7   2 7.533e+06  10.100  20.010   0.140   1.995 5.400000e+10 5.347e+09
+  7   3 5.022e+06  10.080  20.020   0.120   1.998 5.400000e+10 5.357e+09
+  7   4 3.767e+06  10.080  20.010   0.100   1.995 5.400000e+10 5.357e+09
+  7   5 3.013e+06  10.070  20.030   0.080   1.997 5.399998e+10 5.362e+09
+  7   6 2.511e+06  10.080  20.010   0.090   1.994 5.399998e+10 5.357e+09
+  7   7 2.152e+06  10.080  20.060   0.070   1.997 5.399999e+10 5.357e+09
+  7   8 1.883e+06  10.070  20.040   0.070   1.997 5.399998e+10 5.362e+09
+  8   1 1.318e+07  10.220  20.080   0.270   1.991 5.400000e+10 5.284e+09
+  8   2 6.592e+06  10.100  20.010   0.140   1.995 5.399999e+10 5.347e+09
+  8   3 4.395e+06  10.110  20.020   0.120   1.992 5.400000e+10 5.341e+09
+  8   4 3.296e+06  10.090  20.040   0.090   1.995 5.399999e+10 5.352e+09
+  8   5 2.637e+06  10.090  20.040   0.090   1.995 5.399998e+10 5.352e+09
+  8   6 2.197e+06  10.070  20.040   0.100   2.000 5.399998e+10 5.362e+09
+  8   7 1.883e+06  10.090  20.050   0.080   1.995 5.399998e+10 5.352e+09
+  8   8 1.648e+06  10.090  20.040   0.090   1.995 5.399999e+10 5.352e+09
diff --git a/gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat b/gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat
new file mode 100644 (file)
index 0000000..d67dee8
--- /dev/null
@@ -0,0 +1,65 @@
+#D Core2 Duo 2.66 GHz (6700)
+  1   1 1.406e+08   9.890  10.100   0.230   1.044 7.200000e+10 7.280e+09
+  1   2 1.406e+08  10.400  19.900   0.290   1.941 1.440000e+11 1.385e+10
+  1   3 9.375e+07  11.410  19.950   0.200   1.766 1.440000e+11 1.262e+10
+  1   4 7.031e+07  10.230  19.800   0.230   1.958 1.440000e+11 1.408e+10
+  1   5 5.625e+07  10.640  19.800   0.180   1.878 1.440000e+11 1.353e+10
+  1   6 4.688e+07  10.000  19.780   0.130   1.991 1.440000e+11 1.440e+10
+  1   7 4.018e+07  10.500  19.690   0.180   1.892 1.440000e+11 1.371e+10
+  1   8 3.516e+07  10.020  19.750   0.170   1.988 1.440000e+11 1.437e+10
+  2   1 1.406e+08  10.330  20.000   0.460   1.981 1.440000e+11 1.394e+10
+  2   2 7.031e+07  10.160  19.870   0.270   1.982 1.440000e+11 1.417e+10
+  2   3 4.688e+07  10.210  19.780   0.230   1.960 1.440000e+11 1.410e+10
+  2   4 3.516e+07  10.050  19.730   0.210   1.984 1.440000e+11 1.433e+10
+  2   5 2.812e+07  10.060  19.760   0.170   1.981 1.440000e+11 1.431e+10
+  2   6 2.344e+07  10.030  19.780   0.180   1.990 1.440000e+11 1.436e+10
+  2   7 2.009e+07  10.040  19.820   0.180   1.992 1.440000e+11 1.434e+10
+  2   8 1.758e+07  10.050  19.820   0.180   1.990 1.440000e+11 1.433e+10
+  3   1 9.375e+07  13.140  19.950   0.450   1.553 1.440000e+11 1.096e+10
+  3   2 4.688e+07  10.570  19.840   0.290   1.904 1.440000e+11 1.362e+10
+  3   3 3.125e+07  10.420  19.730   0.280   1.920 1.440000e+11 1.382e+10
+  3   4 2.344e+07  10.120  19.710   0.240   1.971 1.440000e+11 1.423e+10
+  3   5 1.875e+07  10.140  19.750   0.190   1.966 1.440000e+11 1.420e+10
+  3   6 1.562e+07  10.030  19.730   0.190   1.986 1.440000e+11 1.436e+10
+  3   7 1.339e+07  10.020  19.720   0.200   1.988 1.440000e+11 1.437e+10
+  3   8 1.172e+07   9.990  19.720   0.170   1.991 1.440000e+11 1.441e+10
+  4   1 7.031e+07  10.310  19.980   0.460   1.983 1.440000e+11 1.397e+10
+  4   2 3.516e+07  10.300  19.830   0.320   1.956 1.440000e+11 1.398e+10
+  4   3 2.344e+07  10.180  19.780   0.230   1.966 1.440000e+11 1.415e+10
+  4   4 1.758e+07  10.070  19.750   0.220   1.983 1.440000e+11 1.430e+10
+  4   5 1.406e+07  10.090  19.750   0.190   1.976 1.440000e+11 1.427e+10
+  4   6 1.172e+07  10.020  19.720   0.190   1.987 1.440000e+11 1.437e+10
+  4   7 1.004e+07  10.040  19.780   0.190   1.989 1.440000e+11 1.434e+10
+  4   8 8.789e+06  10.000  19.750   0.160   1.991 1.440000e+11 1.440e+10
+  5   1 5.625e+07  11.580  19.930   0.500   1.764 1.440000e+11 1.244e+10
+  5   2 2.812e+07  10.300  19.830   0.320   1.956 1.440000e+11 1.398e+10
+  5   3 1.875e+07  10.240  19.760   0.240   1.953 1.440000e+11 1.406e+10
+  5   4 1.406e+07  10.140  19.880   0.230   1.983 1.440000e+11 1.420e+10
+  5   5 1.125e+07  10.040  19.730   0.200   1.985 1.440000e+11 1.434e+10
+  5   6 9.375e+06  10.030  19.770   0.200   1.991 1.440000e+11 1.436e+10
+  5   7 8.036e+06  10.030  19.780   0.170   1.989 1.440000e+11 1.436e+10
+  5   8 7.031e+06  10.000  19.750   0.180   1.993 1.440000e+11 1.440e+10
+  6   1 4.688e+07  10.340  19.910   0.560   1.980 1.440000e+11 1.393e+10
+  6   2 2.344e+07  10.290  19.770   0.330   1.953 1.440000e+11 1.399e+10
+  6   3 1.562e+07  10.150  19.770   0.270   1.974 1.440000e+11 1.419e+10
+  6   4 1.172e+07  10.170  19.880   0.240   1.978 1.440000e+11 1.416e+10
+  6   5 9.375e+06  10.080  19.780   0.240   1.986 1.440000e+11 1.429e+10
+  6   6 7.812e+06  10.020  19.740   0.220   1.992 1.440000e+11 1.437e+10
+  6   7 6.696e+06  10.050  19.760   0.200   1.986 1.440000e+11 1.433e+10
+  6   8 5.859e+06  10.070  19.750   0.210   1.982 1.440000e+11 1.430e+10
+  7   1 4.018e+07  11.220  19.880   0.530   1.819 1.440000e+11 1.283e+10
+  7   2 2.009e+07  10.280  19.790   0.340   1.958 1.440000e+11 1.401e+10
+  7   3 1.339e+07  10.190  19.760   0.250   1.964 1.440000e+11 1.413e+10
+  7   4 1.004e+07  10.060  19.750   0.240   1.987 1.440000e+11 1.431e+10
+  7   5 8.036e+06  10.070  19.750   0.240   1.985 1.440000e+11 1.430e+10
+  7   6 6.696e+06  10.040  19.810   0.220   1.995 1.440000e+11 1.434e+10
+  7   7 5.740e+06  10.050  19.780   0.210   1.989 1.440000e+11 1.433e+10
+  7   8 5.022e+06  10.010  19.790   0.190   1.996 1.440000e+11 1.439e+10
+  8   1 3.516e+07  10.320  19.900   0.470   1.974 1.440000e+11 1.395e+10
+  8   2 1.758e+07  10.340  19.900   0.320   1.956 1.440000e+11 1.393e+10
+  8   3 1.172e+07  10.130  19.770   0.290   1.980 1.440000e+11 1.422e+10
+  8   4 8.789e+06  10.120  19.780   0.230   1.977 1.440000e+11 1.423e+10
+  8   5 7.031e+06  10.040  19.790   0.200   1.991 1.440000e+11 1.434e+10
+  8   6 5.859e+06  10.050  19.770   0.220   1.989 1.440000e+11 1.433e+10
+  8   7 5.022e+06  10.030  19.800   0.200   1.994 1.440000e+11 1.436e+10
+  8   8 4.395e+06  10.050  19.800   0.210   1.991 1.440000e+11 1.433e+10
diff --git a/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat
new file mode 100644 (file)
index 0000000..fa182c6
--- /dev/null
@@ -0,0 +1,257 @@
+#D Dual quad-core Xeon 2.33GHz (Clovertown E5345)
+  1   1 1.367e+08  10.980  12.080   0.360   1.133 7.000000e+10 6.375e+09
+  1   2 1.367e+08  12.250  24.310   0.400   2.017 1.400000e+11 1.143e+10
+  1   3 1.367e+08  12.830  36.080   0.580   2.857 2.100000e+11 1.637e+10
+  1   4 1.367e+08  12.600  46.820   0.770   3.777 2.800000e+11 2.222e+10
+  1   5 1.367e+08  12.620  58.850   0.720   4.720 3.500000e+11 2.773e+10
+  1   6 1.367e+08  12.310  69.430   0.860   5.710 4.200000e+11 3.412e+10
+  1   7 1.367e+08  12.720  80.580   0.950   6.410 4.900000e+11 3.852e+10
+  1   8 1.367e+08  12.440  91.530   1.010   7.439 5.600000e+11 4.502e+10
+  1   9 1.367e+08  22.310 102.660   1.080   4.650 6.300000e+11 2.824e+10
+  1  10 1.367e+08  22.610 113.670   1.160   5.079 7.000000e+11 3.096e+10
+  1  11 1.367e+08  22.690 124.730   1.030   5.543 7.700000e+11 3.394e+10
+  1  12 1.367e+08  23.260 136.520   1.030   5.914 8.400000e+11 3.611e+10
+  1  13 1.367e+08  23.330 147.270   1.130   6.361 9.100000e+11 3.901e+10
+  1  14 1.367e+08  24.110 158.070   1.010   6.598 9.800000e+11 4.065e+10
+  1  15 1.367e+08  25.380 168.370   1.080   6.677 1.050000e+12 4.137e+10
+  1  16 1.367e+08  26.660 179.130   1.250   6.766 1.120000e+12 4.201e+10
+  2   1 1.367e+08  11.190  23.330   0.420   2.122 1.400000e+11 1.251e+10
+  2   2 1.367e+08  12.650  46.350   0.940   3.738 2.800000e+11 2.213e+10
+  2   3 1.367e+08  12.510  69.010   0.980   5.595 4.200000e+11 3.357e+10
+  2   4 1.367e+08  13.250  89.330   0.890   6.809 5.600000e+11 4.226e+10
+  2   5 1.367e+08  22.540 113.580   1.150   5.090 7.000000e+11 3.106e+10
+  2   6 1.367e+08  22.940 135.790   1.260   5.974 8.400000e+11 3.662e+10
+  2   7 1.367e+08  24.250 158.360   1.520   6.593 9.800000e+11 4.041e+10
+  2   8 1.367e+08  26.610 179.840   1.490   6.814 1.120000e+12 4.209e+10
+  2   9 1.215e+08  26.860 179.400   1.540   6.736 1.120000e+12 4.170e+10
+  2  10 1.094e+08  26.350 178.740   1.430   6.838 1.120000e+12 4.250e+10
+  2  11 9.943e+07  25.790 177.910   1.350   6.951 1.120000e+12 4.343e+10
+  2  12 9.115e+07  25.200 176.980   1.460   7.081 1.120000e+12 4.444e+10
+  2  13 8.413e+07  24.840 177.320   1.260   7.189 1.120000e+12 4.509e+10
+  2  14 7.812e+07  24.450 176.920   1.130   7.282 1.120000e+12 4.581e+10
+  2  15 7.292e+07  24.280 177.400   1.140   7.353 1.120000e+12 4.613e+10
+  2  16 6.836e+07  23.830 176.290   1.100   7.444 1.120000e+12 4.700e+10
+  3   1 1.367e+08  11.360  34.790   0.930   3.144 2.100000e+11 1.849e+10
+  3   2 1.367e+08  12.560  68.800   1.400   5.589 4.200000e+11 3.344e+10
+  3   3 1.367e+08  22.310 103.250   1.310   4.687 6.300000e+11 2.824e+10
+  3   4 1.367e+08  22.940 136.120   1.500   5.999 8.400000e+11 3.662e+10
+  3   5 1.367e+08  25.240 168.550   1.790   6.749 1.050000e+12 4.160e+10
+  3   6 1.215e+08  26.800 178.710   1.610   6.728 1.120000e+12 4.179e+10
+  3   7 1.042e+08  26.090 178.710   1.490   6.907 1.120000e+12 4.293e+10
+  3   8 9.115e+07  25.420 178.140   1.360   7.061 1.120000e+12 4.406e+10
+  3   9 8.102e+07  24.680 177.260   1.410   7.239 1.120000e+12 4.538e+10
+  3  10 7.292e+07  24.270 176.830   1.390   7.343 1.120000e+12 4.615e+10
+  3  11 6.629e+07  23.890 177.060   1.240   7.463 1.120000e+12 4.688e+10
+  3  12 6.076e+07  23.620 176.290   1.300   7.519 1.120000e+12 4.742e+10
+  3  13 5.609e+07  23.340 176.780   1.230   7.627 1.120000e+12 4.799e+10
+  3  14 5.208e+07  23.140 176.330   1.300   7.676 1.120000e+12 4.840e+10
+  3  15 4.861e+07  23.100 176.940   1.080   7.706 1.120000e+12 4.848e+10
+  3  16 4.557e+07  22.850 176.120   1.060   7.754 1.120000e+12 4.902e+10
+  4   1 1.367e+08  11.440  45.520   1.080   4.073 2.800000e+11 2.448e+10
+  4   2 1.367e+08  12.410  90.020   1.440   7.370 5.600000e+11 4.512e+10
+  4   3 1.367e+08  23.060 135.570   1.600   5.948 8.400000e+11 3.643e+10
+  4   4 1.367e+08  26.720 179.780   1.880   6.799 1.120000e+12 4.192e+10
+  4   5 1.094e+08  26.280 178.110   1.890   6.849 1.120000e+12 4.262e+10
+  4   6 9.115e+07  25.250 177.280   1.700   7.088 1.120000e+12 4.436e+10
+  4   7 7.812e+07  24.880 177.830   1.570   7.211 1.120000e+12 4.502e+10
+  4   8 6.836e+07  24.150 177.240   1.350   7.395 1.120000e+12 4.638e+10
+  4   9 6.076e+07  23.730 176.590   1.370   7.499 1.120000e+12 4.720e+10
+  4  10 5.469e+07  23.380 176.570   1.310   7.608 1.120000e+12 4.790e+10
+  4  11 4.972e+07  23.230 176.400   1.290   7.649 1.120000e+12 4.821e+10
+  4  12 4.557e+07  22.950 176.100   1.250   7.728 1.120000e+12 4.880e+10
+  4  13 4.207e+07  22.980 176.430   1.260   7.732 1.120000e+12 4.874e+10
+  4  14 3.906e+07  22.820 176.300   1.350   7.785 1.120000e+12 4.908e+10
+  4  15 3.646e+07  22.750 176.450   1.220   7.810 1.120000e+12 4.923e+10
+  4  16 3.418e+07  22.620 176.350   1.080   7.844 1.120000e+12 4.951e+10
+  5   1 1.367e+08  12.000  56.890   1.600   4.874 3.500000e+11 2.917e+10
+  5   2 1.367e+08  22.390 112.870   1.920   5.127 7.000000e+11 3.126e+10
+  5   3 1.367e+08  25.170 167.880   2.110   6.754 1.050000e+12 4.172e+10
+  5   4 1.094e+08  26.380 178.010   1.900   6.820 1.120000e+12 4.246e+10
+  5   5 8.750e+07  25.190 177.570   1.660   7.115 1.120000e+12 4.446e+10
+  5   6 7.292e+07  24.400 176.750   1.650   7.311 1.120000e+12 4.590e+10
+  5   7 6.250e+07  24.020 177.580   1.570   7.458 1.120000e+12 4.663e+10
+  5   8 5.469e+07  23.470 176.650   1.350   7.584 1.120000e+12 4.772e+10
+  5   9 4.861e+07  23.200 176.350   1.280   7.656 1.120000e+12 4.828e+10
+  5  10 4.375e+07  23.140 176.230   1.410   7.677 1.120000e+12 4.840e+10
+  5  11 3.977e+07  22.930 176.120   1.320   7.738 1.120000e+12 4.884e+10
+  5  12 3.646e+07  22.740 176.060   1.330   7.801 1.120000e+12 4.925e+10
+  5  13 3.365e+07  22.690 176.450   1.210   7.830 1.120000e+12 4.936e+10
+  5  14 3.125e+07  22.690 176.430   1.230   7.830 1.120000e+12 4.936e+10
+  5  15 2.917e+07  22.690 176.410   1.260   7.830 1.120000e+12 4.936e+10
+  5  16 2.734e+07  22.560 176.150   1.110   7.857 1.120000e+12 4.965e+10
+  6   1 1.367e+08  12.600  68.590   2.230   5.621 4.200000e+11 3.333e+10
+  6   2 1.367e+08  22.830 135.260   2.100   6.017 8.400000e+11 3.679e+10
+  6   3 1.215e+08  26.860 178.470   2.140   6.724 1.120000e+12 4.170e+10
+  6   4 9.115e+07  25.450 177.110   2.060   7.040 1.120000e+12 4.401e+10
+  6   5 7.292e+07  24.510 176.850   1.910   7.293 1.120000e+12 4.570e+10
+  6   6 6.076e+07  23.890 176.450   1.760   7.460 1.120000e+12 4.688e+10
+  6   7 5.208e+07  23.460 175.980   1.540   7.567 1.120000e+12 4.774e+10
+  6   8 4.557e+07  23.150 176.480   1.370   7.683 1.120000e+12 4.838e+10
+  6   9 4.051e+07  22.920 176.030   1.400   7.741 1.120000e+12 4.887e+10
+  6  10 3.646e+07  22.880 176.300   1.350   7.764 1.120000e+12 4.895e+10
+  6  11 3.314e+07  22.830 175.970   1.360   7.767 1.120000e+12 4.906e+10
+  6  12 3.038e+07  22.710 176.040   1.190   7.804 1.120000e+12 4.932e+10
+  6  13 2.804e+07  22.690 176.050   1.340   7.818 1.120000e+12 4.936e+10
+  6  14 2.604e+07  22.650 176.410   1.140   7.839 1.120000e+12 4.945e+10
+  6  15 2.431e+07  22.570 175.940   1.250   7.851 1.120000e+12 4.962e+10
+  6  16 2.279e+07  22.500 175.980   1.170   7.873 1.120000e+12 4.978e+10
+  7   1 1.367e+08  12.960  79.970   2.850   6.390 4.900000e+11 3.781e+10
+  7   2 1.367e+08  24.040 156.540   2.500   6.616 9.800000e+11 4.077e+10
+  7   3 1.042e+08  26.130 178.060   2.210   6.899 1.120000e+12 4.286e+10
+  7   4 7.812e+07  24.860 176.880   1.810   7.188 1.120000e+12 4.505e+10
+  7   5 6.250e+07  24.000 176.590   1.790   7.433 1.120000e+12 4.667e+10
+  7   6 5.208e+07  23.540 176.480   1.670   7.568 1.120000e+12 4.758e+10
+  7   7 4.464e+07  23.180 176.030   1.510   7.659 1.120000e+12 4.832e+10
+  7   8 3.906e+07  22.980 176.500   1.340   7.739 1.120000e+12 4.874e+10
+  7   9 3.472e+07  22.870 175.970   1.280   7.750 1.120000e+12 4.897e+10
+  7  10 3.125e+07  22.730 176.220   1.300   7.810 1.120000e+12 4.927e+10
+  7  11 2.841e+07  22.700 176.030   1.300   7.812 1.120000e+12 4.934e+10
+  7  12 2.604e+07  22.650 176.300   1.210   7.837 1.120000e+12 4.945e+10
+  7  13 2.404e+07  22.580 176.140   1.170   7.853 1.120000e+12 4.960e+10
+  7  14 2.232e+07  22.540 176.550   1.130   7.883 1.120000e+12 4.969e+10
+  7  15 2.083e+07  22.570 175.870   1.260   7.848 1.120000e+12 4.962e+10
+  7  16 1.953e+07  22.520 175.980   1.310   7.873 1.120000e+12 4.973e+10
+  8   1 1.367e+08  13.250  91.770   3.010   7.153 5.600000e+11 4.226e+10
+  8   2 1.367e+08  26.280 178.100   2.980   6.890 1.120000e+12 4.262e+10
+  8   3 9.115e+07  25.510 177.140   2.270   7.033 1.120000e+12 4.390e+10
+  8   4 6.836e+07  24.330 176.850   1.870   7.346 1.120000e+12 4.603e+10
+  8   5 5.469e+07  23.680 176.850   1.690   7.540 1.120000e+12 4.730e+10
+  8   6 4.557e+07  23.430 176.210   1.700   7.593 1.120000e+12 4.780e+10
+  8   7 3.906e+07  23.100 176.680   1.440   7.711 1.120000e+12 4.848e+10
+  8   8 3.418e+07  22.890 176.270   1.430   7.763 1.120000e+12 4.893e+10
+  8   9 3.038e+07  22.760 175.980   1.320   7.790 1.120000e+12 4.921e+10
+  8  10 2.734e+07  22.760 176.340   1.290   7.804 1.120000e+12 4.921e+10
+  8  11 2.486e+07  22.660 176.220   1.170   7.828 1.120000e+12 4.943e+10
+  8  12 2.279e+07  22.660 176.050   1.280   7.826 1.120000e+12 4.943e+10
+  8  13 2.103e+07  22.590 176.170   1.350   7.858 1.120000e+12 4.958e+10
+  8  14 1.953e+07  22.550 176.120   1.320   7.869 1.120000e+12 4.967e+10
+  8  15 1.823e+07  22.590 176.130   1.270   7.853 1.120000e+12 4.958e+10
+  8  16 1.709e+07  22.500 176.090   1.230   7.881 1.120000e+12 4.978e+10
+  9   1 1.367e+08  21.110 101.410   2.640   4.929 6.300000e+11 2.984e+10
+  9   2 1.215e+08  27.400 178.180   2.720   6.602 1.120000e+12 4.088e+10
+  9   3 8.102e+07  25.140 177.370   2.230   7.144 1.120000e+12 4.455e+10
+  9   4 6.076e+07  24.110 176.810   1.910   7.413 1.120000e+12 4.645e+10
+  9   5 4.861e+07  23.460 176.240   1.600   7.581 1.120000e+12 4.774e+10
+  9   6 4.051e+07  23.200 176.310   1.620   7.669 1.120000e+12 4.828e+10
+  9   7 3.472e+07  22.970 176.560   1.540   7.754 1.120000e+12 4.876e+10
+  9   8 3.038e+07  22.920 176.300   1.440   7.755 1.120000e+12 4.887e+10
+  9   9 2.701e+07  22.830 176.090   1.370   7.773 1.120000e+12 4.906e+10
+  9  10 2.431e+07  22.730 175.960   1.430   7.804 1.120000e+12 4.927e+10
+  9  11 2.210e+07  22.750 176.160   1.260   7.799 1.120000e+12 4.923e+10
+  9  12 2.025e+07  22.660 176.100   1.380   7.832 1.120000e+12 4.943e+10
+  9  13 1.870e+07  22.700 176.040   1.400   7.817 1.120000e+12 4.934e+10
+  9  14 1.736e+07  22.620 175.940   1.410   7.840 1.120000e+12 4.951e+10
+  9  15 1.620e+07  22.490 175.910   1.340   7.881 1.120000e+12 4.980e+10
+  9  16 1.519e+07  22.540 175.990   1.330   7.867 1.120000e+12 4.969e+10
+ 10   1 1.367e+08  21.730 113.690   2.870   5.364 7.000000e+11 3.221e+10
+ 10   2 1.094e+08  26.660 177.920   3.180   6.793 1.120000e+12 4.201e+10
+ 10   3 7.292e+07  24.740 176.810   2.090   7.231 1.120000e+12 4.527e+10
+ 10   4 5.469e+07  23.880 176.280   2.020   7.466 1.120000e+12 4.690e+10
+ 10   5 4.375e+07  23.330 176.510   1.610   7.635 1.120000e+12 4.801e+10
+ 10   6 3.646e+07  23.170 176.160   1.680   7.675 1.120000e+12 4.834e+10
+ 10   7 3.125e+07  22.950 176.490   1.470   7.754 1.120000e+12 4.880e+10
+ 10   8 2.734e+07  22.830 176.260   1.360   7.780 1.120000e+12 4.906e+10
+ 10   9 2.431e+07  22.770 175.930   1.410   7.788 1.120000e+12 4.919e+10
+ 10  10 2.188e+07  22.680 175.870   1.440   7.818 1.120000e+12 4.938e+10
+ 10  11 1.989e+07  22.700 176.140   1.310   7.817 1.120000e+12 4.934e+10
+ 10  12 1.823e+07  22.630 176.040   1.430   7.842 1.120000e+12 4.949e+10
+ 10  13 1.683e+07  22.640 176.000   1.320   7.832 1.120000e+12 4.947e+10
+ 10  14 1.562e+07  22.610 176.160   1.230   7.846 1.120000e+12 4.954e+10
+ 10  15 1.458e+07  22.570 176.010   1.290   7.856 1.120000e+12 4.962e+10
+ 10  16 1.367e+07  22.640 176.060   1.270   7.833 1.120000e+12 4.947e+10
+ 11   1 1.367e+08  22.060 124.440   3.050   5.779 7.700000e+11 3.490e+10
+ 11   2 9.943e+07  26.060 178.400   3.000   6.961 1.120000e+12 4.298e+10
+ 11   3 6.629e+07  24.380 176.690   2.200   7.338 1.120000e+12 4.594e+10
+ 11   4 4.972e+07  23.650 176.730   1.830   7.550 1.120000e+12 4.736e+10
+ 11   5 3.977e+07  23.310 176.030   1.780   7.628 1.120000e+12 4.805e+10
+ 11   6 3.314e+07  23.050 176.210   1.680   7.718 1.120000e+12 4.859e+10
+ 11   7 2.841e+07  22.940 176.300   1.540   7.752 1.120000e+12 4.882e+10
+ 11   8 2.486e+07  22.830 175.990   1.530   7.776 1.120000e+12 4.906e+10
+ 11   9 2.210e+07  22.760 176.060   1.440   7.799 1.120000e+12 4.921e+10
+ 11  10 1.989e+07  22.630 176.010   1.430   7.841 1.120000e+12 4.949e+10
+ 11  11 1.808e+07  22.720 176.040   1.390   7.809 1.120000e+12 4.930e+10
+ 11  12 1.657e+07  22.640 175.890   1.400   7.831 1.120000e+12 4.947e+10
+ 11  13 1.530e+07  22.570 176.090   1.260   7.858 1.120000e+12 4.962e+10
+ 11  14 1.420e+07  22.610 176.150   1.450   7.855 1.120000e+12 4.954e+10
+ 11  15 1.326e+07  22.550 175.980   1.310   7.862 1.120000e+12 4.967e+10
+ 11  16 1.243e+07  22.610 175.920   1.400   7.843 1.120000e+12 4.954e+10
+ 12   1 1.367e+08  22.220 136.260   3.390   6.285 8.400000e+11 3.780e+10
+ 12   2 9.115e+07  25.610 178.090   2.800   7.063 1.120000e+12 4.373e+10
+ 12   3 6.076e+07  24.180 176.320   2.230   7.384 1.120000e+12 4.632e+10
+ 12   4 4.557e+07  23.570 176.570   2.010   7.577 1.120000e+12 4.752e+10
+ 12   5 3.646e+07  23.210 176.420   1.710   7.675 1.120000e+12 4.826e+10
+ 12   6 3.038e+07  23.040 175.910   1.640   7.706 1.120000e+12 4.861e+10
+ 12   7 2.604e+07  22.980 176.390   1.510   7.742 1.120000e+12 4.874e+10
+ 12   8 2.279e+07  22.840 176.110   1.640   7.782 1.120000e+12 4.904e+10
+ 12   9 2.025e+07  22.760 175.950   1.500   7.797 1.120000e+12 4.921e+10
+ 12  10 1.823e+07  22.660 175.810   1.600   7.829 1.120000e+12 4.943e+10
+ 12  11 1.657e+07  22.710 175.940   1.410   7.809 1.120000e+12 4.932e+10
+ 12  12 1.519e+07  22.650 175.870   1.400   7.826 1.120000e+12 4.945e+10
+ 12  13 1.402e+07  22.640 176.040   1.260   7.831 1.120000e+12 4.947e+10
+ 12  14 1.302e+07  22.650 176.130   1.450   7.840 1.120000e+12 4.945e+10
+ 12  15 1.215e+07  22.580 175.990   1.370   7.855 1.120000e+12 4.960e+10
+ 12  16 1.139e+07  22.640 175.870   1.440   7.832 1.120000e+12 4.947e+10
+ 13   1 1.367e+08  22.640 147.020   3.570   6.652 9.100000e+11 4.019e+10
+ 13   2 8.413e+07  25.600 177.820   2.870   7.058 1.120000e+12 4.375e+10
+ 13   3 5.609e+07  24.020 176.980   2.270   7.463 1.120000e+12 4.663e+10
+ 13   4 4.207e+07  23.440 176.430   2.030   7.613 1.120000e+12 4.778e+10
+ 13   5 3.365e+07  23.080 176.110   1.790   7.708 1.120000e+12 4.853e+10
+ 13   6 2.804e+07  22.870 176.210   1.600   7.775 1.120000e+12 4.897e+10
+ 13   7 2.404e+07  22.940 176.340   1.580   7.756 1.120000e+12 4.882e+10
+ 13   8 2.103e+07  22.880 176.050   1.520   7.761 1.120000e+12 4.895e+10
+ 13   9 1.870e+07  22.740 176.020   1.400   7.802 1.120000e+12 4.925e+10
+ 13  10 1.683e+07  22.710 175.880   1.440   7.808 1.120000e+12 4.932e+10
+ 13  11 1.530e+07  22.590 176.040   1.350   7.853 1.120000e+12 4.958e+10
+ 13  12 1.402e+07  22.600 175.930   1.380   7.846 1.120000e+12 4.956e+10
+ 13  13 1.294e+07  22.710 176.010   1.340   7.809 1.120000e+12 4.932e+10
+ 13  14 1.202e+07  22.690 176.270   1.350   7.828 1.120000e+12 4.936e+10
+ 13  15 1.122e+07  22.590 175.960   1.290   7.846 1.120000e+12 4.958e+10
+ 13  16 1.052e+07  22.610 175.960   1.370   7.843 1.120000e+12 4.954e+10
+ 14   1 1.367e+08  23.120 157.180   3.810   6.963 9.800000e+11 4.239e+10
+ 14   2 7.812e+07  25.310 177.210   3.020   7.121 1.120000e+12 4.425e+10
+ 14   3 5.208e+07  24.130 177.110   2.340   7.437 1.120000e+12 4.642e+10
+ 14   4 3.906e+07  23.390 176.660   1.800   7.630 1.120000e+12 4.788e+10
+ 14   5 3.125e+07  23.060 176.420   1.750   7.726 1.120000e+12 4.857e+10
+ 14   6 2.604e+07  22.890 176.180   1.530   7.764 1.120000e+12 4.893e+10
+ 14   7 2.232e+07  22.940 176.060   1.550   7.742 1.120000e+12 4.882e+10
+ 14   8 1.953e+07  22.810 176.110   1.500   7.786 1.120000e+12 4.910e+10
+ 14   9 1.736e+07  22.750 176.370   1.370   7.813 1.120000e+12 4.923e+10
+ 14  10 1.562e+07  22.720 176.020   1.450   7.811 1.120000e+12 4.930e+10
+ 14  11 1.420e+07  22.680 176.090   1.310   7.822 1.120000e+12 4.938e+10
+ 14  12 1.302e+07  22.710 175.950   1.510   7.814 1.120000e+12 4.932e+10
+ 14  13 1.202e+07  22.700 176.100   1.500   7.824 1.120000e+12 4.934e+10
+ 14  14 1.116e+07  22.660 176.150   1.460   7.838 1.120000e+12 4.943e+10
+ 14  15 1.042e+07  22.680 176.120   1.370   7.826 1.120000e+12 4.938e+10
+ 14  16 9.766e+06  22.710 176.110   1.430   7.818 1.120000e+12 4.932e+10
+ 15   1 1.367e+08  23.710 168.080   4.140   7.264 1.050000e+12 4.429e+10
+ 15   2 7.292e+07  25.170 176.640   2.930   7.134 1.120000e+12 4.450e+10
+ 15   3 4.861e+07  23.820 176.980   2.110   7.518 1.120000e+12 4.702e+10
+ 15   4 3.646e+07  23.250 176.190   1.970   7.663 1.120000e+12 4.817e+10
+ 15   5 2.917e+07  23.050 176.450   1.690   7.728 1.120000e+12 4.859e+10
+ 15   6 2.431e+07  22.900 175.980   1.680   7.758 1.120000e+12 4.891e+10
+ 15   7 2.083e+07  22.830 176.090   1.640   7.785 1.120000e+12 4.906e+10
+ 15   8 1.823e+07  22.850 176.160   1.530   7.776 1.120000e+12 4.902e+10
+ 15   9 1.620e+07  22.780 176.390   1.360   7.803 1.120000e+12 4.917e+10
+ 15  10 1.458e+07  22.660 176.000   1.440   7.831 1.120000e+12 4.943e+10
+ 15  11 1.326e+07  22.660 176.110   1.430   7.835 1.120000e+12 4.943e+10
+ 15  12 1.215e+07  22.660 176.150   1.380   7.835 1.120000e+12 4.943e+10
+ 15  13 1.122e+07  22.760 175.970   1.580   7.801 1.120000e+12 4.921e+10
+ 15  14 1.042e+07  22.670 176.290   1.270   7.832 1.120000e+12 4.940e+10
+ 15  15 9.722e+06  22.710 176.060   1.550   7.821 1.120000e+12 4.932e+10
+ 15  16 9.115e+06  22.800 176.020   1.490   7.786 1.120000e+12 4.912e+10
+ 16   1 1.367e+08  25.470 179.270   4.730   7.224 1.120000e+12 4.397e+10
+ 16   2 6.836e+07  24.870 176.820   2.960   7.229 1.120000e+12 4.503e+10
+ 16   3 4.557e+07  23.810 176.930   2.250   7.525 1.120000e+12 4.704e+10
+ 16   4 3.418e+07  23.240 176.650   1.950   7.685 1.120000e+12 4.819e+10
+ 16   5 2.734e+07  23.090 175.940   1.940   7.704 1.120000e+12 4.851e+10
+ 16   6 2.279e+07  22.900 176.120   1.680   7.764 1.120000e+12 4.891e+10
+ 16   7 1.953e+07  22.890 176.290   1.440   7.765 1.120000e+12 4.893e+10
+ 16   8 1.709e+07  22.820 176.040   1.610   7.785 1.120000e+12 4.908e+10
+ 16   9 1.519e+07  22.890 175.990   1.470   7.753 1.120000e+12 4.893e+10
+ 16  10 1.367e+07  22.700 175.890   1.470   7.813 1.120000e+12 4.934e+10
+ 16  11 1.243e+07  22.770 175.960   1.520   7.794 1.120000e+12 4.919e+10
+ 16  12 1.139e+07  22.730 176.000   1.430   7.806 1.120000e+12 4.927e+10
+ 16  13 1.052e+07  22.670 175.990   1.540   7.831 1.120000e+12 4.940e+10
+ 16  14 9.766e+06  22.720 176.130   1.440   7.816 1.120000e+12 4.930e+10
+ 16  15 9.115e+06  22.740 176.320   1.360   7.814 1.120000e+12 4.925e+10
+ 16  16 8.545e+06  22.680 176.170   1.320   7.826 1.120000e+12 4.938e+10
diff --git a/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat
new file mode 100644 (file)
index 0000000..57d49ed
--- /dev/null
@@ -0,0 +1,257 @@
+#D Dual quad-core Xeon 3.0 GHz (Penryn E5472, 1600 MHz FSB, 5400 chipset)
+  1   1 5.000e+07   2.720   3.020   0.110   1.151 2.560000e+10 9.412e+09
+  1   2 5.000e+07   2.870   5.630   0.170   2.021 5.120000e+10 1.784e+10
+  1   3 5.000e+07   2.880   8.380   0.160   2.965 7.680000e+10 2.667e+10
+  1   4 5.000e+07   2.990  11.080   0.200   3.773 1.024000e+11 3.425e+10
+  1   5 5.000e+07   2.950  13.950   0.190   4.793 1.280000e+11 4.339e+10
+  1   6 5.000e+07   3.020  16.620   0.240   5.583 1.536000e+11 5.086e+10
+  1   7 5.000e+07   2.930  19.250   0.200   6.638 1.792000e+11 6.116e+10
+  1   8 5.000e+07   3.170  22.240   0.290   7.107 2.048000e+11 6.461e+10
+  1   9 5.000e+07   5.450  24.410   0.310   4.536 2.304000e+11 4.228e+10
+  1  10 5.000e+07   5.610  27.400   0.370   4.950 2.560000e+11 4.563e+10
+  1  11 5.000e+07   5.680  29.960   0.370   5.340 2.816000e+11 4.958e+10
+  1  12 5.000e+07   5.440  32.490   0.350   6.037 3.072000e+11 5.647e+10
+  1  13 5.000e+07   5.630  35.270   0.400   6.336 3.328000e+11 5.911e+10
+  1  14 5.000e+07   6.270  38.500   0.480   6.217 3.584000e+11 5.716e+10
+  1  15 5.000e+07   6.080  40.880   0.490   6.804 3.840000e+11 6.316e+10
+  1  16 5.000e+07   7.740  43.390   0.600   5.683 4.096000e+11 5.292e+10
+  2   1 5.000e+07   2.820   5.700   0.210   2.096 5.120000e+10 1.816e+10
+  2   2 5.000e+07   2.820  11.130   0.230   4.028 1.024000e+11 3.631e+10
+  2   3 5.000e+07   2.960  16.570   0.320   5.706 1.536000e+11 5.189e+10
+  2   4 5.000e+07   3.110  21.920   0.390   7.174 2.048000e+11 6.585e+10
+  2   5 5.000e+07   5.650  27.550   0.520   4.968 2.560000e+11 4.531e+10
+  2   6 5.000e+07   5.880  32.890   0.440   5.668 3.072000e+11 5.224e+10
+  2   7 5.000e+07   6.750  38.210   0.560   5.744 3.584000e+11 5.310e+10
+  2   8 5.000e+07   6.360  43.480   0.580   6.928 4.096000e+11 6.440e+10
+  2   9 5.000e+07   8.270  48.750   0.730   5.983 4.608000e+11 5.572e+10
+  2  10 5.000e+07   8.210  54.400   0.610   6.700 5.120000e+11 6.236e+10
+  2  11 5.000e+07   8.750  59.760   0.640   6.903 5.632000e+11 6.437e+10
+  2  12 5.000e+07   9.300  65.050   0.700   7.070 6.144000e+11 6.606e+10
+  2  13 5.000e+07   9.990  70.750   0.750   7.157 6.656000e+11 6.663e+10
+  2  14 5.000e+07  10.610  75.950   0.810   7.235 7.168000e+11 6.756e+10
+  2  15 5.000e+07  11.900  80.400   0.870   6.829 7.680000e+11 6.454e+10
+  2  16 5.000e+07  11.820  86.790   0.900   7.419 8.192000e+11 6.931e+10
+  3   1 5.000e+07   2.970   8.300   0.380   2.923 7.680000e+10 2.586e+10
+  3   2 5.000e+07   2.980  16.660   0.390   5.721 1.536000e+11 5.154e+10
+  3   3 5.000e+07   5.480  24.690   0.420   4.582 2.304000e+11 4.204e+10
+  3   4 5.000e+07   5.620  32.820   0.560   5.940 3.072000e+11 5.466e+10
+  3   5 5.000e+07   6.940  40.800   0.620   5.968 3.840000e+11 5.533e+10
+  3   6 5.000e+07   7.860  49.010   0.710   6.326 4.608000e+11 5.863e+10
+  3   7 5.000e+07   8.470  57.130   0.750   6.834 5.376000e+11 6.347e+10
+  3   8 5.000e+07   9.420  65.310   0.820   7.020 6.144000e+11 6.522e+10
+  3   9 5.000e+07  10.350  73.640   0.940   7.206 6.912000e+11 6.678e+10
+  3  10 5.000e+07  11.460  82.230   1.030   7.265 7.680000e+11 6.702e+10
+  3  11 5.000e+07  12.200  89.590   1.050   7.430 8.448000e+11 6.925e+10
+  3  12 5.000e+07  13.040  97.520   1.140   7.566 9.216000e+11 7.067e+10
+  3  13 5.000e+07  14.000 105.560   1.150   7.622 9.984000e+11 7.131e+10
+  3  14 5.000e+07  14.930 113.630   1.210   7.692 1.075200e+12 7.202e+10
+  3  15 5.000e+07  15.920 121.610   1.350   7.724 1.152000e+12 7.236e+10
+  3  16 5.000e+07  16.870 129.770   1.390   7.775 1.228800e+12 7.284e+10
+  4   1 5.000e+07   2.900  11.100   0.340   3.945 1.024000e+11 3.531e+10
+  4   2 5.000e+07   4.380  21.980   0.480   5.128 2.048000e+11 4.676e+10
+  4   3 5.000e+07   5.720  32.800   0.610   5.841 3.072000e+11 5.371e+10
+  4   4 5.000e+07   6.820  43.880   0.700   6.537 4.096000e+11 6.006e+10
+  4   5 5.000e+07   8.150  54.420   0.760   6.771 5.120000e+11 6.282e+10
+  4   6 5.000e+07   9.510  65.180   0.980   6.957 6.144000e+11 6.461e+10
+  4   7 5.000e+07  10.650  76.080   1.020   7.239 7.168000e+11 6.731e+10
+  4   8 5.000e+07  11.880  86.720   1.110   7.393 8.192000e+11 6.896e+10
+  4   9 5.000e+07  13.150  97.920   1.250   7.541 9.216000e+11 7.008e+10
+  4  10 5.000e+07  14.640 109.260   1.410   7.559 1.024000e+12 6.995e+10
+  4  11 5.000e+07  15.710 119.170   1.440   7.677 1.126400e+12 7.170e+10
+  4  12 5.000e+07  16.950 129.960   1.420   7.751 1.228800e+12 7.250e+10
+  4  13 5.000e+07  18.260 140.520   1.620   7.784 1.331200e+12 7.290e+10
+  4  14 5.000e+07  19.610 151.290   1.780   7.806 1.433600e+12 7.311e+10
+  4  15 5.000e+07  21.060 162.760   1.890   7.818 1.536000e+12 7.293e+10
+  4  16 5.000e+07  22.280 172.870   1.980   7.848 1.638400e+12 7.354e+10
+  5   1 5.000e+07   3.040  13.810   0.390   4.671 1.280000e+11 4.211e+10
+  5   2 5.000e+07   5.590  27.510   0.610   5.030 2.560000e+11 4.580e+10
+  5   3 5.000e+07   6.550  40.970   0.780   6.374 3.840000e+11 5.863e+10
+  5   4 5.000e+07   8.520  54.470   0.940   6.504 5.120000e+11 6.009e+10
+  5   5 5.000e+07   9.920  67.950   1.060   6.957 6.400000e+11 6.452e+10
+  5   6 5.000e+07  11.350  81.490   1.180   7.284 7.680000e+11 6.767e+10
+  5   7 5.000e+07  12.910  94.960   1.300   7.456 8.960000e+11 6.940e+10
+  5   8 5.000e+07  14.520 108.510   1.400   7.570 1.024000e+12 7.052e+10
+  5   9 5.000e+07  16.070 122.120   1.620   7.700 1.152000e+12 7.169e+10
+  5  10 5.000e+07  17.950 136.140   1.730   7.681 1.280000e+12 7.131e+10
+  5  11 5.000e+07  19.470 148.330   1.830   7.712 1.408000e+12 7.232e+10
+  5  12 5.000e+07  20.980 162.100   2.030   7.823 1.536000e+12 7.321e+10
+  5  13 5.000e+07  22.670 175.470   2.160   7.835 1.664000e+12 7.340e+10
+  5  14 5.000e+07  24.440 189.630   2.170   7.848 1.792000e+12 7.332e+10
+  5  15 5.000e+07  26.100 203.010   2.450   7.872 1.920000e+12 7.356e+10
+  5  16 5.000e+07  27.720 216.000   2.550   7.884 2.048000e+12 7.388e+10
+  6   1 5.000e+07   2.950  16.560   0.540   5.797 1.536000e+11 5.207e+10
+  6   2 5.000e+07   5.540  32.900   0.720   6.069 3.072000e+11 5.545e+10
+  6   3 5.000e+07   8.490  48.860   1.000   5.873 4.608000e+11 5.428e+10
+  6   4 5.000e+07  10.000  64.670   1.100   6.577 6.144000e+11 6.144e+10
+  6   5 5.000e+07  11.440  81.430   1.310   7.233 7.680000e+11 6.713e+10
+  6   6 5.000e+07  13.250  97.690   1.360   7.475 9.216000e+11 6.955e+10
+  6   7 5.000e+07  15.270 113.730   1.610   7.553 1.075200e+12 7.041e+10
+  6   8 5.000e+07  17.180 129.780   1.820   7.660 1.228800e+12 7.153e+10
+  6   9 5.000e+07  19.200 146.020   1.870   7.703 1.382400e+12 7.200e+10
+  6  10 5.000e+07  21.220 162.290   2.100   7.747 1.536000e+12 7.238e+10
+  6  11 5.000e+07  23.070 178.420   2.160   7.827 1.689600e+12 7.324e+10
+  6  12 5.000e+07  25.120 194.590   2.450   7.844 1.843200e+12 7.338e+10
+  6  13 5.000e+07  27.110 210.640   2.660   7.868 1.996800e+12 7.366e+10
+  6  14 5.000e+07  29.110 226.820   2.750   7.886 2.150400e+12 7.387e+10
+  6  15 5.000e+07  31.130 242.800   2.940   7.894 2.304000e+12 7.401e+10
+  6  16 5.000e+07  33.100 258.790   3.210   7.915 2.457600e+12 7.425e+10
+  7   1 5.000e+07   2.940  19.140   0.590   6.711 1.792000e+11 6.095e+10
+  7   2 5.000e+07   5.920  37.910   1.030   6.578 3.584000e+11 6.054e+10
+  7   3 5.000e+07   8.570  57.010   1.150   6.786 5.376000e+11 6.273e+10
+  7   4 5.000e+07  10.840  76.060   1.320   7.138 7.168000e+11 6.613e+10
+  7   5 5.000e+07  13.070  94.920   1.540   7.380 8.960000e+11 6.855e+10
+  7   6 5.000e+07  15.270 113.790   1.730   7.565 1.075200e+12 7.041e+10
+  7   7 5.000e+07  17.700 132.560   1.960   7.600 1.254400e+12 7.087e+10
+  7   8 5.000e+07  19.930 151.500   2.130   7.708 1.433600e+12 7.193e+10
+  7   9 5.000e+07  22.250 170.570   2.340   7.771 1.612800e+12 7.249e+10
+  7  10 5.000e+07  24.600 189.280   2.450   7.794 1.792000e+12 7.285e+10
+  7  11 5.000e+07  26.950 208.030   2.700   7.819 1.971200e+12 7.314e+10
+  7  12 5.000e+07  29.280 227.070   2.850   7.852 2.150400e+12 7.344e+10
+  7  13 5.000e+07  31.570 245.750   3.040   7.881 2.329600e+12 7.379e+10
+  7  14 5.000e+07  33.930 264.960   3.160   7.902 2.508800e+12 7.394e+10
+  7  15 5.000e+07  36.310 283.960   3.440   7.915 2.688000e+12 7.403e+10
+  7  16 5.000e+07  38.560 302.120   3.630   7.929 2.867200e+12 7.436e+10
+  8   1 5.000e+07   3.200  21.880   0.860   7.106 2.048000e+11 6.400e+10
+  8   2 5.000e+07   5.890  43.450   0.930   7.535 4.096000e+11 6.954e+10
+  8   3 5.000e+07   9.520  65.180   1.250   6.978 6.144000e+11 6.454e+10
+  8   4 5.000e+07  12.200  86.780   1.480   7.234 8.192000e+11 6.715e+10
+  8   5 5.000e+07  14.760 108.420   1.670   7.459 1.024000e+12 6.938e+10
+  8   6 5.000e+07  17.300 129.850   1.960   7.619 1.228800e+12 7.103e+10
+  8   7 5.000e+07  20.020 151.430   2.190   7.673 1.433600e+12 7.161e+10
+  8   8 5.000e+07  22.750 173.550   2.420   7.735 1.638400e+12 7.202e+10
+  8   9 5.000e+07  25.410 194.560   2.760   7.765 1.843200e+12 7.254e+10
+  8  10 5.000e+07  28.410 217.250   2.920   7.750 2.048000e+12 7.209e+10
+  8  11 5.000e+07  30.720 237.990   3.210   7.852 2.252800e+12 7.333e+10
+  8  12 5.000e+07  33.310 259.340   3.280   7.884 2.457600e+12 7.378e+10
+  8  13 5.000e+07  36.000 280.760   3.670   7.901 2.662400e+12 7.396e+10
+  8  14 5.000e+07  38.800 302.570   3.740   7.895 2.867200e+12 7.390e+10
+  8  15 5.000e+07  41.530 324.520   4.060   7.912 3.072000e+12 7.397e+10
+  8  16 5.000e+07  44.060 345.420   4.250   7.936 3.276800e+12 7.437e+10
+  9   1 5.000e+07   5.460  24.660   1.000   4.700 2.304000e+11 4.220e+10
+  9   2 5.000e+07   8.460  49.010   1.200   5.935 4.608000e+11 5.447e+10
+  9   3 5.000e+07  10.810  71.410   1.400   6.735 6.912000e+11 6.394e+10
+  9   4 5.000e+07  13.470  97.570   1.710   7.370 9.216000e+11 6.842e+10
+  9   5 5.000e+07  16.490 121.780   2.130   7.514 1.152000e+12 6.986e+10
+  9   6 5.000e+07  19.540 146.070   2.280   7.592 1.382400e+12 7.075e+10
+  9   7 5.000e+07  22.660 170.830   2.570   7.652 1.612800e+12 7.117e+10
+  9   8 5.000e+07  25.520 194.720   2.760   7.738 1.843200e+12 7.223e+10
+  9   9 5.000e+07  28.400 219.020   3.060   7.820 2.073600e+12 7.301e+10
+  9  10 5.000e+07  31.490 243.030   3.320   7.823 2.304000e+12 7.317e+10
+  9  11 5.000e+07  34.530 267.230   3.420   7.838 2.534400e+12 7.340e+10
+  9  12 5.000e+07  37.520 291.720   3.860   7.878 2.764800e+12 7.369e+10
+  9  13 5.000e+07  40.550 315.780   4.170   7.890 2.995200e+12 7.386e+10
+  9  14 5.000e+07  43.470 339.930   4.290   7.919 3.225600e+12 7.420e+10
+  9  15 5.000e+07  46.820 364.970   4.640   7.894 3.456000e+12 7.381e+10
+  9  16 5.000e+07  49.660 388.630   4.890   7.924 3.686400e+12 7.423e+10
+ 10   1 5.000e+07   5.500  27.290   0.980   5.140 2.560000e+11 4.655e+10
+ 10   2 5.000e+07   8.480  54.830   1.420   6.633 5.120000e+11 6.038e+10
+ 10   3 5.000e+07  11.540  81.580   1.630   7.211 7.680000e+11 6.655e+10
+ 10   4 5.000e+07  14.950 108.480   1.860   7.381 1.024000e+12 6.849e+10
+ 10   5 5.000e+07  18.330 135.300   2.280   7.506 1.280000e+12 6.983e+10
+ 10   6 5.000e+07  21.680 162.380   2.540   7.607 1.536000e+12 7.085e+10
+ 10   7 5.000e+07  24.950 189.360   2.730   7.699 1.792000e+12 7.182e+10
+ 10   8 5.000e+07  28.280 216.090   3.110   7.751 2.048000e+12 7.242e+10
+ 10   9 5.000e+07  31.730 243.290   3.450   7.776 2.304000e+12 7.261e+10
+ 10  10 5.000e+07  35.040 270.380   3.680   7.821 2.560000e+12 7.306e+10
+ 10  11 5.000e+07  38.340 297.080   4.050   7.854 2.816000e+12 7.345e+10
+ 10  12 5.000e+07  41.770 323.840   4.330   7.857 3.072000e+12 7.355e+10
+ 10  13 5.000e+07  45.120 351.380   4.710   7.892 3.328000e+12 7.376e+10
+ 10  14 5.000e+07  48.360 377.870   4.880   7.915 3.584000e+12 7.411e+10
+ 10  15 5.000e+07  51.760 404.740   5.110   7.918 3.840000e+12 7.419e+10
+ 10  16 5.000e+07  55.130 431.760   5.430   7.930 4.096000e+12 7.430e+10
+ 11   1 5.000e+07   5.570  30.080   1.080   5.594 2.816000e+11 5.056e+10
+ 11   2 5.000e+07   9.000  60.230   1.470   6.856 5.632000e+11 6.258e+10
+ 11   3 5.000e+07  12.630  89.890   1.770   7.257 8.448000e+11 6.689e+10
+ 11   4 5.000e+07  16.290 119.110   2.140   7.443 1.126400e+12 6.915e+10
+ 11   5 5.000e+07  19.940 148.730   2.440   7.581 1.408000e+12 7.061e+10
+ 11   6 5.000e+07  23.800 178.620   2.790   7.622 1.689600e+12 7.099e+10
+ 11   7 5.000e+07  27.480 208.510   3.160   7.703 1.971200e+12 7.173e+10
+ 11   8 5.000e+07  31.140 237.820   3.490   7.749 2.252800e+12 7.234e+10
+ 11   9 5.000e+07  34.770 267.390   3.800   7.800 2.534400e+12 7.289e+10
+ 11  10 5.000e+07  38.510 297.250   4.240   7.829 2.816000e+12 7.312e+10
+ 11  11 5.000e+07  42.080 326.570   4.610   7.870 3.097600e+12 7.361e+10
+ 11  12 5.000e+07  45.860 356.540   4.590   7.875 3.379200e+12 7.369e+10
+ 11  13 5.000e+07  49.570 386.250   5.150   7.896 3.660800e+12 7.385e+10
+ 11  14 5.000e+07  53.220 415.630   5.360   7.910 3.942400e+12 7.408e+10
+ 11  15 5.000e+07  57.000 445.200   5.870   7.914 4.224000e+12 7.411e+10
+ 11  16 5.000e+07  60.800 474.810   6.250   7.912 4.505600e+12 7.411e+10
+ 12   1 5.000e+07   5.600  32.770   1.240   6.073 3.072000e+11 5.486e+10
+ 12   2 5.000e+07  10.220  65.660   1.600   6.581 6.144000e+11 6.012e+10
+ 12   3 5.000e+07  13.680  97.900   2.000   7.303 9.216000e+11 6.737e+10
+ 12   4 5.000e+07  17.790 129.710   2.330   7.422 1.228800e+12 6.907e+10
+ 12   5 5.000e+07  21.770 162.420   2.700   7.585 1.536000e+12 7.056e+10
+ 12   6 5.000e+07  25.770 194.770   3.090   7.678 1.843200e+12 7.153e+10
+ 12   7 5.000e+07  29.940 227.290   3.390   7.705 2.150400e+12 7.182e+10
+ 12   8 5.000e+07  34.030 259.370   3.860   7.735 2.457600e+12 7.222e+10
+ 12   9 5.000e+07  38.070 291.890   4.310   7.780 2.764800e+12 7.262e+10
+ 12  10 5.000e+07  42.080 324.370   4.660   7.819 3.072000e+12 7.300e+10
+ 12  11 5.000e+07  45.950 356.370   5.000   7.864 3.379200e+12 7.354e+10
+ 12  12 5.000e+07  49.960 388.790   5.250   7.887 3.686400e+12 7.379e+10
+ 12  13 5.000e+07  54.010 422.050   5.420   7.915 3.993600e+12 7.394e+10
+ 12  14 5.000e+07  58.010 453.330   6.120   7.920 4.300800e+12 7.414e+10
+ 12  15 5.000e+07  62.080 485.830   6.310   7.928 4.608000e+12 7.423e+10
+ 12  16 5.000e+07  66.200 518.060   6.780   7.928 4.915200e+12 7.425e+10
+ 13   1 5.000e+07   5.630  35.420   1.300   6.522 3.328000e+11 5.911e+10
+ 13   2 5.000e+07  10.730  71.050   1.830   6.792 6.656000e+11 6.203e+10
+ 13   3 5.000e+07  14.690 105.710   2.160   7.343 9.984000e+11 6.796e+10
+ 13   4 5.000e+07  19.120 140.630   2.510   7.486 1.331200e+12 6.962e+10
+ 13   5 5.000e+07  23.600 175.730   3.000   7.573 1.664000e+12 7.051e+10
+ 13   6 5.000e+07  27.910 211.000   3.350   7.680 1.996800e+12 7.154e+10
+ 13   7 5.000e+07  32.370 246.320   3.860   7.729 2.329600e+12 7.197e+10
+ 13   8 5.000e+07  36.790 281.150   4.260   7.758 2.662400e+12 7.237e+10
+ 13   9 5.000e+07  41.080 316.080   4.520   7.804 2.995200e+12 7.291e+10
+ 13  10 5.000e+07  45.600 352.020   5.090   7.831 3.328000e+12 7.298e+10
+ 13  11 5.000e+07  49.760 386.130   5.470   7.870 3.660800e+12 7.357e+10
+ 13  12 5.000e+07  54.080 421.160   5.780   7.895 3.993600e+12 7.385e+10
+ 13  13 5.000e+07  58.520 455.980   6.170   7.897 4.326400e+12 7.393e+10
+ 13  14 5.000e+07  63.000 491.340   6.710   7.906 4.659200e+12 7.396e+10
+ 13  15 5.000e+07  67.250 525.920   6.920   7.923 4.992000e+12 7.423e+10
+ 13  16 5.000e+07  72.090 560.640   7.160   7.876 5.324800e+12 7.386e+10
+ 14   1 5.000e+07   5.670  38.290   1.330   6.988 3.584000e+11 6.321e+10
+ 14   2 5.000e+07  10.850  75.880   1.940   7.172 7.168000e+11 6.606e+10
+ 14   3 5.000e+07  15.840 114.160   2.400   7.359 1.075200e+12 6.788e+10
+ 14   4 5.000e+07  20.610 151.540   2.710   7.484 1.433600e+12 6.956e+10
+ 14   5 5.000e+07  25.330 189.160   3.320   7.599 1.792000e+12 7.075e+10
+ 14   6 5.000e+07  30.160 227.510   3.670   7.665 2.150400e+12 7.130e+10
+ 14   7 5.000e+07  34.730 265.020   3.960   7.745 2.508800e+12 7.224e+10
+ 14   8 5.000e+07  39.530 302.550   4.640   7.771 2.867200e+12 7.253e+10
+ 14   9 5.000e+07  44.220 340.330   5.180   7.813 3.225600e+12 7.294e+10
+ 14  10 5.000e+07  48.800 378.180   5.430   7.861 3.584000e+12 7.344e+10
+ 14  11 5.000e+07  53.550 415.790   5.800   7.873 3.942400e+12 7.362e+10
+ 14  12 5.000e+07  58.250 453.340   6.430   7.893 4.300800e+12 7.383e+10
+ 14  13 5.000e+07  63.150 492.200   6.960   7.904 4.659200e+12 7.378e+10
+ 14  14 5.000e+07  67.850 528.470   6.970   7.892 5.017600e+12 7.395e+10
+ 14  15 5.000e+07  72.510 566.950   7.720   7.925 5.376000e+12 7.414e+10
+ 14  16 5.000e+07  77.230 604.250   8.170   7.930 5.734400e+12 7.425e+10
+ 15   1 5.000e+07   5.800  41.070   1.460   7.333 3.840000e+11 6.621e+10
+ 15   2 5.000e+07  11.900  80.380   2.190   6.939 7.680000e+11 6.454e+10
+ 15   3 5.000e+07  16.990 121.790   2.610   7.322 1.152000e+12 6.780e+10
+ 15   4 5.000e+07  22.040 162.330   3.030   7.503 1.536000e+12 6.969e+10
+ 15   5 5.000e+07  27.120 202.750   3.460   7.604 1.920000e+12 7.080e+10
+ 15   6 5.000e+07  32.290 243.420   3.870   7.658 2.304000e+12 7.135e+10
+ 15   7 5.000e+07  37.450 284.300   4.410   7.709 2.688000e+12 7.178e+10
+ 15   8 5.000e+07  42.560 323.740   4.890   7.722 3.072000e+12 7.218e+10
+ 15   9 5.000e+07  47.440 364.880   5.330   7.804 3.456000e+12 7.285e+10
+ 15  10 5.000e+07  52.440 405.400   5.750   7.840 3.840000e+12 7.323e+10
+ 15  11 5.000e+07  57.270 445.500   6.070   7.885 4.224000e+12 7.376e+10
+ 15  12 5.000e+07  62.450 485.920   6.770   7.889 4.608000e+12 7.379e+10
+ 15  13 5.000e+07  67.680 527.540   7.440   7.905 4.992000e+12 7.376e+10
+ 15  14 5.000e+07  72.740 566.990   7.790   7.902 5.376000e+12 7.391e+10
+ 15  15 5.000e+07  77.760 607.620   8.060   7.918 5.760000e+12 7.407e+10
+ 15  16 5.000e+07  82.750 647.630   8.640   7.931 6.144000e+12 7.425e+10
+ 16   1 5.000e+07   6.310  43.540   1.790   7.184 4.096000e+11 6.491e+10
+ 16   2 5.000e+07  12.340  87.310   2.190   7.253 8.192000e+11 6.639e+10
+ 16   3 5.000e+07  17.930 130.440   2.830   7.433 1.228800e+12 6.853e+10
+ 16   4 5.000e+07  23.530 173.540   3.140   7.509 1.638400e+12 6.963e+10
+ 16   5 5.000e+07  28.910 216.290   3.710   7.610 2.048000e+12 7.084e+10
+ 16   6 5.000e+07  34.310 259.400   4.260   7.685 2.457600e+12 7.163e+10
+ 16   7 5.000e+07  39.790 302.740   4.620   7.725 2.867200e+12 7.206e+10
+ 16   8 5.000e+07  44.970 346.250   5.340   7.818 3.276800e+12 7.287e+10
+ 16   9 5.000e+07  50.470 388.870   5.910   7.822 3.686400e+12 7.304e+10
+ 16  10 5.000e+07  55.890 432.480   6.140   7.848 4.096000e+12 7.329e+10
+ 16  11 5.000e+07  61.250 475.380   6.770   7.872 4.505600e+12 7.356e+10
+ 16  12 5.000e+07  66.670 518.940   7.160   7.891 4.915200e+12 7.372e+10
+ 16  13 5.000e+07  72.160 562.230   7.890   7.901 5.324800e+12 7.379e+10
+ 16  14 5.000e+07  77.600 604.950   8.230   7.902 5.734400e+12 7.390e+10
+ 16  15 5.000e+07  82.970 648.420   8.690   7.920 6.144000e+12 7.405e+10
+ 16  16 5.000e+07  88.370 690.730   9.460   7.923 6.553600e+12 7.416e+10
diff --git a/gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat
new file mode 100644 (file)
index 0000000..d0b8148
--- /dev/null
@@ -0,0 +1,65 @@
+#D JS21 4-core PPC970M 2.5 GHz (using Altivec)
+  1   1 9.766e+07   9.820  10.210   0.360   1.076 5.000000e+10 5.092e+09
+  1   2 9.766e+07  10.620  19.890   0.640   1.933 1.000000e+11 9.416e+09
+  1   3 9.766e+07  10.310  29.590   0.610   2.929 1.500000e+11 1.455e+10
+  1   4 9.766e+07  10.440  39.290   0.680   3.829 2.000000e+11 1.916e+10
+  1   5 7.812e+07  15.730  39.150   0.590   2.526 2.000000e+11 1.271e+10
+  1   6 6.510e+07  13.100  39.080   0.590   3.028 2.000000e+11 1.527e+10
+  1   7 5.580e+07  11.550  39.030   0.500   3.423 2.000000e+11 1.732e+10
+  1   8 4.883e+07  10.410  39.010   0.510   3.796 2.000000e+11 1.921e+10
+  2   1 9.766e+07  10.080  20.070   0.700   2.061 1.000000e+11 9.921e+09
+  2   2 9.766e+07  11.360  39.650   0.960   3.575 2.000000e+11 1.761e+10
+  2   3 6.510e+07  13.120  39.270   0.740   3.050 2.000000e+11 1.524e+10
+  2   4 4.883e+07  10.410  39.110   0.650   3.819 2.000000e+11 1.921e+10
+  2   5 3.906e+07  11.030  39.080   0.610   3.598 2.000000e+11 1.813e+10
+  2   6 3.255e+07  10.640  39.020   0.560   3.720 2.000000e+11 1.880e+10
+  2   7 2.790e+07  10.510  38.980   0.550   3.761 2.000000e+11 1.903e+10
+  2   8 2.441e+07  10.440  38.970   0.570   3.787 2.000000e+11 1.916e+10
+  3   1 9.766e+07  12.130  29.970   0.920   2.547 1.500000e+11 1.237e+10
+  3   2 6.510e+07  13.100  39.300   0.920   3.070 2.000000e+11 1.527e+10
+  3   3 4.340e+07  11.400  39.200   0.760   3.505 2.000000e+11 1.754e+10
+  3   4 3.255e+07  10.730  39.100   0.690   3.708 2.000000e+11 1.864e+10
+  3   5 2.604e+07  10.470  39.010   0.620   3.785 2.000000e+11 1.910e+10
+  3   6 2.170e+07  10.380  39.010   0.620   3.818 2.000000e+11 1.927e+10
+  3   7 1.860e+07  10.280  39.120   0.580   3.862 2.000000e+11 1.946e+10
+  3   8 1.628e+07  10.230  39.000   0.600   3.871 2.000000e+11 1.955e+10
+  4   1 9.766e+07  10.700  39.990   1.540   3.881 2.000000e+11 1.869e+10
+  4   2 4.883e+07  10.530  39.260   0.940   3.818 2.000000e+11 1.899e+10
+  4   3 3.255e+07  10.840  39.140   0.760   3.681 2.000000e+11 1.845e+10
+  4   4 2.441e+07  10.530  39.040   0.680   3.772 2.000000e+11 1.899e+10
+  4   5 1.953e+07  10.380  39.030   0.650   3.823 2.000000e+11 1.927e+10
+  4   6 1.628e+07  10.310  39.020   0.650   3.848 2.000000e+11 1.940e+10
+  4   7 1.395e+07  10.160  38.980   0.620   3.898 2.000000e+11 1.969e+10
+  4   8 1.221e+07  10.150  38.990   0.580   3.899 2.000000e+11 1.970e+10
+  5   1 7.812e+07  14.750  39.780   1.470   2.797 2.000000e+11 1.356e+10
+  5   2 3.906e+07  11.350  39.240   0.950   3.541 2.000000e+11 1.762e+10
+  5   3 2.604e+07  10.720  39.120   0.800   3.724 2.000000e+11 1.866e+10
+  5   4 1.953e+07  10.440  39.060   0.730   3.811 2.000000e+11 1.916e+10
+  5   5 1.562e+07  10.410  39.060   0.690   3.818 2.000000e+11 1.921e+10
+  5   6 1.302e+07  10.260  38.970   0.650   3.862 2.000000e+11 1.949e+10
+  5   7 1.116e+07  10.270  39.020   0.650   3.863 2.000000e+11 1.947e+10
+  5   8 9.766e+06  10.130  39.010   0.660   3.916 2.000000e+11 1.974e+10
+  6   1 6.510e+07  12.850  39.730   1.450   3.205 2.000000e+11 1.556e+10
+  6   2 3.255e+07  10.700  39.300   0.990   3.765 2.000000e+11 1.869e+10
+  6   3 2.170e+07  10.770  39.110   0.810   3.707 2.000000e+11 1.857e+10
+  6   4 1.628e+07  10.570  39.090   0.750   3.769 2.000000e+11 1.892e+10
+  6   5 1.302e+07  10.310  39.040   0.690   3.854 2.000000e+11 1.940e+10
+  6   6 1.085e+07  10.260  39.030   0.700   3.872 2.000000e+11 1.949e+10
+  6   7 9.301e+06  10.170  39.020   0.680   3.904 2.000000e+11 1.967e+10
+  6   8 8.138e+06  10.150  39.020   0.670   3.910 2.000000e+11 1.970e+10
+  7   1 5.580e+07  11.440  39.730   1.500   3.604 2.000000e+11 1.748e+10
+  7   2 2.790e+07  10.950  39.260   0.990   3.676 2.000000e+11 1.826e+10
+  7   3 1.860e+07  10.620  39.140   0.860   3.766 2.000000e+11 1.883e+10
+  7   4 1.395e+07  10.420  39.070   0.750   3.821 2.000000e+11 1.919e+10
+  7   5 1.116e+07  10.290  39.040   0.710   3.863 2.000000e+11 1.944e+10
+  7   6 9.301e+06  10.200  39.040   0.720   3.898 2.000000e+11 1.961e+10
+  7   7 7.972e+06  10.210  39.020   0.670   3.887 2.000000e+11 1.959e+10
+  7   8 6.975e+06  10.160  39.020   0.650   3.905 2.000000e+11 1.969e+10
+  8   1 4.883e+07  10.870  39.950   1.520   3.815 2.000000e+11 1.840e+10
+  8   2 2.441e+07  10.690  39.270   1.000   3.767 2.000000e+11 1.871e+10
+  8   3 1.628e+07  10.540  39.130   0.860   3.794 2.000000e+11 1.898e+10
+  8   4 1.221e+07  10.410  39.110   0.790   3.833 2.000000e+11 1.921e+10
+  8   5 9.766e+06  10.230  39.040   0.710   3.886 2.000000e+11 1.955e+10
+  8   6 8.138e+06  10.260  39.050   0.700   3.874 2.000000e+11 1.949e+10
+  8   7 6.975e+06  10.220  39.100   0.690   3.893 2.000000e+11 1.957e+10
+  8   8 6.104e+06  10.170  39.020   0.650   3.901 2.000000e+11 1.967e+10
diff --git a/gnuradio-examples/python/mp-sched/perf-data/js21.dat b/gnuradio-examples/python/mp-sched/perf-data/js21.dat
new file mode 100644 (file)
index 0000000..a23bceb
--- /dev/null
@@ -0,0 +1,65 @@
+#D JS21 4-core PPC970MP 2.5 GHz
+  1   1 5.273e+07  10.050  10.180   0.290   1.042 2.700000e+10 2.687e+09
+  1   2 5.273e+07  10.240  20.210   0.260   1.999 5.400000e+10 5.273e+09
+  1   3 5.273e+07  10.300  30.090   0.340   2.954 8.100000e+10 7.864e+09
+  1   4 5.273e+07  10.490  40.120   0.490   3.871 1.080000e+11 1.030e+10
+  1   5 4.219e+07  16.010  39.900   0.380   2.516 1.080000e+11 6.746e+09
+  1   6 3.516e+07  13.360  39.920   0.370   3.016 1.080000e+11 8.084e+09
+  1   7 3.013e+07  11.510  39.900   0.330   3.495 1.080000e+11 9.383e+09
+  1   8 2.637e+07  10.420  39.880   0.320   3.858 1.080000e+11 1.036e+10
+  2   1 5.273e+07  10.370  20.340   0.470   2.007 5.400000e+10 5.207e+09
+  2   2 5.273e+07  10.320  40.080   0.550   3.937 1.080000e+11 1.047e+10
+  2   3 3.516e+07  13.340  39.990   0.470   3.033 1.080000e+11 8.096e+09
+  2   4 2.637e+07  10.480  39.970   0.400   3.852 1.080000e+11 1.031e+10
+  2   5 2.109e+07  10.910  39.920   0.390   3.695 1.080000e+11 9.899e+09
+  2   6 1.758e+07  10.610  39.860   0.360   3.791 1.080000e+11 1.018e+10
+  2   7 1.507e+07  10.520  39.890   0.360   3.826 1.080000e+11 1.027e+10
+  2   8 1.318e+07  10.470  39.980   0.350   3.852 1.080000e+11 1.032e+10
+  3   1 5.273e+07  10.230  30.320   0.600   3.022 8.100000e+10 7.918e+09
+  3   2 3.516e+07  13.250  40.050   0.560   3.065 1.080000e+11 8.151e+09
+  3   3 2.344e+07  11.160  40.010   0.470   3.627 1.080000e+11 9.677e+09
+  3   4 1.758e+07  10.710  39.950   0.420   3.769 1.080000e+11 1.008e+10
+  3   5 1.406e+07  10.520  39.920   0.400   3.833 1.080000e+11 1.027e+10
+  3   6 1.172e+07  10.420  39.880   0.380   3.864 1.080000e+11 1.036e+10
+  3   7 1.004e+07  10.340  39.880   0.370   3.893 1.080000e+11 1.044e+10
+  3   8 8.789e+06  10.380  39.960   0.380   3.886 1.080000e+11 1.040e+10
+  4   1 5.273e+07  10.570  40.390   0.890   3.905 1.080000e+11 1.022e+10
+  4   2 2.637e+07  10.690  40.020   0.560   3.796 1.080000e+11 1.010e+10
+  4   3 1.758e+07  10.790  39.980   0.480   3.750 1.080000e+11 1.001e+10
+  4   4 1.318e+07  10.570  39.950   0.430   3.820 1.080000e+11 1.022e+10
+  4   5 1.055e+07  10.440  39.950   0.420   3.867 1.080000e+11 1.034e+10
+  4   6 8.789e+06  10.340  39.900   0.420   3.899 1.080000e+11 1.044e+10
+  4   7 7.533e+06  10.290  39.870   0.410   3.914 1.080000e+11 1.050e+10
+  4   8 6.592e+06  10.270  39.950   0.390   3.928 1.080000e+11 1.052e+10
+  5   1 4.219e+07  15.110  40.290   0.830   2.721 1.080000e+11 7.148e+09
+  5   2 2.109e+07  11.240  40.000   0.580   3.610 1.080000e+11 9.609e+09
+  5   3 1.406e+07  10.710  39.970   0.490   3.778 1.080000e+11 1.008e+10
+  5   4 1.055e+07  10.490  39.980   0.460   3.855 1.080000e+11 1.030e+10
+  5   5 8.438e+06  10.430  39.940   0.440   3.872 1.080000e+11 1.035e+10
+  5   6 7.031e+06  10.280  39.890   0.420   3.921 1.080000e+11 1.051e+10
+  5   7 6.027e+06  10.290  39.870   0.400   3.914 1.080000e+11 1.050e+10
+  5   8 5.273e+06  10.290  39.940   0.400   3.920 1.080000e+11 1.050e+10
+  6   1 3.516e+07  12.880  40.250   0.850   3.191 1.080000e+11 8.385e+09
+  6   2 1.758e+07  10.730  39.980   0.580   3.780 1.080000e+11 1.007e+10
+  6   3 1.172e+07  10.740  39.980   0.490   3.768 1.080000e+11 1.006e+10
+  6   4 8.789e+06  10.510  39.940   0.460   3.844 1.080000e+11 1.028e+10
+  6   5 7.031e+06  10.430  39.920   0.450   3.871 1.080000e+11 1.035e+10
+  6   6 5.859e+06  10.300  39.910   0.430   3.917 1.080000e+11 1.049e+10
+  6   7 5.022e+06  10.290  39.870   0.420   3.915 1.080000e+11 1.050e+10
+  6   8 4.395e+06  10.300  39.950   0.420   3.919 1.080000e+11 1.049e+10
+  7   1 3.013e+07  11.240  40.270   0.860   3.659 1.080000e+11 9.609e+09
+  7   2 1.507e+07  11.040  40.000   0.590   3.677 1.080000e+11 9.783e+09
+  7   3 1.004e+07  10.660  39.970   0.520   3.798 1.080000e+11 1.013e+10
+  7   4 7.533e+06  10.430  39.930   0.470   3.873 1.080000e+11 1.035e+10
+  7   5 6.027e+06  10.390  39.920   0.470   3.887 1.080000e+11 1.039e+10
+  7   6 5.022e+06  10.320  39.910   0.430   3.909 1.080000e+11 1.047e+10
+  7   7 4.305e+06  10.330  39.890   0.420   3.902 1.080000e+11 1.045e+10
+  7   8 3.767e+06  10.300  39.930   0.420   3.917 1.080000e+11 1.049e+10
+  8   1 2.637e+07  10.530  40.290   0.910   3.913 1.080000e+11 1.026e+10
+  8   2 1.318e+07  10.850  40.040   0.610   3.747 1.080000e+11 9.954e+09
+  8   3 8.789e+06  10.500  39.960   0.540   3.857 1.080000e+11 1.029e+10
+  8   4 6.592e+06  10.490  39.960   0.500   3.857 1.080000e+11 1.030e+10
+  8   5 5.273e+06  10.330  39.930   0.480   3.912 1.080000e+11 1.045e+10
+  8   6 4.395e+06  10.340  39.900   0.450   3.902 1.080000e+11 1.044e+10
+  8   7 3.767e+06  10.260  39.900   0.430   3.931 1.080000e+11 1.053e+10
+  8   8 3.296e+06  10.250  39.960   0.430   3.940 1.080000e+11 1.054e+10
diff --git a/gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat
new file mode 100644 (file)
index 0000000..dd01b31
--- /dev/null
@@ -0,0 +1,65 @@
+#D Playstation 3 (using Altivec)
+  1   1 3.906e+07  10.500  10.580   0.440   1.050 2.000000e+10 1.905e+09
+  1   2 1.953e+07   7.010  13.200   0.400   1.940 2.000000e+10 2.853e+09
+  1   3 1.302e+07   7.540  13.140   0.380   1.793 2.000000e+10 2.653e+09
+  1   4 9.766e+06   7.200  13.620   0.370   1.943 2.000000e+10 2.778e+09
+  1   5 7.812e+06   7.170  13.670   0.340   1.954 2.000000e+10 2.789e+09
+  1   6 6.510e+06   7.010  13.590   0.320   1.984 2.000000e+10 2.853e+09
+  1   7 5.580e+06   6.990  13.530   0.330   1.983 2.000000e+10 2.861e+09
+  1   8 4.883e+06   6.980  13.490   0.320   1.979 2.000000e+10 2.865e+09
+  2   1 1.953e+07   8.110  14.730   0.530   1.882 2.000000e+10 2.466e+09
+  2   2 9.766e+06   7.090  13.570   0.420   1.973 2.000000e+10 2.821e+09
+  2   3 6.510e+06   7.040  13.590   0.410   1.989 2.000000e+10 2.841e+09
+  2   4 4.883e+06   6.990  13.490   0.370   1.983 2.000000e+10 2.861e+09
+  2   5 3.906e+06   6.970  13.480   0.360   1.986 2.000000e+10 2.869e+09
+  2   6 3.255e+06   6.990  13.530   0.370   1.989 2.000000e+10 2.861e+09
+  2   7 2.790e+06   6.890  13.390   0.350   1.994 2.000000e+10 2.903e+09
+  2   8 2.441e+06   6.880  13.380   0.350   1.996 2.000000e+10 2.907e+09
+  3   1 1.302e+07   8.220  13.720   0.510   1.731 2.000000e+10 2.433e+09
+  3   2 6.510e+06   7.050  13.480   0.450   1.976 2.000000e+10 2.837e+09
+  3   3 4.340e+06   6.990  13.460   0.400   1.983 2.000000e+10 2.861e+09
+  3   4 3.255e+06   6.990  13.550   0.380   1.993 2.000000e+10 2.861e+09
+  3   5 2.604e+06   6.920  13.430   0.360   1.993 1.999999e+10 2.890e+09
+  3   6 2.170e+06   6.940  13.460   0.360   1.991 1.999999e+10 2.882e+09
+  3   7 1.860e+06   6.920  13.440   0.360   1.994 2.000000e+10 2.890e+09
+  3   8 1.628e+06   6.890  13.380   0.350   1.993 2.000000e+10 2.903e+09
+  4   1 9.766e+06   7.620  14.550   0.590   1.987 2.000000e+10 2.625e+09
+  4   2 4.883e+06   7.010  13.460   0.440   1.983 2.000000e+10 2.853e+09
+  4   3 3.255e+06   7.040  13.580   0.410   1.987 2.000000e+10 2.841e+09
+  4   4 2.441e+06   6.960  13.470   0.390   1.991 2.000000e+10 2.874e+09
+  4   5 1.953e+06   6.920  13.410   0.370   1.991 2.000000e+10 2.890e+09
+  4   6 1.628e+06   6.950  13.490   0.370   1.994 2.000000e+10 2.878e+09
+  4   7 1.395e+06   6.890  13.350   0.370   1.991 2.000000e+10 2.903e+09
+  4   8 1.221e+06   6.940  13.490   0.360   1.996 2.000000e+10 2.882e+09
+  5   1 7.812e+06   7.680  14.000   0.560   1.896 2.000000e+10 2.604e+09
+  5   2 3.906e+06   7.070  13.460   0.460   1.969 2.000000e+10 2.829e+09
+  5   3 2.604e+06   6.990  13.430   0.420   1.981 1.999999e+10 2.861e+09
+  5   4 1.953e+06   7.010  13.550   0.390   1.989 2.000000e+10 2.853e+09
+  5   5 1.562e+06   6.920  13.430   0.380   1.996 2.000000e+10 2.890e+09
+  5   6 1.302e+06   6.920  13.410   0.380   1.993 1.999999e+10 2.890e+09
+  5   7 1.116e+06   6.920  13.420   0.370   1.993 1.999999e+10 2.890e+09
+  5   8 9.766e+05   6.910  13.360   0.370   1.987 1.999999e+10 2.894e+09
+  6   1 6.510e+06   7.350  13.970   0.630   1.986 2.000000e+10 2.721e+09
+  6   2 3.255e+06   7.040  13.470   0.470   1.980 2.000000e+10 2.841e+09
+  6   3 2.170e+06   7.050  13.600   0.420   1.989 1.999999e+10 2.837e+09
+  6   4 1.628e+06   6.970  13.480   0.400   1.991 2.000000e+10 2.869e+09
+  6   5 1.302e+06   6.990  13.540   0.390   1.993 1.999999e+10 2.861e+09
+  6   6 1.085e+06   6.970  13.470   0.380   1.987 1.999999e+10 2.869e+09
+  6   7 9.301e+05   6.890  13.350   0.380   1.993 1.999999e+10 2.903e+09
+  6   8 8.138e+05   6.920  13.420   0.370   1.993 2.000000e+10 2.890e+09
+  7   1 5.580e+06   7.530  14.030   0.580   1.940 2.000000e+10 2.656e+09
+  7   2 2.790e+06   7.000  13.370   0.460   1.976 2.000000e+10 2.857e+09
+  7   3 1.860e+06   7.000  13.520   0.420   1.991 2.000000e+10 2.857e+09
+  7   4 1.395e+06   7.060  13.590   0.410   1.983 2.000000e+10 2.833e+09
+  7   5 1.116e+06   6.950  13.460   0.390   1.993 1.999999e+10 2.878e+09
+  7   6 9.301e+05   6.950  13.420   0.380   1.986 1.999999e+10 2.878e+09
+  7   7 7.972e+05   6.880  13.300   0.380   1.988 1.999998e+10 2.907e+09
+  7   8 6.975e+05   6.920  13.390   0.380   1.990 1.999998e+10 2.890e+09
+  8   1 4.883e+06   7.440  14.150   0.620   1.985 2.000000e+10 2.688e+09
+  8   2 2.441e+06   6.990  13.400   0.480   1.986 2.000000e+10 2.861e+09
+  8   3 1.628e+06   6.990  13.460   0.430   1.987 2.000000e+10 2.861e+09
+  8   4 1.221e+06   7.020  13.550   0.410   1.989 2.000000e+10 2.849e+09
+  8   5 9.766e+05   6.920  13.370   0.390   1.988 1.999999e+10 2.890e+09
+  8   6 8.138e+05   6.950  13.400   0.390   1.984 2.000000e+10 2.878e+09
+  8   7 6.975e+05   6.930  13.360   0.390   1.984 1.999998e+10 2.886e+09
+  8   8 6.104e+05   6.920  13.390   0.380   1.990 1.999998e+10 2.890e+09
diff --git a/gnuradio-examples/python/mp-sched/perf-data/ps3.dat b/gnuradio-examples/python/mp-sched/perf-data/ps3.dat
new file mode 100644 (file)
index 0000000..c9bac37
--- /dev/null
@@ -0,0 +1,65 @@
+#D Playstation 3
+  1   1 2.344e+07   9.970   9.960   0.280   1.027 1.200000e+10 1.204e+09
+  1   2 1.172e+07  12.590  24.430   0.400   1.972 1.200000e+10 9.531e+08
+  1   3 7.812e+06  12.200  22.790   0.360   1.898 1.200000e+10 9.836e+08
+  1   4 5.859e+06  12.450  24.440   0.360   1.992 1.200000e+10 9.639e+08
+  1   5 4.688e+06  12.390  24.100   0.360   1.974 1.200000e+10 9.685e+08
+  1   6 3.906e+06  12.360  24.200   0.370   1.988 1.200000e+10 9.709e+08
+  1   7 3.348e+06  12.460  24.390   0.360   1.986 1.200000e+10 9.631e+08
+  1   8 2.930e+06  12.440  24.400   0.360   1.990 1.200000e+10 9.646e+08
+  2   1 1.172e+07  12.580  24.660   0.490   1.999 1.200000e+10 9.539e+08
+  2   2 5.859e+06  12.480  24.290   0.420   1.980 1.200000e+10 9.615e+08
+  2   3 3.906e+06  12.500  24.500   0.400   1.992 1.200000e+10 9.600e+08
+  2   4 2.930e+06  12.440  24.400   0.390   1.993 1.200000e+10 9.646e+08
+  2   5 2.344e+06  12.500  24.510   0.380   1.991 1.200000e+10 9.600e+08
+  2   6 1.953e+06  12.450  24.480   0.380   1.997 1.200000e+10 9.639e+08
+  2   7 1.674e+06  12.450  24.430   0.380   1.993 1.200000e+10 9.639e+08
+  2   8 1.465e+06  12.430  24.450   0.380   1.998 1.199999e+10 9.654e+08
+  3   1 7.812e+06  12.280  23.600   0.460   1.959 1.200000e+10 9.772e+08
+  3   2 3.906e+06  12.690  24.760   0.430   1.985 1.200000e+10 9.456e+08
+  3   3 2.604e+06  12.610  24.700   0.410   1.991 1.200000e+10 9.516e+08
+  3   4 1.953e+06  12.440  24.410   0.400   1.994 1.200000e+10 9.646e+08
+  3   5 1.562e+06  12.400  24.370   0.380   1.996 1.200000e+10 9.677e+08
+  3   6 1.302e+06  12.440  24.450   0.380   1.996 1.200000e+10 9.646e+08
+  3   7 1.116e+06  12.470  24.470   0.380   1.993 1.200000e+10 9.623e+08
+  3   8 9.766e+05  12.440  24.440   0.380   1.995 1.199999e+10 9.646e+08
+  4   1 5.859e+06  12.670  24.710   0.500   1.990 1.200000e+10 9.471e+08
+  4   2 2.930e+06  12.600  24.600   0.440   1.987 1.200000e+10 9.524e+08
+  4   3 1.953e+06  12.490  24.480   0.410   1.993 1.200000e+10 9.608e+08
+  4   4 1.465e+06  12.400  24.340   0.400   1.995 1.199999e+10 9.677e+08
+  4   5 1.172e+06  12.440  24.410   0.390   1.994 1.200000e+10 9.646e+08
+  4   6 9.766e+05  12.440  24.440   0.390   1.996 1.199999e+10 9.646e+08
+  4   7 8.371e+05  12.450  24.420   0.390   1.993 1.199999e+10 9.639e+08
+  4   8 7.324e+05  12.370  24.310   0.380   1.996 1.199999e+10 9.701e+08
+  5   1 4.688e+06  12.890  24.790   0.500   1.962 1.200000e+10 9.310e+08
+  5   2 2.344e+06  12.620  24.680   0.450   1.991 1.200000e+10 9.509e+08
+  5   3 1.562e+06  12.430  24.360   0.410   1.993 1.200000e+10 9.654e+08
+  5   4 1.172e+06  12.420  24.390   0.410   1.997 1.200000e+10 9.662e+08
+  5   5 9.375e+05  12.430  24.380   0.400   1.994 1.200000e+10 9.654e+08
+  5   6 7.812e+05  12.400  24.340   0.400   1.995 1.200000e+10 9.677e+08
+  5   7 6.696e+05  12.360  24.290   0.390   1.997 1.199998e+10 9.709e+08
+  5   8 5.859e+05  12.420  24.370   0.390   1.994 1.199999e+10 9.662e+08
+  6   1 3.906e+06  12.990  25.320   0.560   1.992 1.200000e+10 9.238e+08
+  6   2 1.953e+06  12.610  24.550   0.440   1.982 1.200000e+10 9.516e+08
+  6   3 1.302e+06  12.520  24.310   0.420   1.975 1.200000e+10 9.585e+08
+  6   4 9.766e+05  12.460  24.310   0.420   1.985 1.199999e+10 9.631e+08
+  6   5 7.812e+05  12.440  24.240   0.410   1.982 1.200000e+10 9.646e+08
+  6   6 6.510e+05  12.430  24.170   0.410   1.977 1.199999e+10 9.654e+08
+  6   7 5.580e+05  12.450  24.230   0.410   1.979 1.199998e+10 9.639e+08
+  6   8 4.883e+05  12.490  24.190   0.420   1.970 1.199999e+10 9.608e+08
+  7   1 3.348e+06  13.150  24.280   0.500   1.884 1.200000e+10 9.125e+08
+  7   2 1.674e+06  12.480  24.170   0.430   1.971 1.200000e+10 9.615e+08
+  7   3 1.116e+06  12.480  24.430   0.440   1.993 1.200000e+10 9.615e+08
+  7   4 8.371e+05  12.380  24.270   0.420   1.994 1.199999e+10 9.693e+08
+  7   5 6.696e+05  12.390  24.290   0.430   1.995 1.199998e+10 9.685e+08
+  7   6 5.580e+05  12.430  24.300   0.430   1.990 1.199998e+10 9.654e+08
+  7   7 4.783e+05  12.460  24.360   0.430   1.990 1.199999e+10 9.631e+08
+  7   8 4.185e+05  12.460  24.340   0.430   1.988 1.199998e+10 9.631e+08
+  8   1 2.930e+06  12.960  24.600   0.530   1.939 1.200000e+10 9.259e+08
+  8   2 1.465e+06  12.580  24.240   0.440   1.962 1.199999e+10 9.539e+08
+  8   3 9.766e+05  12.520  24.060   0.430   1.956 1.199999e+10 9.585e+08
+  8   4 7.324e+05  12.420  24.200   0.410   1.981 1.199999e+10 9.662e+08
+  8   5 5.859e+05  12.430  24.310   0.430   1.990 1.199999e+10 9.654e+08
+  8   6 4.883e+05  12.430  24.130   0.420   1.975 1.199999e+10 9.654e+08
+  8   7 4.185e+05  12.800  24.220   0.490   1.930 1.199998e+10 9.375e+08
+  8   8 3.662e+05  12.460  24.340   0.430   1.988 1.199997e+10 9.631e+08
diff --git a/gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat
new file mode 100644 (file)
index 0000000..8364be3
--- /dev/null
@@ -0,0 +1,65 @@
+#D QS21 dual cell 3.2 GHz (using Altivec)
+  1   1 3.516e+07   9.810  10.240   0.430   1.088 1.800000e+10 1.835e+09
+  1   2 3.516e+07  11.650  22.840   0.750   2.025 3.600000e+10 3.090e+09
+  1   3 2.344e+07   9.400  24.860   0.680   2.717 3.600000e+10 3.830e+09
+  1   4 1.758e+07   7.800  26.820   0.740   3.533 3.600000e+10 4.615e+09
+  1   5 1.406e+07   8.810  25.970   0.760   3.034 3.600000e+10 4.086e+09
+  1   6 1.172e+07   8.110  25.710   0.740   3.261 3.600000e+10 4.439e+09
+  1   7 1.004e+07   7.750  26.020   0.710   3.449 3.600000e+10 4.645e+09
+  1   8 8.789e+06   7.290  26.600   0.690   3.743 3.600000e+10 4.938e+09
+  2   1 3.516e+07  10.130  20.690   0.770   2.118 3.600000e+10 3.554e+09
+  2   2 1.758e+07   7.240  26.820   0.920   3.831 3.600000e+10 4.972e+09
+  2   3 1.172e+07   8.090  26.670   0.840   3.400 3.600000e+10 4.450e+09
+  2   4 8.789e+06   7.480  27.010   0.790   3.717 3.600000e+10 4.813e+09
+  2   5 7.031e+06   7.180  26.530   0.740   3.798 3.600000e+10 5.014e+09
+  2   6 5.859e+06   7.060  26.590   0.730   3.870 3.600000e+10 5.099e+09
+  2   7 5.022e+06   7.040  26.610   0.740   3.885 3.600000e+10 5.114e+09
+  2   8 4.395e+06   7.090  27.020   0.730   3.914 3.600000e+10 5.078e+09
+  3   1 2.344e+07   9.670  25.850   1.020   2.779 3.600000e+10 3.723e+09
+  3   2 1.172e+07   7.700  25.940   0.930   3.490 3.600000e+10 4.675e+09
+  3   3 7.812e+06   7.290  26.760   0.830   3.785 3.600000e+10 4.938e+09
+  3   4 5.859e+06   7.210  26.900   0.800   3.842 3.600000e+10 4.993e+09
+  3   5 4.688e+06   7.060  26.690   0.770   3.890 3.600000e+10 5.099e+09
+  3   6 3.906e+06   7.060  26.830   0.810   3.915 3.600000e+10 5.099e+09
+  3   7 3.348e+06   6.960  26.680   0.780   3.945 3.600000e+10 5.172e+09
+  3   8 2.930e+06   6.960  26.600   0.770   3.932 3.599999e+10 5.172e+09
+  4   1 1.758e+07   7.640  28.700   1.250   3.920 3.600000e+10 4.712e+09
+  4   2 8.789e+06   7.230  26.640   0.940   3.815 3.600000e+10 4.979e+09
+  4   3 5.859e+06   7.200  26.800   0.860   3.842 3.600000e+10 5.000e+09
+  4   4 4.395e+06   7.110  26.900   0.840   3.902 3.600000e+10 5.063e+09
+  4   5 3.516e+06   7.020  26.680   0.800   3.915 3.600000e+10 5.128e+09
+  4   6 2.930e+06   6.950  26.700   0.800   3.957 3.599999e+10 5.180e+09
+  4   7 2.511e+06   6.930  26.590   0.800   3.952 3.599999e+10 5.195e+09
+  4   8 2.197e+06   6.960  26.570   0.790   3.931 3.599999e+10 5.172e+09
+  5   1 1.406e+07   8.730  26.540   1.190   3.176 3.600000e+10 4.124e+09
+  5   2 7.031e+06   7.270  26.450   0.960   3.770 3.600000e+10 4.952e+09
+  5   3 4.688e+06   7.100  26.630   0.880   3.875 3.600000e+10 5.070e+09
+  5   4 3.516e+06   7.050  26.700   0.850   3.908 3.600000e+10 5.106e+09
+  5   5 2.812e+06   6.970  26.610   0.830   3.937 3.600000e+10 5.165e+09
+  5   6 2.344e+06   6.980  26.710   0.840   3.947 3.600000e+10 5.158e+09
+  5   7 2.009e+06   6.900  26.470   0.800   3.952 3.599999e+10 5.217e+09
+  5   8 1.758e+06   6.940  26.580   0.820   3.948 3.599999e+10 5.187e+09
+  6   1 1.172e+07   8.200  26.510   1.190   3.378 3.600000e+10 4.390e+09
+  6   2 5.859e+06   7.210  26.590   0.970   3.822 3.600000e+10 4.993e+09
+  6   3 3.906e+06   7.070  26.580   0.910   3.888 3.600000e+10 5.092e+09
+  6   4 2.930e+06   7.090  26.750   0.860   3.894 3.599999e+10 5.078e+09
+  6   5 2.344e+06   7.040  26.830   0.830   3.929 3.600000e+10 5.114e+09
+  6   6 1.953e+06   6.960  26.600   0.830   3.941 3.600000e+10 5.172e+09
+  6   7 1.674e+06   6.940  26.500   0.810   3.935 3.600000e+10 5.187e+09
+  6   8 1.465e+06   6.940  26.540   0.830   3.944 3.599998e+10 5.187e+09
+  7   1 1.004e+07   7.730  26.940   1.190   3.639 3.600000e+10 4.657e+09
+  7   2 5.022e+06   7.240  26.600   0.980   3.809 3.600000e+10 4.972e+09
+  7   3 3.348e+06   7.120  26.680   0.930   3.878 3.600000e+10 5.056e+09
+  7   4 2.511e+06   7.070  26.840   0.890   3.922 3.599999e+10 5.092e+09
+  7   5 2.009e+06   6.980  26.570   0.850   3.928 3.599999e+10 5.158e+09
+  7   6 1.674e+06   6.950  26.530   0.840   3.938 3.600000e+10 5.180e+09
+  7   7 1.435e+06   6.940  26.570   0.860   3.952 3.599998e+10 5.187e+09
+  7   8 1.256e+06   6.980  26.590   0.840   3.930 3.599999e+10 5.158e+09
+  8   1 8.789e+06   7.570  27.360   1.260   3.781 3.600000e+10 4.756e+09
+  8   2 4.395e+06   7.130  26.460   0.980   3.849 3.600000e+10 5.049e+09
+  8   3 2.930e+06   7.060  26.680   0.920   3.909 3.599999e+10 5.099e+09
+  8   4 2.197e+06   7.040  26.670   0.880   3.913 3.599999e+10 5.114e+09
+  8   5 1.758e+06   6.970  26.600   0.860   3.940 3.599999e+10 5.165e+09
+  8   6 1.465e+06   6.940  26.490   0.840   3.938 3.599998e+10 5.187e+09
+  8   7 1.256e+06   6.980  26.630   0.850   3.937 3.599999e+10 5.158e+09
+  8   8 1.099e+06   7.010  26.820   0.860   3.949 3.599997e+10 5.136e+09
diff --git a/gnuradio-examples/python/mp-sched/perf-data/qs21.dat b/gnuradio-examples/python/mp-sched/perf-data/qs21.dat
new file mode 100644 (file)
index 0000000..cc62874
--- /dev/null
@@ -0,0 +1,65 @@
+#D QS21 dual cell 3.2 GHz
+  1   1 1.953e+07   8.480   8.730   0.270   1.061 1.000000e+10 1.179e+09
+  1   2 1.953e+07   8.750  17.210   0.460   2.019 2.000000e+10 2.286e+09
+  1   3 1.302e+07  12.390  29.530   0.540   2.427 2.000000e+10 1.614e+09
+  1   4 9.766e+06  10.120  31.500   0.590   3.171 2.000000e+10 1.976e+09
+  1   5 7.812e+06  10.200  31.350   0.610   3.133 2.000000e+10 1.961e+09
+  1   6 6.510e+06   9.520  31.690   0.590   3.391 2.000000e+10 2.101e+09
+  1   7 5.580e+06   9.430  32.610   0.600   3.522 2.000000e+10 2.121e+09
+  1   8 4.883e+06   9.400  34.160   0.620   3.700 2.000000e+10 2.128e+09
+  2   1 1.953e+07   8.800  17.750   0.500   2.074 2.000000e+10 2.273e+09
+  2   2 9.766e+06   8.990  28.900   0.640   3.286 2.000000e+10 2.225e+09
+  2   3 6.510e+06   9.390  32.450   0.660   3.526 2.000000e+10 2.130e+09
+  2   4 4.883e+06   9.220  34.450   0.660   3.808 2.000000e+10 2.169e+09
+  2   5 3.906e+06   9.180  34.730   0.650   3.854 2.000000e+10 2.179e+09
+  2   6 3.255e+06   9.150  34.960   0.650   3.892 2.000000e+10 2.186e+09
+  2   7 2.790e+06   9.140  35.290   0.650   3.932 2.000000e+10 2.188e+09
+  2   8 2.441e+06   9.080  35.240   0.650   3.953 2.000000e+10 2.203e+09
+  3   1 1.302e+07  11.720  28.890   0.740   2.528 2.000000e+10 1.706e+09
+  3   2 6.510e+06   9.390  32.700   0.730   3.560 2.000000e+10 2.130e+09
+  3   3 4.340e+06   9.150  33.930   0.690   3.784 2.000000e+10 2.186e+09
+  3   4 3.255e+06   9.040  34.650   0.680   3.908 2.000000e+10 2.212e+09
+  3   5 2.604e+06   9.090  34.990   0.680   3.924 1.999999e+10 2.200e+09
+  3   6 2.170e+06   9.050  34.870   0.670   3.927 1.999999e+10 2.210e+09
+  3   7 1.860e+06   9.010  34.850   0.660   3.941 2.000000e+10 2.220e+09
+  3   8 1.628e+06   8.980  34.860   0.670   3.957 2.000000e+10 2.227e+09
+  4   1 9.766e+06   9.000  34.680   0.940   3.958 2.000000e+10 2.222e+09
+  4   2 4.883e+06   9.020  34.180   0.740   3.871 2.000000e+10 2.217e+09
+  4   3 3.255e+06   9.150  34.640   0.710   3.863 2.000000e+10 2.186e+09
+  4   4 2.441e+06   9.010  34.780   0.690   3.937 2.000000e+10 2.220e+09
+  4   5 1.953e+06   8.980  34.680   0.690   3.939 2.000000e+10 2.227e+09
+  4   6 1.628e+06   9.050  35.120   0.690   3.957 2.000000e+10 2.210e+09
+  4   7 1.395e+06   9.010  34.900   0.670   3.948 2.000000e+10 2.220e+09
+  4   8 1.221e+06   8.960  34.900   0.680   3.971 2.000000e+10 2.232e+09
+  5   1 7.812e+06  10.150  31.760   0.840   3.212 2.000000e+10 1.970e+09
+  5   2 3.906e+06   9.090  34.040   0.750   3.827 2.000000e+10 2.200e+09
+  5   3 2.604e+06   9.030  34.650   0.720   3.917 1.999999e+10 2.215e+09
+  5   4 1.953e+06   8.990  34.610   0.700   3.928 2.000000e+10 2.225e+09
+  5   5 1.562e+06   9.000  34.920   0.700   3.958 2.000000e+10 2.222e+09
+  5   6 1.302e+06   9.120  35.370   0.690   3.954 1.999999e+10 2.193e+09
+  5   7 1.116e+06   8.910  34.680   0.690   3.970 1.999999e+10 2.245e+09
+  5   8 9.766e+05   8.930  34.790   0.680   3.972 1.999999e+10 2.240e+09
+  6   1 6.510e+06   9.390  31.810   0.840   3.477 2.000000e+10 2.130e+09
+  6   2 3.255e+06   9.000  34.320   0.760   3.898 2.000000e+10 2.222e+09
+  6   3 2.170e+06   8.960  34.310   0.740   3.912 1.999999e+10 2.232e+09
+  6   4 1.628e+06   8.970  34.640   0.730   3.943 2.000000e+10 2.230e+09
+  6   5 1.302e+06   9.110  35.360   0.710   3.959 1.999999e+10 2.195e+09
+  6   6 1.085e+06   8.970  34.750   0.710   3.953 1.999999e+10 2.230e+09
+  6   7 9.301e+05   8.950  34.710   0.700   3.956 1.999999e+10 2.235e+09
+  6   8 8.138e+05   8.920  34.570   0.710   3.955 2.000000e+10 2.242e+09
+  7   1 5.580e+06   9.290  32.840   0.870   3.629 2.000000e+10 2.153e+09
+  7   2 2.790e+06   9.040  34.400   0.770   3.890 2.000000e+10 2.212e+09
+  7   3 1.860e+06   8.940  34.380   0.740   3.928 2.000000e+10 2.237e+09
+  7   4 1.395e+06   8.990  34.820   0.730   3.954 2.000000e+10 2.225e+09
+  7   5 1.116e+06   8.990  34.820   0.720   3.953 1.999999e+10 2.225e+09
+  7   6 9.301e+05   8.940  34.720   0.720   3.964 1.999999e+10 2.237e+09
+  7   7 7.972e+05   8.930  34.700   0.710   3.965 1.999998e+10 2.240e+09
+  7   8 6.975e+05   8.910  34.510   0.700   3.952 1.999998e+10 2.245e+09
+  8   1 4.883e+06   9.070  33.770   0.910   3.824 2.000000e+10 2.205e+09
+  8   2 2.441e+06   9.000  34.340   0.780   3.902 2.000000e+10 2.222e+09
+  8   3 1.628e+06   8.990  34.510   0.740   3.921 2.000000e+10 2.225e+09
+  8   4 1.221e+06   8.980  34.650   0.740   3.941 2.000000e+10 2.227e+09
+  8   5 9.766e+05   8.960  34.700   0.720   3.953 1.999999e+10 2.232e+09
+  8   6 8.138e+05   8.920  34.680   0.710   3.967 2.000000e+10 2.242e+09
+  8   7 6.975e+05   8.900  34.580   0.720   3.966 1.999998e+10 2.247e+09
+  8   8 6.104e+05   8.930  34.590   0.710   3.953 1.999998e+10 2.240e+09
diff --git a/gnuradio-examples/python/multi-antenna/.gitignore b/gnuradio-examples/python/multi-antenna/.gitignore
new file mode 100644 (file)
index 0000000..ff40c06
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/*.dat
diff --git a/gnuradio-examples/python/multi_usrp/.gitignore b/gnuradio-examples/python/multi_usrp/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gnuradio-examples/python/network/.gitignore b/gnuradio-examples/python/network/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index e59d50834acbfa82fab2967e31ecfc28f0a35b32..eb18a75aa2a993329228c08258fdc83764e4f083 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006,2007 Free Software Foundation, Inc.
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,30 +25,36 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class audio_sink(gr.top_block):
-    def __init__(self, src, port, pkt_size, sample_rate):
+    def __init__(self, host, port, pkt_size, sample_rate, eof, wait):
         gr.top_block.__init__(self, "audio_sink")
-        src = gr.udp_source(gr.sizeof_float, src, port, pkt_size)
+        src = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+                            eof=eof, wait=wait)
         dst = audio.sink(sample_rate)
         self.connect(src, dst)
         
 if __name__ == '__main__':
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="0.0.0.0",
                       help="local host name (domain name or IP address)")
-    parser.add_option("", "--src-port", type="int", default=65500,
+    parser.add_option("", "--port", type="int", default=65500,
                       help="port value to listen to for connection")
     parser.add_option("", "--packet-size", type="int", default=1472,
                       help="packet size.")
     parser.add_option("-r", "--sample-rate", type="int", default=32000,
                       help="audio signal sample rate [default=%default]")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
+    parser.add_option("", "--no-wait", action="store_true", default=False,
+                      help="don't wait for source")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
 
     # Create an instance of a hierarchical block
-    top_block = audio_sink(options.src_name, options.src_port,
-                           options.packet_size, options.sample_rate)
+    top_block = audio_sink(options.host, options.port,
+                           options.packet_size, options.sample_rate,
+                           not options.no_eof, not options.no_wait)
     
     try:    
         # Run forever
index d7f4f6d9369c41991c539c9d9f2b823a9cb6dec4..5818ccbd8bc30e53b689838bcddd535a3abdeb07 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006,2007 Free Software Foundation, Inc.
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,32 +25,33 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class audio_source(gr.top_block):
-    def __init__(self, src, dst, port, pkt_size, sample_rate):
+    def __init__(self, host, port, pkt_size, sample_rate, eof):
         gr.top_block.__init__(self, "audio_source")
         self.audio = audio.source(sample_rate)
-       self.sink = gr.udp_sink(gr.sizeof_float, src, 0, dst, port, pkt_size)
+       self.sink = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
         self.connect(self.audio, self.sink)
 
 if __name__ == '__main__':
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
-                      help="local host name (domain name or IP address)")
-    parser.add_option("", "--dst-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="localhost",
                       help="Remote host name (domain name or IP address")
-    parser.add_option("", "--dst-port", type="int", default=65500,
-                      help="port value to connect to")
+    parser.add_option("", "--port", type="int", default=65500,
+                      help="port number to connect to")
     parser.add_option("", "--packet-size", type="int", default=1472,
                       help="packet size.")
     parser.add_option("-r", "--sample-rate", type="int", default=32000 ,
                       help="audio signal sample rate [default=%default]")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
 
     # Create an instance of a hierarchical block
-    top_block = audio_source(options.src_name, options.dst_name, options.dst_port,
-                             options.packet_size, options.sample_rate)
+    top_block = audio_source(options.host, options.port,
+                             options.packet_size, options.sample_rate,
+                             not options.no_eof)
     
     try:    
         # Run forever
index 47d24b9bcfb006764e6180b63cc95503d0e81122..1b9009552e5d7e152169d483036e3f743c571568 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006,2007 Free Software Foundation, Inc.
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,30 +25,36 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class dial_tone_sink(gr.top_block):
-    def __init__(self, src, port, pkt_size, sample_rate):
+    def __init__(self, host, port, pkt_size, sample_rate, eof, wait):
         gr.top_block.__init__(self, "dial_tone_sink")
-        udp = gr.udp_source(gr.sizeof_float, src, port, pkt_size)
+        udp = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+                            eof=eof, wait=wait)
         sink = audio.sink(sample_rate)
         self.connect(udp, sink)
         
 if __name__ == '__main__':
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="0.0.0.0",
                       help="local host name (domain name or IP address)")
-    parser.add_option("", "--src-port", type="int", default=65500,
+    parser.add_option("", "--port", type="int", default=65500,
                       help="port value to listen to for connection")
     parser.add_option("", "--packet-size", type="int", default=1472,
                       help="packet size.")
     parser.add_option("-r", "--sample-rate", type="int", default=8000,
                       help="audio signal sample rate [default=%default]")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
+    parser.add_option("", "--no-wait", action="store_true", default=False,
+                      help="don't wait for source")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
 
     # Create an instance of a hierarchical block
-    top_block = dial_tone_sink(options.src_name, options.src_port,
-                               options.packet_size, options.sample_rate)
+    top_block = dial_tone_sink(options.host, options.port,
+                               options.packet_size, options.sample_rate,
+                               not options.no_eof, not options.no_wait)
     
     try:    
         # Run forever
index 835f9aafcb34558d97909a6ff21200ff64038a19..766ecf16d85771df360f70f8991d153bfa694957 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006,2007 Free Software Foundation, Inc.
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,7 +25,7 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class dial_tone_source(gr.top_block):
-    def __init__(self, src, dst, port, pkt_size, sample_rate):
+    def __init__(self, host, port, pkt_size, sample_rate, eof):
         gr.top_block.__init__(self, "dial_tone_source")
 
         amplitude = 0.3
@@ -35,31 +35,32 @@ class dial_tone_source(gr.top_block):
 
         # Throttle needed here to account for the other side's audio card sampling rate
        thr = gr.throttle(gr.sizeof_float, sample_rate)
-       sink = gr.udp_sink(gr.sizeof_float, src, 0, dst, port, pkt_size)
+       sink = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
        self.connect(src0, (add, 0))
        self.connect(src1, (add, 1))
        self.connect(add, thr, sink)
 
 if __name__ == '__main__':
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
-                      help="local host name (domain name or IP address)")
-    parser.add_option("", "--dst-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="localhost",
                       help="Remote host name (domain name or IP address")
-    parser.add_option("", "--dst-port", type="int", default=65500,
-                      help="port value to connect to")
+    parser.add_option("", "--port", type="int", default=65500,
+                      help="port number to connect to")
     parser.add_option("", "--packet-size", type="int", default=1472,
                       help="packet size.")
     parser.add_option("-r", "--sample-rate", type="int", default=8000,
                       help="audio signal sample rate [default=%default]")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
 
     # Create an instance of a hierarchical block
-    top_block = dial_tone_source(options.src_name, options.dst_name, options.dst_port,
-                                 options.packet_size, options.sample_rate)
+    top_block = dial_tone_source(options.host, options.port,
+                                 options.packet_size, options.sample_rate,
+                                 not options.no_eof)
     
     try:    
         # Run forever
@@ -67,4 +68,3 @@ if __name__ == '__main__':
     except KeyboardInterrupt:
         # Ctrl-C exits
         pass
-    
index 981cc598b96178d9c33df76798502bcd2c52d7e9..5d73858a35e8f0ccf60cc541dd4c236136a7415c 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006 Free Software Foundation, Inc.
+# Copyright 2006,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,28 +25,35 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class vector_sink(gr.top_block):
-    def __init__(self, src, port, pkt_size):
+    def __init__(self, host, port, pkt_size, eof, wait):
         gr.top_block.__init__(self, "vector_sink")
 
-        udp = gr.udp_source(gr.sizeof_float, src, port, pkt_size)
+        udp = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+                            eof=eof, wait=wait)
         sink = gr.file_sink(gr.sizeof_float, "received.dat")
         self.connect(udp, sink)
 
 if __name__ == "__main__":
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="0.0.0.0",
                       help="local host name (domain name or IP address)")
-    parser.add_option("", "--src-port", type="int", default=65500,
+    parser.add_option("", "--port", type="int", default=65500,
                       help="port value to listen to for connection")
     parser.add_option("", "--packet-size", type="int", default=1471,
                       help="packet size.")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
+    parser.add_option("", "--no-wait", action="store_true", default=False,
+                      help="don't wait for source")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
     
     # Create an instance of a hierarchical block
-    top_block = vector_sink(options.src_name, options.src_port, options.packet_size)
+    top_block = vector_sink(options.host, options.port,
+                            options.packet_size,
+                            not options.no_eof, not options.no_wait)
     
     try:    
         # Run forever
index e7ec2a461d15bbe15ddb91ff605864faabf74bf0..0e7d678445e90b1a44d3b3f5096ca7dd66878485 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2006 Free Software Foundation, Inc.
+# Copyright 2006,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,31 +25,31 @@ from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
 class vector_source(gr.top_block):
-    def __init__(self, src, dst, port, pkt_size):
+    def __init__(self, host, port, pkt_size, eof):
         gr.top_block.__init__(self, "vector_source")
         data = [i*0.01 for i in range(1000)]
         vec = gr.vector_source_f(data, True)
-        udp = gr.udp_sink(gr.sizeof_float, src, 0, dst, port, pkt_size)
+        udp = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
         self.connect(vec, udp)
 
 if __name__ == '__main__':
     parser = OptionParser(option_class=eng_option)
-    parser.add_option("", "--src-name", type="string", default="localhost",
-                      help="local host name (domain name or IP address)")
-    parser.add_option("", "--dst-name", type="string", default="localhost",
+    parser.add_option("", "--host", type="string", default="localhost",
                       help="Remote host name (domain name or IP address")
-    parser.add_option("", "--dst-port", type="int", default=65500,
-                      help="port value to connect to")
+    parser.add_option("", "--port", type="int", default=65500,
+                      help="port number to connect to")
     parser.add_option("", "--packet-size", type="int", default=1471,
                       help="packet size.")
+    parser.add_option("", "--no-eof", action="store_true", default=False,
+                      help="don't send EOF on disconnect")
     (options, args) = parser.parse_args()
     if len(args) != 0:
         parser.print_help()
         raise SystemExit, 1
 
 # Create an instance of a hierarchical block
-    top_block = vector_source(options.src_name, options.dst_name,
-                              options.dst_port, options.packet_size)
+    top_block = vector_source(options.host, options.port, options.packet_size,
+                              not options.no_eof)
     
     try:    
         # Run forever
diff --git a/gnuradio-examples/python/ofdm/.gitignore b/gnuradio-examples/python/ofdm/.gitignore
new file mode 100644 (file)
index 0000000..2f6a10e
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/*.pyc
+/*.dat
diff --git a/gnuradio-examples/python/ofdm/gr_plot_ofdm.py b/gnuradio-examples/python/ofdm/gr_plot_ofdm.py
new file mode 100755 (executable)
index 0000000..e3b3471
--- /dev/null
@@ -0,0 +1,268 @@
+#!/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 scipy, pylab, math
+import struct, sys
+from pylab import *
+from matplotlib.font_manager import fontManager, FontProperties
+from optparse import OptionParser
+from scipy import fftpack
+from math import log10
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_constellation:
+    def __init__(self, options):
+        derot_file = "ofdm_frame_sink_c.dat"
+        acq_file = "ofdm_frame_acq_c.dat"
+        fft_file = "ofdm_receiver-fft_out_c.dat"
+
+        self.h_derot_file = open(derot_file, "r")
+        self.h_acq_file = open(acq_file, "r")
+        self.h_fft_file = open(fft_file, "r")
+
+        self.occ_tones = options.occ_tones
+        self.fft_size  = options.fft_size
+        self.symbol = options.start
+        self.sample_rate = options.sample_rate
+        
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+        
+        # Setup PLOT
+        self.fig = figure(1, figsize=(14, 9), facecolor='w')
+        rcParams['xtick.labelsize'] = self.axis_font_size
+        rcParams['ytick.labelsize'] = self.axis_font_size
+
+        self.text_sym = figtext(0.05, 0.95, ("Symbol: %s" % self.symbol), weight="heavy", size=self.text_size)
+
+        self.make_plots()
+
+        self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05], frameon=True)
+        self.button_left = Button(self.button_left_axes, "<")
+        self.button_left_callback = self.button_left.on_clicked(self.button_left_click)
+
+        self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05], frameon=True)
+        self.button_right = Button(self.button_right_axes, ">")
+        self.button_right_callback = self.button_right.on_clicked(self.button_right_click)
+
+        self.xlim = self.sp_eq.get_xlim()
+
+        self.manager = get_current_fig_manager()
+        #connect('draw_event', self.zoom)
+        connect('key_press_event', self.click)
+        show()
+
+    def get_data(self):
+        self.text_sym.set_text("Symbol: %d" % (self.symbol))
+
+        derot_data = scipy.fromfile(self.h_derot_file, dtype=scipy.complex64, count=self.occ_tones)
+        acq_data = scipy.fromfile(self.h_acq_file, dtype=scipy.complex64, count=self.occ_tones)
+        fft_data = scipy.fromfile(self.h_fft_file, dtype=scipy.complex64, count=self.fft_size)
+        if(len(acq_data) == 0):
+            print "End of File"
+        else:
+            self.acq_data_reals = [r.real for r in acq_data]
+            self.acq_data_imags = [i.imag for i in acq_data]
+            self.derot_data_reals = [r.real for r in derot_data]
+            self.derot_data_imags = [i.imag for i in derot_data]
+
+            self.unequalized_angle = [math.atan2(x.imag, x.real) for x in fft_data]
+            self.equalized_angle = [math.atan2(x.imag, x.real) for x in acq_data]
+            self.derot_equalized_angle = [math.atan2(x.imag, x.real) for x in derot_data]
+
+            self.time = [i*(1/self.sample_rate) for i in range(len(acq_data))]
+            ffttime = [i*(1/self.sample_rate) for i in range(len(fft_data))]
+
+            self.freq = self.get_freq(ffttime, self.sample_rate)
+
+            for i in range(len(fft_data)):
+                if(abs(fft_data[i]) == 0.0):
+                    fft_data[i] = complex(1e-6,1e-6)
+            self.fft_data = [20*log10(abs(f)) for f in fft_data]
+              
+    def get_freq(self, time, sample_rate, T=1):
+        N = len(time)
+        Fs = 1.0 / (max(time) - min(time))
+        Fn = 0.5 * sample_rate
+        freq = [-Fn + i*Fs for i in range(N)]
+        return freq
+
+    def make_plots(self):
+        self.h_acq_file.seek(8*self.symbol*self.occ_tones, 0)
+        self.h_fft_file.seek(8*self.symbol*self.fft_size, 0)
+        self.h_derot_file.seek(8*self.symbol*self.occ_tones, 0)
+
+        self.get_data()
+        
+        # Subplot:  constellation of rotated symbols
+        self.sp_const = self.fig.add_subplot(4,1,1, position=[0.15, 0.55, 0.3, 0.35])
+        self.sp_const.set_title(("Constellation"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_const.set_xlabel("Inphase", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_const.set_ylabel("Qaudrature", fontsize=self.label_font_size, fontweight="bold")
+        self.plot_const = plot(self.acq_data_reals, self.acq_data_imags, 'bo')
+        self.plot_const += plot(self.derot_data_reals, self.derot_data_imags, 'ro')
+        self.sp_const.axis([-2, 2, -2, 2])
+
+        # Subplot: unequalized angle
+        self.sp_uneq = self.fig.add_subplot(4,2,1, position=[0.575, 0.55, 0.3, 0.35])
+        self.sp_uneq.set_title(("Unequalized Angle"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_uneq.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_uneq.set_ylabel("Angle", fontsize=self.label_font_size, fontweight="bold")
+        uneqscale = range(len(self.unequalized_angle))
+        self.plot_uneq = plot(uneqscale, self.unequalized_angle, 'bo')
+
+        # Subplot: equalized angle
+        self.sp_eq = self.fig.add_subplot(4,1,2, position=[0.15, 0.1, 0.3, 0.35])
+        self.sp_eq.set_title(("Equalized Angle"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_eq.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_eq.set_ylabel("Angle", fontsize=self.label_font_size, fontweight="bold")
+        eqscale = range(len(self.equalized_angle))
+        self.plot_eq = plot(eqscale, self.equalized_angle, 'bo')
+        self.plot_eq += plot(eqscale, self.derot_equalized_angle, 'ro', markersize=4)
+
+        # Subplot: FFT
+        self.sp_fft = self.fig.add_subplot(4,2,2, position=[0.575, 0.1, 0.3, 0.35])
+        self.sp_fft.set_title(("FFT"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_fft.set_xlabel("Frequency (MHz)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_fft.set_ylabel("Power (dBm)", fontsize=self.label_font_size, fontweight="bold")
+        self.plot_fft = plot(self.freq, self.fft_data, '-bo')
+
+        draw()
+
+    def update_plots(self):
+        eqscale = range(len(self.equalized_angle))
+        uneqscale = range(len(self.unequalized_angle))
+        self.plot_eq[0].set_data([eqscale, self.equalized_angle])
+        self.plot_eq[1].set_data([eqscale, self.derot_equalized_angle])
+        self.plot_uneq[0].set_data([uneqscale, self.unequalized_angle])
+        self.sp_eq.set_ylim([-4, 4])
+        self.sp_uneq.set_ylim([-4, 4])
+
+        #self.sp_iq.axis([min(self.time), max(self.time),
+        #                 1.5*min([min(self.acq_data_reals), min(self.acq_data_imags)]),
+        #                 1.5*max([max(self.acq_data_reals), max(self.acq_data_imags)])])
+
+        self.plot_const[0].set_data([self.acq_data_reals, self.acq_data_imags])
+        self.plot_const[1].set_data([self.derot_data_reals, self.derot_data_imags])
+        self.sp_const.axis([-2, 2, -2, 2])
+
+        self.plot_fft[0].set_data([self.freq, self.fft_data])
+
+        draw()
+        
+    def zoom(self, event):
+        newxlim = self.sp_eq.get_xlim()
+        if(newxlim != self.xlim):
+            self.xlim = newxlim
+            r = self.reals[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+            i = self.imags[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+
+            self.plot_const[0].set_data(r, i)
+            self.sp_const.axis([-2, 2, -2, 2])
+            self.manager.canvas.draw()
+            draw()
+
+    def click(self, event):
+        forward_valid_keys = [" ", "down", "right"]
+        backward_valid_keys = ["up", "left"]
+
+        if(find(event.key, forward_valid_keys)):
+            self.step_forward()
+            
+        elif(find(event.key, backward_valid_keys)):
+            self.step_backward()
+
+    def button_left_click(self, event):
+        self.step_backward()
+
+    def button_right_click(self, event):
+        self.step_forward()
+
+    def step_forward(self):
+        self.symbol += 1
+        self.get_data()
+        self.update_plots()
+
+    def step_backward(self):
+        # Step back in file position
+        self.symbol -= 1
+        if(self.h_acq_file.tell() >= 16*self.occ_tones):
+            self.h_acq_file.seek(-16*self.occ_tones, 1)
+        else:
+            self.symbol = 0
+            self.h_acq_file.seek(-self.h_acq_file.tell(),1)
+
+
+        if(self.h_derot_file.tell() >= 16*self.occ_tones):
+            self.h_derot_file.seek(-16*self.occ_tones, 1)
+        else:
+            self.symbol = 0
+            self.h_derot_file.seek(-self.h_derot_file.tell(),1)
+
+
+        if(self.h_fft_file.tell() >= 16*self.fft_size):
+            self.h_fft_file.seek(-16*self.fft_size, 1)
+        else:
+            self.symbol = 0
+            self.h_fft_file.seek(-self.h_fft_file.tell(),1)
+
+        self.get_data()
+        self.update_plots()
+        
+            
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+    for l in list_search:
+        if item_in == l:
+            return True
+    return False
+
+def main():
+    usage="%prog: [options]"
+
+    parser = OptionParser(conflict_handler="resolve", usage=usage)
+    parser.add_option("", "--fft-size", type="int", default=512,
+                      help="Specify the size of the FFT [default=%default]")
+    parser.add_option("", "--occ-tones", type="int", default=200,
+                      help="Specify the number of occupied tones [default=%default]")
+    parser.add_option("-s", "--start", type="int", default=0,
+                      help="Specify the starting symbol to plot [default=%default]")
+    parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+                      help="Set the sampler rate of the data [default=%default]")
+    
+    (options, args) = parser.parse_args ()
+
+    dc = draw_constellation(options)
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
+
+
diff --git a/gnuradio-examples/python/pfb/.gitignore b/gnuradio-examples/python/pfb/.gitignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/gnuradio-examples/python/pfb/Makefile.am b/gnuradio-examples/python/pfb/Makefile.am
new file mode 100644 (file)
index 0000000..0b91d0a
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+ourdatadir = $(exampledir)/pfb
+
+dist_ourdata_SCRIPTS =         \
+       channelize.py           \
+       chirp_channelize.py     \
+       decimate.py             \
+       interpolate.py          \
+       fmtest.py
+
+dist_ourdata_DATA =            \
+       resampler_demo.grc
diff --git a/gnuradio-examples/python/pfb/channelize.py b/gnuradio-examples/python/pfb/channelize.py
new file mode 100755 (executable)
index 0000000..27d87e5
--- /dev/null
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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, blks2
+import os, time
+import scipy, pylab
+from scipy import fftpack
+from pylab import mlab
+
+class pfb_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        self._N = 2000000        # number of samples to use
+        self._fs = 9000          # initial sampling rate
+        self._M = 9              # Number of channels to channelize
+
+        # Create a set of taps for the PFB channelizer
+        self._taps = gr.firdes.low_pass_2(1, self._fs, 475.50, 50, 
+                                          attenuation_dB=10, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+        # Calculate the number of taps per channel for our own information
+        tpc = scipy.ceil(float(len(self._taps)) /  float(self._M))
+        print "Number of taps:     ", len(self._taps)
+        print "Number of channels: ", self._M
+        print "Taps per channel:   ", tpc
+        
+        # Create a set of signals at different frequencies
+        #   freqs lists the frequencies of the signals that get stored 
+        #   in the list "signals", which then get summed together
+        self.signals = list()
+        self.add = gr.add_cc()
+        freqs = [-4070, -3050, -2030, -1010, 10, 1020, 2040, 3060, 4080]
+        for i in xrange(len(freqs)):
+            self.signals.append(gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freqs[i], 1))
+            self.connect(self.signals[i], (self.add,i))
+
+        self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+        # Construct the channelizer filter
+        self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps)
+
+        # Construct a vector sink for the input signal to the channelizer
+        self.snk_i = gr.vector_sink_c()
+
+        # Connect the blocks
+        self.connect(self.add, self.head, self.pfb)
+        self.connect(self.add, self.snk_i)
+
+        # Create a vector sink for each of M output channels of the filter and connect it
+        self.snks = list()
+        for i in xrange(self._M):
+            self.snks.append(gr.vector_sink_c())
+            self.connect((self.pfb, i), self.snks[i])
+                             
+
+def main():
+    tstart = time.time()
+    
+    tb = pfb_top_block()
+    tb.run()
+
+    tend = time.time()
+    print "Run time: %f" % (tend - tstart)
+
+    if 1:
+        fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+        fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+        fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+        
+        Ns = 1000
+        Ne = 10000
+
+        fftlen = 8192
+        winfunc = scipy.blackman
+        fs = tb._fs
+
+        # Plot the input signal on its own figure
+        d = tb.snk_i.data()[Ns:Ne]
+        spin_f = fig_in.add_subplot(2, 1, 1)
+
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_in = 10.0*scipy.log10(abs(X))
+        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+        pin_f = spin_f.plot(f_in, X_in, "b")
+        spin_f.set_xlim([min(f_in), max(f_in)+1]) 
+        spin_f.set_ylim([-200.0, 50.0]) 
+
+        spin_f.set_title("Input Signal", weight="bold")
+        spin_f.set_xlabel("Frequency (Hz)")
+        spin_f.set_ylabel("Power (dBW)")
+
+
+        Ts = 1.0/fs
+        Tmax = len(d)*Ts
+        
+        t_in = scipy.arange(0, Tmax, Ts)
+        x_in = scipy.array(d)
+        spin_t = fig_in.add_subplot(2, 1, 2)
+        pin_t = spin_t.plot(t_in, x_in.real, "b")
+        pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+        spin_t.set_xlabel("Time (s)")
+        spin_t.set_ylabel("Amplitude")
+
+        Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+        Nrows = int(scipy.floor(tb._M / Ncols))
+        if(tb._M % Ncols != 0):
+            Nrows += 1
+
+        # Plot each of the channels outputs. Frequencies on Figure 2 and
+        # time signals on Figure 3
+        fs_o = tb._fs / tb._M
+        Ts_o = 1.0/fs_o
+        Tmax_o = len(d)*Ts_o
+        for i in xrange(len(tb.snks)):
+            # remove issues with the transients at the beginning
+            # also remove some corruption at the end of the stream
+            #    this is a bug, probably due to the corner cases
+            d = tb.snks[i].data()[Ns:Ne]
+
+            sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+            X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+                              window = lambda d: d*winfunc(fftlen),
+                              scale_by_freq=True)
+            X_o = 10.0*scipy.log10(abs(X))
+            f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+            p2_f = sp1_f.plot(f_o, X_o, "b")
+            sp1_f.set_xlim([min(f_o), max(f_o)+1]) 
+            sp1_f.set_ylim([-200.0, 50.0]) 
+
+            sp1_f.set_title(("Channel %d" % i), weight="bold")
+            sp1_f.set_xlabel("Frequency (Hz)")
+            sp1_f.set_ylabel("Power (dBW)")
+
+            x_o = scipy.array(d)
+            t_o = scipy.arange(0, Tmax_o, Ts_o)
+            sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+            p2_o = sp2_o.plot(t_o, x_o.real, "b")
+            p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+            sp2_o.set_xlim([min(t_o), max(t_o)+1]) 
+            sp2_o.set_ylim([-2, 2]) 
+
+            sp2_o.set_title(("Channel %d" % i), weight="bold")
+            sp2_o.set_xlabel("Time (s)")
+            sp2_o.set_ylabel("Amplitude")
+
+        pylab.show()
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gnuradio-examples/python/pfb/chirp_channelize.py b/gnuradio-examples/python/pfb/chirp_channelize.py
new file mode 100755 (executable)
index 0000000..edebf5f
--- /dev/null
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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, blks2
+import os, time
+import scipy, pylab
+from scipy import fftpack
+from pylab import mlab
+
+class pfb_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        self._N = 200000         # number of samples to use
+        self._fs = 9000          # initial sampling rate
+        self._M = 9              # Number of channels to channelize
+
+        # Create a set of taps for the PFB channelizer
+        self._taps = gr.firdes.low_pass_2(1, self._fs, 500, 20, 
+                                          attenuation_dB=10, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+        # Calculate the number of taps per channel for our own information
+        tpc = scipy.ceil(float(len(self._taps)) /  float(self._M))
+        print "Number of taps:     ", len(self._taps)
+        print "Number of channels: ", self._M
+        print "Taps per channel:   ", tpc
+
+        repeated = True
+        if(repeated):
+            self.vco_input = gr.sig_source_f(self._fs, gr.GR_SIN_WAVE, 0.25, 110)
+        else:
+            amp = 100
+            data = scipy.arange(0, amp, amp/float(self._N))
+            self.vco_input = gr.vector_source_f(data, False)
+            
+        # Build a VCO controlled by either the sinusoid or single chirp tone
+        # Then convert this to a complex signal
+        self.vco = gr.vco_f(self._fs, 225, 1)
+        self.f2c = gr.float_to_complex()
+
+        self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+        # Construct the channelizer filter
+        self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps)
+
+        # Construct a vector sink for the input signal to the channelizer
+        self.snk_i = gr.vector_sink_c()
+
+        # Connect the blocks
+        self.connect(self.vco_input, self.vco, self.f2c)
+        self.connect(self.f2c, self.head, self.pfb)
+        self.connect(self.f2c, self.snk_i)
+
+        # Create a vector sink for each of M output channels of the filter and connect it
+        self.snks = list()
+        for i in xrange(self._M):
+            self.snks.append(gr.vector_sink_c())
+            self.connect((self.pfb, i), self.snks[i])
+                             
+
+def main():
+    tstart = time.time()
+    
+    tb = pfb_top_block()
+    tb.run()
+
+    tend = time.time()
+    print "Run time: %f" % (tend - tstart)
+
+    if 1:
+        fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+        fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+        fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+        fig3 = pylab.figure(4, figsize=(16,9), facecolor="w")
+        
+        Ns = 650
+        Ne = 20000
+
+        fftlen = 8192
+        winfunc = scipy.blackman
+        fs = tb._fs
+
+        # Plot the input signal on its own figure
+        d = tb.snk_i.data()[Ns:Ne]
+        spin_f = fig_in.add_subplot(2, 1, 1)
+
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+        pin_f = spin_f.plot(f_in, X_in, "b")
+        spin_f.set_xlim([min(f_in), max(f_in)+1]) 
+        spin_f.set_ylim([-200.0, 50.0]) 
+
+        spin_f.set_title("Input Signal", weight="bold")
+        spin_f.set_xlabel("Frequency (Hz)")
+        spin_f.set_ylabel("Power (dBW)")
+
+
+        Ts = 1.0/fs
+        Tmax = len(d)*Ts
+        
+        t_in = scipy.arange(0, Tmax, Ts)
+        x_in = scipy.array(d)
+        spin_t = fig_in.add_subplot(2, 1, 2)
+        pin_t = spin_t.plot(t_in, x_in.real, "b")
+        pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+        spin_t.set_xlabel("Time (s)")
+        spin_t.set_ylabel("Amplitude")
+
+        Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+        Nrows = int(scipy.floor(tb._M / Ncols))
+        if(tb._M % Ncols != 0):
+            Nrows += 1
+
+        # Plot each of the channels outputs. Frequencies on Figure 2 and
+        # time signals on Figure 3
+        fs_o = tb._fs / tb._M
+        Ts_o = 1.0/fs_o
+        Tmax_o = len(d)*Ts_o
+        for i in xrange(len(tb.snks)):
+            # remove issues with the transients at the beginning
+            # also remove some corruption at the end of the stream
+            #    this is a bug, probably due to the corner cases
+            d = tb.snks[i].data()[Ns:Ne]
+
+            sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+            X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+                              window = lambda d: d*winfunc(fftlen),
+                              scale_by_freq=True)
+            X_o = 10.0*scipy.log10(abs(X))
+            f_o = freq
+            p2_f = sp1_f.plot(f_o, X_o, "b")
+            sp1_f.set_xlim([min(f_o), max(f_o)+1]) 
+            sp1_f.set_ylim([-200.0, 50.0]) 
+
+            sp1_f.set_title(("Channel %d" % i), weight="bold")
+            sp1_f.set_xlabel("Frequency (Hz)")
+            sp1_f.set_ylabel("Power (dBW)")
+
+            x_o = scipy.array(d)
+            t_o = scipy.arange(0, Tmax_o, Ts_o)
+            sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+            p2_o = sp2_o.plot(t_o, x_o.real, "b")
+            p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+            sp2_o.set_xlim([min(t_o), max(t_o)+1]) 
+            sp2_o.set_ylim([-2, 2]) 
+
+            sp2_o.set_title(("Channel %d" % i), weight="bold")
+            sp2_o.set_xlabel("Time (s)")
+            sp2_o.set_ylabel("Amplitude")
+
+
+            sp3 = fig3.add_subplot(1,1,1)
+            p3 = sp3.plot(t_o, x_o.real)
+            sp3.set_xlim([min(t_o), max(t_o)+1]) 
+            sp3.set_ylim([-2, 2]) 
+
+        sp3.set_title("All Channels")
+        sp3.set_xlabel("Time (s)")
+        sp3.set_ylabel("Amplitude") 
+
+        pylab.show()
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gnuradio-examples/python/pfb/decimate.py b/gnuradio-examples/python/pfb/decimate.py
new file mode 100755 (executable)
index 0000000..cb5d61b
--- /dev/null
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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, blks2
+import os
+import scipy, pylab
+from scipy import fftpack
+from pylab import mlab
+import time
+
+#print os.getpid()
+#raw_input()
+
+class pfb_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        self._N = 10000000      # number of samples to use
+        self._fs = 10000        # initial sampling rate
+        self._decim = 20        # Decimation rate
+        
+        # Generate the prototype filter taps for the decimators with a 200 Hz bandwidth
+        self._taps = gr.firdes.low_pass_2(1, self._fs, 200, 150,
+                                          attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+        # Calculate the number of taps per channel for our own information
+        tpc = scipy.ceil(float(len(self._taps)) /  float(self._decim))
+        print "Number of taps:     ", len(self._taps)
+        print "Number of filters:  ", self._decim
+        print "Taps per channel:   ", tpc
+        
+        # Build the input signal source
+        # We create a list of freqs, and a sine wave is generated and added to the source
+        # for each one of these frequencies.
+        self.signals = list()
+        self.add = gr.add_cc()
+        freqs = [10, 20, 2040]
+        for i in xrange(len(freqs)):
+            self.signals.append(gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freqs[i], 1))
+            self.connect(self.signals[i], (self.add,i))
+
+        self.head = gr.head(gr.sizeof_gr_complex, self._N)
+        
+        # Construct a PFB decimator filter
+        self.pfb = blks2.pfb_decimator_ccf(self._decim, self._taps, 0)
+
+        # Construct a standard FIR decimating filter
+        self.dec = gr.fir_filter_ccf(self._decim, self._taps)
+
+        self.snk_i = gr.vector_sink_c()
+
+        # Connect the blocks
+        self.connect(self.add, self.head, self.pfb)
+        self.connect(self.add, self.snk_i)
+
+        # Create the sink for the decimated siganl
+        self.snk = gr.vector_sink_c()
+        self.connect(self.pfb, self.snk)
+                             
+
+def main():
+    tb = pfb_top_block()
+
+    tstart = time.time()    
+    tb.run()
+    tend = time.time()
+    print "Run time: %f" % (tend - tstart)
+
+    if 1:
+        fig1 = pylab.figure(1, figsize=(16,9))
+        fig2 = pylab.figure(2, figsize=(16,9))
+        
+        Ns = 10000
+        Ne = 10000
+
+        fftlen = 8192
+        winfunc = scipy.blackman
+        fs = tb._fs
+
+        # Plot the input to the decimator
+
+        d = tb.snk_i.data()[Ns:Ns+Ne]
+        sp1_f = fig1.add_subplot(2, 1, 1)
+
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+        p1_f = sp1_f.plot(f_in, X_in, "b")
+        sp1_f.set_xlim([min(f_in), max(f_in)+1]) 
+        sp1_f.set_ylim([-200.0, 50.0]) 
+
+        sp1_f.set_title("Input Signal", weight="bold")
+        sp1_f.set_xlabel("Frequency (Hz)")
+        sp1_f.set_ylabel("Power (dBW)")
+        
+        Ts = 1.0/fs
+        Tmax = len(d)*Ts
+
+        t_in = scipy.arange(0, Tmax, Ts)
+        x_in = scipy.array(d)
+        sp1_t = fig1.add_subplot(2, 1, 2)
+        p1_t = sp1_t.plot(t_in, x_in.real, "b")
+        p1_t = sp1_t.plot(t_in, x_in.imag, "r")
+        sp1_t.set_ylim([-tb._decim*1.1, tb._decim*1.1])
+
+        sp1_t.set_xlabel("Time (s)")
+        sp1_t.set_ylabel("Amplitude")
+
+        
+        # Plot the output of the decimator
+        fs_o = tb._fs / tb._decim
+
+        sp2_f = fig2.add_subplot(2, 1, 1)
+        d = tb.snk.data()[Ns:Ns+Ne]
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+        p2_f = sp2_f.plot(f_o, X_o, "b")
+        sp2_f.set_xlim([min(f_o), max(f_o)+1]) 
+        sp2_f.set_ylim([-200.0, 50.0]) 
+
+        sp2_f.set_title("PFB Decimated Signal", weight="bold")
+        sp2_f.set_xlabel("Frequency (Hz)")
+        sp2_f.set_ylabel("Power (dBW)")
+        
+
+        Ts_o = 1.0/fs_o
+        Tmax_o = len(d)*Ts_o
+
+        x_o = scipy.array(d)
+        t_o = scipy.arange(0, Tmax_o, Ts_o)
+        sp2_t = fig2.add_subplot(2, 1, 2)
+        p2_t = sp2_t.plot(t_o, x_o.real, "b-o")
+        p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+        sp2_t.set_ylim([-2.5, 2.5])
+
+        sp2_t.set_xlabel("Time (s)")
+        sp2_t.set_ylabel("Amplitude")
+
+        pylab.show()
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gnuradio-examples/python/pfb/fmtest.py b/gnuradio-examples/python/pfb/fmtest.py
new file mode 100755 (executable)
index 0000000..97df0e0
--- /dev/null
@@ -0,0 +1,197 @@
+#!/usr/bin/env python
+#
+
+
+from gnuradio import gr, eng_notation
+from gnuradio import blks2
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import math, time, sys, scipy, pylab
+from scipy import fftpack
+
+class fmtx(gr.hier_block2):
+    def __init__(self, lo_freq, audio_rate, if_rate):
+
+        gr.hier_block2.__init__(self, "build_fm",
+                                gr.io_signature(1, 1, gr.sizeof_float),      # Input signature
+                                gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+        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
+                              gr.GR_SIN_WAVE, # waveform type
+                              lo_freq,        #frequency
+                              1.0,            # amplitude
+                              0)              # DC Offset
+        mixer = gr.multiply_cc ()
+    
+        self.connect (self, fmtx, (mixer, 0))
+        self.connect (lo, (mixer, 1))
+        self.connect (mixer, self)
+
+class fmtest(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        self._nsamples = 1000000
+        self._audio_rate = 8000
+
+        # Set up N channels with their own baseband and IF frequencies
+        self._N = 5
+        chspacing = 16000
+        freq = [10, 20, 30, 40, 50]
+        f_lo = [0, 1*chspacing, -1*chspacing, 2*chspacing, -2*chspacing]
+
+        self._if_rate = 4*self._N*self._audio_rate
+
+        # Create a signal source and frequency modulate it
+        self.sum = gr.add_cc ()
+        for n in xrange(self._N):
+            sig = gr.sig_source_f(self._audio_rate, gr.GR_SIN_WAVE, freq[n], 0.5)
+            fm = fmtx(f_lo[n], self._audio_rate, self._if_rate)
+            self.connect(sig, fm)
+            self.connect(fm, (self.sum, n))
+
+        self.head = gr.head(gr.sizeof_gr_complex, self._nsamples)
+        self.snk_tx = gr.vector_sink_c()
+        self.channel = blks2.channel_model(0.1)
+
+        self.connect(self.sum, self.head, self.channel, self.snk_tx)
+
+
+        # Design the channlizer
+        self._M = 10
+        bw = chspacing/2.0
+        t_bw = chspacing/10.0
+        self._chan_rate = self._if_rate / self._M
+        self._taps = gr.firdes.low_pass_2(1, self._if_rate, bw, t_bw, 
+                                          attenuation_dB=100,
+                                          window=gr.firdes.WIN_BLACKMAN_hARRIS)
+        tpc = math.ceil(float(len(self._taps)) /  float(self._M))
+
+        print "Number of taps:     ", len(self._taps)
+        print "Number of channels: ", self._M
+        print "Taps per channel:   ", tpc
+        
+        self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps)
+        
+        self.connect(self.channel, self.pfb)
+        
+        # Create a file sink for each of M output channels of the filter and connect it
+        self.fmdet = list()
+        self.squelch = list()
+        self.snks = list()
+        for i in xrange(self._M):
+            self.fmdet.append(blks2.nbfm_rx(self._audio_rate, self._chan_rate))
+            self.squelch.append(blks2.standard_squelch(self._audio_rate*10))
+            self.snks.append(gr.vector_sink_f())
+            self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i])
+
+    def num_tx_channels(self):
+        return self._N
+
+    def num_rx_channels(self):
+        return self._M
+
+def main():
+
+    fm = fmtest()
+
+    tstart = time.time()
+    fm.run()
+    tend = time.time()
+
+    if 1:
+        fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+        fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+        fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+
+        Ns = 10000
+        Ne = 100000
+
+        fftlen = 8192
+        winfunc = scipy.blackman
+
+        # Plot transmitted signal
+        fs = fm._if_rate
+
+        d = fm.snk_tx.data()[Ns:Ns+Ne]
+        sp1_f = fig1.add_subplot(2, 1, 1)
+
+        X,freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                           window = lambda d: d*winfunc(fftlen),
+                           visible=False)
+        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+        p1_f = sp1_f.plot(f_in, X_in, "b")
+        sp1_f.set_xlim([min(f_in), max(f_in)+1]) 
+        sp1_f.set_ylim([-120.0, 20.0]) 
+
+        sp1_f.set_title("Input Signal", weight="bold")
+        sp1_f.set_xlabel("Frequency (Hz)")
+        sp1_f.set_ylabel("Power (dBW)")
+
+        Ts = 1.0/fs
+        Tmax = len(d)*Ts
+        
+        t_in = scipy.arange(0, Tmax, Ts)
+        x_in = scipy.array(d)
+        sp1_t = fig1.add_subplot(2, 1, 2)
+        p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+        #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+        sp1_t.set_ylim([-5, 5])
+
+        # Set up the number of rows and columns for plotting the subfigures
+        Ncols = int(scipy.floor(scipy.sqrt(fm.num_rx_channels())))
+        Nrows = int(scipy.floor(fm.num_rx_channels() / Ncols))
+        if(fm.num_rx_channels() % Ncols != 0):
+            Nrows += 1
+
+        # Plot each of the channels outputs. Frequencies on Figure 2 and
+        # time signals on Figure 3
+        fs_o = fm._audio_rate
+        for i in xrange(len(fm.snks)):
+            # remove issues with the transients at the beginning
+            # also remove some corruption at the end of the stream
+            #    this is a bug, probably due to the corner cases
+            d = fm.snks[i].data()[Ns:Ne]
+
+            sp2_f = fig2.add_subplot(Nrows, Ncols, 1+i)
+            X,freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+                               window = lambda d: d*winfunc(fftlen),
+                               visible=False)
+            #X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+            X_o = 10.0*scipy.log10(abs(X))
+            #f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+            f_o = scipy.arange(0, fs_o/2.0, fs_o/2.0/float(X_o.size))
+            p2_f = sp2_f.plot(f_o, X_o, "b")
+            sp2_f.set_xlim([min(f_o), max(f_o)+0.1]) 
+            sp2_f.set_ylim([-120.0, 20.0]) 
+            sp2_f.grid(True)
+
+            sp2_f.set_title(("Channel %d" % i), weight="bold")
+            sp2_f.set_xlabel("Frequency (kHz)")
+            sp2_f.set_ylabel("Power (dBW)")
+
+
+            Ts = 1.0/fs_o
+            Tmax = len(d)*Ts
+            t_o = scipy.arange(0, Tmax, Ts)
+
+            x_t = scipy.array(d)
+            sp2_t = fig3.add_subplot(Nrows, Ncols, 1+i)
+            p2_t = sp2_t.plot(t_o, x_t.real, "b")
+            p2_t = sp2_t.plot(t_o, x_t.imag, "r")
+            sp2_t.set_xlim([min(t_o), max(t_o)+1]) 
+            sp2_t.set_ylim([-1, 1]) 
+
+            sp2_t.set_xlabel("Time (s)")
+            sp2_t.set_ylabel("Amplitude")
+
+
+        pylab.show()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/gnuradio-examples/python/pfb/interpolate.py b/gnuradio-examples/python/pfb/interpolate.py
new file mode 100755 (executable)
index 0000000..a7a2522
--- /dev/null
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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, blks2
+import os
+import scipy, pylab
+from scipy import fftpack
+from pylab import mlab
+import time
+
+#print os.getpid()
+#raw_input()
+
+class pfb_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        self._N = 100000        # number of samples to use
+        self._fs = 2000         # initial sampling rate
+        self._interp = 5        # Interpolation rate for PFB interpolator
+        self._ainterp = 5.5       # Resampling rate for the PFB arbitrary resampler
+
+        # Frequencies of the signals we construct 
+        freq1 = 100
+        freq2 = 200
+
+        # Create a set of taps for the PFB interpolator
+        # This is based on the post-interpolation sample rate
+        self._taps = gr.firdes.low_pass_2(self._interp, self._interp*self._fs, freq2+50, 50, 
+                                          attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+        # Create a set of taps for the PFB arbitrary resampler
+        # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes,
+        # and larger numbers will reduce these even farther
+        # The taps in this filter are based on a sampling rate of the filter size since it acts
+        # internally as an interpolator.
+        flt_size = 32
+        self._taps2 = gr.firdes.low_pass_2(flt_size, flt_size*self._fs, freq2+50, 150, 
+                                           attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+        # Calculate the number of taps per channel for our own information
+        tpc = scipy.ceil(float(len(self._taps)) /  float(self._interp))
+        print "Number of taps:     ", len(self._taps)
+        print "Number of filters:  ", self._interp
+        print "Taps per channel:   ", tpc
+
+        # Create a couple of signals at different frequencies
+        self.signal1 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq1, 0.5)
+        self.signal2 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq2, 0.5)
+        self.signal = gr.add_cc()
+        
+        self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+        # Construct the PFB interpolator filter
+        self.pfb = blks2.pfb_interpolator_ccf(self._interp, self._taps)
+
+        # Construct the PFB arbitrary resampler filter
+        self.pfb_ar = blks2.pfb_arb_resampler_ccf(self._ainterp, self._taps2, flt_size)
+        self.snk_i = gr.vector_sink_c()
+
+        #self.pfb_ar.pfb.print_taps()
+        #self.pfb.pfb.print_taps()
+        
+        # Connect the blocks
+        self.connect(self.signal1, self.head, (self.signal,0))
+        self.connect(self.signal2, (self.signal,1))
+        self.connect(self.signal, self.pfb)
+        self.connect(self.signal, self.pfb_ar)
+        self.connect(self.signal, self.snk_i)
+
+        # Create the sink for the interpolated signals
+        self.snk1 = gr.vector_sink_c()
+        self.snk2 = gr.vector_sink_c()
+        self.connect(self.pfb, self.snk1)
+        self.connect(self.pfb_ar, self.snk2)
+                             
+
+def main():
+    tb = pfb_top_block()
+
+    tstart = time.time()
+    tb.run()
+    tend = time.time()
+    print "Run time: %f" % (tend - tstart)
+
+
+    if 1:
+        fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+        fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+        fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+        
+        Ns = 10000
+        Ne = 10000
+
+        fftlen = 8192
+        winfunc = scipy.blackman
+
+        # Plot input signal
+        fs = tb._fs
+
+        d = tb.snk_i.data()[Ns:Ns+Ne]
+        sp1_f = fig1.add_subplot(2, 1, 1)
+
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+        p1_f = sp1_f.plot(f_in, X_in, "b")
+        sp1_f.set_xlim([min(f_in), max(f_in)+1]) 
+        sp1_f.set_ylim([-200.0, 50.0]) 
+
+
+        sp1_f.set_title("Input Signal", weight="bold")
+        sp1_f.set_xlabel("Frequency (Hz)")
+        sp1_f.set_ylabel("Power (dBW)")
+
+        Ts = 1.0/fs
+        Tmax = len(d)*Ts
+        
+        t_in = scipy.arange(0, Tmax, Ts)
+        x_in = scipy.array(d)
+        sp1_t = fig1.add_subplot(2, 1, 2)
+        p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+        #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+        sp1_t.set_ylim([-2.5, 2.5])
+
+        sp1_t.set_title("Input Signal", weight="bold")
+        sp1_t.set_xlabel("Time (s)")
+        sp1_t.set_ylabel("Amplitude")
+
+
+        # Plot output of PFB interpolator
+        fs_int = tb._fs*tb._interp
+
+        sp2_f = fig2.add_subplot(2, 1, 1)
+        d = tb.snk1.data()[Ns:Ns+(tb._interp*Ne)]
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_o = scipy.arange(-fs_int/2.0, fs_int/2.0, fs_int/float(X_o.size))
+        p2_f = sp2_f.plot(f_o, X_o, "b")
+        sp2_f.set_xlim([min(f_o), max(f_o)+1]) 
+        sp2_f.set_ylim([-200.0, 50.0]) 
+
+        sp2_f.set_title("Output Signal from PFB Interpolator", weight="bold")
+        sp2_f.set_xlabel("Frequency (Hz)")
+        sp2_f.set_ylabel("Power (dBW)")
+
+        Ts_int = 1.0/fs_int
+        Tmax = len(d)*Ts_int
+
+        t_o = scipy.arange(0, Tmax, Ts_int)
+        x_o1 = scipy.array(d)
+        sp2_t = fig2.add_subplot(2, 1, 2)
+        p2_t = sp2_t.plot(t_o, x_o1.real, "b-o")
+        #p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+        sp2_t.set_ylim([-2.5, 2.5])
+
+        sp2_t.set_title("Output Signal from PFB Interpolator", weight="bold")
+        sp2_t.set_xlabel("Time (s)")
+        sp2_t.set_ylabel("Amplitude")
+
+
+        # Plot output of PFB arbitrary resampler
+        fs_aint = tb._fs * tb._ainterp
+
+        sp3_f = fig3.add_subplot(2, 1, 1)
+        d = tb.snk2.data()[Ns:Ns+(tb._interp*Ne)]
+        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+                          window = lambda d: d*winfunc(fftlen),
+                          scale_by_freq=True)
+        X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+        f_o = scipy.arange(-fs_aint/2.0, fs_aint/2.0, fs_aint/float(X_o.size))
+        p3_f = sp3_f.plot(f_o, X_o, "b")
+        sp3_f.set_xlim([min(f_o), max(f_o)+1]) 
+        sp3_f.set_ylim([-200.0, 50.0]) 
+
+        sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+        sp3_f.set_xlabel("Frequency (Hz)")
+        sp3_f.set_ylabel("Power (dBW)")
+
+        Ts_aint = 1.0/fs_aint
+        Tmax = len(d)*Ts_aint
+
+        t_o = scipy.arange(0, Tmax, Ts_aint)
+        x_o2 = scipy.array(d)
+        sp3_f = fig3.add_subplot(2, 1, 2)
+        p3_f = sp3_f.plot(t_o, x_o2.real, "b-o")
+        p3_f = sp3_f.plot(t_o, x_o1.real, "m-o")
+        #p3_f = sp3_f.plot(t_o, x_o2.imag, "r-o")
+        sp3_f.set_ylim([-2.5, 2.5])
+        
+        sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+        sp3_f.set_xlabel("Time (s)")
+        sp3_f.set_ylabel("Amplitude")
+
+        pylab.show()
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gnuradio-examples/python/pfb/resampler_demo.grc b/gnuradio-examples/python/pfb/resampler_demo.grc
new file mode 100644 (file)
index 0000000..468636a
--- /dev/null
@@ -0,0 +1,598 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sun Aug 23 11:39:47 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>resampler_demo</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 59)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>rs_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(273, 154)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_add_const_vxx</key>
+    <param>
+      <key>id</key>
+      <value>adder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>const</key>
+      <value>-1.0</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(227, 303)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(227, 493)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>orig_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Original Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 3</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(409, 289)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>resamp_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Resampled Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>new_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 1, 3</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(640, 256)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>tri_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>gr.GR_TRI_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>0.05</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(21, 271)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_frequency_modulator_fc</key>
+    <param>
+      <key>id</key>
+      <value>fm_mod</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>sensitivity</key>
+      <value>math.pi</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(411, 493)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_pfb_arb_resampler_ccf</key>
+    <param>
+      <key>id</key>
+      <value>resampler</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>float(new_rate)/samp_rate</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>rs_taps</value>
+    </param>
+    <param>
+      <key>size</key>
+      <value>nphases</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(641, 477)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>nphases</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(185, 153)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Sample Rate</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>44100</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(179, 14)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>new_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Resampled Rate</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>48000</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(328, 15)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>frac_bw</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Fractional Bandwidth</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.45</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>lambda x: "%0.2f"%x</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0,2,1,1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(473, 14)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>tri_source</source_block_id>
+    <sink_block_id>adder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>adder</source_block_id>
+    <sink_block_id>throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>resampler</source_block_id>
+    <sink_block_id>resamp_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>fm_mod</source_block_id>
+    <sink_block_id>resampler</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>fm_mod</source_block_id>
+    <sink_block_id>orig_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>throttle</source_block_id>
+    <sink_block_id>fm_mod</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gnuradio-examples/python/usrp/.gitignore b/gnuradio-examples/python/usrp/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index b1135598501429bf9e2b7a16a28e51472a4f1225..60f6c5825b2acef62a1dc5ee070aac1e89e404d2 100755 (executable)
@@ -44,7 +44,10 @@ def pick_subdevice(u):
                                 usrp_dbid.LF_RX,
                                 usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
-                               usrp_dbid.TV_RX_REV_3))
+                               usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO))
 
 
 class wfm_rx_block (stdgui2.std_top_block):
index 537e339befb95c725bccf2d96c9d560c7236ade9..4e13a83ab51c14cda204d4a53fdbe51c5437667a 100755 (executable)
@@ -62,6 +62,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
index 098897cfe2345d73bf745b03419ab3b67b3272b0..fba2a12107f2a84b0a89e7d57119ad6e0d2b0ea8 100755 (executable)
@@ -43,6 +43,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
@@ -97,7 +100,11 @@ class wfm_rx_block (stdgui2.std_top_block):
         if not (dbid == usrp_dbid.BASIC_RX or
                 dbid == usrp_dbid.TV_RX or
                 dbid == usrp_dbid.TV_RX_REV_2 or
-                dbid == usrp_dbid.TV_RX_REV_3):
+                dbid == usrp_dbid.TV_RX_REV_3 or
+                dbid == usrp_dbid.TV_RX_MIMO or
+                dbid == usrp_dbid.TV_RX_REV_2_MIMO or
+                dbid == usrp_dbid.TV_RX_REV_3_MIMO
+):
             print "This daughterboard does not cover the required frequency range"
             print "for this application.  Please use a BasicRX or TVRX daughterboard."
             raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.")
index 0103982b8d06f4d170bed64efef9cb7f1a21d968..edfbc365713af1396003ac78876d3e25bf79898e 100755 (executable)
@@ -51,6 +51,10 @@ def pick_subdevice(u):
     """
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
+                               usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
index 82c521d567ca63ed03a6474aa3e043769ab528d7..30744ee01036663708ee78403a2ba1dc615b6b8b 100755 (executable)
@@ -43,6 +43,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 class wfm_rx_block (stdgui2.std_top_block):
index 44f86885567cd32ad32806bce25f5578ed5cdf30..217f207c5a9d47902c705ea1f486f9877ce42f52 100755 (executable)
@@ -40,6 +40,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
index 84992955a20f79eddfa209b805222afe89775c83..0d52ed7ee3c4085eb4337a0f39b631391f2dfa3a 100755 (executable)
@@ -43,6 +43,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 class wfm_rx_block (stdgui2.std_top_block):
index 75bbc0acd6941feaca546a1f86f3d69cb2f291f8..39547b3ae0cf33ad3de5a53698bbacc8d60f5738 100755 (executable)
@@ -72,6 +72,10 @@ def pick_subdevice(u):
     """
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
+                               usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
index 11b8c431f27f697eadf1e0abcbd19fde4f445772..b356702a688e9c6a3caae6389c9d5e70cb8fa93d 100755 (executable)
@@ -43,6 +43,9 @@ def pick_subdevice(u):
     return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
                                 usrp_dbid.TV_RX_REV_2,
                                usrp_dbid.TV_RX_REV_3,
+                               usrp_dbid.TV_RX_MIMO,
+                                usrp_dbid.TV_RX_REV_2_MIMO,
+                               usrp_dbid.TV_RX_REV_3_MIMO,
                                 usrp_dbid.BASIC_RX))
 
 
diff --git a/gnuradio-examples/python/usrp2/.gitignore b/gnuradio-examples/python/usrp2/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 0be21ceb988f438d8cb6ee6594cb572e2a0c9073..0c74769211227b193f1a483f93bcfaad4331c762 100755 (executable)
@@ -194,7 +194,10 @@ class wfm_rx_block (gr.top_block):
         #if not (dbid == 0x0001 or #usrp_dbid.BASIC_RX
         #        dbid == 0x0003 or #usrp_dbid.TV_RX
         #        dbid == 0x000c or #usrp_dbid.TV_RX_REV_2
-        #        dbid == 0x0040):  #usrp_dbid.TV_RX_REV_3    
+        #        dbid == 0x0040 or #usrp_dbid.TV_RX_REV_3
+        #        dbid == 0x0043 or #usrp_dbid.TV_RX_MIMO
+        #        dbid == 0x0044 or #usrp_dbid.TV_RX_REV_2_MIMO
+        #        dbid == 0x0045 ): #usrp_dbid.TV_RX_REV_3_MIMO
         #    print "This daughterboard does not cover the required frequency range"
         #    print "for this application.  Please use a BasicRX or TVRX daughterboard."
         #    raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.")
index 8ea5baf574f8f84a489e5886db756b1797d3ed70..1783660d6641db49d56b1d42f5d536dc187e4457 100755 (executable)
@@ -84,7 +84,10 @@ class wfm_rx_block (stdgui2.std_top_block):
         if not (dbid == 0x0001 or #usrp_dbid.BASIC_RX
                 dbid == 0x0003 or #usrp_dbid.TV_RX
                 dbid == 0x000c or #usrp_dbid.TV_RX_REV_2
-                dbid == 0x0040):  #usrp_dbid.TV_RX_REV_3    
+                dbid == 0x0040 or #usrp_dbid.TV_RX_REV_3
+                dbid == 0x0043 or #usrp_dbid.TV_RX_MIMO
+                dbid == 0x0044 or #usrp_dbid.TV_RX_REV_2_MIMO
+                dbid == 0x0045 ): #usrp_dbid.TV_RX_REV_3_MIMO
             print "This daughterboard does not cover the required frequency range"
             print "for this application.  Please use a BasicRX or TVRX daughterboard."
             raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.")
diff --git a/gnuradio-pkg_chk.conf b/gnuradio-pkg_chk.conf
new file mode 100644 (file)
index 0000000..7f81101
--- /dev/null
@@ -0,0 +1,79 @@
+# Copyright 2007, 2008 Free Software Foundation
+
+# pkg_chk -a -k -C gnuradio-pkg_chk.conf
+# pkg_chk -a -k -C gnuradio-pkg_chk.conf -D doc
+
+# This is a control file for pkg_chk, an automatic package manager for
+# pkgsrc.  After installing pkgsrc, install pkgtools/pkg_chk, use the
+# commented-out first line above.  The second addtionally includes
+# packages needed for documentation.  Note that gnuradio is in pkgsrc;
+# this file is useful for those who want dependencies from pkgsrc but
+# want to build GNU Radio itself from svn.  This file should perhaps
+# grow conventions for building minimal vs. expanded dependencies.
+
+# See http://www.netbsd.org/Documentation/software/packages.html for
+# more information about pkgsrc.
+
+# To build against pkgsrc, run configure as
+# LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" CPPFLAGS="-I/usr/pkg/include" ./configure
+
+# This file is intended to be useful even to those not using pkgsrc by
+# crisply listing the dependencies required for GNU Radio.
+
+# This file may be incorrect; please feel free to correct or mail
+# comments to gdt@ir.bbn.com or discuss-gnuradio@gnu.org.
+
+## Core
+
+devel/autoconf
+devel/automake
+devel/libtool-base
+# gmake isn't actually required, but it's helpful to have to separate
+# real build failures from unportable makefiles.
+devel/gmake
+
+devel/pkg-config
+
+math/fftwf
+
+# python is forced by py-Numeric.  pkgsrc now (200701) defaults to 2.4,
+# which is fine.  We don't include python explicitly since we'd have to
+# specify a version.
+math/py-Numeric
+# numarray is not documented to be needed, but the pkgsrc packages depend on it.
+# Include it until this confusion is resolved.
+math/py-numarray
+
+# Smart pointers.
+devel/boost-headers
+# Apparently all of boost is not needed.
+#meta-pkgs/boost
+
+devel/cppunit
+
+devel/swig
+
+lang/guile
+
+## audio
+audio/jack
+audio/portaudio-devel
+devel/SDL
+
+## documentation
+
+devel/doxygen          doc
+textproc/xmlto         doc
+
+## USRP
+
+devel/sdcc
+devel/libusb
+
+## GUI
+
+x11/py-wxWidgets
+
+## gr-radio-astronomy
+
+math/py-ephem
diff --git a/gr-atsc/.gitignore b/gr-atsc/.gitignore
new file mode 100644 (file)
index 0000000..1690515
--- /dev/null
@@ -0,0 +1,23 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/gnuradio-atsc.pc
diff --git a/gr-atsc/Makefile.am b/gr-atsc/Makefile.am
new file mode 100644 (file)
index 0000000..ffb37f7
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Copyright 2004,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+DIST_SUBDIRS = src doc
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-atsc.pc
diff --git a/gr-atsc/README b/gr-atsc/README
new file mode 100644 (file)
index 0000000..c6837ae
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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.
+# 
+
+This module contains the GNU Radio 2.x code for the 
+ATSC (HDTV) transmitter and receiver.
+
+See http://www.atsc.org for specifications.  The most relevant ones
+are XXX and YYY.
+
diff --git a/gr-atsc/README.signal_flow b/gr-atsc/README.signal_flow
new file mode 100644 (file)
index 0000000..879cb2c
--- /dev/null
@@ -0,0 +1,41 @@
+This describes the signal flow through the gnuradio-0.9 ATSC Transmitter
+and Receiver programs.
+
+ATSC Transmitter
+================
+
+module                  input                         output                       notes
+--------------------    ----------------              -------------------          --------
+VrFileSource            "MPEG transport stream"       atsc_mpeg_packet
+GrAtscRandomizer        atsc_mpeg_packet              atsc_mpeg_packet_no_sync     whiten data with LFSR
+GrAtscRSEncoder         atsc_mpeg_packet_no_sync      atsc_mpeg_packet_rs_encoded  Reed-Soloman encoder
+GrAtscInterleaver       atsc_mpeg_packet_rs_encoded   atsc_mpeg_packet_rs_encoded  convolutional interleaver
+GrAtscTrellisEncoder    atsc_mpeg_packet_rs_encoded   atsc_data_segment            trellis encoder
+GrAtscFieldSyncMux      atsc_data_segment             atsc_data_segment            add in field syncs
+GrAtscSymbolMapper      atsc_data_segment             float                        map [0,7] to +/- {1,3,5,7} and add pilot    
+GrWeaverModHead         float                         float,float                  front half of Weaver VSB modulator
+GrFIRfilterFFF (2x)     float                         float                        low pass root raised cosine (matched filter)
+GrWeaverModTail         float,float                   short                        back half of Weaver VSB modulator
+VrFileSink              short                         "16-bit passband data"
+
+
+ATSC Receiver
+=============
+
+module                    input                        output                       notes         
+--------------------      ----------------             -------------------          -------
+VrFileSource              "16-bit passband data"       short
+GrConvertSF               short                        float                        convert short to float
+GrFIRfilterFFF            float                        float                        band pass root raised cosine centered at IF freq (matched filter)
+GrAtscFPLL                float                        float                        carrier tracking freq and phase lock loop with down converting mixer
+GrFIRfilterFFF            float                        float                        low pass to kill unwanted mixer image
+GrRemoveDcFFF             float                        float                        remove DC offset prior to symbol timing module
+GrAtscBitTimingLoop3      float                        float,syminfo                track symbol & segment timing and do fractional interpolation
+GrAtscFieldSyncChecker    float,syminfo                float,syminfo                look for field sync patterns
+GrAtscEqualizer           float,syminfo                float,syminfo                LMS equalizer
+GrAtscFieldSyncDemux      float,syminfo                atsc_soft_data_segment       remove field syncs and pack into data segments
+GrAtscViterbiDecoder      atsc_soft_data_segment       atsc_mpeg_packet_rs_encoded  Viterbi decoder (12 seg delay)
+GrAtscDeinterleaver       atsc_mpeg_packet_rs_encoded  atsc_mpeg_packet_rs_encoded  convolutional de-interleaver (52 seg delay)
+GrAtscRSDecoder           atsc_mpeg_packet_rs_encoded  atsc_mpeg_packet_no_sync     Reed-Solomon decoder
+GrAtscDerandomizer        atsc_mpeg_packet_no_sync     atsc_mpeg_packet             de-whiten with LFSR
+VrFileSink                atsc_mpeg_packet             "MPEG transport stream"     
diff --git a/gr-atsc/doc/.gitignore b/gr-atsc/doc/.gitignore
new file mode 100644 (file)
index 0000000..bb3f277
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
diff --git a/gr-atsc/doc/Makefile.am b/gr-atsc/doc/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-atsc/gnuradio-atsc.pc.in b/gr-atsc/gnuradio-atsc.pc.in
new file mode 100644 (file)
index 0000000..4413bfc
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-atsc
+Description: The GNU Radio blocks for ATSC decoding
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-atsc
+Cflags: -I${includedir}
diff --git a/gr-atsc/src/.gitignore b/gr-atsc/src/.gitignore
new file mode 100644 (file)
index 0000000..bb3f277
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
diff --git a/gr-atsc/src/Makefile.am b/gr-atsc/src/Makefile.am
new file mode 100644 (file)
index 0000000..78e03f5
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
+
diff --git a/gr-atsc/src/lib/.gitignore b/gr-atsc/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..01e4ffe
--- /dev/null
@@ -0,0 +1,14 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/atsc.cc
+/atsc.py
+/atsci_viterbi_gen
+/atsci_viterbi_mux.cc
+/test_atsci
+/*.pyc
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop.cc
new file mode 100644 (file)
index 0000000..97b62cb
--- /dev/null
@@ -0,0 +1,223 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cmath>
+#include <GrAtscBitTimingLoop.h>
+#include "fpll_btloop_coupling.h"
+#include <algorithm>
+#include <atsc_consts.h>
+#include <stdio.h>
+#include <assert.h>
+
+using std::abs;
+
+static const int     DEC = 2;  // nominal decimation factor
+
+/*
+ * I strongly suggest that you not mess with these...
+ */
+static const double   DEFAULT_TIMING_RATE = 2.19e-4 / FPLL_BTLOOP_COUPLING_CONST;
+static const double   DEFAULT_LOOP_TAP    = 0.05;
+
+
+GrAtscBitTimingLoop::GrAtscBitTimingLoop ()
+  : VrDecimatingSigProc<float,float> (1, DEC),
+    next_input(0), w (1.0), mu (0.5), last_right(0),
+    debug_no_update (false)
+{
+  d_timing_rate = DEFAULT_TIMING_RATE;
+  loop.set_taps (DEFAULT_LOOP_TAP);
+  
+  history = 1500;      // spare input samples in case we need them.
+
+#ifdef _BT_DIAG_OUTPUT_
+  fp_loop = fopen ("loop.out", "w");
+  if (fp_loop == 0){
+    perror ("loop.out");
+    exit (1);
+  }
+    
+  fp_ps = fopen ("ps.out", "w");
+  if (fp_ps == 0){
+    perror ("ps.out");
+    exit (1);
+  }
+#endif
+}
+
+//
+// We are nominally a 2x decimator, but our actual rate varies slightly
+// depending on the difference between the transmitter and receiver
+// sampling clocks.  Hence, we need to compute our input ranges
+// explictly.
+
+int
+GrAtscBitTimingLoop::forecast(VrSampleRange output,
+                             VrSampleRange inputs[]) {
+  /* dec:1 ratio with history */
+  for(unsigned int i=0;i<numberInputs;i++) {
+    inputs[i].index=next_input;
+    inputs[i].size=output.size*decimation + history-1;
+  }
+  return 0;
+}  
+
+inline double
+GrAtscBitTimingLoop::filter_error (double e)
+{
+  static const double limit = 50 * FPLL_BTLOOP_COUPLING_CONST;
+  
+  // first limit
+
+  if (e > limit)
+    e = limit;
+  else if (e < -limit)
+    e = -limit;
+
+  return loop.filter (e);
+}
+
+int 
+GrAtscBitTimingLoop::work (VrSampleRange output, void *ao[],
+                          VrSampleRange inputs[], void *ai[])
+{
+  iType         *in = ((iType **)ai)[0];
+  oType  *out = ((oType **)ao)[0];
+
+  // Force in-order computation of output stream.
+  // This is required because of our slightly variable decimation factor
+  sync (output.index);
+
+  
+  // We are tasked with producing output.size output samples.  
+  // We will consume approximately 2 * output.size input samples.
+
+
+  unsigned int ii = 0;         // input index
+  unsigned int k;              // output index
+
+  // We look at a window of 3 samples that we call left (oldest),
+  // middle, right (newest).  Each time through the loop, the previous
+  // right becomes the new left, and the new samples are middle and
+  // right.
+  //
+  // The basic game plan is to drive the average difference between
+  // right and left to zero.  Given that all transitions are
+  // equiprobable (the data is white) and that the composite matched
+  // filter is symmetric (raised cosine) it turns out that in the
+  // average, if we drive that difference to zero, (implying that the
+  // average slope at the middle point is zero), we'll be sampling
+  // middle at the maximum or minimum point in the pulse.
+
+  iType        left;
+  iType middle;
+  iType        right = last_right;
+
+  for (k = 0; k < output.size; k++){
+
+    left = right;
+    middle = produce_sample (in, ii);
+    right = produce_sample (in, ii);
+
+    // assert (ii < inputs[0].size);
+    if (!(ii < inputs[0].size)){
+      fprintf (stderr, "ii < inputs[0].size\n");
+      fprintf (stderr, "ii = %d, inputs[0].size = %lu, k = %d, output.size = %lu\n",
+              ii, inputs[0].size, k, output.size);
+      assert (0);
+    }
+
+
+    out[k] = middle;   // produce our output
+
+    double timing_error = -middle * ((double) right - left);
+
+    // update_timing_control_word
+
+    double filtered_timing_error = filter_error (timing_error);
+
+    if (!debug_no_update){
+      mu += filtered_timing_error * d_timing_rate;
+    }
+    
+#ifdef _BT_DIAG_OUTPUT_
+    float      iodata[8];
+    iodata[0] = left;
+    iodata[1] = middle;
+    iodata[2] = right;
+    iodata[3] = timing_error;
+    iodata[4] = filtered_timing_error;
+    iodata[5] = mu;
+    iodata[6] = w;
+    iodata[7] = 0;
+    if (fwrite (iodata, sizeof (iodata), 1, fp_loop) != 1){
+      perror ("fwrite: loop");
+      exit (1);
+    }
+#endif
+
+  }
+
+  last_right = right;
+  next_input += ii;    // update next_input so forecast can get us what we need
+  return output.size;
+}
+
+/*!
+ * Produce samples equally spaced in time that are referenced
+ * to the transmitter's sample clock, not ours.
+ *
+ * See pp 523-527 of "Digital Communication Receivers", Meyr,
+ * Moeneclaey and Fechtel, Wiley, 1998.
+ */
+
+GrAtscBitTimingLoop::iType
+GrAtscBitTimingLoop::produce_sample (const iType *in, unsigned int &index)
+{
+  // update mu and index as function of control word, w
+
+  double sum = mu + w;
+  double f = floor (sum);
+  int incr = (int) f;          // mostly 1, rarely 0 or 2
+  mu = sum - f;
+
+  assert (0 <= incr && incr <= 2);
+  assert (0.0 <= mu && mu <= 1.0);
+
+  index += incr;
+
+  iType n = intr.interpolate (&in[index], mu);
+
+#if defined(_BT_DIAG_OUTPUT_) && 0
+  float        iodata[4];
+  iodata[0] = incr;
+  iodata[1] = mu;
+  iodata[2] = w;
+  iodata[3] = 0;
+  if (fwrite (iodata, sizeof (iodata), 1, fp_ps) != 1){
+    perror ("fwrite: ps");
+    exit (1);
+  }
+#endif
+
+  return n;
+}
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop.h b/gr-atsc/src/lib/GrAtscBitTimingLoop.h
new file mode 100644 (file)
index 0000000..9fcffcf
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCBITTIMINGLOOP_H_
+#define _GRATSCBITTIMINGLOOP_H_
+
+#include <gr_nco.h>
+#include <VrSigProc.h>
+#include <VrHistoryProc.h>
+#include <VrDecimatingSigProc.h>
+#include <interleaver_fifo.h>
+#include <gr_single_pole_iir.h>
+#include <gr_mmse_fir_interpolator.h>
+#include <atsci_slicer_agc.h>
+#include <stdio.h>
+#include <atsci_diag_output.h>
+
+
+/*!
+ * \brief ATSC BitTimingLoop
+ *
+ * This class accepts a single real input and produces a single real output
+ */
+
+class GrAtscBitTimingLoop : public VrDecimatingSigProc<float,float> {
+
+ public:
+
+  GrAtscBitTimingLoop ();
+  virtual ~GrAtscBitTimingLoop () { };
+
+  virtual const char *name () { return "GrAtscBitTimingLoop"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+  // debug
+  void set_mu (double a_mu) { mu = a_mu; }
+  void set_no_update (bool a_no_update) { debug_no_update = a_no_update; }
+  void set_loop_filter_tap (double tap)  { loop.set_taps (tap); }
+  void set_timing_rate (double rate)     { d_timing_rate = rate; }
+
+ protected:
+
+  typedef float iType;
+  typedef float oType;
+
+  iType produce_sample (const iType *in, unsigned int &index);
+  double filter_error (double e);
+
+  VrSampleIndex                                next_input;
+  gr_mmse_fir_interpolator             intr;
+  double                               w;              // timing control word
+  double                               mu;             // fractional delay
+  iType                                        last_right;     // last right hand sample
+  gr_single_pole_iir<double,double,double>     loop;
+  bool                                 debug_no_update;// debug
+
+  double                               d_loop_filter_tap;
+  double                               d_timing_rate;
+  
+#ifdef _BT_DIAG_OUTPUT_
+  FILE                                 *fp_loop;
+  FILE                                 *fp_ps;
+#endif
+};
+
+#endif // _GRATSCBITTIMINGLOOP_H_
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop2.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop2.cc
new file mode 100644 (file)
index 0000000..3f9cf10
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscBitTimingLoop2.h>
+#include <algorithm>
+#include <atsc_consts.h>
+#include <stdio.h>
+#include <assert.h>
+
+
+static const int       DEC = 2;        // nominal decimation factor
+
+static const unsigned  AVG_WINDOW_LEN = 256;
+static const float     TIMING_RATE_CONST = 1e-5;    // FIXME document interaction with AGC
+
+
+GrAtscBitTimingLoop2::GrAtscBitTimingLoop2 ()
+  : VrDecimatingSigProc<float,float> (1, DEC),
+    next_input(0), dc (0.0002), mu (0.0), last_right(0), use_right_p (true)
+{
+  history = 100;       // spare input samples in case we need them.
+
+#ifdef _BT_DIAG_OUTPUT_
+  fp_loop = fopen ("loop.out", "w");
+  if (fp_loop == 0){
+    perror ("loop.out");
+    exit (1);
+  }
+    
+  fp_ps = fopen ("ps.out", "w");
+  if (fp_ps == 0){
+    perror ("ps.out");
+    exit (1);
+  }
+#endif
+
+}
+
+//
+// We are nominally a 2x decimator, but our actual rate varies slightly
+// depending on the difference between the transmitter and receiver
+// sampling clocks.  Hence, we need to compute our input ranges
+// explictly.
+
+int
+GrAtscBitTimingLoop2::forecast(VrSampleRange output,
+                             VrSampleRange inputs[]) {
+  /* dec:1 ratio with history */
+  for(unsigned int i=0;i<numberInputs;i++) {
+    inputs[i].index=next_input;
+    inputs[i].size=output.size*decimation + history-1;
+  }
+  return 0;
+}  
+
+inline float
+GrAtscBitTimingLoop2::filter_error (float e)
+{
+  return e;    // identity function
+}
+
+int 
+GrAtscBitTimingLoop2::work (VrSampleRange output, void *ao[],
+                          VrSampleRange inputs[], void *ai[])
+{
+  iType         *in = ((iType **)ai)[0];
+  oType  *out = ((oType **)ao)[0];
+
+  // Force in-order computation of output stream.
+  // This is required because of our slightly variable decimation factor
+  sync (output.index);
+
+  
+  // We are tasked with producing output.size output samples.  
+  // We will consume approximately 2 * output.size input samples.
+
+
+  unsigned int ii = 0;         // input index
+  unsigned int k;              // output index
+
+  // We look at a window of 3 samples that we call left (oldest),
+  // middle, right (newest).  Each time through the loop, the previous
+  // right becomes the new left, and the new samples are middle and
+  // right.
+  //
+  // The basic game plan is to drive the average difference between
+  // right and left to zero.  Given that all transitions are
+  // equiprobable (the data is white) and that the composite matched
+  // filter is symmetric (raised cosine) it turns out that in the
+  // average, if we drive that difference to zero, (implying that the
+  // average slope at the middle point is zero), we'll be sampling
+  // middle at the maximum or minimum point in the pulse.
+
+  iType        left;
+  iType middle;
+  iType        right = last_right;
+
+  for (k = 0; k < output.size; k++){
+
+    left = right;
+    
+    iType middle_raw = produce_sample (in, ii);
+    iType middle_dc = dc.filter (middle_raw);
+    middle = middle_raw - middle_dc;
+
+    iType right_raw = produce_sample (in, ii);
+    iType right_dc = dc.filter (right_raw);
+    right = right_raw - right_dc;
+
+    if (use_right_p)   // produce our output
+      out[k] = right;  
+    else
+      out[k] = middle;
+  }
+
+#ifdef _BT_DIAG_OUTPUT_
+  float        iodata[8];
+  iodata[0] = 0;
+  iodata[1] = out[k];
+  iodata[2] = 0;
+  iodata[3] = 0;
+  iodata[4] = 0;
+  iodata[5] = mu;
+  iodata[6] = 0;
+  iodata[7] = 0;       // spare
+  if (fwrite (iodata, sizeof (iodata), 1, fp_loop) != 1){
+    perror ("fwrite: loop");
+    exit (1);
+  }
+#endif
+
+
+  last_right = right;
+  next_input += ii;    // update next_input so forecast can get us what we need
+  return output.size;
+}
+
+/*!
+ * Produce samples equally spaced in time that are referenced
+ * to the transmitter's sample clock, not ours.
+ *
+ * See pp 523-527 of "Digital Communication Receivers", Meyr,
+ * Moeneclaey and Fechtel, Wiley, 1998.
+ */
+
+GrAtscBitTimingLoop2::iType
+GrAtscBitTimingLoop2::produce_sample (const iType *in, unsigned int &index)
+{
+  iType n = intr.interpolate (&in[index], mu);
+
+  index++;
+  return n;
+}
+
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop2.h b/gr-atsc/src/lib/GrAtscBitTimingLoop2.h
new file mode 100644 (file)
index 0000000..c03e64a
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCBITTIMINGLOOP2_H_
+#define _GRATSCBITTIMINGLOOP2_H_
+
+#include <gr_nco.h>
+#include <VrSigProc.h>
+#include <VrHistoryProc.h>
+#include <VrDecimatingSigProc.h>
+#include <interleaver_fifo.h>
+#include <gr_single_pole_iir.h>
+#include <gr_mmse_fir_interpolator.h>
+
+/*!
+ * \brief ATSC BitTimingLoop
+ *
+ * This class accepts a single real input and produces a single real output
+ */
+
+class GrAtscBitTimingLoop2 : public VrDecimatingSigProc<float,float> {
+
+ public:
+
+  GrAtscBitTimingLoop2 ();
+  virtual ~GrAtscBitTimingLoop2 () { };
+
+  virtual const char *name () { return "GrAtscBitTimingLoop2"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+  // debug
+  void set_mu (float a_mu) {
+    assert (0 <= a_mu && a_mu <= 1.9);
+    use_right_p = a_mu < 1.0;
+    mu = a_mu - floor (a_mu);
+    cerr << "BTL2:  mu: " << mu << " use_right_p: " << use_right_p << endl;
+  }
+
+ protected:
+
+  typedef float iType;
+  typedef float oType;
+
+  iType produce_sample (const iType *in, unsigned int &index);
+  float filter_error (float e);
+
+  VrSampleIndex                                next_input;
+  gr_single_pole_iir<float,float,float>        dc;             // used to estimate DC component
+  gr_mmse_fir_interpolator             intr;
+  float                                        mu;             // fractional delay
+  iType                                        last_right;     // last right hand sample
+
+  bool                                 use_right_p;    // ...else middle
+};
+
+#endif // _GRATSCBITTIMINGLOOP2_H_
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop3.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop3.cc
new file mode 100644 (file)
index 0000000..3ee2880
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscBitTimingLoop3.h>
+#include <cmath>
+#include <cstdio>
+#include <assert.h>
+
+using std::abs;
+
+
+static const int NOUTPUTS = 2;
+
+GrAtscBitTimingLoop3::GrAtscBitTimingLoop3 (double ratio_of_rx_clock_to_symbol_freq)
+  : VrDecimatingSigProc<float,float> (NOUTPUTS, (int) rint (ratio_of_rx_clock_to_symbol_freq)),
+    d_interp (ratio_of_rx_clock_to_symbol_freq), d_next_input(0),
+    d_rx_clock_to_symbol_freq (ratio_of_rx_clock_to_symbol_freq)
+
+{
+  assert (ratio_of_rx_clock_to_symbol_freq >= 1.8);    // sanity check
+  
+  history = 1500;      // spare input samples in case we need them.
+}
+
+//
+// We are nominally a 2x decimator, but our actual rate varies slightly
+// depending on the difference between the transmitter and receiver
+// sampling clocks.  Hence, we need to compute our input ranges
+// explictly.
+
+int
+GrAtscBitTimingLoop3::forecast(VrSampleRange output,
+                              VrSampleRange inputs[]) {
+  assert (numberInputs == 1);
+  
+  /* dec:1 ratio with history */
+  inputs[0].index = d_next_input;
+  inputs[0].size =
+    ((unsigned long) (output.size * d_rx_clock_to_symbol_freq) + history - 1);
+
+  return 0;
+}  
+
+
+int 
+GrAtscBitTimingLoop3::work (VrSampleRange output, void *ao[],
+                           VrSampleRange inputs[], void *ai[])
+{
+  iType         *in = ((iType **)ai)[0];
+  oDataType *out_sample = ((oDataType **)ao)[0];
+  oTagType  *out_tag =    ((oTagType **) ao)[1];
+
+  // Force in-order computation of output stream.
+  // This is required because of our slightly variable decimation factor
+  sync (output.index);
+
+  // We are tasked with producing output.size output samples.  
+  // We will consume approximately 2 * output.size input samples.
+
+  int          si = 0;         // source index
+  unsigned int k;              // output index
+
+  float                interp_sample;
+  int          symbol_index;
+  double       timing_adjustment = 0;
+  bool         seg_locked;
+  oTagType     tag;
+
+  memset (&tag, 0, sizeof (tag));
+
+  for (k = 0; k < output.size; k++){
+
+    if (!d_interp.update (in, inputs[0].size, &si, timing_adjustment, &interp_sample)){
+      fprintf (stderr, "GrAtscBitTimingLoop3: ran short on data...\n");
+      break;
+    }
+      
+    d_sssr.update (interp_sample, &seg_locked, &symbol_index, &timing_adjustment);
+    out_sample[k] = interp_sample;
+    tag.valid = seg_locked;
+    tag.symbol_num = symbol_index;
+    out_tag[k] = tag;
+  }
+
+  d_next_input += si;  // update next_input so forecast can get us what we need
+  return k;
+}
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop3.h b/gr-atsc/src/lib/GrAtscBitTimingLoop3.h
new file mode 100644 (file)
index 0000000..fd2ea03
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCBITTIMINGLOOP3_H_
+#define _GRATSCBITTIMINGLOOP3_H_
+
+#include <cstdio>
+#include <VrDecimatingSigProc.h>
+#include <atsci_diag_output.h>
+#include <atsci_sssr.h>
+#include <atsci_syminfo.h>
+
+/*!
+ * \brief ATSC BitTimingLoop3
+ *
+ * This class accepts a single real input and produces two outputs,
+ *  the raw symbol (float) and the tag (atsc_syminfo)
+ */
+
+class GrAtscBitTimingLoop3 : public VrDecimatingSigProc<float,float> {
+
+ public:
+
+  GrAtscBitTimingLoop3 (double ratio_of_rx_clock_to_symbol_freq);
+  virtual ~GrAtscBitTimingLoop3 () { };
+
+  virtual const char *name () { return "GrAtscBitTimingLoop3"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+  // debug (NOPs)
+  void set_mu (double a_mu) {  }
+  void set_no_update (bool a_no_update) {  }
+  void set_loop_filter_tap (double tap)  { }
+  void set_timing_rate (double rate)     { }
+
+ protected:
+
+  typedef float        iType;
+  typedef float        oDataType;
+  typedef atsc::syminfo        oTagType;
+
+  atsci_sssr                   d_sssr;
+  atsci_interpolator           d_interp;
+  VrSampleIndex                        d_next_input;
+  double                       d_rx_clock_to_symbol_freq;
+};
+
+#endif // _GRATSCBITTIMINGLOOP3_H_
diff --git a/gr-atsc/src/lib/GrAtscConvert2xTo20.cc b/gr-atsc/src/lib/GrAtscConvert2xTo20.cc
new file mode 100644 (file)
index 0000000..ec74503
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscConvert2xTo20.h>
+#include <atsc_consts.h>
+#include <cmath>
+#include <cstdio>
+
+static const int    N_OUTPUTS = 1;
+static const double DEC_RATIO = (2.0 * ATSC_SYMBOL_RATE) / 20e6;       // ~ 1.076
+
+GrAtscConvert2xTo20::GrAtscConvert2xTo20 ()
+  : VrDecimatingSigProc<float,float> (N_OUTPUTS, (int) rint (DEC_RATIO))
+{
+  d_next_input = 0;
+  d_frac_part = 0;
+  history = 2 * d_interp.ntaps ();     // some slack
+}
+
+GrAtscConvert2xTo20::~GrAtscConvert2xTo20 ()
+{
+  // Nop
+}
+
+void
+GrAtscConvert2xTo20::pre_initialize ()
+{
+  fprintf (stderr,
+          "GrAtscConvert2xTo20: input freq = %g\n", getInputSamplingFrequencyN(0));
+  fprintf (stderr,
+          "GrAtscConvert2xTo20: DEC_RATIO = %g\n", DEC_RATIO);
+  fprintf (stderr,
+          "GrAtscConvert2xTo20: argument to setSamplingFrequency = %g\n",
+          getInputSamplingFrequencyN(0) / DEC_RATIO);
+  
+  int  r;
+  r = setSamplingFrequency (getInputSamplingFrequencyN (0) / DEC_RATIO);
+
+  fprintf (stderr, "GrAtscConvert2xTo20: result = %d\n", r);
+
+  fprintf (stderr, "GrAtscConvert2xTo20: getSamplingFrequency = %g\n",
+          getSamplingFrequency ());
+}
+
+
+int
+GrAtscConvert2xTo20::forecast (VrSampleRange output,
+                              VrSampleRange inputs[])
+{
+  assert (numberInputs == 1);  // I hate these free references to
+                               // superclass's instance variables...
+
+  inputs[0].index = d_next_input;
+  inputs[0].size =
+    ((long unsigned int) (output.size * DEC_RATIO) + history - 1);
+
+  return 0;
+}
+
+int
+GrAtscConvert2xTo20::work (VrSampleRange output, void *ao[],
+                          VrSampleRange inputs[], void *ai[])
+{
+  float        *in = ((float **) ai)[0];
+  float *out = ((float **) ao)[0];
+
+  sync (output.index);
+
+  unsigned long  si = 0;               // source index
+  unsigned long         oi = 0;                // output index
+  double frac_part = d_frac_part;
+
+  for (oi = 0; oi < output.size; oi++){
+    assert (si + d_interp.ntaps () < inputs[0].size);
+    out[oi] = d_interp.interpolate (&in[si], (1. - frac_part));
+
+    double s = frac_part + DEC_RATIO;
+    double float_incr = floor (s);
+    frac_part = s - float_incr;
+    int incr = (int) float_incr;
+    si += incr;
+  }
+  
+  d_next_input += si;
+  d_frac_part = frac_part;
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscConvert2xTo20.h b/gr-atsc/src/lib/GrAtscConvert2xTo20.h
new file mode 100644 (file)
index 0000000..eba6f71
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _GRATSCCONVERT2XTO20_H_
+#define _GRATSCCONVERT2XTO20_H_
+
+#include <VrDecimatingSigProc.h>
+#include <gr_mmse_fir_interpolator.h>
+
+class GrAtscConvert2xTo20 : public VrDecimatingSigProc<float,float> {
+  gr_mmse_fir_interpolator     d_interp;
+  double                       d_frac_part;
+  VrSampleIndex                        d_next_input;
+  
+public:
+  GrAtscConvert2xTo20 ();
+  ~GrAtscConvert2xTo20 ();
+
+  virtual const char *name () { return "GrAtscConvert2xTo20"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+  void pre_initialize ();
+  int checkOutputSamplingFrequency(float) { return 0; } // bogus, but required
+
+};
+
+#endif /* _GRATSCCONVERT2XTO20_H_ */
diff --git a/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc
new file mode 100644 (file)
index 0000000..417e108
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscDataSegToSoftDataSeg.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_data_segment              iType;
+typedef atsc_soft_data_segment         oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+static void
+map_to_soft_symbols (atsc_soft_data_segment &out,
+                    const atsc_data_segment &in)
+{
+  for (unsigned int i = 0; i < NELEM (in.data); i++){
+    out.data[i] = in.data[i] * 2 - 7;
+  }
+}
+
+
+GrAtscDataSegToSoftDataSeg::GrAtscDataSegToSoftDataSeg ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscDataSegToSoftDataSeg::~GrAtscDataSegToSoftDataSeg ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscDataSegToSoftDataSeg::work (VrSampleRange output, void *ao[],
+                                 VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    map_to_soft_symbols (out[i], in[i]);
+    out[i].pli = in[i].pli;
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h
new file mode 100644 (file)
index 0000000..7579bed
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCDATASEGTOSOFTDATASEG_H_
+#define _GRATSCDATASEGTOSOFTDATASEG_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+
+/*!
+ * \brief Debug glue routine (atsc_data_segment --> atsc_soft_data_segment)
+ */
+
+class GrAtscDataSegToSoftDataSeg : public VrHistoryProc<atsc_data_segment,
+                                                       atsc_soft_data_segment>
+{
+
+public:
+
+  GrAtscDataSegToSoftDataSeg ();
+  ~GrAtscDataSegToSoftDataSeg ();
+
+  const char *name () { return "GrAtscDataSegToSoftDataSeg"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+};
+
+#endif /* _GRATSCDATASEGTOSOFTDATASEG_H_ */
diff --git a/gr-atsc/src/lib/GrAtscDeinterleaver.cc b/gr-atsc/src/lib/GrAtscDeinterleaver.cc
new file mode 100644 (file)
index 0000000..357b9be
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscDeinterleaver.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_rs_encoded    iType;
+typedef atsc_mpeg_packet_rs_encoded    oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscDeinterleaver::GrAtscDeinterleaver ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscDeinterleaver::~GrAtscDeinterleaver ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscDeinterleaver::work (VrSampleRange output, void *ao[],
+                          VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current contents of the LFSR in the randomizer, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    // pipeline info is handled in the primitive
+    deinterleaver.deinterleave (out[i], in[i]);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscDeinterleaver.h b/gr-atsc/src/lib/GrAtscDeinterleaver.h
new file mode 100644 (file)
index 0000000..c10e17d
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCDEINTERLEAVER_H_
+#define _GRATSCDEINTERLEAVER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_data_interleaver.h>
+
+/*!
+ * \brief Deinterleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)
+ */
+
+class GrAtscDeinterleaver : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_rs_encoded>
+{
+
+public:
+
+  GrAtscDeinterleaver ();
+  ~GrAtscDeinterleaver ();
+
+  const char *name () { return "GrAtscDeinterleaver"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_data_deinterleaver     deinterleaver;
+};
+
+#endif /* _GRATSCDEINTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscDerandomizer.cc b/gr-atsc/src/lib/GrAtscDerandomizer.cc
new file mode 100644 (file)
index 0000000..4935483
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscDerandomizer.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_no_sync       iType;
+typedef atsc_mpeg_packet               oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscDerandomizer::GrAtscDerandomizer ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscDerandomizer::~GrAtscDerandomizer ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscDerandomizer::work (VrSampleRange output, void *ao[],
+                         VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current contents of the LFSR in the randomizer, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+
+    assert (in[i].pli.regular_seg_p ());
+
+    if (in[i].pli.first_regular_seg_p ())
+      rand.reset ();
+    
+    rand.derandomize (out[i], in[i]);
+
+    // take a look at the transport error bit in the pipeline info
+    // and set bit as required
+
+    if (in[i].pli.transport_error_p ())
+      out[i].data[1] |= MPEG_TRANSPORT_ERROR_BIT;
+    else
+      out[i].data[1] &= ~MPEG_TRANSPORT_ERROR_BIT;
+
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscDerandomizer.h b/gr-atsc/src/lib/GrAtscDerandomizer.h
new file mode 100644 (file)
index 0000000..d1de3a5
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCDERANDOMIZER_H_
+#define _GRATSCDERANDOMIZER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_randomizer.h>
+
+/*!
+ * \brief Derandomize ATSC data (atsc_mpeg_packet_no_sync --> atsc_mpeg_packet)
+ */
+
+class GrAtscDerandomizer : public VrHistoryProc<atsc_mpeg_packet_no_sync, atsc_mpeg_packet>
+{
+
+public:
+
+  GrAtscDerandomizer ();
+  ~GrAtscDerandomizer ();
+
+  const char *name () { return "GrAtscDerandomizer"; }
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_randomizer     rand;
+};
+
+#endif /* _GRATSCDERANDOMIZER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscEqualizer.cc b/gr-atsc/src/lib/GrAtscEqualizer.cc
new file mode 100644 (file)
index 0000000..b0a9d99
--- /dev/null
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscEqualizer.h>
+#include <atsci_equalizer.h>
+
+// typedefs for fundamental i/o types
+
+typedef float          dataType;
+typedef atsc::syminfo  tagType;
+
+static const int NUMBER_OF_OUTPUTS = 2;        // # of output streams 
+
+
+GrAtscEqualizer::GrAtscEqualizer (atsci_equalizer *equalizer)
+  : VrHistoryProc<dataType,dataType> (NUMBER_OF_OUTPUTS)
+{
+  // due to limitation of runtime, all inputs must be the same size
+  assert (sizeof (dataType) == sizeof (tagType));
+  
+  d_equalizer = equalizer;
+
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  //
+  // Set this to the answer returned by the equalizer primitive we were passed.
+  history = d_equalizer->ntaps ();
+}
+
+GrAtscEqualizer::~GrAtscEqualizer ()
+{
+  // Anything that isn't automatically cleaned up...
+
+  delete d_equalizer;
+}
+
+
+/*
+ * non-standard forecast routine that handles getting the correct amount of
+ * history for the data input as well as ensuring correct alignment of
+ * the data and tags.
+ */
+
+int
+GrAtscEqualizer::forecast (VrSampleRange output,
+                          VrSampleRange inputs[]) 
+{
+  assert (numberInputs == 2);
+  
+  int ntaps = d_equalizer->ntaps ();
+  int npretaps = d_equalizer->npretaps ();
+  
+  assert (ntaps >= 1);
+  assert (npretaps >= 0 && npretaps < ntaps);
+  
+  inputs[0].index = output.index;              // the equalizer data
+  inputs[0].size  = output.size + ntaps - 1;   // history on data
+  
+  // FIXME if there's a problem, it's probably on the next line...
+  int offset = ntaps - npretaps - 1;
+
+  assert (offset >= 0 && offset < ntaps);
+
+  inputs[1].index = output.index + offset;     // align equalizer tags
+  inputs[1].size = output.size;                        // N.B., no extra history on tags
+
+  return 0;
+}  
+
+/*
+ * This is the real work horse.  We consume 2 input streams
+ * and produce 2 output streams.
+ */
+
+int 
+GrAtscEqualizer::work (VrSampleRange output, void *ao[],
+                      VrSampleRange inputs[], void *ai[])
+{
+  // assert (numberInputs == 2);
+  
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, hence we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  dataType *input_samples  = ((dataType **) ai)[0];
+  tagType  *input_tags     = ((tagType **)  ai)[1];
+  dataType *output_samples = ((dataType **) ao)[0];
+  tagType  *output_tags    = ((tagType **)  ao)[1];
+
+
+  // peform the actual equalization
+
+  d_equalizer->filter (input_samples, input_tags,
+                      output_samples, output.size);
+
+  // write the output tags
+
+  for (unsigned int i = 0; i < output.size; i++)
+    output_tags[i] = input_tags[i];
+
+  // Return the number of units we produced.
+
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscEqualizer.h b/gr-atsc/src/lib/GrAtscEqualizer.h
new file mode 100644 (file)
index 0000000..b67e984
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCEQUALIZER_H_
+#define _GRATSCEQUALIZER_H_
+
+#include <VrHistoryProc.h>
+
+class atsci_equalizer;
+
+/*!
+ * \brief ATSC equalizer (float,syminfo --> float,syminfo)
+ *
+ * first inputs are data samples, second inputs are tags.
+ * first outputs are equalized data samples, second outputs are tags.
+ *
+ * tag values are defined in atsci_syminfo.h
+ */
+
+class GrAtscEqualizer : public VrHistoryProc<float,float>
+{
+
+public:
+
+  GrAtscEqualizer (atsci_equalizer *equalizer);
+  ~GrAtscEqualizer ();
+
+  const char *name () { return "GrAtscEqualizer"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+  // we've got a non-standard forecast routine
+  int forecast (VrSampleRange output, VrSampleRange inputs[]);
+
+protected:
+  atsci_equalizer      *d_equalizer;
+};
+
+#endif /* _GRATSCEQUALIZER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscFPLL.cc b/gr-atsc/src/lib/GrAtscFPLL.cc
new file mode 100644 (file)
index 0000000..ce5b183
--- /dev/null
@@ -0,0 +1,150 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscFPLL.h>
+#include <algorithm>
+#include "fpll_btloop_coupling.h"
+
+/*
+ * I strongly suggest that you not mess with these...
+ *
+ * They are strongly coupled into the symbol timing code and
+ * their value also sets the level of the symbols going
+ * into the equalizer and viterbi decoder.
+ */
+static const float FPLL_AGC_REFERENCE = 2.5 * FPLL_BTLOOP_COUPLING_CONST;
+static const float FPLL_AGC_RATE = 0.25e-6;
+
+
+GrAtscFPLL::GrAtscFPLL (double a_initial_freq)
+  : VrSigProc (1, sizeof (iType), sizeof (oType)),
+    initial_phase(0), debug_no_update(false)
+{
+  initial_freq = a_initial_freq;
+  agc.set_rate (FPLL_AGC_RATE);
+  agc.set_reference (FPLL_AGC_REFERENCE);
+
+  if (_FPLL_DIAG_OUTPUT_){
+    fp = fopen ("fpll.out", "w");
+    if (fp == 0){
+      perror ("fpll.out");
+      exit (1);
+    }
+  }
+
+}
+
+void
+GrAtscFPLL::initialize ()
+{
+  float Fs = getInputSamplingFrequencyN (0);
+
+  float alpha = 1 - exp(-1.0 / Fs / 5e-6);
+  
+  afci.set_taps (alpha);
+  afcq.set_taps (alpha);
+
+  nco.set_freq (initial_freq / Fs * 2 * M_PI);
+  nco.set_phase (initial_phase);
+}
+
+int 
+GrAtscFPLL::work (VrSampleRange output, void *ao[],
+                 VrSampleRange inputs[], void *ai[])
+{
+  iType         *in = ((iType **)ai)[0];
+  oType  *out = ((oType **)ao)[0];
+
+  unsigned int k;
+
+  for (k = 0; k < output.size; k++){
+
+    float a_cos, a_sin;
+
+    float input = agc.scale (in[k]);
+
+    nco.step ();               // increment phase
+    nco.sincos (a_sin, a_cos); // compute cos and sin
+
+    float I = input * a_sin;
+    float Q = input * a_cos;
+
+    out[k] = I;
+
+    float filtered_I = afci.filter (I);
+    float filtered_Q = afcq.filter (Q);
+
+    // phase detector
+
+    float x = atan2 (filtered_Q, filtered_I);
+
+    // avoid slamming filter with big transitions
+
+    static const float limit = M_PI / 2;
+
+    if (x > limit)
+      x = limit;
+    else if (x < -limit)
+      x = -limit;
+
+    // static const float alpha = 0.037;   // Max value
+    // static const float alpha = 0.005;   // takes about 5k samples to pull in, stddev = 323
+    // static const float alpha = 0.002;   // takes about 15k samples to pull in, stddev =  69
+                                          //  or about 120k samples on noisy data, 
+    static const float alpha = 0.001;
+    static const float beta = alpha * alpha / 4;
+
+
+    if (!debug_no_update){
+      nco.adjust_phase (alpha * x);
+      nco.adjust_freq (beta * x);
+    }
+
+    if (_FPLL_DIAG_OUTPUT_){
+#if 0  // lots of data...
+      float    iodata[8];
+      iodata[0] = nco.get_freq () * getSamplingFrequency () * (1.0 / (2 * M_PI));
+      iodata[1] = in[k];
+      iodata[2] = input;
+      iodata[3] = I;
+      iodata[4] = Q;
+      iodata[5] = filtered_I;
+      iodata[6] = filtered_Q;
+      iodata[7] = x;
+      if (fwrite (iodata, sizeof (iodata), 1, fp) != 1){
+       perror ("fwrite: fpll");
+       exit (1);
+      }
+#else  // just the frequency
+      float    iodata[1];
+      iodata[0] = nco.get_freq () * getSamplingFrequency () * (1.0 / (2 * M_PI));
+      if (fwrite (iodata, sizeof (iodata), 1, fp) != 1){
+       perror ("fwrite: fpll");
+       exit (1);
+      }
+#endif
+    }
+  }
+
+  return output.size;
+}
+
diff --git a/gr-atsc/src/lib/GrAtscFPLL.h b/gr-atsc/src/lib/GrAtscFPLL.h
new file mode 100644 (file)
index 0000000..f89411a
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+
+#ifndef _GRATSCFPLL_H_
+#define _GRATSCFPLL_H_
+
+#include <gr_nco.h>
+#include <gr_iir.h>
+#include <gr_single_pole_iir.h>
+#include <gr_agc.h>
+#include <VrSigProc.h>
+#include <stdio.h>
+#include <atsci_diag_output.h>
+
+/*!
+ * \brief ATSC FPLL (2nd Version)
+ *
+ * Used as follows:
+ *                         float             float
+ *  A/D --> GrFIRfilterFFF ----> GrAtscFPLL ----> 
+ *
+ * We use GrFIRfilterFFF to bandpass filter the signal of interest.
+ *
+ * This class accepts a single real input and produces a single real output
+ */
+
+class GrAtscFPLL : public VrSigProc {
+ protected:
+
+  typedef float  iType;
+  typedef float         oType;
+  
+ public:
+
+  GrAtscFPLL (double a_initial_freq);
+  virtual ~GrAtscFPLL () {}
+
+  virtual const char *name () { return "GrAtscFPLL"; }
+
+  virtual void initialize ();
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+
+  // diagnostic routines
+  void set_initial_phase (double phase) { initial_phase = phase; }        // radians
+  void set_no_update (bool a_no_update) { debug_no_update = a_no_update; }
+
+
+ protected:
+
+  double                       initial_freq;
+  double                       initial_phase;
+  bool                         debug_no_update;
+  gr_nco<float,float>          nco;
+  gr_agc                       agc;    // automatic gain control
+  gr_single_pole_iir<float,float,float>        afci;
+  gr_single_pole_iir<float,float,float>        afcq;
+  
+#ifdef _FPLL_DIAG_OUTPUT_
+  FILE                         *fp;
+#endif
+
+};
+
+
+#endif // _GRATSCFPLL_H_
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncChecker.cc b/gr-atsc/src/lib/GrAtscFieldSyncChecker.cc
new file mode 100644 (file)
index 0000000..c52b184
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscFieldSyncChecker.h>
+#include <create_atsci_fs_checker.h>
+#include <atsci_fs_checker.h>
+
+// typedefs for fundamental i/o types
+
+typedef float          iDataType;
+typedef atsc::syminfo  iTagType;
+typedef float          oDataType;
+typedef atsc::syminfo  oTagType;
+
+static const int NUMBER_OF_OUTPUTS = 2;        // # of output streams 
+
+
+GrAtscFieldSyncChecker::GrAtscFieldSyncChecker ()
+  : VrHistoryProc<iDataType,oDataType> (NUMBER_OF_OUTPUTS)
+{
+  // tags and data must be same size due to limitation of runtime
+  assert (sizeof (iDataType) == sizeof (iTagType));
+  assert (sizeof (oDataType) == sizeof (oTagType));
+
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  d_fsc = create_atsci_fs_checker ();
+}
+
+GrAtscFieldSyncChecker::~GrAtscFieldSyncChecker ()
+{
+  // Anything that isn't automatically cleaned up...
+
+  delete d_fsc;
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscFieldSyncChecker::work (VrSampleRange output, void *ao[],
+                             VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, hence we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iDataType *sample_in  = ((iDataType **) ai)[0];
+  iTagType  *tag_in     = ((iTagType **)  ai)[1];
+  oDataType *sample_out = ((oDataType **) ao)[0];
+  oTagType  *tag_out    = ((oTagType **)  ao)[1];
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    d_fsc->filter (sample_in[i], tag_in[i], &sample_out[i], &tag_out[i]);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncChecker.h b/gr-atsc/src/lib/GrAtscFieldSyncChecker.h
new file mode 100644 (file)
index 0000000..e2f4828
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCFIELDSYNCCHECKER_H_
+#define _GRATSCFIELDSYNCCHECKER_H_
+
+#include <VrHistoryProc.h>
+
+class atsci_fs_checker;
+
+/*!
+ * \brief ATSC field sync checker (float,syminfo --> float,syminfo)
+ *
+ * first output is delayed version of input.
+ * second output is set of tags, one-for-one with first output.
+ */
+
+class GrAtscFieldSyncChecker : public VrHistoryProc<float,float>
+{
+
+public:
+
+  GrAtscFieldSyncChecker ();
+  ~GrAtscFieldSyncChecker ();
+
+  const char *name () { return "GrAtscFieldSyncChecker"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_fs_checker     *d_fsc;
+};
+
+#endif /* _GRATSCFIELDSYNCCHECKER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc
new file mode 100644 (file)
index 0000000..4cbf171
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscFieldSyncCorrelator.h>
+#include <create_atsci_fs_correlator.h>
+#include <atsci_fs_correlator.h>
+
+// typedefs for fundamental i/o types
+
+typedef float  iType;
+typedef float  oType;
+
+static const int NUMBER_OF_OUTPUTS = 2;        // # of output streams 
+
+
+GrAtscFieldSyncCorrelator::GrAtscFieldSyncCorrelator ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  d_fsc = create_atsci_fs_correlator ();
+}
+
+GrAtscFieldSyncCorrelator::~GrAtscFieldSyncCorrelator ()
+{
+  // Anything that isn't automatically cleaned up...
+
+  delete d_fsc;
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscFieldSyncCorrelator::work (VrSampleRange output, void *ao[],
+                                VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, hence we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *sample_out = ((oType **) ao)[0];
+  oType *tag_out    = ((oType **) ao)[1];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    d_fsc->filter (in[i], &sample_out[i], &tag_out[i]);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;
+}
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h
new file mode 100644 (file)
index 0000000..9f5c435
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCFIELDSYNCCORRELATOR_H_
+#define _GRATSCFIELDSYNCCORRELATOR_H_
+
+#include <VrHistoryProc.h>
+
+class atsci_fs_correlator;
+
+/*!
+ * \brief ATSC field sync correlator (float --> float,float)
+ *
+ * first output is delayed version of input.
+ * second output is set of tags, one-for-one with first output.
+ *
+ * tag values are defined in atsci_sync_tag.h
+ */
+
+class GrAtscFieldSyncCorrelator : public VrHistoryProc<float,float>
+{
+
+public:
+
+  GrAtscFieldSyncCorrelator ();
+  ~GrAtscFieldSyncCorrelator ();
+
+  const char *name () { return "GrAtscFieldSyncCorrelator"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_fs_correlator  *d_fsc;
+};
+
+#endif /* _GRATSCFIELDSYNCCORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncDemux.cc b/gr-atsc/src/lib/GrAtscFieldSyncDemux.cc
new file mode 100644 (file)
index 0000000..2394993
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cmath>
+#include <GrAtscFieldSyncDemux.h>
+#include <atsc_consts.h>
+#include <atsc_types.h>
+#include <atsci_syminfo.h>
+#include <stdio.h>
+#include <assert.h>
+
+using std::abs;
+
+static const int       DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor
+
+GrAtscFieldSyncDemux::GrAtscFieldSyncDemux ()
+  : VrDecimatingSigProc<float,atsc_soft_data_segment> (1, DEC),
+    d_locked (false), d_in_field2(true), d_segment_number(0), d_next_input(0),
+    d_lost_index (0)
+{
+  history = 2 * ATSC_DATA_SEGMENT_LENGTH;  // spare input samples in case we need them.
+}
+
+GrAtscFieldSyncDemux::~GrAtscFieldSyncDemux ()
+{
+}
+
+int
+GrAtscFieldSyncDemux::forecast (VrSampleRange output,
+                               VrSampleRange inputs[]) {
+  /* dec:1 ratio with history */
+
+  assert (numberInputs == 2);
+  
+  for (unsigned int i = 0; i < numberInputs; i++) {
+    inputs[i].index = d_next_input;
+    inputs[i].size = output.size * decimation + history - 1;
+  }
+  return 0;
+}  
+
+inline static bool
+tag_is_seg_sync_or_field_sync (atsc::syminfo tag)
+{
+  return tag.symbol_num == 0 && tag.valid;
+}
+
+int
+GrAtscFieldSyncDemux::work (VrSampleRange output, void *ao[],
+                           VrSampleRange inputs[], void *ai[])
+{
+  float         *input_samples = (float *) ai[0];
+  atsc::syminfo *input_tags    = (atsc::syminfo *) ai[1];
+  atsc_soft_data_segment  *out = ((atsc_soft_data_segment **)ao)[0];
+
+  sync (output.index);
+
+  unsigned int ii = 0;         // input index
+
+  // Are we in sync?
+  if (!tag_is_seg_sync_or_field_sync (input_tags[0])){     // No ...
+
+    if (d_locked){
+      d_locked = false;
+      d_lost_index = inputs[0].index + ii;
+      cerr << "GrAtscFieldSyncDemux: lost sync at  "
+          << d_lost_index << endl;
+    }
+
+    // ... search for beginning of a field sync
+
+    // cerr << "GrAtscFieldSyncDemux: searching for sync at "
+    //      << inputs[0].index + ii << endl;
+
+    for (ii = 1; ii < inputs[0].size; ii++){
+      if (atsc::tag_is_start_field_sync (input_tags[ii])){
+       // found one
+       d_locked = true;
+
+       const char *str;
+       if (atsc::tag_is_start_field_sync_1 (input_tags[ii]))
+         str = "FIELD-1";
+       else if (atsc::tag_is_start_field_sync_2 (input_tags[ii]))
+         str = "FIELD-2";
+       else
+         str = "SEGMENT";
+       
+       cerr << "GrAtscFieldSyncDemux: synced (" << str << ") at "
+            << inputs[0].index + ii
+            << " [delta = " << inputs[0].index + ii - d_lost_index
+            << "]\n";
+       
+       d_next_input += ii;     // update for forecast
+       return 0;               // no work completed so far
+      }
+    }
+    // no non-NORMAL tag found
+    d_next_input += ii;                // update for forecast
+    return 0;                  // no work completed so far
+  }
+    
+  // We are in sync.  Produce output...
+
+  unsigned int k = 0;          // output index
+
+  while (k < output.size){
+
+    if (inputs[0].size - ii < (unsigned) ATSC_DATA_SEGMENT_LENGTH){
+      // We're out of input data.
+      cerr << "GrAtscFieldSyncDemux: ran out of input data\n";
+      d_next_input += ii;      // update for forecast
+      return k;                        // return amount of work completed so far
+    }
+
+    if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){
+      // lost sync...
+      // cerr << "GrAtscFieldSyncDemux: lost sync at "
+      //    << inputs[0].index + ii << endl;
+      
+      d_next_input += ii;      // update for forecast
+      return k;                        // return amount of work completed so far
+    }
+
+    if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){
+      d_in_field2 = false;
+      d_segment_number = 0;
+      ii += ATSC_DATA_SEGMENT_LENGTH;  // skip over field sync
+      continue;
+    }
+    
+    if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){
+      d_in_field2 = true;
+      d_segment_number = 0;
+      ii += ATSC_DATA_SEGMENT_LENGTH;  // skip over field sync
+      continue;
+    }
+
+    if (d_segment_number >= ATSC_DSEGS_PER_FIELD){
+      // something's wrong...
+      cerr << "GrAtscFieldSyncDemux: segment number overflow\n";
+      d_segment_number = 0;
+    }
+
+    out[k].pli.set_regular_seg (d_in_field2, d_segment_number++);
+    for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++)
+      out[k].data[jj] = input_samples[ii + jj];
+    ii += ATSC_DATA_SEGMENT_LENGTH;
+    k++;
+  }
+
+  d_next_input += ii;          // update for forecast
+  return k;                    // return amount of work completed
+}
+
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncDemux.h b/gr-atsc/src/lib/GrAtscFieldSyncDemux.h
new file mode 100644 (file)
index 0000000..5796aa2
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCFIELDSYNCDEMUX_H_
+#define _GRATSCFIELDSYNCDEMUX_H_
+
+#include <VrDecimatingSigProc.h>
+#include <atsc_types.h>
+
+/*!
+ * \brief ATSC Field Sync Demux
+ *
+ * This class accepts 1 stream of floats (data), and 1 stream of tags (syminfo).
+ * It outputs one stream of atsc_soft_data_segment packets
+ */
+
+class GrAtscFieldSyncDemux : public VrDecimatingSigProc<float,atsc_soft_data_segment> {
+
+ public:
+
+  GrAtscFieldSyncDemux ();
+  virtual ~GrAtscFieldSyncDemux ();
+
+  virtual const char *name () { return "GrAtscFieldSyncDemux"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+ protected:
+
+  bool           d_locked;
+  bool           d_in_field2;
+  int            d_segment_number;
+  VrSampleIndex          d_next_input;
+  VrSampleIndex          d_lost_index;         // diagnostic fluff
+};
+
+#endif // _GRATSCFIELDSYNCDEMUX_H_
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncMux.cc b/gr-atsc/src/lib/GrAtscFieldSyncMux.cc
new file mode 100644 (file)
index 0000000..8df36ba
--- /dev/null
@@ -0,0 +1,246 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscFieldSyncMux.h>
+#include <atsci_pnXXX.h>
+
+
+// typedefs for fundamental i/o types
+
+typedef atsc_data_segment      iType;
+typedef atsc_data_segment      oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+static const int N_SAVED_SYMBOLS = GrAtscFieldSyncMux::N_SAVED_SYMBOLS;
+
+static void
+init_field_sync_common (unsigned char *p, int mask,
+                       const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+{
+  static const unsigned char bin_map[2] = { 1, 6 };  // map binary values to 1 of 8 levels
+
+  int  i = 0;
+
+  p[i++] = bin_map[1];                 // data segment sync pulse
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  for (int j = 0; j < 511; j++)                // PN511
+    p[i++] = bin_map[atsc_pn511[j]];
+
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map[atsc_pn63[j]];
+
+  for (int j = 0; j < 63; j++)         // PN63, toggled on field 2
+    p[i++] = bin_map[atsc_pn63[j] ^ mask];
+  
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map[atsc_pn63[j]];
+
+  p[i++] = bin_map[0];                 // 24 bits of VSB8 mode identifiera
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+
+
+  for (int j = 0; j < 92; j++)         // 92 more bits
+    p[i++] = bin_map[atsc_pn63[j % 63]];
+
+  // now copy the last 12 symbols of the previous segment
+
+  for (int j = 0; j < N_SAVED_SYMBOLS; j++)
+    p[i++] = saved_symbols[j];
+
+  assert (i == ATSC_DATA_SEGMENT_LENGTH);
+}
+
+inline static void
+init_field_sync_1 (atsc_data_segment *s,
+                  const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+{
+  init_field_sync_common (&s->data[0], 0, saved_symbols);
+}
+
+inline static void
+init_field_sync_2 (atsc_data_segment *s,
+                  const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+
+{
+  init_field_sync_common (&s->data[0], 1, saved_symbols);
+}
+
+static void
+save_last_symbols (unsigned char saved_symbols[N_SAVED_SYMBOLS],
+                  const atsc_data_segment &seg)
+{
+  for (int i = 0; i < N_SAVED_SYMBOLS; i++)
+    saved_symbols[i] = seg.data[i + ATSC_DATA_SEGMENT_LENGTH - N_SAVED_SYMBOLS];
+}
+
+
+inline static bool 
+last_regular_seg_p (const plinfo &pli)
+{
+  return pli.regular_seg_p () && (pli.segno () == ATSC_DSEGS_PER_FIELD - 1);
+}
+
+
+GrAtscFieldSyncMux::GrAtscFieldSyncMux ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS),
+    d_current_index (0), d_already_output_field_sync (false)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscFieldSyncMux::~GrAtscFieldSyncMux ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+void
+GrAtscFieldSyncMux::pre_initialize ()
+{
+  // we jack our output sampling frequency up to account for inserted field syncs
+  setSamplingFrequency (getInputSamplingFrequencyN (0) * 313./312.);
+}
+
+/*
+ * we need a non-standard version of forecast because our output isn't
+ * exactly 1:1 with our input.
+ */
+
+int 
+GrAtscFieldSyncMux::forecast (VrSampleRange output, VrSampleRange inputs[])
+{
+  for(unsigned int i = 0; i < numberInputs; i++) {
+    inputs[i].index = d_current_index;
+    inputs[i].size = output.size;
+  }
+  return 0;
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+int 
+GrAtscFieldSyncMux::work (VrSampleRange output, void *ao[],
+                         VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, hence we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  unsigned int index = 0;
+  for (unsigned int outdex = 0; outdex < output.size; outdex++){
+
+    assert (in[index].pli.regular_seg_p ());
+    
+    if (!in[index].pli.first_regular_seg_p ()){
+      out[outdex] = in[index];                 // just copy in to out
+
+      if (last_regular_seg_p (in[index].pli))
+       save_last_symbols (d_saved_symbols, in[index]);
+
+      index++;
+    }
+    else {                                     // first_regular_seg_p
+      if (!d_already_output_field_sync){
+       // write out field sync...
+       atsc_data_segment       field_sync;
+
+       if (in[index].pli.in_field1_p ())
+         init_field_sync_1 (&field_sync, d_saved_symbols);
+       else
+         init_field_sync_2 (&field_sync, d_saved_symbols);
+
+       // note that index doesn't advance in this branch
+       out[outdex] = field_sync;
+       d_already_output_field_sync = true;
+      }
+      else {
+       // already output field sync, now output first regular segment
+       out[outdex] = in[index];
+       index++;
+       d_already_output_field_sync = false;
+      }
+    }
+  }
+
+  d_current_index += index;
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscFieldSyncMux.h b/gr-atsc/src/lib/GrAtscFieldSyncMux.h
new file mode 100644 (file)
index 0000000..66dd449
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCFIELDSYNCMUX_H_
+#define _GRATSCFIELDSYNCMUX_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+
+/*!
+ * \brief Insert ATSC Field Syncs as required (atsc_data_segment --> atsc_data_segment)
+ */
+
+class GrAtscFieldSyncMux : public VrHistoryProc<atsc_data_segment, atsc_data_segment>
+{
+
+public:
+
+  GrAtscFieldSyncMux ();
+  ~GrAtscFieldSyncMux ();
+
+  const char *name () { return "GrAtscFieldSyncMux"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+  int forecast (VrSampleRange output, VrSampleRange inputs[]);
+
+  void pre_initialize ();
+  
+  static const int     N_SAVED_SYMBOLS = 12;
+
+protected:
+  VrSampleIndex                d_current_index;
+  bool                 d_already_output_field_sync;
+  unsigned char                d_saved_symbols[N_SAVED_SYMBOLS];
+};
+
+#endif /* _GRATSCFIELDSYNCMUX_H_ */
diff --git a/gr-atsc/src/lib/GrAtscInterleaver.cc b/gr-atsc/src/lib/GrAtscInterleaver.cc
new file mode 100644 (file)
index 0000000..cd50a86
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscInterleaver.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_rs_encoded    iType;
+typedef atsc_mpeg_packet_rs_encoded    oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscInterleaver::GrAtscInterleaver ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscInterleaver::~GrAtscInterleaver ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscInterleaver::work (VrSampleRange output, void *ao[],
+                        VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current contents of the FIFOs, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+#if 0
+  cerr << "@@@ GrAtscInterleaver: output.index = " << output.index
+       << " output.size = " << output.size
+       << " sum = " << output.index + output.size
+       << " \t[out = " << out << "]"
+       << endl;
+#endif
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    // pipeline info is handled in the primitive
+    interleaver.interleave (out[i], in[i]);
+  }
+
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscInterleaver.h b/gr-atsc/src/lib/GrAtscInterleaver.h
new file mode 100644 (file)
index 0000000..0706613
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCINTERLEAVER_H_
+#define _GRATSCINTERLEAVER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_data_interleaver.h>
+
+/*!
+ * \brief Interleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)
+ */
+
+class GrAtscInterleaver : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_rs_encoded>
+{
+
+public:
+
+  GrAtscInterleaver ();
+  ~GrAtscInterleaver ();
+
+  const char *name () { return "GrAtscInterleaver"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_data_interleaver       interleaver;
+};
+
+#endif /* _GRATSCINTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscRSDecoder.cc b/gr-atsc/src/lib/GrAtscRSDecoder.cc
new file mode 100644 (file)
index 0000000..c9092a2
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscRSDecoder.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_rs_encoded    iType;
+typedef atsc_mpeg_packet_no_sync       oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscRSDecoder::GrAtscRSDecoder ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscRSDecoder::~GrAtscRSDecoder ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscRSDecoder::work (VrSampleRange output, void *ao[],
+                         VrSampleRange inputs[], void *ai[])
+{
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+    assert (in[i].pli.regular_seg_p ());
+    out[i].pli = in[i].pli;            // copy pipeline info
+
+    int nerrors_not_corrected = rs_decoder.decode (out[i], in[i]);
+    out[i].pli.set_transport_error (nerrors_not_corrected == -1);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscRSDecoder.h b/gr-atsc/src/lib/GrAtscRSDecoder.h
new file mode 100644 (file)
index 0000000..4586a20
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCRSDECODER_H_
+#define _GRATSCRSDECODER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_reed_solomon.h>
+
+/*!
+ * \brief Pass ATSC data Reed-Solomon decoder( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_rs_no_sync)
+ */
+
+class GrAtscRSDecoder : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_no_sync>
+{
+
+public:
+
+  GrAtscRSDecoder ();
+  ~GrAtscRSDecoder ();
+
+  const char *name () { return "GrAtscRSDecoder"; }
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_reed_solomon   rs_decoder;
+};
+
+#endif /* _GRATSCRSDECODER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscRSEncoder.cc b/gr-atsc/src/lib/GrAtscRSEncoder.cc
new file mode 100644 (file)
index 0000000..2954779
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscRSEncoder.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_no_sync       iType;
+typedef atsc_mpeg_packet_rs_encoded    oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscRSEncoder::GrAtscRSEncoder ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscRSEncoder::~GrAtscRSEncoder ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscRSEncoder::work (VrSampleRange output, void *ao[],
+                       VrSampleRange inputs[], void *ai[])
+{
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+
+    // ensure that on the way in, the error bit is clear
+    // [assertion is not valid, because the randomizer has already scrambled the bits]
+    // assert ((in[i].data[0] & MPEG_TRANSPORT_ERROR_BIT) == 0);
+
+    assert (in[i].pli.regular_seg_p ());
+    out[i].pli = in[i].pli;                    // copy pipeline info...
+    rs_encoder.encode (out[i], in[i]);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscRSEncoder.h b/gr-atsc/src/lib/GrAtscRSEncoder.h
new file mode 100644 (file)
index 0000000..3f41d77
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCRSENCODER_H_
+#define _GRATSCRSENCODER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_reed_solomon.h>
+
+/*!
+ * \brief Encode using Reed Solomon ATSC data (atsc_mpeg_packet_no_sync --> atsc_mpeg_packet_rs_encoded)
+ */
+
+class GrAtscRSEncoder : public VrHistoryProc<atsc_mpeg_packet_no_sync, atsc_mpeg_packet_rs_encoded>
+{
+
+public:
+
+  GrAtscRSEncoder ();
+  ~GrAtscRSEncoder ();
+
+  const char *name () { return "GrAtscRSEncoder"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_reed_solomon   rs_encoder;
+};
+
+#endif /* _GRATSCRSENCODER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscRandomizer.cc b/gr-atsc/src/lib/GrAtscRandomizer.cc
new file mode 100644 (file)
index 0000000..3217b9b
--- /dev/null
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscRandomizer.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet               iType;
+typedef atsc_mpeg_packet_no_sync       oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscRandomizer::GrAtscRandomizer ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS),
+    field2 (false), segno (0)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  // We're one-to-one input-to-output so set it to 1.
+  history = 1; 
+
+  // any other init here.
+}
+
+GrAtscRandomizer::~GrAtscRandomizer ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscRandomizer::work (VrSampleRange output, void *ao[],
+                       VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current contents of the LFSR in the randomizer, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i++){
+
+    // initialize plinfo for downstream
+    //
+    // We do this here because the randomizer is effectively
+    // the head of the tx processing chain
+    //
+    out[i].pli.set_regular_seg (field2, segno);
+    segno++;
+    if (segno == 312){
+      segno = 0;
+      field2 = !field2;
+    }
+
+    assert ((in[i].data[1] & MPEG_TRANSPORT_ERROR_BIT) == 0);
+
+    if (out[i].pli.first_regular_seg_p ())
+      rand.reset ();
+
+    rand.randomize (out[i], in[i]);
+  }
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscRandomizer.h b/gr-atsc/src/lib/GrAtscRandomizer.h
new file mode 100644 (file)
index 0000000..7a1908d
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCRANDOMIZER_H_
+#define _GRATSCRANDOMIZER_H_
+
+#include <VrHistoryProc.h>
+#include <atsc_types.h>
+#include <atsci_randomizer.h>
+
+/*!
+ * \brief Randomize ATSC data (atsc_mpeg_packet --> atsc_mpeg_packet_no_sync)
+ */
+
+class GrAtscRandomizer : public VrHistoryProc<atsc_mpeg_packet, atsc_mpeg_packet_no_sync>
+{
+
+public:
+
+  GrAtscRandomizer ();
+  ~GrAtscRandomizer ();
+
+  const char *name () { return "GrAtscRandomizer"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_randomizer     rand;
+
+  // used to initialize plinfo in output
+  bool                 field2;
+  int                  segno;
+};
+
+#endif /* _GRATSCRANDOMIZER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscSegSymSync.cc b/gr-atsc/src/lib/GrAtscSegSymSync.cc
new file mode 100644 (file)
index 0000000..721f36c
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscSegSymSync.h>
+#include <GrAtscSegSymSyncImpl_export.h>
+#include <iostream>
+#include <assert.h>
+
+static const int DECIMATION = 2;       // close enough for super class's use
+static const int N_OUTPUTS = 2;
+
+GrAtscSegSymSync::GrAtscSegSymSync ()
+  : VrDecimatingSigProc<float,float> (N_OUTPUTS, DECIMATION)
+{
+  if (sizeof (float) != sizeof (atsc::syminfo)){
+    cerr << "GrAtscSegSymSync: sizeof (float) != sizeof (atsc::syminfo)\n";
+    assert (0);
+  }
+}
+
+GrAtscSegSymSync::~GrAtscSegSymSync ()
+{
+  // Nop
+}
+
+
+GrAtscSegSymSync *
+GrAtscSegSymSync::create (double nominal_ratio_of_rx_clock_to_symbol_freq)
+{
+  return create_GrAtscSegSymSyncImpl (nominal_ratio_of_rx_clock_to_symbol_freq);
+}
diff --git a/gr-atsc/src/lib/GrAtscSegSymSync.h b/gr-atsc/src/lib/GrAtscSegSymSync.h
new file mode 100644 (file)
index 0000000..0f01a8d
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCSEGSYMSYNC_H_
+#define _GRATSCSEGSYMSYNC_H_
+
+#include <VrDecimatingSigProc.h>
+
+/*!
+ * \brief ATSC SegSymSync
+ *
+ * Abstract class that establishes symbol timing and synchronizes
+ * with data segment boundaries.
+ *
+ * Takes a single stream of floats as the input and
+ * produces two streams as output.  The first stream is the data samples
+ * and is of type float.  The second stream is the tags, and is of type syminfo.
+ *
+ * The current GNU Radio interface doesn't currently support different
+ * types on the input ports (or output ports for that matter), but
+ * since they are the same size, it works.
+ */
+
+#include <atsci_syminfo.h>
+
+class GrAtscSegSymSync : public VrDecimatingSigProc<float,float> {
+
+public:
+
+  GrAtscSegSymSync ();
+  ~GrAtscSegSymSync ();
+  
+  /*!
+   * \brief reset bit timing loop on channel change
+   */
+  virtual void reset () = 0;
+
+  /*!
+   * \brief create an instance of GrAtscSegSymSync
+   */
+  static GrAtscSegSymSync *create (double nominal_ratio_of_rx_clock_to_symbol_freq);
+
+};
+
+#endif // _GRATSCSEGSYMSYNC_H_
diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc
new file mode 100644 (file)
index 0000000..a7925bf
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscSegSymSyncImpl.h>
+#include <GrAtscSegSymSyncImpl_export.h>
+#include <cmath>
+#include <assert.h>
+
+GrAtscSegSymSyncImpl::GrAtscSegSymSyncImpl (
+    double nominal_ratio_of_rx_clock_to_symbol_freq)
+  : d_interp (nominal_ratio_of_rx_clock_to_symbol_freq)
+{
+  // set approximate decimation rate for superclass's benefit
+  decimation = (int) rint (nominal_ratio_of_rx_clock_to_symbol_freq);
+
+  history = 1500;      // spare input samples in case we need them.
+  
+  d_sssr.reset ();
+  d_interp.reset ();
+  d_next_input = 0;
+  d_rx_clock_to_symbol_freq = nominal_ratio_of_rx_clock_to_symbol_freq;
+}
+
+GrAtscSegSymSyncImpl::~GrAtscSegSymSyncImpl ()
+{
+  // Nop
+}
+
+void
+GrAtscSegSymSyncImpl::pre_initialize ()
+{
+  setSamplingFrequency (
+     getInputSamplingFrequencyN (0) / d_rx_clock_to_symbol_freq);
+}
+
+int
+GrAtscSegSymSyncImpl::forecast (VrSampleRange output,
+                               VrSampleRange inputs[])
+{
+  assert (numberInputs == 1);  // I hate these free references to
+                               // superclass's instance variables...
+
+  inputs[0].index = d_next_input;
+  inputs[0].size =
+    ((long unsigned int) (output.size * d_rx_clock_to_symbol_freq)
+     + history - 1);
+
+  return 0;
+}
+
+int
+GrAtscSegSymSyncImpl::work (VrSampleRange output, void *ao[],
+                           VrSampleRange inputs[], void *ai[])
+{
+#if 0
+  float                *input_samples  = ((float **) ai)[0];
+  float         *output_samples = ((float **) ao)[0];
+  atsc::syminfo *output_info    = ((atsc::syminfo **) ao)[1];
+
+  // FIXME finish...
+#endif
+  assert (0);
+
+  return output.size;
+}
+
+void
+GrAtscSegSymSyncImpl::reset ()
+{
+  d_sssr.reset ();
+  d_interp.reset ();
+}
+
+
+/*
+ * Exported constructor.
+ * Doesn't expose any of the internals or our compile time dependencies.
+ */
+
+GrAtscSegSymSync *
+create_GrAtscSegSymSyncImpl (double nominal_ratio_of_rx_clock_to_symbol_freq)
+{
+  return new GrAtscSegSymSyncImpl (nominal_ratio_of_rx_clock_to_symbol_freq);
+}
diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl.h b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.h
new file mode 100644 (file)
index 0000000..b1052cf
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _GRATSCSEGSYMSYNCIMPL_H_
+#define _GRATSCSEGSYMSYNCIMPL_H_
+
+#include <GrAtscSegSymSync.h>
+#include <atsci_sssr.h>
+
+
+/*!
+ * \brief concrete implementation of GrAtscSegSymSync
+ *
+ * This class implements data segment sync tracking and symbol timing
+ * using a variation of the method described in
+ * "ATSC/VSB Tutorial - Receiver Technology" by Wayne E. Bretl of
+ * Zenith, pgs 41-45.
+ */
+
+class GrAtscSegSymSyncImpl : public GrAtscSegSymSync {
+
+  atsci_sssr           d_sssr;
+  atsci_interpolator   d_interp;
+  VrSampleIndex                d_next_input;
+  double               d_rx_clock_to_symbol_freq;      // nominal ratio
+
+public:
+
+  // the standard methods...
+  
+  GrAtscSegSymSyncImpl (double nominal_ratio_of_rx_clock_to_symbol_freq);
+  virtual ~GrAtscSegSymSyncImpl ();
+
+  virtual const char *name () { return "GrAtscSegSymSyncImpl"; }
+
+  virtual int forecast (VrSampleRange output,
+                       VrSampleRange inputs[]);
+
+  virtual int work (VrSampleRange output, void *o[],
+                   VrSampleRange inputs[], void *i[]);
+
+  void pre_initialize ();
+  
+
+  // reset on channel change
+
+  virtual void reset ();
+
+};
+
+#endif /* _GRATSCSEGSYMSYNCIMPL_H_ */
diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h b/gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h
new file mode 100644 (file)
index 0000000..569c0dd
--- /dev/null
@@ -0,0 +1,26 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+class GrAtscSegSymSync;
+
+GrAtscSegSymSync *create_GrAtscSegSymSyncImpl (
+       double nominal_ratio_of_rx_clock_to_symbol_freq);
diff --git a/gr-atsc/src/lib/GrAtscSymbolMapper.h b/gr-atsc/src/lib/GrAtscSymbolMapper.h
new file mode 100644 (file)
index 0000000..41bea59
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCSYMBOLMAPPER_H_
+#define _GRATSCSYMBOLMAPPER_H_
+
+
+#include <VrInterpolatingSigProcNoWork.h>
+#include <atsc_types.h>
+#include <gr_nco.h>
+
+/*!
+ * \brief take atsc_data_segments and map them to symbols.
+ *
+ * Input is a stream of atsc_data_segments.
+ * Output is a stream of symbols at 1x the symbol rate
+ *
+ * This module performs the signal mapping & pilot addition.
+ */
+
+template<class oType>
+class GrAtscSymbolMapper
+  : public VrInterpolatingSigProcNoWork<atsc_data_segment, oType> {
+
+public:
+  GrAtscSymbolMapper ()
+    : VrInterpolatingSigProcNoWork<atsc_data_segment, oType>(1, INTERP_FACTOR) {};
+
+  ~GrAtscSymbolMapper () {};
+
+  const char *name () { return "GrAtscSymbolMapper"; }
+
+  int work (VrSampleRange output, void *ao[],
+           VrSampleRange inputs[], void *ai[]);
+
+protected:
+  static const int     INTERP_FACTOR = ATSC_DATA_SEGMENT_LENGTH;
+};
+
+
+template<class oType>
+int 
+GrAtscSymbolMapper<oType>::work (VrSampleRange output, void *ao[],
+                                VrSampleRange inputs[], void *ai[])
+{
+  atsc_data_segment    *in =  ((atsc_data_segment **) ai)[0];
+  oType                *out = ((oType **) ao)[0];
+  
+  assert ((output.size % INTERP_FACTOR) == 0);
+  
+  static const float pilot_add = 1.25;
+  static const float map[8] = {
+    -7 + pilot_add,
+    -5 + pilot_add,
+    -3 + pilot_add,
+    -1 + pilot_add,
+     1 + pilot_add,
+     3 + pilot_add,
+     5 + pilot_add,
+     7 + pilot_add
+  };
+
+  unsigned int oo = 0;
+  unsigned int nsegs = output.size / INTERP_FACTOR;
+
+  for (unsigned int n = 0; n < nsegs; n++){
+    unsigned char *symbol = in[n].data;
+
+    for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++){
+      out[oo++] = (oType) map[symbol[i] & 0x7];
+    }
+  }
+
+  assert (oo == output.size);
+  return output.size;
+}
+
+#endif /* _GRATSCSYMBOLMAPPER_H_ */
diff --git a/gr-atsc/src/lib/GrAtscTrellisEncoder.cc b/gr-atsc/src/lib/GrAtscTrellisEncoder.cc
new file mode 100644 (file)
index 0000000..9def275
--- /dev/null
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscTrellisEncoder.h>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_mpeg_packet_rs_encoded    iType;
+typedef atsc_data_segment              oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscTrellisEncoder::GrAtscTrellisEncoder ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), last_start(-1)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  //
+  // We need our input to be aligned on a 12-segment boundary,
+  // to ensure satisfaction, ask for 11 more
+  history = 1 + (atsci_trellis_encoder::NCODERS - 1);
+
+  // any other init here.
+
+  // Let the bottom end know we must produce output in multiples of 12 segments.  
+  setOutputSize (atsci_trellis_encoder::NCODERS);
+}
+
+GrAtscTrellisEncoder::~GrAtscTrellisEncoder ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscTrellisEncoder::work (VrSampleRange output, void *ao[],
+                           VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current state of the encoders, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+#if 0
+  cerr << "@@@ GrAtscTrellisEncoder: output.index = " << output.index
+       << " output.size = " << output.size
+       << " sum = " << output.index + output.size
+       << " \t[in  = " << in << "]"
+       << endl;
+#endif  
+
+  assert (output.size % atsci_trellis_encoder::NCODERS == 0);
+
+
+  // find the first mod 12 boundary to begin decoding
+  int start;
+  for (start = 0; start < atsci_trellis_encoder::NCODERS; start++){
+    plinfo::sanity_check (in[start].pli);
+    assert (in[start].pli.regular_seg_p ());
+    if ((in[start].pli.segno () % atsci_trellis_encoder::NCODERS) == 0)
+      break;
+  }
+
+  if (start == atsci_trellis_encoder::NCODERS){
+    // we didn't find a mod 12 boundary.  There's some kind of problem
+    // upstream of us (not yet sync'd??)
+    cerr << "!!!GrAtscTrellisEncoder: no mod-12 boundary found\7\n";
+    start = 0;
+  }
+  else if (start != last_start){
+    cerr << "GrAtscTrellisEncoder: new starting offset = " << start
+        << " output.index = " << output.index << endl;
+    last_start = start;
+  }
+
+
+  // FIXME paranoid check for problem
+  for (unsigned int i = 0; i < output.size; i++){
+    plinfo::sanity_check (in[i + start].pli);
+  }
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i += atsci_trellis_encoder::NCODERS){
+    // primitive does 12 segments at a time.
+    // pipeline info is handled in the primitive.
+    encoder.encode (&out[i], &in[i + start]);
+  }
+
+#if 0
+  // FIXME paranoid check for problem
+  for (unsigned int i = 0; i < output.size; i++){
+    plinfo::sanity_check (out[i].pli);
+    assert (out[i].pli.regular_seg_p ());
+  }
+#endif
+
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscTrellisEncoder.h b/gr-atsc/src/lib/GrAtscTrellisEncoder.h
new file mode 100644 (file)
index 0000000..ebe8daf
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCTRELLISENCODER_H_
+
+#include <VrHistoryProc.h>
+#include <atsci_trellis_encoder.h>
+
+/*!
+ * \brief ATSC 12-way interleaved trellis encoder (atsc_mpeg_packet_rs_encoded --> atsc_data_segment)
+ */
+
+class GrAtscTrellisEncoder : public VrHistoryProc<atsc_mpeg_packet_rs_encoded,atsc_data_segment>
+{
+
+public:
+
+  GrAtscTrellisEncoder ();
+  ~GrAtscTrellisEncoder ();
+
+  const char *name () { return "GrAtscTrellisEncoder"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_trellis_encoder        encoder;
+  int                  last_start;
+};
+
+#endif
diff --git a/gr-atsc/src/lib/GrAtscViterbiDecoder.cc b/gr-atsc/src/lib/GrAtscViterbiDecoder.cc
new file mode 100644 (file)
index 0000000..98e0a81
--- /dev/null
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <GrAtscViterbiDecoder.h>
+#include <iostream>
+
+// typedefs for fundamental i/o types
+
+typedef atsc_soft_data_segment         iType;
+typedef atsc_mpeg_packet_rs_encoded    oType;
+
+static const int NUMBER_OF_OUTPUTS = 1;        // # of output streams (almost always one)
+
+
+GrAtscViterbiDecoder::GrAtscViterbiDecoder ()
+  : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), last_start(-1)
+{
+  // 1 + number of extra input elements at which we look.  This is
+  // used by the superclass's forecast routine to get us the correct
+  // range on our inputs.
+  //
+  // We need our input to be aligned on a 12-segment boundary,
+  // to ensure satisfaction, ask for 11 more
+  history = 1 + (atsci_viterbi_decoder::NCODERS - 1);
+
+  // any other init here.
+
+  // Let the bottom end know we must produce output in multiples of 12 segments.  
+  setOutputSize (atsci_viterbi_decoder::NCODERS);
+}
+
+GrAtscViterbiDecoder::~GrAtscViterbiDecoder ()
+{
+  // Anything that isn't automatically cleaned up...
+}
+
+/*
+ * This is the real work horse.  In general this interface can handle
+ * multiple streams of input and output, but we almost always
+ * use a single input and output stream.
+ */
+
+int 
+GrAtscViterbiDecoder::work (VrSampleRange output, void *ao[],
+                           VrSampleRange inputs[], void *ai[])
+{
+  // If we have state that persists across invocations (e.g., we have
+  // instance variables that we modify), we must use the sync method
+  // to indicate to the scheduler that our output must be computed in
+  // order.  This doesn't keep other things from being run in
+  // parallel, it just means that at any given time, there is only a
+  // single thread working this code, and that the scheduler will
+  // ensure that we are asked to produce output that is contiguous and
+  // that will be presented to us in order of increasing time.
+
+  // We have state, the current state of the decoder, hence
+  // we must use sync.
+
+  sync (output.index);
+
+  // construct some nicer i/o pointers to work with.
+
+  iType *in  = ((iType **) ai)[0];
+  oType *out = ((oType **) ao)[0];
+
+
+  assert (output.size % atsci_viterbi_decoder::NCODERS == 0);
+
+  // find the first mod 12 boundary to begin decoding
+  int start;
+  for (start = 0; start < atsci_viterbi_decoder::NCODERS; start++){
+    assert (in[start].pli.regular_seg_p ());
+    if ((in[start].pli.segno () % atsci_viterbi_decoder::NCODERS) == 0)
+      break;
+  }
+
+  if (start == atsci_viterbi_decoder::NCODERS){
+    // we didn't find a mod 12 boundary.  There's some kind of problem
+    // upstream of us (not yet sync'd??)
+    cerr << "!!!GrAtscViterbiDecoder: no mod-12 boundary found\7\n";
+    start = 0;
+  }
+  else if (start != last_start){
+    cerr << "GrAtscViterbiDecoder: new starting offset = " << start
+        << " output.index = " << output.index << endl;
+    last_start = start;
+  }
+
+  // We must produce output.size units of output.
+
+  for (unsigned int i = 0; i < output.size; i += atsci_viterbi_decoder::NCODERS){
+    // primitive does 12 segments at a time.
+    // pipeline info is handled in the primitive.
+    decoder.decode (&out[i], &in[i + start]);
+  }
+
+#if 0
+  // FIXME paranoid check...
+  for (unsigned int i = 0; i < output.size; i++){
+    plinfo::sanity_check (out[i].pli);
+    assert (out[i].pli.regular_seg_p ());
+  }
+#endif
+
+#if 0
+  cerr << "@@@ GrAtscViterbiDecoder: output.index = " << output.index
+       << " output.size = " << output.size
+       << " sum = " << output.index + output.size << endl;
+#endif
+  
+  // Return the number of units we produced.
+  // Note that for all intents and purposes, it is an error to
+  // produce less than you are asked for.
+
+  return output.size;  
+}
diff --git a/gr-atsc/src/lib/GrAtscViterbiDecoder.h b/gr-atsc/src/lib/GrAtscViterbiDecoder.h
new file mode 100644 (file)
index 0000000..4bc93e8
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _GRATSCVITERBIDECODER_H_
+
+#include <VrHistoryProc.h>
+#include <atsci_viterbi_decoder.h>
+
+/*!
+ * \brief ATSC 12-way interleaved viterbi decoder (atsc_soft_data_segment --> atsc_mpeg_packet_rs_encoded)
+ */
+
+class GrAtscViterbiDecoder : public VrHistoryProc<atsc_soft_data_segment,
+                                                 atsc_mpeg_packet_rs_encoded>
+{
+
+public:
+
+  GrAtscViterbiDecoder ();
+  ~GrAtscViterbiDecoder ();
+
+  const char *name () { return "GrAtscViterbiDecoder"; }
+
+  int work (VrSampleRange output, void *o[],
+           VrSampleRange inputs[], void *i[]);
+
+protected:
+  atsci_viterbi_decoder        decoder;
+  int                  last_start;
+};
+
+#endif
diff --git a/gr-atsc/src/lib/Makefile.am b/gr-atsc/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..bf9c662
--- /dev/null
@@ -0,0 +1,242 @@
+#
+# Copyright 2001,2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \
+       $(CPPUNIT_INCLUDES) $(WITH_INCLUDES)
+
+EXTRA_DIST =                                   \
+       atsci_viterbi_gen.cc                    \
+       gen_encoder.py                          \
+       qa_atsci_trellis_encoder_t1_input.dat   \
+       qa_atsci_trellis_encoder_t1_output.dat  \
+       qa_atsci_viterbi_decoder_t1_input.dat   \
+       qa_atsci_viterbi_decoder_t1_output.dat
+
+
+TESTS =        test_atsci
+
+lib_LTLIBRARIES = libgnuradio-atsc.la
+
+# FIXME
+#      atsci_exp2_lp.cc                        \
+#      atsci_root_raised_cosine.cc             \
+#      atsci_root_raised_cosine_bandpass.cc    \
+#      atsci_vsbtx_lp.cc                       \
+#
+
+libgnuradio_atsc_la_SOURCES =                  \
+       atsc_derandomizer.cc                    \
+       atsc_randomizer.cc                      \
+       atsc_rs_decoder.cc                      \
+       atsc_rs_encoder.cc                      \
+       atsc_interleaver.cc                     \
+       atsc_deinterleaver.cc                   \
+       atsc_trellis_encoder.cc                 \
+       atsc_viterbi_decoder.cc                 \
+       atsc_ds_to_softds.cc                    \
+       atsc_field_sync_mux.cc                  \
+       atsc_field_sync_demux.cc                \
+       atsc_equalizer.cc                       \
+       atsc_fs_checker.cc                      \
+       atsc_bit_timing_loop.cc                 \
+       atsc_fpll.cc                            \
+       atsc_depad.cc                           \
+       atsc_pad.cc                             \
+       atsci_basic_trellis_encoder.cc          \
+       atsci_data_interleaver.cc               \
+       atsci_equalizer.cc                      \
+       atsci_equalizer_lms.cc                  \
+       atsci_equalizer_lms2.cc                 \
+       atsci_equalizer_nop.cc                  \
+       atsci_fake_single_viterbi.cc            \
+       atsci_fs_checker.cc                     \
+       atsci_fs_checker_naive.cc               \
+       atsci_fs_correlator.cc                  \
+       atsci_fs_correlator_naive.cc            \
+       atsci_single_viterbi.cc                 \
+       atsci_sssr.cc                           \
+       atsci_pnXXX.cc                          \
+       atsci_randomizer.cc                     \
+       atsci_reed_solomon.cc                   \
+       atsci_sliding_correlator.cc             \
+       atsci_trellis_encoder.cc                \
+       atsci_viterbi_decoder.cc                \
+       create_atsci_equalizer.cc               \
+       create_atsci_fs_checker.cc              \
+       create_atsci_fs_correlator.cc           \
+       plinfo.cc                               
+
+BUILT_SOURCES =                                \
+       atsci_viterbi_mux.cc
+
+libgnuradio_atsc_la_LIBADD =                   \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_atsc_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+noinst_LTLIBRARIES = libgnuradio-atsc-qa.la
+
+libgnuradio_atsc_qa_la_SOURCES =               \
+       qa_atsci_basic_trellis_encoder.cc       \
+       qa_atsci_data_interleaver.cc            \
+       qa_atsci_equalizer_nop.cc               \
+       qa_atsci_fake_single_viterbi.cc         \
+       qa_atsci_fs_correlator.cc               \
+       qa_atsci_single_viterbi.cc              \
+       qa_atsci_randomizer.cc                  \
+       qa_atsci_reed_solomon.cc                \
+       qa_atsci_sliding_correlator.cc          \
+       qa_atsci_trellis_encoder.cc             \
+       qa_atsci_viterbi_decoder.cc             \
+       qa_convolutional_interleaver.cc         \
+       qa_atsci.cc                             \
+       qa_interleaver_fifo.cc                  
+
+libgnuradio_atsc_qa_la_LIBADD =                        \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_atsc_qa_la_LDFLAGS = \
+       $(NO_UNDEFINED)
+
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                            \
+       atsc_consts.h                           \
+       atsc_derandomizer.h                     \
+       atsc_randomizer.h                       \
+       atsc_rs_decoder.h                       \
+       atsc_rs_encoder.h                       \
+       atsc_interleaver.h                      \
+       atsc_deinterleaver.h                    \
+       atsc_trellis_encoder.h                  \
+       atsc_viterbi_decoder.h                  \
+       atsc_ds_to_softds.h                     \
+       atsc_field_sync_mux.h                   \
+       atsc_field_sync_demux.h                 \
+       atsc_equalizer.h                        \
+       atsc_fs_checker.h                       \
+       atsc_bit_timing_loop.h                  \
+       atsc_fpll.h                             \
+       atsc_depad.h                            \
+       atsc_pad.h                              \
+       atsc_types.h                            \
+       atsci_basic_trellis_encoder.h           \
+       atsci_data_interleaver.h                \
+       atsci_diag_output.h                     \
+       atsci_equalizer.h                       \
+       atsci_equalizer_lms.h                   \
+       atsci_equalizer_lms2.h                  \
+       atsci_equalizer_nop.h                   \
+       atsci_exp2_lp.h                         \
+       atsci_fake_single_viterbi.h             \
+       atsci_fs_checker.h                      \
+       atsci_fs_checker_naive.h                \
+       atsci_fs_correlator.h                   \
+       atsci_fs_correlator_naive.h             \
+       atsci_pnXXX.h                           \
+       atsci_randomizer.h                      \
+       atsci_reed_solomon.h                    \
+       atsci_root_raised_cosine.h              \
+       atsci_root_raised_cosine_bandpass.h     \
+       atsci_single_viterbi.h                  \
+       atsci_slicer_agc.h                      \
+       atsci_sliding_correlator.h              \
+       atsci_sssr.h                            \
+       atsci_syminfo.h                         \
+       atsci_sync_tag.h                        \
+       atsci_trellis_encoder.h                 \
+       atsci_viterbi_decoder.h                 \
+       atsci_vsbtx_lp.h                        \
+       convolutional_interleaver.h             \
+       create_atsci_equalizer.h                \
+       create_atsci_fs_checker.h               \
+       create_atsci_fs_correlator.h            \
+       fpll_btloop_coupling.h                  \
+       interleaver_fifo.h                      \
+       qa_atsci.h                              \
+       qa_atsci_basic_trellis_encoder.h        \
+       qa_atsci_data_interleaver.h             \
+       qa_atsci_equalizer_nop.h                \
+       qa_atsci_fake_single_viterbi.h          \
+       qa_atsci_fs_correlator.h                \
+       qa_atsci_randomizer.h                   \
+       qa_atsci_reed_solomon.h                 \
+       qa_atsci_single_viterbi.h               \
+       qa_atsci_sliding_correlator.h           \
+       qa_atsci_trellis_encoder.h              \
+       qa_atsci_viterbi_decoder.h              \
+       qa_convolutional_interleaver.h          \
+       qa_interleaver_fifo.h
+
+
+# programs we build but don't install
+# FIXME add test_atsc
+noinst_PROGRAMS =                              \
+       test_atsci
+
+atsci_viterbi_gen$(EXEEXT): $(srcdir)/atsci_viterbi_gen.cc
+       $(CXX_FOR_BUILD) -O2 $(srcdir)/atsci_viterbi_gen.cc -o atsci_viterbi_gen$(EXEEXT)
+
+atsci_viterbi_mux.cc: atsci_viterbi_gen$(EXEEXT) 
+       ./atsci_viterbi_gen$(EXEEXT) -o atsci_viterbi_mux.cc
+
+test_atsci_SOURCES = test_atsci.cc
+test_atsci_LDADD   =           \
+       libgnuradio-atsc-qa.la  \
+       libgnuradio-atsc.la     \
+       $(CPPUNIT_LIBS)
+
+# ------------------------------------------------------------------------
+#  Cleanup
+# ------------------------------------------------------------------------
+
+CLEANFILES = atsci_viterbi_mux.cc atsci_viterbi_gen$(EXEEXT)
+
+if PYTHON
+# ------------------------------------------------------------------------
+#  This is the swig-ish part of the Makefile.
+#  It builds the atsc module which we'll load into python
+# ------------------------------------------------------------------------
+
+TOP_SWIG_IFILES =              \
+       atsc.i
+
+# Install so that they end up available as:
+#   import gnuradio
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+atsc_pythondir_category =      \
+       gnuradio
+
+# additional libraries for linking with the SWIG-generated library
+atsc_la_swig_libadd =          \
+       libgnuradio-atsc.la
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES += $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-atsc/src/lib/Makefile.swig.gen b/gr-atsc/src/lib/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..e52d653
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for atsc.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/atsc
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/atsc
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+atsc_pythondir_category ?= gnuradio/atsc
+atsc_pylibdir_category ?= $(atsc_pythondir_category)
+atsc_pythondir = $(pythondir)/$(atsc_pythondir_category)
+atsc_pylibdir = $(pyexecdir)/$(atsc_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+atsc_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/atsc-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += atsc.py atsc.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+atsc_swiginclude_HEADERS =             \
+       atsc.i                  \
+       $(atsc_swiginclude_headers)
+
+atsc_pylib_LTLIBRARIES =               \
+       _atsc.la
+
+_atsc_la_SOURCES =                     \
+       atsc.cc                 \
+       $(atsc_la_swig_sources)
+
+_atsc_la_LIBADD =                      \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(atsc_la_swig_libadd)
+
+_atsc_la_LDFLAGS =                     \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(atsc_la_swig_ldflags)
+
+_atsc_la_CXXFLAGS =                    \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(atsc_la_swig_cxxflags)
+
+atsc_python_PYTHON =                   \
+       atsc.py                 \
+       $(atsc_python)
+
+## Entry rule for running SWIG
+
+atsc.h atsc.py atsc.cc: atsc.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/atsc-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/atsc-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/atsc-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/atsc-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/atsc-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/atsc-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/atsc-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/atsc-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/atsc-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(atsc_swig_args) \
+               -MD -MF $(DEPDIR)/atsc.Std \
+               -module atsc -o atsc.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/atsc.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/atsc.Std \
+                       > $(DEPDIR)/atsc.Sd; \
+               $(RM) $(DEPDIR)/atsc.Std; \
+               $(MV) $(DEPDIR)/atsc.Sd $(DEPDIR)/atsc.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/atsc.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/atsc.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/atsc.Std $(DEPDIR)/atsc.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/atsc.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/atsc.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/atsc.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/atsc.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/atsc-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/atsc.d@am__quote@
+
diff --git a/gr-atsc/src/lib/atsc.i b/gr-atsc/src/lib/atsc.i
new file mode 100644 (file)
index 0000000..e974655
--- /dev/null
@@ -0,0 +1,301 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"                          // the common stuff
+
+%{
+#include <atsc_randomizer.h>
+#include <atsc_derandomizer.h>
+#include <atsc_rs_encoder.h>
+#include <atsc_rs_decoder.h>
+#include <atsc_interleaver.h>
+#include <atsc_deinterleaver.h>
+#include <atsc_trellis_encoder.h>
+#include <atsc_viterbi_decoder.h>
+#include <atsc_ds_to_softds.h>
+#include <atsc_field_sync_mux.h>
+#include <atsc_field_sync_demux.h>
+#include <atsc_equalizer.h>
+#include <atsc_fs_checker.h>
+#include <atsc_bit_timing_loop.h>
+#include <atsc_fpll.h>
+#include <atsc_depad.h>
+#include <atsc_pad.h>
+%}
+
+%include "atsc_consts.h"
+
+%constant int sizeof_atsc_mpeg_packet = sizeof(atsc_mpeg_packet);
+%constant int sizeof_atsc_mpeg_packet_no_sync = sizeof(atsc_mpeg_packet_no_sync);
+%constant int sizeof_atsc_mpeg_packet_rs_encoded = sizeof(atsc_mpeg_packet_rs_encoded);
+%constant int sizeof_atsc_data_segment = sizeof(atsc_data_segment);
+%constant int sizeof_atsc_soft_data_segment = sizeof(atsc_soft_data_segment);
+
+%constant int sizeof_atsc_mpeg_packet_pad = atsc_mpeg_packet::NPAD;
+%constant int sizeof_atsc_mpeg_packet_no_sync_pad = atsc_mpeg_packet_no_sync::NPAD;
+%constant int sizeof_atsc_mpeg_packet_rs_encoded_pad = atsc_mpeg_packet_rs_encoded::NPAD;
+%constant int sizeof_atsc_data_segment_pad = atsc_data_segment::NPAD;
+%constant int sizeof_atsc_soft_data_segment_pad = atsc_soft_data_segment::NPAD;
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,randomizer);
+
+atsc_randomizer_sptr atsc_make_randomizer();
+
+class atsc_randomizer : public gr_sync_block
+{
+  atsc_randomizer();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,derandomizer);
+
+atsc_derandomizer_sptr atsc_make_derandomizer();
+
+class atsc_derandomizer : public gr_sync_block
+{
+  atsc_derandomizer();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,rs_encoder);
+
+atsc_rs_encoder_sptr atsc_make_rs_encoder();
+
+class atsc_rs_encoder : public gr_sync_block
+{
+  atsc_rs_encoder();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,rs_decoder);
+
+atsc_rs_decoder_sptr atsc_make_rs_decoder();
+
+class atsc_rs_decoder : public gr_sync_block
+{
+  atsc_rs_decoder();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,interleaver);
+
+atsc_interleaver_sptr atsc_make_interleaver();
+
+class atsc_interleaver : public gr_sync_block
+{
+  atsc_interleaver();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,deinterleaver);
+
+atsc_deinterleaver_sptr atsc_make_deinterleaver();
+
+class atsc_deinterleaver : public gr_sync_block
+{
+  atsc_deinterleaver();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,trellis_encoder);
+
+atsc_trellis_encoder_sptr atsc_make_trellis_encoder();
+
+class atsc_trellis_encoder : public gr_sync_block
+{
+  atsc_trellis_encoder();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,viterbi_decoder);
+
+atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder();
+
+class atsc_viterbi_decoder : public gr_sync_block
+{
+  atsc_viterbi_decoder();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,ds_to_softds);
+
+atsc_ds_to_softds_sptr atsc_make_ds_to_softds();
+
+class atsc_ds_to_softds : public gr_sync_block
+{
+  atsc_ds_to_softds();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,field_sync_mux);
+
+atsc_field_sync_mux_sptr atsc_make_field_sync_mux();
+
+class atsc_field_sync_mux : public gr_sync_block
+{
+  atsc_field_sync_mux();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,field_sync_demux);
+
+atsc_field_sync_demux_sptr atsc_make_field_sync_demux();
+
+class atsc_field_sync_demux : public gr_block
+{
+  atsc_field_sync_demux();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,equalizer);
+
+atsc_equalizer_sptr atsc_make_equalizer();
+
+class atsc_equalizer : public gr_sync_block
+{
+  atsc_equalizer();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,fs_checker);
+
+atsc_fs_checker_sptr atsc_make_fs_checker();
+
+class atsc_fs_checker : public gr_sync_block
+{
+  atsc_fs_checker();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,bit_timing_loop);
+
+atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop();
+
+class atsc_bit_timing_loop : public gr_block
+{
+  atsc_bit_timing_loop();
+
+public:
+  void reset();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,fpll);
+
+atsc_fpll_sptr atsc_make_fpll();
+
+class atsc_fpll : public gr_sync_block
+{
+  atsc_fpll();
+
+public:
+  void reset();
+
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,depad);
+
+atsc_depad_sptr atsc_make_depad();
+
+class atsc_depad : public gr_sync_interpolator
+{
+  atsc_depad();
+
+public:
+  void reset();
+
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(atsc,pad);
+
+atsc_pad_sptr atsc_make_pad();
+
+class atsc_pad : public gr_sync_decimator
+{
+  atsc_pad();
+
+public:
+  void reset();
+
+};
+
+// ----------------------------------------------------------------
+
diff --git a/gr-atsc/src/lib/atsc_bit_timing_loop.cc b/gr-atsc/src/lib/atsc_bit_timing_loop.cc
new file mode 100644 (file)
index 0000000..a661e70
--- /dev/null
@@ -0,0 +1,121 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_bit_timing_loop.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <string.h>
+
+// Input rate changed from 20MHz to 19.2 to support usrp at 3 * 6.4MHz
+float input_rate = 19.2e6;
+double ratio_of_rx_clock_to_symbol_freq = input_rate / ATSC_SYMBOL_RATE;
+
+
+atsc_bit_timing_loop_sptr
+atsc_make_bit_timing_loop()
+{
+  return atsc_bit_timing_loop_sptr(new atsc_bit_timing_loop());
+}
+
+
+atsc_bit_timing_loop::atsc_bit_timing_loop()
+  : gr_block("atsc_bit_timing_loop",
+                 gr_make_io_signature(1, 1, sizeof(float)),
+                 gr_make_io_signature(2, 2, sizeof(float))),
+                 d_interp(ratio_of_rx_clock_to_symbol_freq), d_next_input(0),
+                 d_rx_clock_to_symbol_freq (ratio_of_rx_clock_to_symbol_freq),
+                 d_si(0)
+{
+  reset();
+}
+
+void
+atsc_bit_timing_loop::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned i = 0; i < ninputs; i++)
+    ninput_items_required[i] = static_cast<int>(noutput_items * d_rx_clock_to_symbol_freq) + 1500 - 1;
+
+}
+
+int
+atsc_bit_timing_loop::general_work (int noutput_items,
+                                 gr_vector_int &ninput_items,
+                                 gr_vector_const_void_star &input_items,
+                                 gr_vector_void_star &output_items)
+{
+  int   r = work (noutput_items, input_items, output_items);
+  if (r > 0)
+    consume_each (d_si);
+  return r;
+}
+
+
+int
+atsc_bit_timing_loop::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out_sample = (float *) output_items[0];
+  atsc::syminfo *out_tag = (atsc::syminfo *) output_items[1];
+
+  assert(sizeof(float) == sizeof(atsc::syminfo));
+
+  // We are tasked with producing output.size output samples.
+  // We will consume approximately 2 * output.size input samples.
+
+  int  k;              // output index
+
+  float         interp_sample;
+  int           symbol_index;
+  double        timing_adjustment = 0;
+  bool          seg_locked;
+  atsc::syminfo    tag;
+  // ammount requested in forecast
+  unsigned long input_size = noutput_items * d_rx_clock_to_symbol_freq + 1500 -1;
+
+  memset (&tag, 0, sizeof (tag));
+
+  // ammount actually consumed
+  d_si = 0;
+  
+  for (k = 0; k < noutput_items; k++){
+    if (!d_interp.update (in, input_size, &d_si, timing_adjustment, &interp_sample)){
+      fprintf (stderr, "GrAtscBitTimingLoop3: ran short on data...\n");
+      break;
+    }
+
+    d_sssr.update (interp_sample, &seg_locked, &symbol_index, &timing_adjustment);
+    out_sample[k] = interp_sample;
+    tag.valid = seg_locked;
+    tag.symbol_num = symbol_index;
+    out_tag[k] = tag;
+
+  }
+
+  return k;
+}
diff --git a/gr-atsc/src/lib/atsc_bit_timing_loop.h b/gr-atsc/src/lib/atsc_bit_timing_loop.h
new file mode 100644 (file)
index 0000000..c9b63fe
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_BIT_TIMING_LOOP_H
+#define INCLUDED_ATSC_BIT_TIMING_LOOP_H
+
+#include <cstdio>
+#include <gr_block.h>
+#include <atsci_diag_output.h>
+#include <atsci_sssr.h>
+#include <atsci_syminfo.h>
+
+class atsc_bit_timing_loop;
+typedef boost::shared_ptr<atsc_bit_timing_loop> atsc_bit_timing_loop_sptr;
+
+atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop();
+
+/*!
+ * \brief ATSC BitTimingLoop3
+ * \ingroup atsc
+ *
+ * This class accepts a single real input and produces two outputs,
+ *  the raw symbol (float) and the tag (atsc_syminfo)
+ */
+class atsc_bit_timing_loop : public gr_block
+{
+  friend atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop();
+
+  atsc_bit_timing_loop();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+  ~atsc_bit_timing_loop () { };
+
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+  int  general_work (int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items);
+
+
+  // debug (NOPs)
+  void set_mu (double a_mu) {  }
+  void set_no_update (bool a_no_update) {  }
+  void set_loop_filter_tap (double tap)  { }
+  void set_timing_rate (double rate)     { }
+
+
+ protected:
+
+  atsci_sssr                    d_sssr;
+  atsci_interpolator            d_interp;
+  unsigned long long            d_next_input;
+  double                        d_rx_clock_to_symbol_freq;
+  int                          d_si;
+
+
+};
+
+#endif /* INCLUDED_ATSC_BIT_TIMING_LOOP_H */
+
+
+
diff --git a/gr-atsc/src/lib/atsc_consts.h b/gr-atsc/src/lib/atsc_consts.h
new file mode 100644 (file)
index 0000000..160ad76
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_CONSTS_H_
+#define        _ATSC_CONSTS_H_
+
+static const double ATSC_SYMBOL_RATE = 4.5e6 / 286 * 684;              // ~10.76 MHz
+static const double ATSC_DATA_SEGMENT_RATE = ATSC_SYMBOL_RATE / 832;   // ~12.935 kHz
+
+
+static const int ATSC_MPEG_DATA_LENGTH                 = 187;
+static const int ATSC_MPEG_PKT_LENGTH          = 188;  // sync + data 
+static const int ATSC_MPEG_RS_ENCODED_LENGTH   = 207;
+static const int ATSC_DATA_SEGMENT_LENGTH      = 832;  // includes 4 sync symbols at beginning
+static const int ATSC_DSEGS_PER_FIELD          = 312;  // regular data segs / field
+
+
+static const int MPEG_SYNC_BYTE = 0x47;
+
+static const int MPEG_TRANSPORT_ERROR_BIT      = 0x80; // top bit of byte after SYNC
+
+
+#endif // _ATSC_CONSTS_H_
diff --git a/gr-atsc/src/lib/atsc_deinterleaver.cc b/gr-atsc/src/lib/atsc_deinterleaver.cc
new file mode 100644 (file)
index 0000000..af58777
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_deinterleaver.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_deinterleaver_sptr
+atsc_make_deinterleaver()
+{
+  return atsc_deinterleaver_sptr(new atsc_deinterleaver());
+}
+
+atsc_deinterleaver::atsc_deinterleaver()
+  : gr_sync_block("atsc_deinterleaver",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
+{
+  reset();
+}
+
+int
+atsc_deinterleaver::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0];
+  atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    d_deinterleaver.deinterleave (out[i], in[i]);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_deinterleaver.h b/gr-atsc/src/lib/atsc_deinterleaver.h
new file mode 100644 (file)
index 0000000..0920818
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_DEINTERLEAVER_H
+#define INCLUDED_ATSC_DEINTERLEAVER_H
+
+#include <gr_sync_block.h>
+#include <atsci_data_interleaver.h>
+
+class atsc_deinterleaver;
+typedef boost::shared_ptr<atsc_deinterleaver> atsc_deinterleaver_sptr;
+
+atsc_deinterleaver_sptr atsc_make_deinterleaver();
+
+/*!
+ * \brief Deinterleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_rs_encoded
+ */
+class atsc_deinterleaver : public gr_sync_block
+{
+  friend atsc_deinterleaver_sptr atsc_make_deinterleaver();
+
+  atsci_data_deinterleaver     d_deinterleaver;
+
+  atsc_deinterleaver();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_DEINTERLEAVER_H */
diff --git a/gr-atsc/src/lib/atsc_depad.cc b/gr-atsc/src/lib/atsc_depad.cc
new file mode 100644 (file)
index 0000000..f1e8305
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_depad.h>
+#include <gr_io_signature.h>
+#include <atsc_types.h>
+
+atsc_depad_sptr
+atsc_make_depad()
+{
+  return atsc_depad_sptr(new atsc_depad());
+}
+
+atsc_depad::atsc_depad()
+  : gr_sync_interpolator("atsc_depad",
+                        gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)),
+                        gr_make_io_signature(1, 1, sizeof(unsigned char)),
+                        ATSC_MPEG_PKT_LENGTH)
+{
+  reset();
+}
+
+int
+atsc_depad::work (int noutput_items,
+                 gr_vector_const_void_star &input_items,
+                 gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet *in = (const atsc_mpeg_packet *) input_items[0];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  int i;
+
+  for (i = 0; i < noutput_items/ATSC_MPEG_PKT_LENGTH; i++){
+    memcpy(&out[i * ATSC_MPEG_PKT_LENGTH], in[i].data, ATSC_MPEG_PKT_LENGTH);
+  }
+
+  return i * ATSC_MPEG_PKT_LENGTH;
+}
diff --git a/gr-atsc/src/lib/atsc_depad.h b/gr-atsc/src/lib/atsc_depad.h
new file mode 100644 (file)
index 0000000..58dfdaf
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_DEPAD_H
+#define INCLUDED_ATSC_DEPAD_H
+
+#include <gr_sync_interpolator.h>
+
+class atsc_depad;
+typedef boost::shared_ptr<atsc_depad> atsc_depad_sptr;
+
+atsc_depad_sptr atsc_make_depad();
+
+/*!
+ * \brief depad mpeg ts packets from 256 byte atsc_mpeg_packet to 188 byte char
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet; output: unsigned char
+ */
+class atsc_depad : public gr_sync_interpolator
+{
+  friend atsc_depad_sptr atsc_make_depad();
+
+  atsc_depad();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_DEPAD_H */
diff --git a/gr-atsc/src/lib/atsc_derandomizer.cc b/gr-atsc/src/lib/atsc_derandomizer.cc
new file mode 100644 (file)
index 0000000..361b781
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_derandomizer.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_derandomizer_sptr
+atsc_make_derandomizer()
+{
+  return atsc_derandomizer_sptr(new atsc_derandomizer());
+}
+
+atsc_derandomizer::atsc_derandomizer()
+  : gr_sync_block("atsc_derandomizer",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)))
+{
+  reset();
+}
+
+void
+atsc_derandomizer::reset()
+{
+  d_rand.reset();
+}
+
+int
+atsc_derandomizer::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_no_sync *in = (const atsc_mpeg_packet_no_sync *) input_items[0];
+  atsc_mpeg_packet *out = (atsc_mpeg_packet *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+
+    assert(in[i].pli.regular_seg_p());
+
+    if (in[i].pli.first_regular_seg_p())
+      d_rand.reset();
+
+    d_rand.derandomize(out[i], in[i]);
+
+    // Check the pipeline info for error status and and set the
+    // corresponding bit in transport packet header.
+
+    if (in[i].pli.transport_error_p())
+      out[i].data[1] |= MPEG_TRANSPORT_ERROR_BIT;
+    else
+      out[i].data[1] &= ~MPEG_TRANSPORT_ERROR_BIT;
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_derandomizer.h b/gr-atsc/src/lib/atsc_derandomizer.h
new file mode 100644 (file)
index 0000000..a72efbd
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_DERANDOMIZER_H
+#define INCLUDED_ATSC_DERANDOMIZER_H
+
+#include <gr_sync_block.h>
+#include <atsci_randomizer.h>
+
+class atsc_derandomizer;
+typedef boost::shared_ptr<atsc_derandomizer> atsc_derandomizer_sptr;
+
+atsc_derandomizer_sptr atsc_make_derandomizer();
+
+/*!
+ * \brief "dewhiten" incoming mpeg transport stream packets
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_no_sync; output: atsc_mpeg_packet; 
+ */
+class atsc_derandomizer : public gr_sync_block
+{
+  friend atsc_derandomizer_sptr atsc_make_derandomizer();
+
+  atsci_randomizer     d_rand;
+
+  atsc_derandomizer();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset();
+};
+
+
+#endif /* INCLUDED_ATSC_DERANDOMIZER_H */
diff --git a/gr-atsc/src/lib/atsc_ds_to_softds.cc b/gr-atsc/src/lib/atsc_ds_to_softds.cc
new file mode 100644 (file)
index 0000000..8d3fc33
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_ds_to_softds.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_ds_to_softds_sptr
+atsc_make_ds_to_softds()
+{
+  return atsc_ds_to_softds_sptr(new atsc_ds_to_softds());
+}
+
+atsc_ds_to_softds::atsc_ds_to_softds()
+  : gr_sync_block("atsc_ds_to_softds",
+                 gr_make_io_signature(1, 1, sizeof(atsc_data_segment)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment)))
+{
+  reset();
+}
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+void
+atsc_ds_to_softds::map_to_soft_symbols (atsc_soft_data_segment &out,
+                     const atsc_data_segment &in)
+{
+  for (unsigned int i = 0; i < NELEM (in.data); i++){
+    out.data[i] = in.data[i] * 2 - 7;
+  }
+}
+
+
+int
+atsc_ds_to_softds::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_data_segment *in = (const atsc_data_segment *) input_items[0];
+  atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+
+    out[i].pli = in[i].pli;                    // copy pipeline info...
+    map_to_soft_symbols(out[i], in[i]);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_ds_to_softds.h b/gr-atsc/src/lib/atsc_ds_to_softds.h
new file mode 100644 (file)
index 0000000..f8623e3
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_DS_TO_SOFTDS_H
+#define INCLUDED_ATSC_DS_TO_SOFTDS_H
+
+#include <gr_sync_block.h>
+#include <atsc_types.h>
+
+class atsc_ds_to_softds;
+typedef boost::shared_ptr<atsc_ds_to_softds> atsc_ds_to_softds_sptr;
+
+atsc_ds_to_softds_sptr atsc_make_ds_to_softds();
+
+/*!
+ * \brief Debug glue routine (atsc_data_segment --> atsc_soft_data_segment)
+ * \ingroup atsc
+ *
+ * input: atsc_data_segment; output: atsc_soft_data_segment
+ */
+class atsc_ds_to_softds : public gr_sync_block
+{
+  friend atsc_ds_to_softds_sptr atsc_make_ds_to_softds();
+
+  atsc_ds_to_softds();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void map_to_soft_symbols (atsc_soft_data_segment &out,
+                     const atsc_data_segment &in);
+
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_DS_TO_SOFTDS_H */
diff --git a/gr-atsc/src/lib/atsc_equalizer.cc b/gr-atsc/src/lib/atsc_equalizer.cc
new file mode 100644 (file)
index 0000000..3053c00
--- /dev/null
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_equalizer.h>
+#include <create_atsci_equalizer.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <atsci_syminfo.h>
+
+
+atsc_equalizer_sptr
+atsc_make_equalizer()
+{
+  return atsc_equalizer_sptr(new atsc_equalizer());
+}
+
+// had atsc_equalizer(atsci_equalizer *equalizer)
+atsc_equalizer::atsc_equalizer()
+  : gr_sync_block("atsc_equalizer",
+                 gr_make_io_signature(2, 2, sizeof(float)),
+                 gr_make_io_signature(2, 2, sizeof(float)))
+{
+  d_equalizer = create_atsci_equalizer_lms();
+}
+
+atsc_equalizer::~atsc_equalizer ()
+{
+  // Anything that isn't automatically cleaned up...
+
+  delete d_equalizer;
+}
+
+
+void
+atsc_equalizer::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+
+  int ntaps = d_equalizer->ntaps ();
+
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned i = 0; i < ninputs; i++)
+    ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items + ntaps);
+
+
+}
+
+
+
+int
+atsc_equalizer::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  const atsc::syminfo *in_tags = (const atsc::syminfo *) input_items[1];
+  float *out = (float *) output_items[0];
+  atsc::syminfo *out_tags = (atsc::syminfo *) output_items[1];
+
+  assert(sizeof(float) == sizeof(atsc::syminfo));
+
+  int ntaps = d_equalizer->ntaps ();
+  int npretaps = d_equalizer->npretaps ();
+
+  assert (ntaps >= 1);
+  assert (npretaps >= 0 && npretaps < ntaps);
+
+  int offset = ntaps - npretaps - 1;
+  assert (offset >= 0 && offset < ntaps);
+
+
+  // peform the actual equalization
+
+  d_equalizer->filter (in, in_tags + offset,
+                       out, noutput_items);
+
+  // write the output tags
+
+  for (int i = 0; i < noutput_items; i++)
+    out_tags[i] = in_tags[i + offset];
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_equalizer.h b/gr-atsc/src/lib/atsc_equalizer.h
new file mode 100644 (file)
index 0000000..52b5cd3
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_EQUALIZER_H
+#define INCLUDED_ATSC_EQUALIZER_H
+
+#include <gr_sync_block.h>
+#include <atsci_equalizer.h>
+
+class atsc_equalizer;
+typedef boost::shared_ptr<atsc_equalizer> atsc_equalizer_sptr;
+
+atsc_equalizer_sptr atsc_make_equalizer();
+
+/*!
+ * \brief ATSC equalizer (float,syminfo --> float,syminfo)
+ * \ingroup atsc
+ *
+ * first inputs are data samples, second inputs are tags.
+ * first outputs are equalized data samples, second outputs are tags.
+ */
+class atsc_equalizer : public gr_sync_block
+{
+  friend atsc_equalizer_sptr atsc_make_equalizer();
+
+  atsc_equalizer();
+
+public:
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+  ~atsc_equalizer ();
+
+
+protected:
+  atsci_equalizer      *d_equalizer;
+
+};
+
+
+#endif /* INCLUDED_ATSC_EQUALIZER_H */
diff --git a/gr-atsc/src/lib/atsc_field_sync_demux.cc b/gr-atsc/src/lib/atsc_field_sync_demux.cc
new file mode 100644 (file)
index 0000000..b6195c6
--- /dev/null
@@ -0,0 +1,209 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cmath>
+#include <atsc_field_sync_demux.h>
+#include <gr_io_signature.h>
+#include <atsc_types.h>
+#include <atsc_consts.h>
+#include <atsci_syminfo.h>
+#include <stdio.h>
+#include <assert.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+
+static const int        DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor
+
+
+atsc_field_sync_demux_sptr
+atsc_make_field_sync_demux()
+{
+  return atsc_field_sync_demux_sptr(new atsc_field_sync_demux());
+}
+
+atsc_field_sync_demux::atsc_field_sync_demux()
+  : gr_block("atsc_field_sync_demux",
+                 gr_make_io_signature(2, 2, sizeof(float)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment))),
+                 d_locked(false), d_in_field2(true), d_segment_number(0),
+                 d_next_input(0), d_lost_index(0), d_inputs0_index(0), 
+                  d_inputs0_size(0), d_consume(0)
+{
+  reset();
+}
+
+inline static bool
+tag_is_seg_sync_or_field_sync (atsc::syminfo tag)
+{
+  return tag.symbol_num == 0 && tag.valid;
+}
+
+void
+atsc_field_sync_demux::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned i = 0; i < ninputs; i++) {
+    ninput_items_required[i] = noutput_items * DEC + 2 * DEC ;
+
+  d_inputs0_index = d_next_input;
+  d_inputs0_size = noutput_items * DEC + 2 * DEC ;
+  }
+}
+
+int
+atsc_field_sync_demux::general_work (int noutput_items,
+                                 gr_vector_int &ninput_items,
+                                 gr_vector_const_void_star &input_items,
+                                 gr_vector_void_star &output_items)
+{
+  int   r = work (noutput_items, input_items, output_items);
+    consume_each (d_consume);
+    // printf("Consumed: %d, produced: %d\n",d_consume,r);
+    // we consume input even if no output is produced
+    // while looking for sync
+  return r;
+}
+
+
+int
+atsc_field_sync_demux::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  float *in = (float *) input_items[0];
+  atsc::syminfo *input_tags    = (atsc::syminfo *) input_items[1];
+  atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0];
+
+  assert(sizeof(float) == sizeof(atsc::syminfo));
+
+  unsigned int  ii = 0;         // input index
+
+  // Are we in sync?
+  if (!tag_is_seg_sync_or_field_sync (input_tags[0])){      // No ...
+
+    if (d_locked){
+      d_locked = false;
+      d_lost_index = d_inputs0_index + ii;
+      cerr << "atsc_field_sync_demux: lost sync at  "
+           << d_lost_index << endl;
+    }
+
+    // ... search for beginning of a field sync
+
+    // cerr << "atsc_field_sync_demux: searching for sync at "
+    //      << d_inputs0_index + ii << endl;
+
+    for (ii = 1; ii < d_inputs0_size; ii++){
+      if (atsc::tag_is_start_field_sync (input_tags[ii])){
+        // found one
+        d_locked = true;
+
+        const char *str;
+        if (atsc::tag_is_start_field_sync_1 (input_tags[ii]))
+          str = "FIELD-1";
+        else if (atsc::tag_is_start_field_sync_2 (input_tags[ii]))
+          str = "FIELD-2";
+        else
+          str = "SEGMENT";
+
+        cerr << "atsc_field_sync_demux: synced (" << str << ") at "
+             << d_inputs0_index + ii
+             << " [delta = " << d_inputs0_index + ii - d_lost_index
+             << "]\n";
+
+        d_next_input += ii;     // update for forecast
+       d_consume = ii;
+        return 0;               // no work completed so far
+      }
+    }
+    // no non-NORMAL tag found
+    d_next_input += ii;         // update for forecast
+    d_consume = ii;
+    // printf("ii: %d, d_next_input: %d\n",ii,d_next_input);
+    return 0;                   // no work completed so far
+  }
+
+  // We are in sync.  Produce output...
+
+  int  k = 0;          // output index
+
+  while (k < noutput_items){
+
+    if (d_inputs0_size - ii <  static_cast<unsigned int>(ATSC_DATA_SEGMENT_LENGTH)){
+      // We're out of input data.
+      cerr << "atsc_field_sync_demux: ran out of input data\n";
+      d_next_input += ii;       // update for forecast
+      return k;                 // return amount of work completed so far
+    }
+
+    if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){
+      // lost sync...
+      cerr << "atsc_field_sync_demux: lost sync at "
+           << d_inputs0_index + ii << endl;
+
+      d_next_input += ii;       // update for forecast
+      return k;                 // return amount of work completed so far
+    }
+
+    if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){
+      d_in_field2 = false;
+      d_segment_number = 0;
+      ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
+      continue;
+    }
+
+    if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){
+      d_in_field2 = true;
+      d_segment_number = 0;
+      ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
+      continue;
+    }
+
+    if (d_segment_number >= ATSC_DSEGS_PER_FIELD){
+      // something's wrong...
+      cerr << "atsc_field_sync_demux: segment number overflow\n";
+      d_segment_number = 0;
+    }
+
+    out[k].pli.set_regular_seg (d_in_field2, d_segment_number++);
+    for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++)
+      out[k].data[jj] = in[ii + jj];
+    ii += ATSC_DATA_SEGMENT_LENGTH;
+    k++;
+  }
+
+  d_next_input += ii;           // update for forecast
+  d_consume = ii;
+  return k;                     // return amount of work completed
+
+}
+
+
+
+
diff --git a/gr-atsc/src/lib/atsc_field_sync_demux.h b/gr-atsc/src/lib/atsc_field_sync_demux.h
new file mode 100644 (file)
index 0000000..01cc33f
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_FIELD_SYNC_DEMUX_H
+#define INCLUDED_ATSC_FIELD_SYNC_DEMUX_H
+
+#include <gr_block.h>
+#include <atsc_types.h>
+
+class atsc_field_sync_demux;
+typedef boost::shared_ptr<atsc_field_sync_demux> atsc_field_sync_demux_sptr;
+
+atsc_field_sync_demux_sptr atsc_make_field_sync_demux();
+
+/*!
+ * \brief ATSC Field Sync Demux
+ *
+ * This class accepts 1 stream of floats (data), and 1 stream of tags (syminfo). * It outputs one stream of atsc_soft_data_segment packets
+ * \ingroup atsc
+ *
+ */
+class atsc_field_sync_demux : public gr_block
+{
+  friend atsc_field_sync_demux_sptr atsc_make_field_sync_demux();
+
+  atsc_field_sync_demux();
+
+public:
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+  int  general_work (int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items);
+
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+protected:
+  bool            d_locked;
+  bool            d_in_field2;
+  int             d_segment_number;
+  gr_uint64       d_next_input;
+  gr_uint64       d_lost_index;         // diagnostic fluff
+
+  unsigned long long d_inputs0_index;  // for inputs[0].index
+  unsigned long          d_inputs0_size;               // for inputs[0].size
+  int            d_consume;
+
+};
+
+
+#endif /* INCLUDED_ATSC_FIELD_SYNC_DEMUX_H */
diff --git a/gr-atsc/src/lib/atsc_field_sync_mux.cc b/gr-atsc/src/lib/atsc_field_sync_mux.cc
new file mode 100644 (file)
index 0000000..526599a
--- /dev/null
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_field_sync_mux.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <atsci_pnXXX.h>
+
+
+atsc_field_sync_mux_sptr
+atsc_make_field_sync_mux()
+{
+  return atsc_field_sync_mux_sptr(new atsc_field_sync_mux());
+}
+
+atsc_field_sync_mux::atsc_field_sync_mux()
+  : gr_sync_block("atsc_field_sync_mux",
+                 gr_make_io_signature(1, 1, sizeof(atsc_data_segment)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_data_segment)))
+{
+  reset();
+}
+
+static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one)
+
+static const int N_SAVED_SYMBOLS = atsc_field_sync_mux::N_SAVED_SYMBOLS;
+
+static void
+init_field_sync_common (unsigned char *p, int mask,
+                        const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+{
+  static const unsigned char bin_map[2] = { 1, 6 };  // map binary values to 1 of 8 levels
+
+  int  i = 0;
+
+  p[i++] = bin_map[1];                  // data segment sync pulse
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  for (int j = 0; j < 511; j++)         // PN511
+    p[i++] = bin_map[atsc_pn511[j]];
+
+  for (int j = 0; j < 63; j++)          // PN63
+    p[i++] = bin_map[atsc_pn63[j]];
+
+  for (int j = 0; j < 63; j++)          // PN63, toggled on field 2
+    p[i++] = bin_map[atsc_pn63[j] ^ mask];
+
+  for (int j = 0; j < 63; j++)          // PN63
+    p[i++] = bin_map[atsc_pn63[j]];
+
+  p[i++] = bin_map[0];                  // 24 bits of VSB8 mode identifiera
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[0];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+  p[i++] = bin_map[1];
+  p[i++] = bin_map[0];
+
+
+  for (int j = 0; j < 92; j++)          // 92 more bits
+    p[i++] = bin_map[atsc_pn63[j % 63]];
+
+  // now copy the last 12 symbols of the previous segment
+
+  for (int j = 0; j < N_SAVED_SYMBOLS; j++)
+    p[i++] = saved_symbols[j];
+
+  assert (i == ATSC_DATA_SEGMENT_LENGTH);
+}
+inline static void
+init_field_sync_1 (atsc_data_segment *s,
+                   const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+{
+  init_field_sync_common (&s->data[0], 0, saved_symbols);
+}
+
+inline static void
+init_field_sync_2 (atsc_data_segment *s,
+                   const unsigned char saved_symbols[N_SAVED_SYMBOLS])
+
+{
+  init_field_sync_common (&s->data[0], 1, saved_symbols);
+}
+
+static void
+save_last_symbols (unsigned char saved_symbols[N_SAVED_SYMBOLS],
+                   const atsc_data_segment &seg)
+{
+  for (int i = 0; i < N_SAVED_SYMBOLS; i++)
+    saved_symbols[i] = seg.data[i + ATSC_DATA_SEGMENT_LENGTH - N_SAVED_SYMBOLS];}
+
+
+inline static bool
+last_regular_seg_p (const plinfo &pli)
+{
+  return pli.regular_seg_p () && (pli.segno () == ATSC_DSEGS_PER_FIELD - 1);
+}
+
+void
+atsc_field_sync_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned i = 0; i < ninputs; i++) 
+    ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items);
+  
+}
+
+
+int
+atsc_field_sync_mux::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_data_segment *in = (const atsc_data_segment *) input_items[0];
+  atsc_data_segment *out = (atsc_data_segment *) output_items[0];
+
+  unsigned int index = 0;
+  for (int outdex = 0; outdex < noutput_items; outdex++){
+
+    assert (in[index].pli.regular_seg_p ());
+
+    if (!in[index].pli.first_regular_seg_p ()){
+      out[outdex] = in[index];                  // just copy in to out
+
+      if (last_regular_seg_p (in[index].pli))
+        save_last_symbols (d_saved_symbols, in[index]);
+
+      index++;
+    }
+    else {                                      // first_regular_seg_p
+      if (!d_already_output_field_sync){
+        // write out field sync...
+        atsc_data_segment       field_sync;
+
+        if (in[index].pli.in_field1_p ())
+          init_field_sync_1 (&field_sync, d_saved_symbols);
+        else
+          init_field_sync_2 (&field_sync, d_saved_symbols);
+
+        // note that index doesn't advance in this branch
+        out[outdex] = field_sync;
+        d_already_output_field_sync = true;
+      }
+      else {
+        // already output field sync, now output first regular segment
+        out[outdex] = in[index];
+        index++;
+        d_already_output_field_sync = false;
+      }
+    }
+  }
+
+  d_current_index += index;
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_field_sync_mux.h b/gr-atsc/src/lib/atsc_field_sync_mux.h
new file mode 100644 (file)
index 0000000..189341c
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_FIELD_SYNC_MUX_H
+#define INCLUDED_ATSC_FIELD_SYNC_MUX_H
+
+#include <gr_sync_block.h>
+#include <atsc_types.h>
+
+class atsc_field_sync_mux;
+typedef boost::shared_ptr<atsc_field_sync_mux> atsc_field_sync_mux_sptr;
+
+atsc_field_sync_mux_sptr atsc_make_field_sync_mux();
+
+/*!
+ * \brief Insert ATSC Field Syncs as required (atsc_data_segment --> atsc_data_segment)
+ * \ingroup atsc
+ *
+ * input: atsc_data_segment; output: atsc_data_segment
+ */
+class atsc_field_sync_mux : public gr_sync_block
+{
+  friend atsc_field_sync_mux_sptr atsc_make_field_sync_mux();
+
+  atsc_field_sync_mux();
+
+public:
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+
+  static const int      N_SAVED_SYMBOLS = 12;
+
+  void reset() { /* nop */ }
+
+protected:
+  gr_uint64             d_current_index;
+  bool                  d_already_output_field_sync;
+  unsigned char         d_saved_symbols[N_SAVED_SYMBOLS];
+};
+
+
+#endif /* INCLUDED_ATSC_FIELD_SYNC_MUX_H */
diff --git a/gr-atsc/src/lib/atsc_fpll.cc b/gr-atsc/src/lib/atsc_fpll.cc
new file mode 100644 (file)
index 0000000..f5bf39d
--- /dev/null
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_fpll.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <algorithm>
+#include "fpll_btloop_coupling.h"
+#include <gr_math.h>
+
+atsc_fpll_sptr
+atsc_make_fpll()
+{
+  return atsc_fpll_sptr(new atsc_fpll());
+}
+
+
+/*
+ * I strongly suggest that you not mess with these...
+ *
+ * They are strongly coupled into the symbol timing code and
+ * their value also sets the level of the symbols going
+ * into the equalizer and viterbi decoder.
+ */
+static const float FPLL_AGC_REFERENCE = 2.5 * FPLL_BTLOOP_COUPLING_CONST;
+static const float FPLL_AGC_RATE = 0.25e-6;
+
+
+
+atsc_fpll::atsc_fpll()
+  : gr_sync_block("atsc_fpll",
+                 gr_make_io_signature(1, 1, sizeof(float)),
+                 gr_make_io_signature(1, 1, sizeof(float))),
+                 initial_phase(0)
+{
+  initial_freq = 5.75e6 - 3e6 + 0.31e6 + 5e3; // a_initial_freq;
+  agc.set_rate (FPLL_AGC_RATE);
+  agc.set_reference (FPLL_AGC_REFERENCE);
+  initialize();
+}
+
+
+void
+atsc_fpll::initialize ()
+{
+  float Fs = 19.2e6;
+
+  float alpha = 1 - exp(-1.0 / Fs / 5e-6);
+
+  afci.set_taps (alpha);
+  afcq.set_taps (alpha);
+
+  printf("Setting initial_freq: %f\n",initial_freq);
+  nco.set_freq (initial_freq / Fs * 2 * M_PI);
+  nco.set_phase (initial_phase);
+}
+
+
+int
+atsc_fpll::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int k = 0; k < noutput_items; k++){
+
+    float a_cos, a_sin;
+
+    float input = agc.scale (in[k]);
+
+    nco.step ();                // increment phase
+    nco.sincos (&a_sin, &a_cos);  // compute cos and sin
+
+    float I = input * a_sin;
+    float Q = input * a_cos;
+
+    out[k] = I;
+
+    float filtered_I = afci.filter (I);
+    float filtered_Q = afcq.filter (Q);
+
+    // phase detector
+
+    // float x = atan2 (filtered_Q, filtered_I);
+    float x = gr_fast_atan2f(filtered_Q, filtered_I);
+
+    // avoid slamming filter with big transitions
+
+    static const float limit = M_PI / 2;
+
+    if (x > limit)
+      x = limit;
+    else if (x < -limit)
+      x = -limit;
+
+    // static const float alpha = 0.037;   // Max value
+    // static const float alpha = 0.005;   // takes about 5k samples to pull in, stddev = 323
+    // static const float alpha = 0.002;   // takes about 15k samples to pull in, stddev =  69
+                                           //  or about 120k samples on noisy data,
+    static const float alpha = 0.001;
+    static const float beta = alpha * alpha / 4;
+
+    nco.adjust_phase (alpha * x);
+    nco.adjust_freq (beta * x);
+
+  }
+
+  return noutput_items;
+}
+
+
+
diff --git a/gr-atsc/src/lib/atsc_fpll.h b/gr-atsc/src/lib/atsc_fpll.h
new file mode 100644 (file)
index 0000000..1ed41d8
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_FPLL_H
+#define INCLUDED_ATSC_FPLL_H
+
+#include <gr_sync_block.h>
+#include <gr_nco.h>
+#include <gr_single_pole_iir.h>
+#include <gri_agc_ff.h>
+#include <stdio.h>
+#include <atsci_diag_output.h>
+
+class atsc_fpll;
+typedef boost::shared_ptr<atsc_fpll> atsc_fpll_sptr;
+
+atsc_fpll_sptr atsc_make_fpll();
+
+/*!
+ * \brief ATSC FPLL (2nd Version)
+ * \ingroup atsc
+ *
+ *  A/D --> GrFIRfilterFFF ----> GrAtscFPLL ---->
+ *
+ * We use GrFIRfilterFFF to bandpass filter the signal of interest.
+ *
+ * This class accepts a single real input and produces a single real output
+ */
+
+class atsc_fpll : public gr_sync_block
+{
+  friend atsc_fpll_sptr atsc_make_fpll();
+
+  atsc_fpll();
+
+public:
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+  void initialize () ;
+
+ protected:
+
+  double                        initial_freq;
+  double                        initial_phase;
+  bool                          debug_no_update;
+  gr_nco<float,float>           nco;
+  gri_agc_ff                    agc;    // automatic gain control
+  gr_single_pole_iir<float,float,float> afci;
+  gr_single_pole_iir<float,float,float> afcq;
+
+
+};
+
+
+#endif /* INCLUDED_ATSC_FPLL_H */
diff --git a/gr-atsc/src/lib/atsc_fs_checker.cc b/gr-atsc/src/lib/atsc_fs_checker.cc
new file mode 100644 (file)
index 0000000..6940665
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_fs_checker.h>
+#include <create_atsci_fs_checker.h>
+#include <atsci_fs_checker.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <atsci_syminfo.h>
+
+
+atsc_fs_checker_sptr
+atsc_make_fs_checker()
+{
+  return atsc_fs_checker_sptr(new atsc_fs_checker());
+}
+
+atsc_fs_checker::atsc_fs_checker()
+  : gr_sync_block("atsc_fs_checker",
+                 gr_make_io_signature(2, 2, sizeof(float)),
+                 gr_make_io_signature(2, 2, sizeof(float)))
+{
+  d_fsc = create_atsci_fs_checker();
+}
+
+
+atsc_fs_checker::~atsc_fs_checker ()
+{
+  // Anything that isn't automatically cleaned up...
+
+  delete d_fsc;
+}
+
+
+int
+atsc_fs_checker::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  const atsc::syminfo *tag_in = (const atsc::syminfo *) input_items[1];
+  float *out = (float *) output_items[0];
+  atsc::syminfo *tag_out = (atsc::syminfo *) output_items[1];
+
+  assert(sizeof(float) == sizeof(atsc::syminfo));
+
+
+  for (int i = 0; i < noutput_items; i++)
+    d_fsc->filter (in[i], tag_in[i], &out[i], &tag_out[i]);
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_fs_checker.h b/gr-atsc/src/lib/atsc_fs_checker.h
new file mode 100644 (file)
index 0000000..e7271af
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_FS_CHECKER_H
+#define INCLUDED_ATSC_FS_CHECKER_H
+
+#include <atsci_fs_checker.h>
+#include <gr_sync_block.h>
+
+class atsc_fs_checker;
+typedef boost::shared_ptr<atsc_fs_checker> atsc_fs_checker_sptr;
+
+atsc_fs_checker_sptr atsc_make_fs_checker();
+
+/*!
+ * \brief ATSC field sync checker (float,syminfo --> float,syminfo)
+ * \ingroup atsc
+ *
+ * first output is delayed version of input.
+ * second output is set of tags, one-for-one with first output.
+ */
+
+class atsc_fs_checker : public gr_sync_block
+{
+  friend atsc_fs_checker_sptr atsc_make_fs_checker();
+
+  atsc_fs_checker();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+  ~atsc_fs_checker ();
+
+protected:
+  atsci_fs_checker     *d_fsc;
+
+};
+
+
+#endif /* INCLUDED_ATSC_FS_CHECKER_H */
diff --git a/gr-atsc/src/lib/atsc_interleaver.cc b/gr-atsc/src/lib/atsc_interleaver.cc
new file mode 100644 (file)
index 0000000..d9fd98b
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_interleaver.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_interleaver_sptr
+atsc_make_interleaver()
+{
+  return atsc_interleaver_sptr(new atsc_interleaver());
+}
+
+atsc_interleaver::atsc_interleaver()
+  : gr_sync_block("atsc_interleaver",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
+{
+  reset();
+}
+
+int
+atsc_interleaver::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0];
+  atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    d_interleaver.interleave (out[i], in[i]);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_interleaver.h b/gr-atsc/src/lib/atsc_interleaver.h
new file mode 100644 (file)
index 0000000..5f82b75
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_INTERLEAVER_H
+#define INCLUDED_ATSC_INTERLEAVER_H
+
+#include <gr_sync_block.h>
+#include <atsci_data_interleaver.h>
+
+class atsc_interleaver;
+typedef boost::shared_ptr<atsc_interleaver> atsc_interleaver_sptr;
+
+atsc_interleaver_sptr atsc_make_interleaver();
+
+/*!  \brief Interleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)* 
+ *   \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_rs_encoded
+ */
+class atsc_interleaver : public gr_sync_block
+{
+  friend atsc_interleaver_sptr atsc_make_interleaver();
+
+  atsci_data_interleaver       d_interleaver;
+
+  atsc_interleaver();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_INTERLEAVER_H */
diff --git a/gr-atsc/src/lib/atsc_pad.cc b/gr-atsc/src/lib/atsc_pad.cc
new file mode 100644 (file)
index 0000000..cd1353e
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_pad.h>
+#include <gr_io_signature.h>
+#include <atsc_types.h>
+
+static const int INTR = ATSC_MPEG_PKT_LENGTH;
+
+atsc_pad_sptr
+atsc_make_pad()
+{
+  return atsc_pad_sptr(new atsc_pad());
+}
+
+atsc_pad::atsc_pad()
+  : gr_sync_decimator("atsc_pad",
+                 gr_make_io_signature(1, 1, sizeof(unsigned char)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)),
+                 INTR)
+{
+  reset();
+}
+
+void
+atsc_pad::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned i = 0; i < ninputs; i++) 
+    ninput_items_required[i] = noutput_items * ATSC_MPEG_PKT_LENGTH;
+}
+
+
+int
+atsc_pad::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const unsigned char *in = (const unsigned char *) input_items[0];
+  atsc_mpeg_packet *out = (atsc_mpeg_packet *) output_items[0];
+  
+  int i;
+
+  for (i = 0; i < noutput_items; i++){
+    for (int j = 0; j < ATSC_MPEG_PKT_LENGTH; j++)
+       out[i].data[j] = in[i * ATSC_MPEG_PKT_LENGTH + j];
+
+  }
+
+  return noutput_items;
+}
+
+
+
+
diff --git a/gr-atsc/src/lib/atsc_pad.h b/gr-atsc/src/lib/atsc_pad.h
new file mode 100644 (file)
index 0000000..e7e6874
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_PAD_H
+#define INCLUDED_ATSC_PAD_H
+
+#include <gr_sync_decimator.h>
+
+class atsc_pad;
+typedef boost::shared_ptr<atsc_pad> atsc_pad_sptr;
+
+atsc_pad_sptr atsc_make_pad();
+
+/*!
+ * \brief pad mpeg ts packets from 188 byte char to 
+ * to 256 byte atsc_mpeg_packet
+ * \ingroup atsc
+ *
+ * input: unsigned char; output: atsc_mpeg_packet
+ */
+class atsc_pad : public gr_sync_decimator
+{
+  friend atsc_pad_sptr atsc_make_pad();
+
+  atsc_pad();
+
+public:
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_PAD_H */
diff --git a/gr-atsc/src/lib/atsc_randomizer.cc b/gr-atsc/src/lib/atsc_randomizer.cc
new file mode 100644 (file)
index 0000000..e6756c6
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_randomizer.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_randomizer_sptr
+atsc_make_randomizer()
+{
+  return atsc_randomizer_sptr(new atsc_randomizer());
+}
+
+atsc_randomizer::atsc_randomizer()
+  : gr_sync_block("atsc_randomizer",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)))
+{
+  reset();
+}
+
+void
+atsc_randomizer::reset()
+{
+  d_rand.reset();
+  d_field2 = false;
+  d_segno = 0;
+}
+
+int
+atsc_randomizer::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet *in = (const atsc_mpeg_packet *) input_items[0];
+  atsc_mpeg_packet_no_sync *out = (atsc_mpeg_packet_no_sync *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+
+    // sanity check incoming data.
+    assert((in[i].data[0] == MPEG_SYNC_BYTE));
+    assert((in[i].data[1] & MPEG_TRANSPORT_ERROR_BIT) == 0);
+
+    // initialize plinfo for downstream
+    //
+    // We do this here because the randomizer is effectively
+    // the head of the tx processing chain
+    //
+    out[i].pli.set_regular_seg(d_field2, d_segno);
+    d_segno++;
+    if (d_segno == 312){
+      d_segno = 0;
+      d_field2 = !d_field2;
+    }
+
+    if (out[i].pli.first_regular_seg_p())
+      d_rand.reset();
+
+    d_rand.randomize(out[i], in[i]);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_randomizer.h b/gr-atsc/src/lib/atsc_randomizer.h
new file mode 100644 (file)
index 0000000..6617bcc
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_RANDOMIZER_H
+#define INCLUDED_ATSC_RANDOMIZER_H
+
+#include <gr_sync_block.h>
+#include <atsci_randomizer.h>
+
+class atsc_randomizer;
+typedef boost::shared_ptr<atsc_randomizer> atsc_randomizer_sptr;
+
+atsc_randomizer_sptr atsc_make_randomizer();
+
+/*!
+ * \brief "Whiten" incoming mpeg transport stream packets
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet; output: atsc_mpeg_packet_no_sync
+ */
+class atsc_randomizer : public gr_sync_block
+{
+  friend atsc_randomizer_sptr atsc_make_randomizer();
+
+  atsci_randomizer     d_rand;
+  bool                 d_field2;       // user to init plinfo in output
+  int                  d_segno;        // likewise
+
+  atsc_randomizer();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset();
+};
+
+
+#endif /* INCLUDED_ATSC_RANDOMIZER_H */
diff --git a/gr-atsc/src/lib/atsc_rs_decoder.cc b/gr-atsc/src/lib/atsc_rs_decoder.cc
new file mode 100644 (file)
index 0000000..680d64e
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_rs_decoder.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_rs_decoder_sptr
+atsc_make_rs_decoder()
+{
+  return atsc_rs_decoder_sptr(new atsc_rs_decoder());
+}
+
+atsc_rs_decoder::atsc_rs_decoder()
+  : gr_sync_block("atsc_rs_decoder",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)))
+{
+  reset();
+}
+
+int
+atsc_rs_decoder::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0];
+  atsc_mpeg_packet_no_sync *out = (atsc_mpeg_packet_no_sync *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    assert(in[i].pli.regular_seg_p());
+    out[i].pli = in[i].pli;                    // copy pipeline info...
+
+    int nerrors_corrrected = d_rs_decoder.decode(out[i], in[i]);
+    out[i].pli.set_transport_error(nerrors_corrrected == -1);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_rs_decoder.h b/gr-atsc/src/lib/atsc_rs_decoder.h
new file mode 100644 (file)
index 0000000..00dea16
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_RS_DECODER_H
+#define INCLUDED_ATSC_RS_DECODER_H
+
+#include <gr_sync_block.h>
+#include <atsci_reed_solomon.h>
+
+class atsc_rs_decoder;
+typedef boost::shared_ptr<atsc_rs_decoder> atsc_rs_decoder_sptr;
+
+atsc_rs_decoder_sptr atsc_make_rs_decoder();
+
+/*!
+ * \brief Reed-Solomon decoder for ATSC
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_no_sync
+ */
+class atsc_rs_decoder : public gr_sync_block
+{
+  friend atsc_rs_decoder_sptr atsc_make_rs_decoder();
+
+  atsci_reed_solomon   d_rs_decoder;
+
+  atsc_rs_decoder();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_RS_DECODER_H */
diff --git a/gr-atsc/src/lib/atsc_rs_encoder.cc b/gr-atsc/src/lib/atsc_rs_encoder.cc
new file mode 100644 (file)
index 0000000..faf9bff
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_rs_encoder.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_rs_encoder_sptr
+atsc_make_rs_encoder()
+{
+  return atsc_rs_encoder_sptr(new atsc_rs_encoder());
+}
+
+atsc_rs_encoder::atsc_rs_encoder()
+  : gr_sync_block("atsc_rs_encoder",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
+{
+  reset();
+}
+
+int
+atsc_rs_encoder::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_no_sync *in = (const atsc_mpeg_packet_no_sync *) input_items[0];
+  atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+
+    assert(in[i].pli.regular_seg_p());
+    out[i].pli = in[i].pli;                    // copy pipeline info...
+    d_rs_encoder.encode(out[i], in[i]);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-atsc/src/lib/atsc_rs_encoder.h b/gr-atsc/src/lib/atsc_rs_encoder.h
new file mode 100644 (file)
index 0000000..312b2e1
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_RS_ENCODER_H
+#define INCLUDED_ATSC_RS_ENCODER_H
+
+#include <gr_sync_block.h>
+#include <atsci_reed_solomon.h>
+
+class atsc_rs_encoder;
+typedef boost::shared_ptr<atsc_rs_encoder> atsc_rs_encoder_sptr;
+
+atsc_rs_encoder_sptr atsc_make_rs_encoder();
+
+/*!
+ * \brief Reed-Solomon encoder for ATSC
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_no_sync; output: atsc_mpeg_packet_rs_encoded
+ */
+class atsc_rs_encoder : public gr_sync_block
+{
+  friend atsc_rs_encoder_sptr atsc_make_rs_encoder();
+
+  atsci_reed_solomon   d_rs_encoder;
+
+  atsc_rs_encoder();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_RS_ENCODER_H */
diff --git a/gr-atsc/src/lib/atsc_trellis_encoder.cc b/gr-atsc/src/lib/atsc_trellis_encoder.cc
new file mode 100644 (file)
index 0000000..efd0883
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_trellis_encoder.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+
+atsc_trellis_encoder_sptr
+atsc_make_trellis_encoder()
+{
+  return atsc_trellis_encoder_sptr(new atsc_trellis_encoder());
+}
+
+atsc_trellis_encoder::atsc_trellis_encoder()
+  : gr_sync_block("atsc_trellis_encoder",
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_data_segment)))
+{
+  set_output_multiple(atsci_trellis_encoder::NCODERS);
+  reset();
+}
+
+int
+atsc_trellis_encoder::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0];
+  atsc_data_segment *out = (atsc_data_segment *) output_items[0];
+
+  for (int i = 0; i < atsci_trellis_encoder::NCODERS; i += atsci_trellis_encoder::NCODERS){
+    d_trellis_encoder.encode(&out[i], &in[i]);
+  }
+  return atsci_trellis_encoder::NCODERS;
+}
+
diff --git a/gr-atsc/src/lib/atsc_trellis_encoder.h b/gr-atsc/src/lib/atsc_trellis_encoder.h
new file mode 100644 (file)
index 0000000..5c93daf
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_TRELLIS_ENCODER_H
+#define INCLUDED_ATSC_TRELLIS_ENCODER_H
+
+#include <gr_sync_block.h>
+#include <atsci_trellis_encoder.h>
+
+class atsc_trellis_encoder;
+typedef boost::shared_ptr<atsc_trellis_encoder> atsc_trellis_encoder_sptr;
+
+atsc_trellis_encoder_sptr atsc_make_trellis_encoder();
+
+/*!
+ * \brief ATSC 12-way interleaved trellis encoder (atsc_mpeg_packet_rs_encoded --> atsc_data_segment)
+ * \ingroup atsc
+ *
+ * input: atsc_mpeg_packet_rs_encoded; output: atsc_data_segment
+ */
+class atsc_trellis_encoder : public gr_sync_block
+{
+  friend atsc_trellis_encoder_sptr atsc_make_trellis_encoder();
+
+  atsci_trellis_encoder        d_trellis_encoder;
+
+  atsc_trellis_encoder();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+};
+
+
+#endif /* INCLUDED_ATSC_TRELLIS_ENCODER_H */
diff --git a/gr-atsc/src/lib/atsc_types.h b/gr-atsc/src/lib/atsc_types.h
new file mode 100644 (file)
index 0000000..d505a51
--- /dev/null
@@ -0,0 +1,238 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef _ATSC_TYPES_H_
+#define _ATSC_TYPES_H_
+
+#include <atsc_consts.h>
+#include <cstring>
+#include <cassert>
+
+
+/*!
+ * \brief pipeline info that flows with data
+ *
+ * Not all modules need all the info
+ */
+class plinfo { 
+public:
+  plinfo () : _flags (0), _segno (0) { }
+
+  // accessors
+
+  bool field_sync1_p () const { return (_flags & fl_field_sync1) != 0; }
+  bool field_sync2_p () const { return (_flags & fl_field_sync2) != 0; }
+  bool field_sync_p ()  const { return field_sync1_p () || field_sync2_p (); }
+
+  bool regular_seg_p () const { return (_flags & fl_regular_seg) != 0; }
+
+  bool in_field1_p ()   const { return (_flags & fl_field2) == 0; }
+  bool in_field2_p ()   const { return (_flags & fl_field2) != 0; }
+
+  bool first_regular_seg_p () const { return (_flags & fl_first_regular_seg) != 0; }
+
+  bool transport_error_p ()   const { return (_flags & fl_transport_error) != 0; }
+
+  unsigned int segno ()        const { return _segno; }
+  unsigned int flags () const { return _flags; }
+
+  // setters
+
+  void set_field_sync1 ()
+  {
+    _segno = 0;
+    _flags = fl_field_sync1;
+  }
+
+  void set_field_sync2 ()
+  {
+    _segno = 0;
+    _flags = fl_field_sync2 | fl_field2;
+  }
+
+  void set_regular_seg (bool field2, int segno)
+  {
+    assert (0 <= segno && segno < ATSC_DSEGS_PER_FIELD);
+    _segno = segno;
+    _flags = fl_regular_seg;
+    if (segno == 0)
+      _flags |= fl_first_regular_seg;
+    if (segno >= ATSC_DSEGS_PER_FIELD)
+      _flags |= fl_transport_error;
+    if (field2)
+      _flags |= fl_field2;
+  }
+
+  void set_transport_error (bool error){
+    if (error)
+      _flags |= fl_transport_error;
+    else
+      _flags &= ~fl_transport_error;
+  }
+
+  // overload equality operator
+  bool operator== (const plinfo &other) const {
+    return (_flags == other._flags && _segno == other._segno);
+  }
+
+  bool operator!= (const plinfo &other) const {
+    return !(_flags == other._flags && _segno == other._segno);
+  }
+
+  /*!
+   * Set \p OUT such that it reflects a \p NSEGS_OF_DELAY
+   * pipeline delay from \p IN.
+   */
+  static void delay (plinfo &out, const plinfo &in, int nsegs_of_delay);
+
+  /*!
+   * confirm that \p X is plausible
+   */
+  static void sanity_check (const plinfo &in);
+  
+
+protected:
+  unsigned short       _flags;         // bitmask
+  unsigned short       _segno;         // segment number [0,311]
+
+  // these three are mutually exclusive
+  //     This is a regular data segment.
+  static const int     fl_regular_seg          = 0x0001;
+  //    This is a field sync segment, for 1st half of a field.
+  static const int     fl_field_sync1          = 0x0002;
+  //    This is a field sync segment, for 2nd half of a field.
+  static const int     fl_field_sync2          = 0x0004;
+
+  // This bit is on ONLY when fl_regular_seg is set AND when this is
+  // the first regular data segment AFTER a field sync segment.  This
+  // segment causes various processing modules to reset.
+  static const int     fl_first_regular_seg    = 0x0008;
+
+  // which field are we in?
+  static const int     fl_field2               = 0x0010;       // else field 1
+
+  // This bit is set when Reed-Solomon decoding detects an error that it
+  // can't correct.  Note that other error detection (e.g. Viterbi) do not
+  // set it, since Reed-Solomon will correct many of those.  This bit is
+  // then copied into the final Transport Stream packet so that MPEG
+  // software can see that the 188-byte data segment has been corrupted.
+  static const int     fl_transport_error      = 0x0020;
+};
+
+
+
+
+class atsc_mpeg_packet {
+ public:
+  static const int NPAD  = 68;
+  unsigned char        data[ATSC_MPEG_DATA_LENGTH + 1];        // first byte is sync
+  unsigned char _pad_[NPAD];                           // pad to power of 2 (256)
+
+  // overload equality operator
+  bool operator== (const atsc_mpeg_packet &other) const {
+    return std::memcmp (data, other.data, sizeof (data)) == 0;
+  };
+
+  bool operator!= (const atsc_mpeg_packet &other) const {
+    return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+  };
+};
+
+class atsc_mpeg_packet_no_sync {
+ public:
+  static const int NPAD = 65;
+  plinfo       pli;
+  unsigned char        data[ATSC_MPEG_DATA_LENGTH];
+  unsigned char _pad_[NPAD];                           // pad to power of 2 (256)
+
+  // overload equality operator
+  bool operator== (const atsc_mpeg_packet_no_sync &other) const {
+    return std::memcmp (data, other.data, sizeof (data)) == 0;
+  }
+
+  bool operator!= (const atsc_mpeg_packet_no_sync &other) const {
+    return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+  }
+};
+
+class atsc_mpeg_packet_rs_encoded {
+ public:
+  static const int NPAD = 45;
+  plinfo       pli;
+  unsigned char        data[ATSC_MPEG_RS_ENCODED_LENGTH];
+  unsigned char _pad_[NPAD];                           // pad to power of 2 (256)
+
+  // overload equality operator
+  bool operator== (const atsc_mpeg_packet_rs_encoded &other) const {
+    return std::memcmp (data, other.data, sizeof (data)) == 0;
+  }
+
+  bool operator!= (const atsc_mpeg_packet_rs_encoded &other) const {
+    return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+  }
+};
+
+
+//! contains 832 3 bit symbols.  The low 3 bits in the byte hold the symbol.
+
+class atsc_data_segment {
+ public:
+  static const int NPAD = 188;
+  plinfo       pli;
+  unsigned char        data[ATSC_DATA_SEGMENT_LENGTH];
+  unsigned char _pad_[NPAD];                           // pad to power of 2 (1024)
+
+  // overload equality operator
+  bool operator== (const atsc_data_segment &other) const {
+    return std::memcmp (data, other.data, sizeof (data)) == 0;
+  }
+
+  bool operator!= (const atsc_data_segment &other) const {
+    return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+  }
+};
+
+/*!
+ * Contains 832 bipolar floating point symbols.
+ * Nominal values are +/- {1, 3, 5, 7}.  
+ * This data type represents the input to the viterbi decoder.
+ */
+
+class atsc_soft_data_segment {
+ public:
+  static const int NPAD = 764;
+  plinfo       pli;
+  float                data[ATSC_DATA_SEGMENT_LENGTH];
+  unsigned char _pad_[NPAD];                   // pad to power of 2 (4096)
+
+  // overload equality operator
+  bool operator== (const atsc_data_segment &other) const {
+    return std::memcmp (data, other.data, sizeof (data)) == 0;
+  }
+
+  bool operator!= (const atsc_data_segment &other) const {
+    return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+  }
+};
+
+
+#endif /* _ATSC_TYPES_H_ */
diff --git a/gr-atsc/src/lib/atsc_viterbi_decoder.cc b/gr-atsc/src/lib/atsc_viterbi_decoder.cc
new file mode 100644 (file)
index 0000000..9db0401
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_viterbi_decoder.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+atsc_viterbi_decoder_sptr
+atsc_make_viterbi_decoder()
+{
+  return atsc_viterbi_decoder_sptr(new atsc_viterbi_decoder());
+}
+
+atsc_viterbi_decoder::atsc_viterbi_decoder()
+  : gr_sync_block("atsc_viterbi_decoder",
+                 gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))),
+                 last_start(-1)
+{
+  set_output_multiple(atsci_viterbi_decoder::NCODERS);
+  reset();
+}
+
+int
+atsc_viterbi_decoder::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0];
+  atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
+
+  assert (noutput_items % atsci_viterbi_decoder::NCODERS == 0);
+
+  // find the first mod 12 boundary to begin decoding
+  int start;
+  for (start = 0; start < atsci_viterbi_decoder::NCODERS; start++){
+    assert (in[start].pli.regular_seg_p ());
+    if ((in[start].pli.segno () % atsci_viterbi_decoder::NCODERS) == 0)
+      break;
+  }
+
+  if (start == atsci_viterbi_decoder::NCODERS){
+    // we didn't find a mod 12 boundary.  There's some kind of problem
+    // upstream of us (not yet sync'd??)
+    cerr << "!!!atsc_viterbi_decoder: no mod-12 boundary found\7\n";
+    start = 0;
+  }
+  else if (start != last_start){
+    cerr << "atsc_viterbi_decoder: new starting offset = " << start
+         << endl;
+    last_start = start;
+  }
+
+  for (int i = 0; i < atsci_viterbi_decoder::NCODERS; i += atsci_viterbi_decoder::NCODERS){
+    d_viterbi_decoder.decode(&out[i], &in[i + start]);
+  }
+  return atsci_viterbi_decoder::NCODERS;
+}
+
diff --git a/gr-atsc/src/lib/atsc_viterbi_decoder.h b/gr-atsc/src/lib/atsc_viterbi_decoder.h
new file mode 100644 (file)
index 0000000..511df0d
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_ATSC_VITERBI_DECODER_H
+#define INCLUDED_ATSC_VITERBI_DECODER_H
+
+#include <gr_sync_block.h>
+#include <atsci_viterbi_decoder.h>
+
+class atsc_viterbi_decoder;
+typedef boost::shared_ptr<atsc_viterbi_decoder> atsc_viterbi_decoder_sptr;
+
+atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder();
+
+/*!
+ * \brief ATSC 12-way interleaved viterbi decoder (atsc_soft_data_segment --> atsc_mpeg_packet_rs_encoded)
+ * \ingroup atsc
+ *
+ * input: atsc_soft_data_segment; output: atsc_mpeg_packet_rs_encoded
+ */
+class atsc_viterbi_decoder : public gr_sync_block
+{
+  friend atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder();
+
+  atsci_viterbi_decoder        d_viterbi_decoder;
+
+  atsc_viterbi_decoder();
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  void reset() { /* nop */ }
+
+protected:
+  int      last_start;
+
+};
+
+
+#endif /* INCLUDED_ATSC_VITERBI_DECODER_H */
diff --git a/gr-atsc/src/lib/atsci_basic_trellis_encoder.cc b/gr-atsc/src/lib/atsci_basic_trellis_encoder.cc
new file mode 100644 (file)
index 0000000..6b6fc19
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_basic_trellis_encoder.h>
+#include <assert.h>
+
+const unsigned char atsci_basic_trellis_encoder::next_state[32] = {
+  0,1,4,5,
+  2,3,6,7,
+  1,0,5,4,
+  3,2,7,6,
+  4,5,0,1,
+  6,7,2,3,
+  5,4,1,0,
+  7,6,3,2
+};
+
+const unsigned char atsci_basic_trellis_encoder::out_symbol[32] = {
+  0,2,4,6,
+  1,3,5,7,
+  0,2,4,6,
+  1,3,5,7,
+  4,6,0,2,
+  5,7,1,3,
+  4,6,0,2,
+  5,7,1,3
+};
+
+
+/*!
+ * Encode two bit INPUT into 3 bit return value.  Domain is [0,3],
+ * Range is [0,7].  The mapping to bipolar levels is not done.
+ */
+
+int
+atsci_basic_trellis_encoder::encode (unsigned int input)
+{
+  assert (input < 4);
+  int index = (state << 2) + input; 
+  state = next_state[index];
+  return out_symbol[index];
+}
+
diff --git a/gr-atsc/src/lib/atsci_basic_trellis_encoder.h b/gr-atsc/src/lib/atsci_basic_trellis_encoder.h
new file mode 100644 (file)
index 0000000..1e40731
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_BASIC_TRELLIS_ENCODER_H_
+#define _ATSC_BASIC_TRELLIS_ENCODER_H_
+
+#include <assert.h>
+
+/*!
+ * \brief ATSC trellis encoder building block.
+ *
+ * Note this is NOT the 12x interleaved interface.
+ *
+ * This implements a single instance of the ATSC trellis encoder.
+ * This is a rate 2/3 encoder (really a constraint length 3, rate 1/2
+ * encoder with the top bit passed through unencoded.  This does not
+ * implement the "precoding" of the top bit, because the NTSC rejection
+ * filter is not supported.
+ */
+
+class atsci_basic_trellis_encoder {
+
+private:
+  int              state;              // two bit state;
+
+public:
+  atsci_basic_trellis_encoder () : state (0) {}
+
+  /*!
+   * Encode two bit INPUT into 3 bit return value.  Domain is [0,3],
+   * Range is [0,7].  The mapping to bipolar levels is not done.
+   */
+  int encode (unsigned int input);
+
+  //! reset encoder state
+  void reset () { state = 0; }
+
+  static const unsigned char next_state[32];
+  static const unsigned char out_symbol[32];
+};
+
+#endif /* _ATSC_BASIC_TRELLIS_ENCODER_H_ */
diff --git a/gr-atsc/src/lib/atsci_data_interleaver.cc b/gr-atsc/src/lib/atsci_data_interleaver.cc
new file mode 100644 (file)
index 0000000..b20dde9
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_data_interleaver.h>
+
+void 
+atsci_data_interleaver::interleave (atsc_mpeg_packet_rs_encoded &out,
+                                  const atsc_mpeg_packet_rs_encoded &in)
+{
+  assert (in.pli.regular_seg_p ());
+  plinfo::sanity_check (in.pli);
+
+  out.pli = in.pli;                    // copy pipeline info
+  if (in.pli.first_regular_seg_p ())   // reset commutator if required
+    sync ();
+
+  transform (out.data, in.data, sizeof (in.data));
+}
+
+
+void 
+atsci_data_deinterleaver::deinterleave (atsc_mpeg_packet_rs_encoded &out,
+                                      const atsc_mpeg_packet_rs_encoded &in)
+{
+  assert (in.pli.regular_seg_p ());
+  plinfo::sanity_check (in.pli);
+
+  // reset commutator if required using INPUT pipeline info
+  if (in.pli.first_regular_seg_p ())
+    sync ();
+  
+  // remap OUTPUT pipeline info to reflect 52 data segment end-to-end delay
+
+  plinfo::delay (out.pli, in.pli, 52);
+
+  // now do the actual deinterleaving
+
+  for (unsigned int i = 0; i < sizeof (in.data); i++){
+    out.data[i] = alignment_fifo.stuff (transform (in.data[i]));
+  }
+}
+
diff --git a/gr-atsc/src/lib/atsci_data_interleaver.h b/gr-atsc/src/lib/atsci_data_interleaver.h
new file mode 100644 (file)
index 0000000..ab4b64d
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_DATA_INTERLEAVER_H_
+#define _ATSC_DATA_INTERLEAVER_H_
+
+#include <atsc_types.h>
+#include <convolutional_interleaver.h>
+
+/*!
+ * \brief atsc convolutional data interleaver
+ */
+class atsci_data_interleaver : public convolutional_interleaver<unsigned char> {
+ public:
+  atsci_data_interleaver () : convolutional_interleaver<unsigned char>(true, 52, 4) {}
+
+  void interleave (atsc_mpeg_packet_rs_encoded &out,
+                  const atsc_mpeg_packet_rs_encoded &in);
+};
+
+/*!
+ * \brief atsc convolutional data deinterleaver
+ */
+class atsci_data_deinterleaver : public convolutional_interleaver<unsigned char> {
+ public:
+  atsci_data_deinterleaver () :
+    convolutional_interleaver<unsigned char>(false, 52, 4), alignment_fifo (156) {}
+
+  void deinterleave (atsc_mpeg_packet_rs_encoded &out,
+                    const atsc_mpeg_packet_rs_encoded &in);
+
+private:
+  /*!
+   * Note: The use of the alignment_fifo keeps the encoder and decoder
+   * aligned if both are synced to a field boundary.  There may be other
+   * ways to implement this function.  This is a best guess as to how
+   * this should behave, as we have no test vectors for either the
+   * interleaver or deinterleaver.
+   */
+  interleaver_fifo<unsigned char> alignment_fifo;
+
+  static void remap_pli (plinfo &out, const plinfo &in);
+};
+
+#endif /* _ATSC_DATA_INTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/atsci_diag_output.h b/gr-atsc/src/lib/atsci_diag_output.h
new file mode 100644 (file)
index 0000000..5e3239d
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+/*
+ * single place to control all compile time diagnostic output options
+ */
+
+#define _BT_DIAG_OUTPUT_       0
+#define        _FPLL_DIAG_OUTPUT_      0
+#define        _SSSR_DIAG_OUTPUT_      0
diff --git a/gr-atsc/src/lib/atsci_equalizer.cc b/gr-atsc/src/lib/atsci_equalizer.cc
new file mode 100644 (file)
index 0000000..fb04db7
--- /dev/null
@@ -0,0 +1,248 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_equalizer.h>
+#include <algorithm>
+#include <iostream>
+#include <atsc_types.h>
+
+using std::cerr;
+using std::endl;
+using std::min;
+
+
+// total number of symbols (including field sync) / field
+static const int SYMBOLS_PER_FIELD =
+  (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH;
+
+
+atsci_equalizer::atsci_equalizer ()
+{
+  d_locked_p = false;
+  d_offset_from_last_field_sync = 0;
+  d_current_field = 0;
+}
+
+atsci_equalizer::~atsci_equalizer ()
+{
+}
+
+void
+atsci_equalizer::reset ()
+{
+  d_locked_p = false;
+  d_offset_from_last_field_sync = 0;
+  d_current_field = 0;
+}
+\f
+/*
+ * Errrr.... Define to 1 if compiler handles tail recursion without pushing
+ * unnecessary stack frames, else define to 0 for lame compilers.
+ */
+#define        WINNING_COMPILER        0
+
+
+/*
+ * divide and conquer...
+ *
+ * Note that this could be refactored to take advantage of the
+ * symbol_num that is contained in the input_tags.  Then we wouldn't
+ * have to be counting here.
+ *
+ * Today's strategy: get it working.
+ */
+
+void 
+atsci_equalizer::filter (const float         *input_samples,
+                       const atsc::syminfo *input_tags,
+                       float               *output_samples,
+                       int                  nsamples)
+{
+ lame_compiler_kludge:
+
+  if (!d_locked_p){
+
+    // look for a field sync
+
+    int        i;
+    for (i = 0; i < nsamples; i++){
+      if (atsc::tag_is_start_field_sync (input_tags[i]))
+       break;
+    }
+
+    // whether we found one or not, everything up to it should
+    // be run through the normal path
+
+    if (i != 0)
+      filter_normal (input_samples, output_samples, i);
+
+    if (i == nsamples)         // no field sync found, still not locked.
+      return;
+
+    // OK, we've just transitioned to the locked state.
+
+    d_locked_p = true;
+    d_offset_from_last_field_sync = 0;
+
+    // handle locked case recursively
+
+    if (WINNING_COMPILER)
+      filter (&input_samples[i], &input_tags[i],
+             &output_samples[i], nsamples - i);
+    else {
+      input_samples += i;
+      input_tags += i;
+      output_samples += i;
+      nsamples -= i;
+      goto lame_compiler_kludge;
+    }
+
+    return;
+  }
+
+  // We're in the locked state.
+  //
+  // Figure out where we are with respect to a data segment boundary
+  // and do the right thing.  Note that in the interested of performance,
+  // we don't scan all the tags looking for trouble.  We only check
+  // them where we expect them to be non-NORMAL.  Worst case, it'll take
+  // us a field to notice that something went wrong...
+
+  if (d_offset_from_last_field_sync % SYMBOLS_PER_FIELD == 0){ // we should be looking
+                                                                //   at a field sync
+    if (atsc::tag_is_start_field_sync_1 (input_tags[0]))
+      d_current_field = 0;
+
+    else if (atsc::tag_is_start_field_sync_2 (input_tags[0]))
+      d_current_field = 1;
+
+    else {     // we're lost... no field sync where we expected it
+
+      cerr << "!!! atsci_equalizer: expected field sync, didn't find one\n";
+       
+      d_locked_p = false;
+      d_offset_from_last_field_sync = 0;       
+
+      if (WINNING_COMPILER)
+       filter (input_samples, input_tags, output_samples, nsamples);
+      else
+       goto lame_compiler_kludge;
+      
+      return;
+    }
+
+    // OK, everything's cool.  We're looking at a field sync.
+
+    int n = min (ATSC_DATA_SEGMENT_LENGTH, nsamples);
+
+    filter_field_sync (input_samples, output_samples, n, 0, d_current_field);
+
+    d_offset_from_last_field_sync = n;
+    nsamples -= n;
+
+    if (nsamples > 0){
+      if (WINNING_COMPILER)
+       filter (&input_samples[n], &input_tags[n],
+               &output_samples[n], nsamples);
+      else {
+       input_samples += n;
+       input_tags += n;
+       output_samples += n;
+       goto lame_compiler_kludge;
+      }
+    }
+    return;
+  }
+
+  if (d_offset_from_last_field_sync < ATSC_DATA_SEGMENT_LENGTH){ // we're in the middle of a field sync
+    int n = min (ATSC_DATA_SEGMENT_LENGTH - d_offset_from_last_field_sync, nsamples);
+
+    filter_field_sync (input_samples, output_samples, n,
+                      d_offset_from_last_field_sync, d_current_field);
+
+    d_offset_from_last_field_sync += n;
+    nsamples -= n;
+
+    if (nsamples > 0){
+      if (WINNING_COMPILER)
+       filter (&input_samples[n], &input_tags[n],
+               &output_samples[n], nsamples);
+      else {
+       input_samples += n;
+       input_tags += n;
+       output_samples += n;
+       goto lame_compiler_kludge;
+      }
+    }
+    return;
+  }
+
+  // OK, we're not in a field sync.  We're either in a data segment sync or in the clear...
+
+  int seg_offset = d_offset_from_last_field_sync % ATSC_DATA_SEGMENT_LENGTH;
+
+  assert (seg_offset >= 0);
+
+  if (seg_offset < 4){ // somewhere in a data seg sync.
+    int n = min (4 - seg_offset, nsamples);
+
+    filter_data_seg_sync (input_samples, output_samples, n, seg_offset);
+    
+    d_offset_from_last_field_sync += n;
+    nsamples -= n;
+
+    if (nsamples > 0){
+      if (WINNING_COMPILER)
+       filter (&input_samples[n], &input_tags[n],
+               &output_samples[n], nsamples);
+      else {
+       input_samples += n;
+       input_tags += n;
+       output_samples += n;
+       goto lame_compiler_kludge;
+      }
+    }
+    return;
+  }
+
+  // otherwise... we're in the normal zone
+
+  int n = min (ATSC_DATA_SEGMENT_LENGTH - seg_offset, nsamples);
+  
+  filter_normal (input_samples, output_samples, n);
+
+  d_offset_from_last_field_sync += n;
+  nsamples -= n;
+
+  if (nsamples <= 0)
+    return;
+  
+  if (WINNING_COMPILER)
+    filter (&input_samples[n], &input_tags[n],
+           &output_samples[n], nsamples);
+  else {
+    input_samples += n;
+    input_tags += n;
+    output_samples += n;
+    goto lame_compiler_kludge;
+  }
+}
diff --git a/gr-atsc/src/lib/atsci_equalizer.h b/gr-atsc/src/lib/atsci_equalizer.h
new file mode 100644 (file)
index 0000000..2120ea9
--- /dev/null
@@ -0,0 +1,163 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_EQUALIZER_H_
+#define _ATSC_EQUALIZER_H_
+
+#include <atsci_syminfo.h>
+
+/*!
+ * \brief abstract base class for ATSC equalizer
+ */
+class atsci_equalizer {
+
+private:
+
+  /*
+   * have we seen a field sync since the last reset or problem?
+   */
+  bool d_locked_p;
+
+  /*
+   * sample offset from the beginning of the last field sync we saw
+   * to the beginning of our current input stream.  When we're locked
+   * this will be in [0, 313*832] i.e., [0, 260416]
+   */
+  int  d_offset_from_last_field_sync;
+
+  int  d_current_field;                // [0,1]
+
+
+public:
+
+  // CREATORS
+  atsci_equalizer ();
+  virtual ~atsci_equalizer ();
+  
+  // MANIPULATORS
+
+  /*!
+   * \brief reset state (e.g., on channel change)
+   *
+   * Note, subclasses must invoke the superclass's method too!
+   */
+  virtual void reset ();
+  
+  /*!
+   * \brief produce \p nsamples of output from given inputs and tags
+   *
+   * This is the main entry point.  It examines the input_tags
+   * and local state and invokes the appropriate virtual function
+   * to handle each sub-segment of the input data.
+   *
+   * \p input_samples must have (nsamples + ntaps() - 1) valid entries.
+   * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] are 
+   * referenced to compute the output values.
+   *
+   * \p input_tags must have nsamples valid entries.
+   * input_tags[0] .. input_tags[nsamples - 1] are referenced to 
+   * compute the output values.
+   */
+  virtual void filter (const float        *input_samples,
+                      const atsc::syminfo *input_tags,
+                      float               *output_samples,
+                      int                  nsamples);
+
+  // ACCESSORS
+
+  /*!
+   * \brief how much history the input data stream requires.
+   *
+   * This must return a value >= 1.  Think of this as the number
+   * of samples you need to look at to compute a single output sample.
+   */
+  virtual int ntaps () const = 0;
+
+  /*!
+   * \brief how many taps are "in the future".  
+   *
+   * This allows us to handle what the ATSC folks call "pre-ghosts".
+   * What it really does is allow the caller to jack with the offset 
+   * between the tags and the data so that everything magically works out.
+   *
+   * npretaps () must return a value between 0 and ntaps() - 1.
+   *
+   * If npretaps () returns 0, this means that the equalizer will only handle
+   * multipath "in the past."  I suspect that a good value would be something
+   * like 15% - 20% of ntaps ().
+   */
+  virtual int npretaps () const = 0;
+  
+
+protected:
+
+  /*!
+   * Input range is known NOT TO CONTAIN data segment syncs
+   * or field syncs.  This should be the fast path.  In the
+   * non decicion directed case, this just runs the input
+   * through the filter without adapting it.
+   *
+   * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+   * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+   * referenced to compute the output values.
+   */
+  virtual void filter_normal (const float *input_samples,
+                             float *output_samples,
+                             int   nsamples) = 0;
+
+  /*!
+   * Input range is known to consist of only a data segment sync or a
+   * portion of a data segment sync.  \p nsamples will be in [1,4].
+   * \p offset will be in [0,3].  \p offset is the offset of the input
+   * from the beginning of the data segment sync pattern.
+   *
+   * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+   * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+   * referenced to compute the output values.
+   */
+  virtual void filter_data_seg_sync (const float *input_samples,
+                                    float *output_samples,
+                                    int   nsamples,
+                                    int   offset) = 0;
+  
+  /*!
+   * Input range is known to consist of only a field sync segment or a
+   * portion of a field sync segment.  \p nsamples will be in [1,832].
+   * \p offset will be in [0,831].  \p offset is the offset of the input
+   * from the beginning of the data segment sync pattern.  We consider the
+   * 4 symbols of the immediately preceding data segment sync to be the
+   * first symbols of the field sync segment.  \p which_field is in [0,1] 
+   * and specifies which field (duh).
+   *
+   * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+   * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+   * referenced to compute the output values.
+   */
+  virtual void filter_field_sync (const float *input_samples,
+                                 float *output_samples,
+                                 int   nsamples,
+                                 int   offset,
+                                 int   which_field) = 0;
+};
+
+
+#endif /* _ATSC_EQUALIZER_H_ */
diff --git a/gr-atsc/src/lib/atsci_equalizer_lms.cc b/gr-atsc/src/lib/atsci_equalizer_lms.cc
new file mode 100644 (file)
index 0000000..6358b53
--- /dev/null
@@ -0,0 +1,307 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_equalizer_lms.h>
+#include <assert.h>
+#include <algorithm>
+#include <atsci_pnXXX.h>
+
+#include <stdio.h>
+
+using std::min;
+using std::max;
+
+static const int       NTAPS = 256;
+static const int       NPRETAPS = (int) (NTAPS * 0.8); // probably should be either .2 or .8
+
+
+// the length of the field sync pattern that we know unequivocally
+static const int KNOWN_FIELD_SYNC_LENGTH = 4 + 511 + 3 * 63;
+
+// static const float *get_data_seg_sync_training_sequence (int offset);
+static int          get_field_sync_training_sequence_length (int offset);
+static const float *get_field_sync_training_sequence (int which_field, int offset);
+
+
+atsci_equalizer_lms::atsci_equalizer_lms () : d_taps (NTAPS)
+{
+  for (int i = 0; i < NTAPS; i++) {
+    d_taps[i] = 0.0;
+  }
+  trainingfile=fopen("taps.txt","w");
+}
+
+atsci_equalizer_lms::~atsci_equalizer_lms ()
+{
+}
+
+void
+atsci_equalizer_lms::reset ()
+{
+  atsci_equalizer::reset ();           // invoke superclass
+
+  for (int i = 0; i < NTAPS; i++) {
+    d_taps[i] = 0.0;
+  }
+}
+
+int
+atsci_equalizer_lms::ntaps () const
+{
+  return NTAPS;
+}
+
+int
+atsci_equalizer_lms::npretaps () const
+{
+  return NPRETAPS;
+}
+
+/*!
+ * Input range is known NOT TO CONTAIN data segment syncs
+ * or field syncs.  This should be the fast path.  In the
+ * non decicion directed case, this just runs the input
+ * through the filter without adapting it.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms::filter_normal (const float *input_samples,
+                                  float *output_samples,
+                                  int   nsamples)
+{
+  // handle data
+  filterN (input_samples, output_samples, nsamples);
+}
+
+
+/*!
+ * Input range is known to consist of only a data segment sync or a
+ * portion of a data segment sync.  \p nsamples will be in [1,4].
+ * \p offset will be in [0,3].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms::filter_data_seg_sync (const float *input_samples,
+                                         float *output_samples,
+                                         int   nsamples,
+                                         int   offset)
+{
+  // handle data
+  //  adaptN (input_samples, get_data_seg_sync_training_sequence (offset),
+  //     output_samples, nsamples);
+ filterN (input_samples, output_samples, nsamples);
+
+ //  cerr << "Seg Sync: offset " << offset << "\tnsamples\t" << nsamples << "\t pre, 5 -5 -5 5\t" <<
+ // output_samples[0] << "\t" << output_samples[1] << "\t" << output_samples[2] << "\t" << output_samples[3] << endl;
+  
+}
+
+  
+/*!
+ * Input range is known to consist of only a field sync segment or a
+ * portion of a field sync segment.  \p nsamples will be in [1,832].
+ * \p offset will be in [0,831].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.  We consider the
+ * 4 symbols of the immediately preceding data segment sync to be the
+ * first symbols of the field sync segment.  \p which_field is in [0,1] 
+ * and specifies which field (duh).
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms::filter_field_sync (const float *input_samples,
+                                      float *output_samples,
+                                      int   nsamples,
+                                      int   offset,
+                                      int   which_field)
+{
+  // Only the first 4 + 511 + 3 * 63 symbols are completely defined.
+  // Those after that the symbols are bilevel, so we could use decision feedback and use 
+  // that to train, but for now, don't train on them.
+
+  int  n = min (nsamples, get_field_sync_training_sequence_length (offset));
+  
+  // handle known training sequence
+  adaptN (input_samples, get_field_sync_training_sequence (which_field, offset),
+                   output_samples, n);
+
+  // just filter any unknown portion
+  if (nsamples > n)
+    filterN (&input_samples[n], &output_samples[n], nsamples - n);
+
+  if (offset == 0 && nsamples > 0){
+    for (int i = 0; i < NTAPS; i++)
+      fprintf(trainingfile,"%f ",d_taps[i]);
+
+    fprintf (trainingfile,"\n");
+  }
+
+}
+
+// ----------------------------------------------------------------
+
+//
+// filter a single output
+//
+float
+atsci_equalizer_lms::filter1 (const float input[])
+{
+  static const int N_UNROLL = 4;
+
+  float        acc0 = 0;
+  float        acc1 = 0;
+  float        acc2 = 0;
+  float        acc3 = 0;
+
+
+  unsigned     i = 0;
+  unsigned     n = (NTAPS / N_UNROLL) * N_UNROLL;
+
+  for (i = 0; i < n; i += N_UNROLL){
+    acc0 += d_taps[i + 0] * input[i + 0];
+    acc1 += d_taps[i + 1] * input[i + 1];
+    acc2 += d_taps[i + 2] * input[i + 2];
+    acc3 += d_taps[i + 3] * input[i + 3];
+  }
+
+  for (; i < (unsigned) NTAPS; i++)
+    acc0 += d_taps[i] * input[i];
+
+  return (acc0 + acc1 + acc2 + acc3);
+}
+
+//
+// filter and adapt a single output
+//
+float
+atsci_equalizer_lms::adapt1 (const float input[], float ideal_output)
+{
+  static const double BETA = 0.00005;  // FIXME figure out what this ought to be
+                                       // FIXME add gear-shifting 
+
+  double y = filter1 (input);
+  double e = y - ideal_output;
+
+  // update taps...
+  for (int i = 0; i < NTAPS; i++){
+    d_taps[i] = d_taps[i] - BETA * e * (double)(input[i]);
+  }
+
+  return y;
+}
+
+void
+atsci_equalizer_lms::filterN (const float *input_samples,
+                            float *output_samples,
+                            int nsamples)
+{
+  for (int i = 0; i < nsamples; i++)
+    output_samples[i] = filter1 (&input_samples[i]);
+}
+
+
+void 
+atsci_equalizer_lms::adaptN (const float *input_samples,
+                           const float *training_pattern,
+                           float *output_samples,
+                           int    nsamples)
+{
+  for (int i = 0; i < nsamples; i++)
+    output_samples[i] = adapt1 (&input_samples[i], training_pattern[i]);
+}
+
+// ----------------------------------------------------------------
+
+static float
+bin_map (int bit)
+{
+  return bit ? +5 : -5;
+}
+
+static void
+init_field_sync_common (float *p, int mask)
+                       
+{
+  int  i = 0;
+
+  p[i++] = bin_map (1);                        // data segment sync pulse
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  for (int j = 0; j < 511; j++)                // PN511
+    p[i++] = bin_map (atsc_pn511[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63, toggled on field 2
+    p[i++] = bin_map (atsc_pn63[j] ^ mask);
+  
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  assert (i == KNOWN_FIELD_SYNC_LENGTH);
+}
+
+#if 0
+static const float *
+get_data_seg_sync_training_sequence (int offset)
+{
+  static const float training_data[4] = { +5, -5, -5, +5 };
+  return &training_data[offset];
+}
+#endif
+
+static int    
+get_field_sync_training_sequence_length (int offset)
+{
+  return max (0, KNOWN_FIELD_SYNC_LENGTH - offset);
+}
+
+static const float *
+get_field_sync_training_sequence (int which_field, int offset)
+{
+  static float *field_1 = 0;
+  static float *field_2 = 0;
+
+  if (field_1 == 0){
+    field_1 = new float[KNOWN_FIELD_SYNC_LENGTH];
+    field_2 = new float[KNOWN_FIELD_SYNC_LENGTH];
+    init_field_sync_common (field_1, 0);
+    init_field_sync_common (field_2, 1);
+  }
+
+  if (which_field == 0)
+    return &field_1[offset];
+  else
+    return &field_2[offset];
+}
diff --git a/gr-atsc/src/lib/atsci_equalizer_lms.h b/gr-atsc/src/lib/atsci_equalizer_lms.h
new file mode 100644 (file)
index 0000000..1626da2
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_EQUALIZER_LMS_H_
+#define _ATSC_EQUALIZER_LMS_H_
+
+#include <atsci_equalizer.h>
+#include <vector>
+#include <stdio.h>
+
+class atsci_equalizer_lms : public atsci_equalizer
+{
+public:
+  atsci_equalizer_lms ();
+  virtual ~atsci_equalizer_lms ();
+
+  virtual void reset ();
+  virtual int ntaps () const;
+  virtual int npretaps () const;
+  
+protected:
+  FILE *trainingfile;
+  virtual void filter_normal (const float *input_samples,
+                             float *output_samples,
+                             int   nsamples);
+
+  virtual void filter_data_seg_sync (const float *input_samples,
+                                    float *output_samples,
+                                    int   nsamples,
+                                    int   offset);
+  
+  virtual void filter_field_sync (const float *input_samples,
+                                 float *output_samples,
+                                 int   nsamples,
+                                 int   offset,
+                                 int   which_field);
+
+private:
+  std::vector<double>  d_taps;
+
+  void filterN (const float *input_samples,
+               float *output_samples,
+               int nsamples);
+
+  void adaptN (const float *input_samples,
+              const float *training_pattern,
+              float *output_samples,
+              int    nsamples);
+
+  float filter1 (const float input[]);
+  float adapt1 (const float input[], float ideal_output);
+
+};
+
+
+#endif /* _ATSC_EQUALIZER_LMS_H_ */
diff --git a/gr-atsc/src/lib/atsci_equalizer_lms2.cc b/gr-atsc/src/lib/atsci_equalizer_lms2.cc
new file mode 100644 (file)
index 0000000..345f620
--- /dev/null
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_equalizer_lms2.h>
+#include <assert.h>
+#include <algorithm>
+#include <atsci_pnXXX.h>
+#include <cmath>
+#include <stdlib.h>
+#include <gr_math.h>
+#include <stdio.h>
+
+using std::min;
+using std::max;
+
+static const int       NFFTAPS =  64;
+static const int       NFBTAPS = 192;
+
+// the length of the field sync pattern that we know unequivocally
+static const int KNOWN_FIELD_SYNC_LENGTH = 4 + 511 + 3 * 63;
+
+// static const float *get_data_seg_sync_training_sequence (int offset);
+static int          get_field_sync_training_sequence_length (int offset);
+static const float *get_field_sync_training_sequence (int which_field, int offset);
+
+static inline int 
+wrap (int d) 
+{
+  assert (d >= 0 && d <= (2 * NFBTAPS));
+  
+  if(d >= NFBTAPS)
+    return d - NFBTAPS;
+  return d;
+}
+
+static inline float 
+slice (float d)
+{
+  if (gr_isnan (d))
+    return 0.0;
+  
+  if (d >= 0.0){
+    if (d >= 4.0){
+      if (d >= 6.0)
+       return 7.0;
+      else
+       return 5.0;
+    }
+    if (d >= 2.0)
+      return 3.0;
+    return 1.0;
+  }
+  else
+    return -slice (-d);
+}
+
+atsci_equalizer_lms2::atsci_equalizer_lms2 ()
+  : d_taps_ff (NFFTAPS), d_taps_fb (NFBTAPS), d_old_output (NFBTAPS)
+{
+  for (int i = 0; i < NFFTAPS; i++) {
+    d_taps_ff[i] = 0.0;
+  }
+  for (int i = 0; i < NFBTAPS; i++) {
+    d_taps_fb[i] = 0.0;
+    d_old_output[i] = 0.0;
+  }
+  d_output_ptr = 0;
+  trainingfile=fopen("taps.txt","w");
+}
+
+atsci_equalizer_lms2::~atsci_equalizer_lms2 ()
+{
+}
+
+void
+atsci_equalizer_lms2::reset ()
+{
+  atsci_equalizer::reset ();           // invoke superclass
+  for (int i = 0; i < NFFTAPS; i++) {
+    d_taps_ff[i] = 0.0;
+  }
+  for (int i = 0; i < NFBTAPS; i++) {
+    d_taps_fb[i] = 0.0;
+    d_old_output[i] = 0.0;
+  }
+  d_output_ptr = 0;
+}
+
+
+int
+atsci_equalizer_lms2::ntaps () const
+{
+  return NFFTAPS + NFBTAPS;
+}
+
+int
+atsci_equalizer_lms2::npretaps () const
+{
+  return NFFTAPS;
+}
+
+/*!
+ * Input range is known NOT TO CONTAIN data segment syncs
+ * or field syncs.  This should be the fast path.  In the
+ * non decicion directed case, this just runs the input
+ * through the filter without adapting it.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms2::filter_normal (const float *input_samples,
+                                  float *output_samples,
+                                  int   nsamples)
+{
+  // handle data
+  filterN (input_samples, output_samples, nsamples);
+}
+
+
+/*!
+ * Input range is known to consist of only a data segment sync or a
+ * portion of a data segment sync.  \p nsamples will be in [1,4].
+ * \p offset will be in [0,3].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms2::filter_data_seg_sync (const float *input_samples,
+                                         float *output_samples,
+                                         int   nsamples,
+                                         int   offset)
+{
+  // handle data
+  //  adaptN (input_samples, get_data_seg_sync_training_sequence (offset),
+  //     output_samples, nsamples);
+ filterN (input_samples, output_samples, nsamples);
+
+ //  cerr << "Seg Sync: offset " << offset << "\tnsamples\t" << nsamples << "\t pre, 5 -5 -5 5\t" <<
+ // output_samples[0] << "\t" << output_samples[1] << "\t" << output_samples[2] << "\t" << output_samples[3] << endl;
+  
+}
+
+  
+/*!
+ * Input range is known to consist of only a field sync segment or a
+ * portion of a field sync segment.  \p nsamples will be in [1,832].
+ * \p offset will be in [0,831].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.  We consider the
+ * 4 symbols of the immediately preceding data segment sync to be the
+ * first symbols of the field sync segment.  \p which_field is in [0,1] 
+ * and specifies which field (duh).
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_lms2::filter_field_sync (const float *input_samples,
+                                      float *output_samples,
+                                      int   nsamples,
+                                      int   offset,
+                                      int   which_field)
+{
+  // Only the first 4 + 511 + 3 * 63 symbols are completely defined.
+  // Those after that the symbols are bilevel, so we could use decision feedback and use 
+  // that to train, but for now, don't train on them.
+
+  int  n = min (nsamples, get_field_sync_training_sequence_length (offset));
+  
+  // handle known training sequence
+  adaptN (input_samples, get_field_sync_training_sequence (which_field, offset),
+                   output_samples, n);
+
+  // just filter any unknown portion
+  if (nsamples > n)
+    filterN (&input_samples[n], &output_samples[n], nsamples - n);
+
+  if (offset == 0 && nsamples > 0){
+    for (int i = 0; i < NFFTAPS; i++)
+      fprintf(trainingfile,"%f ",d_taps_ff[i]);
+    for (int i = 0; i < NFBTAPS; i++)
+      fprintf(trainingfile,"%f ",d_taps_fb[i]);
+    fprintf (trainingfile,"\n");
+  }
+
+}
+
+// ----------------------------------------------------------------
+
+//
+// filter a single output
+//
+float
+atsci_equalizer_lms2::filter1 (const float input[])
+{
+  static const int N_UNROLL = 4;
+
+  float        acc0 = 0;
+  float        acc1 = 0;
+  float        acc2 = 0;
+  float        acc3 = 0;
+  float acc = 0;
+
+
+  unsigned     i = 0;
+  unsigned     n = (NFFTAPS / N_UNROLL) * N_UNROLL;
+
+  for (i = 0; i < n; i += N_UNROLL){
+    acc0 += d_taps_ff[i + 0] * input[i + 0];
+    acc1 += d_taps_ff[i + 1] * input[i + 1];
+    acc2 += d_taps_ff[i + 2] * input[i + 2];
+    acc3 += d_taps_ff[i + 3] * input[i + 3];
+  }
+
+  for (; i < (unsigned) NFFTAPS; i++)
+    acc0 += d_taps_ff[i] * input[i];
+
+  acc = (acc0 + acc1 + acc2 + acc3);
+
+  d_output_ptr = wrap (d_output_ptr + 1);
+
+  for (int i = 0; i < NFBTAPS; i++) {
+    acc -= d_taps_fb[i] * d_old_output[wrap(i + d_output_ptr)];
+  }
+
+  if (gr_isnan (acc)){
+    abort ();
+  }
+
+  d_old_output[d_output_ptr] = slice (acc);
+  return acc;
+}
+
+//
+// filter and adapt a single output
+//
+float kludge ()
+{
+  return 0.0;
+}
+
+float
+atsci_equalizer_lms2::adapt1 (const float input[], float ideal_output)
+{
+  static const double BETA = 0.00005;  // FIXME figure out what this ought to be
+                                       // FIXME add gear-shifting 
+
+  double y = filter1 (input);
+  double e = y - ideal_output;
+
+  // update taps...
+  for (int i = 0; i < NFFTAPS; i++){
+    d_taps_ff[i] = d_taps_ff[i] - BETA * e * (double)(input[i]);
+  }
+
+  for (int i = 0; i < NFBTAPS; i++){
+    // d_taps_fb[i] = d_taps_fb[i] - BETA * e * (double)d_old_output[wrap(i+d_output_ptr)];
+    d_taps_fb[i] = d_taps_fb[i] - kludge() * e * (double)d_old_output[wrap(i+d_output_ptr)];
+  }
+
+  return y;
+}
+
+void
+atsci_equalizer_lms2::filterN (const float *input_samples,
+                            float *output_samples,
+                            int nsamples)
+{
+  for (int i = 0; i < nsamples; i++)
+    output_samples[i] = filter1 (&input_samples[i]);
+}
+
+
+void 
+atsci_equalizer_lms2::adaptN (const float *input_samples,
+                           const float *training_pattern,
+                           float *output_samples,
+                           int    nsamples)
+{
+  for (int i = 0; i < nsamples; i++)
+    output_samples[i] = adapt1 (&input_samples[i], training_pattern[i]);
+}
+
+// ----------------------------------------------------------------
+
+static float
+bin_map (int bit)
+{
+  return bit ? +5 : -5;
+}
+
+static void
+init_field_sync_common (float *p, int mask)
+                       
+{
+  int  i = 0;
+
+  p[i++] = bin_map (1);                        // data segment sync pulse
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  for (int j = 0; j < 511; j++)                // PN511
+    p[i++] = bin_map (atsc_pn511[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63, toggled on field 2
+    p[i++] = bin_map (atsc_pn63[j] ^ mask);
+  
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  assert (i == KNOWN_FIELD_SYNC_LENGTH);
+}
+
+#if 0
+static const float *
+get_data_seg_sync_training_sequence (int offset)
+{
+  static const float training_data[4] = { +5, -5, -5, +5 };
+  return &training_data[offset];
+}
+#endif
+
+static int    
+get_field_sync_training_sequence_length (int offset)
+{
+  return max (0, KNOWN_FIELD_SYNC_LENGTH - offset);
+}
+
+static const float *
+get_field_sync_training_sequence (int which_field, int offset)
+{
+  static float *field_1 = 0;
+  static float *field_2 = 0;
+
+  if (field_1 == 0){
+    field_1 = new float[KNOWN_FIELD_SYNC_LENGTH];
+    field_2 = new float[KNOWN_FIELD_SYNC_LENGTH];
+    init_field_sync_common (field_1, 0);
+    init_field_sync_common (field_2, 1);
+  }
+
+  if (which_field == 0)
+    return &field_1[offset];
+  else
+    return &field_2[offset];
+}
diff --git a/gr-atsc/src/lib/atsci_equalizer_lms2.h b/gr-atsc/src/lib/atsci_equalizer_lms2.h
new file mode 100644 (file)
index 0000000..45b25b7
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_EQUALIZER_LMS2_H_
+#define _ATSC_EQUALIZER_LMS2_H_
+
+#include <atsci_equalizer.h>
+#include <vector>
+#include <stdio.h>
+
+class atsci_equalizer_lms2 : public atsci_equalizer
+{
+public:
+  atsci_equalizer_lms2 ();
+  virtual ~atsci_equalizer_lms2 ();
+
+  virtual void reset ();
+  virtual int ntaps () const;
+  virtual int npretaps () const;
+  
+protected:
+  FILE *trainingfile;
+  virtual void filter_normal (const float *input_samples,
+                             float *output_samples,
+                             int   nsamples);
+
+  virtual void filter_data_seg_sync (const float *input_samples,
+                                    float *output_samples,
+                                    int   nsamples,
+                                    int   offset);
+  
+  virtual void filter_field_sync (const float *input_samples,
+                                 float *output_samples,
+                                 int   nsamples,
+                                 int   offset,
+                                 int   which_field);
+
+private:
+  std::vector<double>  d_taps_ff;
+  std::vector<double>  d_taps_fb;
+  std::vector<float>   d_old_output;
+
+  int d_output_ptr;
+
+  void filterN (const float *input_samples,
+               float *output_samples,
+               int nsamples);
+
+  void adaptN (const float *input_samples,
+              const float *training_pattern,
+              float *output_samples,
+              int    nsamples);
+
+  float filter1 (const float input[]);
+  float adapt1 (const float input[], float ideal_output);
+
+};
+
+
+#endif /* _ATSC_EQUALIZER_LMS2_H_ */
diff --git a/gr-atsc/src/lib/atsci_equalizer_nop.cc b/gr-atsc/src/lib/atsci_equalizer_nop.cc
new file mode 100644 (file)
index 0000000..9b2b532
--- /dev/null
@@ -0,0 +1,133 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_equalizer_nop.h>
+#include <atsci_sync_tag.h>
+#include <assert.h>
+
+atsci_equalizer_nop::atsci_equalizer_nop ()
+{
+}
+
+atsci_equalizer_nop::~atsci_equalizer_nop ()
+{
+}
+
+void
+atsci_equalizer_nop::reset ()
+{
+  atsci_equalizer::reset ();   // invoke superclass
+}
+
+int 
+atsci_equalizer_nop::ntaps () const
+{
+  return 1;
+}
+
+int
+atsci_equalizer_nop::npretaps () const
+{
+  return 0;
+}
+
+/*!
+ * Input range is known NOT TO CONTAIN data segment syncs
+ * or field syncs.  This should be the fast path.  In the
+ * non decicion directed case, this just runs the input
+ * through the filter without adapting it.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_nop::filter_normal (const float *input_samples,
+                                  float *output_samples,
+                                  int   nsamples)
+{
+  for (int i = 0; i < nsamples; i++){
+    output_samples[i] = scale (input_samples[i]);
+  }
+}
+
+
+/*!
+ * Input range is known to consist of only a data segment sync or a
+ * portion of a data segment sync.  \p nsamples will be in [1,4].
+ * \p offset will be in [0,3].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_nop::filter_data_seg_sync (const float *input_samples,
+                                         float *output_samples,
+                                         int   nsamples,
+                                         int   offset)
+{
+  for (int i = 0; i < nsamples; i++){
+    output_samples[i] = scale_and_train (input_samples[i]);
+  }
+}
+
+  
+/*!
+ * Input range is known to consist of only a field sync segment or a
+ * portion of a field sync segment.  \p nsamples will be in [1,832].
+ * \p offset will be in [0,831].  \p offset is the offset of the input
+ * from the beginning of the data segment sync pattern.  We consider the
+ * 4 symbols of the immediately preceding data segment sync to be the
+ * first symbols of the field sync segment.  \p which_field is in [0,1] 
+ * and specifies which field (duh).
+ *
+ * \p input_samples has (nsamples + ntaps() - 1) valid entries.
+ * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be
+ * referenced to compute the output values.
+ */
+void 
+atsci_equalizer_nop::filter_field_sync (const float *input_samples,
+                                      float *output_samples,
+                                      int   nsamples,
+                                      int   offset,
+                                      int   which_field)
+{
+  int  i = 0;
+  
+  if (offset == 0 && nsamples > 0){
+    output_samples[0] = scale_and_train (input_samples[0]);
+    i++;
+  }
+
+  for (; i < nsamples; i++){
+    output_samples[i] = scale_and_train (input_samples[i]);
+  }
+}
+
+
+float
+atsci_equalizer_nop::scale_and_train (float input)
+{
+  return input;
+}
diff --git a/gr-atsc/src/lib/atsci_equalizer_nop.h b/gr-atsc/src/lib/atsci_equalizer_nop.h
new file mode 100644 (file)
index 0000000..399f2da
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_EQUALIZER_NOP_H_
+#define _ATSC_EQUALIZER_NOP_H_
+
+#include <atsci_equalizer.h>
+
+class atsci_equalizer_nop : public atsci_equalizer
+{
+private:
+  float scale (float input) { return input; }
+
+  float scale_and_train (float input);
+  
+
+public:
+  atsci_equalizer_nop ();
+  virtual ~atsci_equalizer_nop ();
+
+  virtual void reset ();
+  virtual int ntaps () const;
+  virtual int npretaps () const;
+  
+protected:
+  virtual void filter_normal (const float   *input_samples,
+                             float *output_samples,
+                             int   nsamples);
+
+  virtual void filter_data_seg_sync (const float *input_samples,
+                                    float *output_samples,
+                                    int   nsamples,
+                                    int   offset);
+  
+  virtual void filter_field_sync (const float *input_samples,
+                                 float *output_samples,
+                                 int   nsamples,
+                                 int   offset,
+                                 int   which_field);
+};
+
+
+#endif /* _ATSC_EQUALIZER_NOP_H_ */
diff --git a/gr-atsc/src/lib/atsci_exp2_lp.cc b/gr-atsc/src/lib/atsci_exp2_lp.cc
new file mode 100644 (file)
index 0000000..38e62d9
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsc_consts.h>
+#include <atsci_exp2_lp.h>
+#include <stdexcept>
+#include <cmath>
+#include <iostream>
+
+using std::vector;
+using std::cerr;
+using std::endl;
+
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:LOW PASS                       1H
+ * PASSBAND RIPPLE IN -dB            -.0100
+ * STOPBAND RIPPLE IN -dB          -66.0000
+ * PASSBAND CUTOFF FREQUENCY    5.69000     HERTZ              
+ * STOPBAND CUTOFF FREQUENCY    6.12000     HERTZ              
+ * SAMPLING FREQUENCY           21.5200     HERTZ
+ */
+static const float atsci_exp2_lp2x[] = {
+#include "atsci_exp2_lp2x.dat"
+};
+
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:LOW PASS                       1H
+ * PASSBAND RIPPLE IN -dB            -.0100
+ * STOPBAND RIPPLE IN -dB          -66.0000
+ * PASSBAND CUTOFF FREQUENCY    5.69000     HERTZ              
+ * STOPBAND CUTOFF FREQUENCY    6.12000     HERTZ              
+ * SAMPLING FREQUENCY           20.0000     HERTZ
+ */
+static const float atsci_exp2_lp20[] = {
+#include "atsci_exp2_lp20.dat"
+};
+
+
+#define NELEM(x) (sizeof (x) / sizeof ((x)[0]))
+
+// is A within 5% of TARGET?
+
+static bool 
+close_enough_p (double a, double target)
+{
+  double delta = fabs (target * 0.05); //  5 percent
+
+  return fabs (target - a) <= delta;
+}
+
+vector<float> 
+atsci_exp2_lp::taps (double sampling_freq)
+{
+  if (close_enough_p (sampling_freq, 20e6)){
+    return vector<float>(&atsci_exp2_lp20[0], &atsci_exp2_lp20[NELEM(atsci_exp2_lp20)]);
+  }
+  if (close_enough_p (sampling_freq, 2 * ATSC_SYMBOL_RATE)){
+    return vector<float>(&atsci_exp2_lp2x[0], &atsci_exp2_lp2x[NELEM(atsci_exp2_lp2x)]);
+  }
+  else
+    throw std::out_of_range (
+     "atsci_exp2_lp: no pre-designed filter close enough");
+}
diff --git a/gr-atsc/src/lib/atsci_exp2_lp.h b/gr-atsc/src/lib/atsci_exp2_lp.h
new file mode 100644 (file)
index 0000000..cf66843
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_EXP2_LP_H_
+#define _ATSC_EXP2_LP_H_
+
+#include <gr_fir_builder.h>
+
+class atsci_exp2_lp : public gr_fir_builder
+{
+public:
+  virtual std::vector<float> taps (double sampling_freq);
+};
+
+#endif /* _ATSC_EXP2_LP_H_ */
diff --git a/gr-atsc/src/lib/atsci_exp2_lp20.dat b/gr-atsc/src/lib/atsci_exp2_lp20.dat
new file mode 100644 (file)
index 0000000..b810fac
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:LOW PASS                       1H
+ * PASSBAND RIPPLE IN -dB            -.0100
+ * STOPBAND RIPPLE IN -dB          -66.0000
+ * PASSBAND CUTOFF FREQUENCY    5.69000     HERTZ              
+ * STOPBAND CUTOFF FREQUENCY    6.12000     HERTZ              
+ * SAMPLING FREQUENCY           20.0000     HERTZ
+ */
+  -.3137849271297455e-03,
+  -.6755953654646874e-04,
+   .2326252870261669e-03,
+  -.1614624634385109e-03,
+  -.1158984377980232e-03,
+   .2114051021635532e-03,
+   .6828224286437035e-04,
+  -.3522797487676144e-03,
+   .1759170554578304e-03,
+   .2849949523806572e-03,
+  -.3568925894796848e-03,
+  -.1521380618214607e-03,
+   .5445396527647972e-03,
+  -.1707794144749641e-03,
+  -.5257474258542061e-03,
+   .5062967538833618e-03,
+   .3262492828071117e-03,
+  -.8037807419896126e-03,
+   .1136297360062599e-03,
+   .8607362397015095e-03,
+  -.6433278322219849e-03,
+  -.6174184381961823e-03,
+   .1120670232921839e-02,
+   .3442214801907539e-04,
+  -.1305819023400545e-02,
+   .7387576624751091e-03,
+   .1056550536304712e-02,
+  -.1477979123592377e-02,
+  -.3192713484168053e-03,
+   .1870564185082912e-02,
+  -.7502869702875614e-03,
+  -.1675266306847334e-02,
+   .1847642473876476e-02,
+   .7931739091873169e-03,
+  -.2555002458393574e-02,
+   .6227688863873482e-03,
+   .2505954820662737e-02,
+  -.2186967991292477e-02,
+  -.1515555195510387e-02,
+   .3349546808749437e-02,
+  -.2860687673091888e-03,
+  -.3578922711312771e-02,
+   .2438103780150414e-02,
+   .2555412705987692e-02,
+  -.4232846200466156e-02,
+  -.3483905456960201e-03,
+   .4926202818751335e-02,
+  -.2523601986467838e-02,
+  -.3997647203505039e-02,
+   .5173782818019390e-02,
+   .1395780127495527e-02,
+  -.6588382180780172e-02,
+   .2339247148483992e-02,
+   .5959283560514450e-02,
+  -.6131949834525585e-02,
+  -.3020572476089001e-02,
+   .8632841985672712e-02,
+  -.1736589241772890e-02,
+  -.8627892937511206e-02,
+   .7060498464852572e-02,
+   .5489445291459560e-02,
+  -.1119629153981805e-01,
+   .4754690453410149e-03,
+   .1235919492319226e-01,
+  -.7909852080047131e-02,
+  -.9316097479313612e-02,
+   .1459939032793045e-01,
+   .1910720951855183e-02,
+  -.1796151325106621e-01,
+   .8631225209683180e-02,
+   .1572139468044043e-01,
+  -.1972115319222212e-01,
+  -.6601144559681416e-02,
+   .2775513892993331e-01,
+  -.9181375615298748e-02,
+  -.2863558568060398e-01,
+   .2976502152159810e-01,
+   .1806837785989046e-01,
+  -.5192282795906067e-01,
+   .9526194538921118e-02,
+   .7172224065288901e-01,
+  -.6965141417458654e-01,
+  -.8541030902415514e-01,
+   .3052920936606824e+00,
+   .5900069065392017e+00,
+   .3052920936606824e+00,
+  -.8541030902415514e-01,
+  -.6965141417458654e-01,
+   .7172224065288901e-01,
+   .9526194538921118e-02,
+  -.5192282795906067e-01,
+   .1806837785989046e-01,
+   .2976502152159810e-01,
+  -.2863558568060398e-01,
+  -.9181375615298748e-02,
+   .2775513892993331e-01,
+  -.6601144559681416e-02,
+  -.1972115319222212e-01,
+   .1572139468044043e-01,
+   .8631225209683180e-02,
+  -.1796151325106621e-01,
+   .1910720951855183e-02,
+   .1459939032793045e-01,
+  -.9316097479313612e-02,
+  -.7909852080047131e-02,
+   .1235919492319226e-01,
+   .4754690453410149e-03,
+  -.1119629153981805e-01,
+   .5489445291459560e-02,
+   .7060498464852572e-02,
+  -.8627892937511206e-02,
+  -.1736589241772890e-02,
+   .8632841985672712e-02,
+  -.3020572476089001e-02,
+  -.6131949834525585e-02,
+   .5959283560514450e-02,
+   .2339247148483992e-02,
+  -.6588382180780172e-02,
+   .1395780127495527e-02,
+   .5173782818019390e-02,
+  -.3997647203505039e-02,
+  -.2523601986467838e-02,
+   .4926202818751335e-02,
+  -.3483905456960201e-03,
+  -.4232846200466156e-02,
+   .2555412705987692e-02,
+   .2438103780150414e-02,
+  -.3578922711312771e-02,
+  -.2860687673091888e-03,
+   .3349546808749437e-02,
+  -.1515555195510387e-02,
+  -.2186967991292477e-02,
+   .2505954820662737e-02,
+   .6227688863873482e-03,
+  -.2555002458393574e-02,
+   .7931739091873169e-03,
+   .1847642473876476e-02,
+  -.1675266306847334e-02,
+  -.7502869702875614e-03,
+   .1870564185082912e-02,
+  -.3192713484168053e-03,
+  -.1477979123592377e-02,
+   .1056550536304712e-02,
+   .7387576624751091e-03,
+  -.1305819023400545e-02,
+   .3442214801907539e-04,
+   .1120670232921839e-02,
+  -.6174184381961823e-03,
+  -.6433278322219849e-03,
+   .8607362397015095e-03,
+   .1136297360062599e-03,
+  -.8037807419896126e-03,
+   .3262492828071117e-03,
+   .5062967538833618e-03,
+  -.5257474258542061e-03,
+  -.1707794144749641e-03,
+   .5445396527647972e-03,
+  -.1521380618214607e-03,
+  -.3568925894796848e-03,
+   .2849949523806572e-03,
+   .1759170554578304e-03,
+  -.3522797487676144e-03,
+   .6828224286437035e-04,
+   .2114051021635532e-03,
+  -.1158984377980232e-03,
+  -.1614624634385109e-03,
+   .2326252870261669e-03,
+  -.6755953654646874e-04,
+  -.3137849271297455e-03
diff --git a/gr-atsc/src/lib/atsci_exp2_lp2x.dat b/gr-atsc/src/lib/atsci_exp2_lp2x.dat
new file mode 100644 (file)
index 0000000..16b2b47
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:LOW PASS                       1H
+ * PASSBAND RIPPLE IN -dB            -.0100
+ * STOPBAND RIPPLE IN -dB          -66.0000
+ * PASSBAND CUTOFF FREQUENCY    5.69000     HERTZ              
+ * STOPBAND CUTOFF FREQUENCY    6.12000     HERTZ              
+ * SAMPLING FREQUENCY           21.5200     HERTZ
+ */
+
+/*
+ * probably total overkill...
+*/
+  -.8815620094537735E-04,
+  -.3356961533427239E-03,
+   .1227599568665028E-03,
+   .1281457953155041E-03,
+  -.1479196362197399E-03,
+  -.1201131381094456E-03,
+   .2271742559969425E-03,
+   .6969040259718895E-04,
+  -.3000237047672272E-03,
+   .1565506681799889E-04,
+   .3562141209840775E-03,
+  -.1368308439850807E-03,
+  -.3795824013650417E-03,
+   .2876669168472290E-03,
+   .3540110774338245E-03,
+  -.4550744779407978E-03,
+  -.2659554593265057E-03,
+   .6190738640725613E-03,
+   .1072990708053112E-03,
+  -.7539116777479649E-03,
+   .1217066310346127E-03,
+   .8306214585900307E-03,
+  -.4104166291654110E-03,
+  -.8203103207051754E-03,
+   .7365280762314796E-03,
+   .6983750499784946E-03,
+  -.1066216267645359E-02,
+  -.4491899162530899E-03,
+   .1356074586510658E-02,
+   .7050111889839172E-04,
+  -.1556793693453074E-02,
+   .4230584017932415E-03,
+   .1618413720279932E-02,
+  -.9978362359106541E-03,
+  -.1497142482548952E-02,
+   .1601643394678831E-02,
+   .1162088476121426E-02,
+  -.2165937330573797E-02,
+  -.6025419570505619E-03,
+   .2611500211060047E-02,
+  -.1667905598878861E-03,
+  -.2855417784303427E-02,
+   .1101639121770859E-02,
+   .2821092493832111E-02,
+  -.2127973828464747E-02,
+  -.2448682673275471E-02,
+   .3145063761621714E-02,
+   .1706911250948906E-02,
+  -.4030079115182161E-02,
+  -.5993186496198177E-03,
+   .4651836119592190E-02,
+  -.8259965106844902E-03,
+  -.4880243912339211E-02,
+   .2475241199135780E-02,
+   .4603198729455471E-02,
+  -.4209769889712334E-02,
+  -.3741886932402849E-02,
+   .5853117443621159E-02,
+   .2264967188239098E-02,
+  -.7202429696917534E-02,
+  -.2001645043492317E-03,
+   .8043776731938124E-02,
+  -.2357403747737408E-02,
+  -.8171265944838524E-02,
+   .5242727231234312E-02,
+   .7407441269606352E-02,
+  -.8224328979849815E-02,
+  -.5622585304081440E-02,
+   .1101253507658839E-01,
+   .2751644235104322E-02,
+  -.1327139046043158E-01,
+   .1191724557429552E-02,
+   .1463502133265138E-01,
+  -.6110311951488257E-02,
+  -.1471871789544821E-01,
+   .1182264182716608E-01,
+   .1312375022098422E-01,
+  -.1807126961648464E-01,
+  -.9420783724635840E-02,
+   .2453883877024055E-01,
+   .3084233496338129E-02,
+  -.3086851537227631E-01,
+   .6689148955047131E-02,
+   .3669126378372312E-01,
+  -.2150753932073712E-01,
+  -.4165294021368027E-01,
+   .4559329804033041E-01,
+   .4544338863343000E-01,
+  -.9483475470915437E-01,
+  -.4782041534781456E-01,
+   .3143207929097116E+00,
+   .5483355415053666E+00,
+   .3143207929097116E+00,
+  -.4782041534781456E-01,
+  -.9483475470915437E-01,
+   .4544338863343000E-01,
+   .4559329804033041E-01,
+  -.4165294021368027E-01,
+  -.2150753932073712E-01,
+   .3669126378372312E-01,
+   .6689148955047131E-02,
+  -.3086851537227631E-01,
+   .3084233496338129E-02,
+   .2453883877024055E-01,
+  -.9420783724635840E-02,
+  -.1807126961648464E-01,
+   .1312375022098422E-01,
+   .1182264182716608E-01,
+  -.1471871789544821E-01,
+  -.6110311951488257E-02,
+   .1463502133265138E-01,
+   .1191724557429552E-02,
+  -.1327139046043158E-01,
+   .2751644235104322E-02,
+   .1101253507658839E-01,
+  -.5622585304081440E-02,
+  -.8224328979849815E-02,
+   .7407441269606352E-02,
+   .5242727231234312E-02,
+  -.8171265944838524E-02,
+  -.2357403747737408E-02,
+   .8043776731938124E-02,
+  -.2001645043492317E-03,
+  -.7202429696917534E-02,
+   .2264967188239098E-02,
+   .5853117443621159E-02,
+  -.3741886932402849E-02,
+  -.4209769889712334E-02,
+   .4603198729455471E-02,
+   .2475241199135780E-02,
+  -.4880243912339211E-02,
+  -.8259965106844902E-03,
+   .4651836119592190E-02,
+  -.5993186496198177E-03,
+  -.4030079115182161E-02,
+   .1706911250948906E-02,
+   .3145063761621714E-02,
+  -.2448682673275471E-02,
+  -.2127973828464747E-02,
+   .2821092493832111E-02,
+   .1101639121770859E-02,
+  -.2855417784303427E-02,
+  -.1667905598878861E-03,
+   .2611500211060047E-02,
+  -.6025419570505619E-03,
+  -.2165937330573797E-02,
+   .1162088476121426E-02,
+   .1601643394678831E-02,
+  -.1497142482548952E-02,
+  -.9978362359106541E-03,
+   .1618413720279932E-02,
+   .4230584017932415E-03,
+  -.1556793693453074E-02,
+   .7050111889839172E-04,
+   .1356074586510658E-02,
+  -.4491899162530899E-03,
+  -.1066216267645359E-02,
+   .6983750499784946E-03,
+   .7365280762314796E-03,
+  -.8203103207051754E-03,
+  -.4104166291654110E-03,
+   .8306214585900307E-03,
+   .1217066310346127E-03,
+  -.7539116777479649E-03,
+   .1072990708053112E-03,
+   .6190738640725613E-03,
+  -.2659554593265057E-03,
+  -.4550744779407978E-03,
+   .3540110774338245E-03,
+   .2876669168472290E-03,
+  -.3795824013650417E-03,
+  -.1368308439850807E-03,
+   .3562141209840775E-03,
+   .1565506681799889E-04,
+  -.3000237047672272E-03,
+   .6969040259718895E-04,
+   .2271742559969425E-03,
+  -.1201131381094456E-03,
+  -.1479196362197399E-03,
+   .1281457953155041E-03,
+   .1227599568665028E-03,
+  -.3356961533427239E-03,
+  -.8815620094537735E-04
diff --git a/gr-atsc/src/lib/atsci_fake_single_viterbi.cc b/gr-atsc/src/lib/atsci_fake_single_viterbi.cc
new file mode 100644 (file)
index 0000000..bf5cf9a
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <atsci_fake_single_viterbi.h>
+#include <iostream>
+#include <algorithm>
+
+using std::cerr;
+using std::cout;
+
+void
+atsci_fake_single_viterbi::reset()
+{
+  post_coder_state = 0;
+}
+
+atsci_fake_single_viterbi::atsci_fake_single_viterbi()
+{
+  reset();
+}
+
+/*
+ * implement simple slicer and post coder
+ */
+char
+atsci_fake_single_viterbi::decode (float input)
+{
+  int  y2, y1;
+  
+  if (input < -4){
+    y2 = 0;
+    y1 = 0;
+  }
+  else if (input < 0){
+    y2 = 0;
+    y1 = 1;
+  }
+  else if (input < 4){
+    y2 = 1;
+    y1 = 0;
+  }
+  else {
+    y2 = 1;
+    y1 = 1;
+  }
+
+  int  x1 = y1;
+  int  x2 = y2 ^ post_coder_state;
+  post_coder_state = y2;
+
+  return (x2 << 1) | x1;
+}
diff --git a/gr-atsc/src/lib/atsci_fake_single_viterbi.h b/gr-atsc/src/lib/atsci_fake_single_viterbi.h
new file mode 100644 (file)
index 0000000..1318256
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSCFAKESINGLEVITERBI_H_
+#define _ATSCFAKESINGLEVITERBI_H_
+
+/*!
+ * \brief single channel viterbi decoder
+ */
+class atsci_fake_single_viterbi
+{
+  
+public:
+  atsci_fake_single_viterbi ();
+
+  /*!
+   * \p INPUT ideally takes on the values +/- 1,3,5,7
+   * return is decoded dibit in the range [0, 3]
+   */
+  char decode (float input);
+
+  void reset ();
+
+  //! internal delay of decoder
+  int delay () { return 0; }
+
+protected:
+  int  post_coder_state;
+};
+
+#endif 
diff --git a/gr-atsc/src/lib/atsci_fs_checker.cc b/gr-atsc/src/lib/atsci_fs_checker.cc
new file mode 100644 (file)
index 0000000..80af123
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_fs_checker.h>
+
+// empty constructor
+atsci_fs_checker::atsci_fs_checker ()
+{
+}
+
+// empty virtual destructor
+atsci_fs_checker::~atsci_fs_checker ()
+{
+}
diff --git a/gr-atsc/src/lib/atsci_fs_checker.h b/gr-atsc/src/lib/atsci_fs_checker.h
new file mode 100644 (file)
index 0000000..76b7549
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_FS_CHECKER_H_
+#define _ATSC_FS_CHECKER_H_
+
+#include <atsci_syminfo.h>
+
+/*!
+ * \brief abstract base class for ATSC field sync checker
+ *
+ * Processes input samples one at a time looking for
+ * an occurence of either the field sync 1 or field sync 2 pattern.
+ *
+ * Note that unlike atsci_fs_correlator, this class uses the symbol_num in 
+ * input_tag to avoid having to test each symbol position.
+ *
+ * For each sample processed, an output sample and an output tag are produced.
+ * The output samples are identical to the input samples but are delayed by
+ * a number of samples given by \p delay().  The output tag associated with
+ * the the given output sample indicates whether this sample is the beginning
+ * of one of the field syncs or is an ordinary sample.  The tags are defined in
+ * atsci_sync_tag.h.
+ *
+ * For ease of use, the field sync patterns are defined to begin with the
+ * first symbol of the 4 symbol data segment sync pattern that immediately
+ * proceeds the actual PN 511 code.  This makes it easier for downstream code
+ * to determine the location of data segment syncs merely by counting.  They'll
+ * occur every 832 samples assuming everything is working.
+ */
+
+class atsci_fs_checker {
+
+public:
+
+  // CREATORS
+  atsci_fs_checker ();
+  virtual ~atsci_fs_checker () = 0;
+
+  // MANIPULATORS
+  virtual void reset () = 0;
+  virtual void filter (float input_sample, atsc::syminfo input_tag,
+                      float *output_sample, atsc::syminfo *output_tag) = 0;
+
+  // ACCESSORS
+
+  //! return delay in samples from input to output
+  virtual int delay () const = 0;
+};
+#endif /* _ATSC_FS_CHECKER_H_ */
diff --git a/gr-atsc/src/lib/atsci_fs_checker_naive.cc b/gr-atsc/src/lib/atsci_fs_checker_naive.cc
new file mode 100644 (file)
index 0000000..ab50aff
--- /dev/null
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_fs_checker_naive.h>
+#include <atsci_syminfo.h>
+#include <atsci_pnXXX.h>
+#include <iostream>
+#include <cstring>
+
+using std::cerr;
+using std::endl;
+
+static const int PN511_ERROR_LIMIT = 20;       // max number of bits wrong
+static const int PN63_ERROR_LIMIT =   5;
+
+unsigned char atsci_fs_checker_naive::s_511[LENGTH_511];
+unsigned char atsci_fs_checker_naive::s_63[LENGTH_2ND_63];
+
+static void
+init_s_511 (unsigned char *p)
+{
+  *p++ = 1;    // data segment sync pattern
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 1;
+
+  for (int i = 0; i < 511; i++){
+    p[i] = atsc_pn511[i];
+  }
+}
+
+static void
+init_s_63 (unsigned char *p)
+{
+  for (int i = 0; i < 63; i++){
+    p[i] = atsc_pn63[i];
+  }
+}
+
+atsci_fs_checker_naive::atsci_fs_checker_naive ()
+{
+  init_s_511 (s_511);
+  init_s_63 (s_63);
+  reset ();
+}
+
+atsci_fs_checker_naive::~atsci_fs_checker_naive ()
+{
+}
+
+void
+atsci_fs_checker_naive::reset ()
+{
+  d_index = 0;
+  memset (d_sample_sr, 0, sizeof (d_sample_sr));
+  memset (d_tag_sr, 0, sizeof (d_tag_sr));
+  memset (d_bit_sr, 0, sizeof (d_bit_sr));
+  d_field_num = 0;
+  d_segment_num = 0;
+}
+
+void
+atsci_fs_checker_naive::filter (float input_sample, atsc::syminfo input_tag,
+                              float *output_sample, atsc::syminfo *output_tag)
+{
+  atsc::syminfo        proto_tag = d_tag_sr[d_index];  // oldest tag in the queue
+
+  if (proto_tag.symbol_num == 0){              // check for field sync pattern
+    
+    d_segment_num = (d_segment_num + 1) & atsc::SI_SEGMENT_NUM_MASK;  // increment
+
+    // check for a hit on the PN 511 pattern
+    int        errors = 0;
+    int        start = wrap (d_index + OFFSET_511);
+
+    for (int i = 0; i < LENGTH_511 && errors < PN511_ERROR_LIMIT; i++)
+      errors += d_bit_sr[wrap (start + i)] ^ s_511[i];
+
+    if (errors < PN511_ERROR_LIMIT){   // 511 pattern is good.
+                                       // determine if this is field 1 or field 2
+      errors = 0;
+      start = wrap (d_index + OFFSET_2ND_63);
+      for (int i = 0; i < LENGTH_2ND_63; i++)
+       errors += d_bit_sr[wrap (start + i)] ^ s_63[i];
+
+      // we should have either field 1 (== PN63) or field 2 (== ~PN63)
+
+      if (errors <= PN63_ERROR_LIMIT){
+       d_segment_num = atsc::SI_FIELD_SYNC_SEGMENT_NUM;        // this is FIELD_SYNC_1
+       d_field_num = 0;
+      }
+      else if (errors >= (LENGTH_2ND_63 - PN63_ERROR_LIMIT)){
+       d_segment_num = atsc::SI_FIELD_SYNC_SEGMENT_NUM;        // this is FIELD_SYNC_2
+       d_field_num = 1;
+      }
+      else {
+       // should be extremely rare.
+       cerr << "!!! atsci_fs_checker_naive: PN63 error count = " << errors << endl;
+      }
+    }
+  }
+
+  proto_tag.segment_num = d_segment_num;       // fill in segment number and field number      
+  proto_tag.field_num = d_field_num;
+
+  // return oldest sample
+  *output_sample = d_sample_sr[d_index];
+  *output_tag    = proto_tag;
+
+  // overwrite with newest sample;
+  d_sample_sr[d_index] = input_sample;
+  d_bit_sr[d_index] = input_sample < 0 ? 0 : 1;
+  d_tag_sr[d_index] = input_tag;
+  d_index = incr (d_index);
+}
+
+int
+atsci_fs_checker_naive::delay () const
+{
+  return SRSIZE;
+}
diff --git a/gr-atsc/src/lib/atsci_fs_checker_naive.h b/gr-atsc/src/lib/atsci_fs_checker_naive.h
new file mode 100644 (file)
index 0000000..9518204
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_FS_CHECKER_NAIVE_H_
+#define _ATSC_FS_CHECKER_NAIVE_H_
+
+#include <atsci_fs_checker.h>
+
+/*!
+ * \brief Naive concrete implementation of field sync checker
+ */
+class atsci_fs_checker_naive : public atsci_fs_checker {
+
+ private:
+  static const int     SRSIZE = 1024;          // must be power of two
+  int                  d_index;                // points at oldest sample
+  float                        d_sample_sr[SRSIZE];    // sample shift register
+  atsc::syminfo                d_tag_sr[SRSIZE];       // tag shift register
+  unsigned char                d_bit_sr[SRSIZE];       // binary decision shift register
+  int                  d_field_num;
+  int                  d_segment_num;
+
+  static const int     OFFSET_511 = 0;         // offset to PN 511 pattern
+  static const int     LENGTH_511 = 511 + 4;   // length of PN 511 pattern (+ 4 seg sync)
+  static const int     OFFSET_2ND_63 = 578;    // offset to second PN 63 pattern
+  static const int     LENGTH_2ND_63 = 63;     // length of PN 63 pattern
+
+  static unsigned char s_511[LENGTH_511];      // PN 511 pattern
+  static unsigned char s_63[LENGTH_2ND_63];    // PN 63 pattern
+
+  inline static int wrap (int index){ return index & (SRSIZE - 1); }
+  inline static int incr (int index){ return wrap (index + 1); }
+  inline static int decr (int index){ return wrap (index - 1); }
+
+ public:
+
+  // CREATORS
+  atsci_fs_checker_naive ();
+  ~atsci_fs_checker_naive ();
+
+  // MANIPULATORS
+  virtual void reset ();
+  void filter (float input_sample, atsc::syminfo input_tag,
+              float *output_sample, atsc::syminfo *output_tag);
+
+  // ACCESSORS
+
+  //! return delay in samples from input to output
+  int delay () const;
+  
+};
+
+
+#endif /* _ATSC_FS_CHECKER_NAIVE_H_ */
diff --git a/gr-atsc/src/lib/atsci_fs_correlator.cc b/gr-atsc/src/lib/atsci_fs_correlator.cc
new file mode 100644 (file)
index 0000000..9e76537
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_fs_correlator.h>
+
+// empty constructor
+atsci_fs_correlator::atsci_fs_correlator ()
+{
+}
+
+// empty virtual destructor
+atsci_fs_correlator::~atsci_fs_correlator ()
+{
+}
diff --git a/gr-atsc/src/lib/atsci_fs_correlator.h b/gr-atsc/src/lib/atsci_fs_correlator.h
new file mode 100644 (file)
index 0000000..f791536
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_FS_CORRELATOR_H_
+#define _ATSC_FS_CORRELATOR_H_
+
+/*!
+ * \brief abstract base class for ATSC field sync correlator
+ *
+ * Processes input samples one at a time looking for
+ * an occurence of either the field sync 1 or field sync 2 pattern.
+ *
+ * For each sample processed, an output sample and an output tag are produced.
+ * The output samples are identical to the input samples but are delayed by
+ * a number of samples given by \p delay().  The output tag associated with
+ * the the given output sample indicates whether this sample is the beginning
+ * of one of the field syncs or is an ordinary sample.  The tags are defined in
+ * atsci_sync_tag.h.
+ *
+ * For ease of use, the field sync patterns are defined to begin with the
+ * first symbol of the 4 symbol data segment sync pattern that immediately
+ * proceeds the actual PN 511 code.  This makes it easier for downstream code
+ * to determine the location of data segment syncs merely by counting.  They'll
+ * occur every 832 samples assuming everything is working.
+ */
+
+class atsci_fs_correlator {
+
+public:
+
+  // CREATORS
+  atsci_fs_correlator ();
+  virtual ~atsci_fs_correlator () = 0;
+
+  // MANIPULATORS
+  virtual void reset () = 0;
+  virtual void filter (float input_sample, float *output_sample, float *output_tag) = 0;
+
+  // ACCESSORS
+
+  //! return delay in samples from input to output
+  virtual int delay () const = 0;
+};
+#endif /* _ATSC_FS_CORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/atsci_fs_correlator_naive.cc b/gr-atsc/src/lib/atsci_fs_correlator_naive.cc
new file mode 100644 (file)
index 0000000..695641c
--- /dev/null
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_fs_correlator_naive.h>
+#include <atsci_sync_tag.h>
+#include <atsci_pnXXX.h>
+#include <iostream>
+#include <cstring>
+
+using std::cerr;
+using std::endl;
+
+static const int PN511_ERROR_LIMIT = 20;       // max number of bits wrong
+static const int PN63_ERROR_LIMIT =   5;
+
+unsigned char atsci_fs_correlator_naive::s_511[LENGTH_511];
+unsigned char atsci_fs_correlator_naive::s_63[LENGTH_2ND_63];
+
+static void
+init_s_511 (unsigned char *p)
+{
+  *p++ = 1;    // data segment sync pattern
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 1;
+
+  for (int i = 0; i < 511; i++){
+    p[i] = atsc_pn511[i];
+  }
+}
+
+static void
+init_s_63 (unsigned char *p)
+{
+  for (int i = 0; i < 63; i++){
+    p[i] = atsc_pn63[i];
+  }
+}
+
+atsci_fs_correlator_naive::atsci_fs_correlator_naive ()
+{
+  init_s_511 (s_511);
+  init_s_63 (s_63);
+  reset ();
+}
+
+atsci_fs_correlator_naive::~atsci_fs_correlator_naive ()
+{
+}
+
+void
+atsci_fs_correlator_naive::reset ()
+{
+  d_index = 0;
+  memset (d_sample_sr, 0, sizeof (d_sample_sr));
+  memset (d_bit_sr, 0, sizeof (d_bit_sr));
+}
+
+void
+atsci_fs_correlator_naive::filter (float input_sample,
+                                 float *output_sample, float *output_tag)
+{
+  // check for a hit on the PN 511 pattern
+  int  errors = 0;
+  int  start = wrap (d_index + OFFSET_511);
+
+  for (int i = 0; i < LENGTH_511 && errors < PN511_ERROR_LIMIT; i++)
+    errors += d_bit_sr[wrap (start + i)] ^ s_511[i];
+
+  if (errors >= PN511_ERROR_LIMIT)
+    *output_tag = atsc_sync_tag::NORMAL;
+
+  else {       // 511 pattern is good.  determine if this is field 1 or field 2
+    errors = 0;
+    start = wrap (d_index + OFFSET_2ND_63);
+    for (int i = 0; i < LENGTH_2ND_63; i++)
+      errors += d_bit_sr[wrap (start + i)] ^ s_63[i];
+
+    // we should have either field 1 (== PN63) or field 2 (== ~PN63)
+    if (errors <= PN63_ERROR_LIMIT)
+      *output_tag = atsc_sync_tag::START_FIELD_SYNC_1;
+
+    else if (errors >= (LENGTH_2ND_63 - PN63_ERROR_LIMIT))
+      *output_tag = atsc_sync_tag::START_FIELD_SYNC_2;
+
+    else {
+      // should be extremely rare.
+      cerr << "!!! atsci_fs_correlator_naive: PN63 error count = " << errors << endl;
+      *output_tag = atsc_sync_tag::NORMAL;
+    }
+  }
+
+  // return oldest sample
+  *output_sample = d_sample_sr[d_index];
+
+  // overwrite with newest sample;
+  d_sample_sr[d_index] = input_sample;
+  d_bit_sr[d_index] = input_sample < 0 ? 0 : 1;
+  d_index = incr (d_index);
+}
+
+int
+atsci_fs_correlator_naive::delay () const
+{
+  return SRSIZE;
+}
diff --git a/gr-atsc/src/lib/atsci_fs_correlator_naive.h b/gr-atsc/src/lib/atsci_fs_correlator_naive.h
new file mode 100644 (file)
index 0000000..c05cff0
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_FS_CORRELATOR_NAIVE_H_
+#define _ATSC_FS_CORRELATOR_NAIVE_H_
+
+#include <atsci_fs_correlator.h>
+
+/*!
+ * \brief Naive concrete implementation of field sync correlator
+ */
+class atsci_fs_correlator_naive : public atsci_fs_correlator {
+
+ private:
+  static const int     SRSIZE = 1024;          // must be power of two
+  int                  d_index;                // points at oldest sample
+  float                        d_sample_sr[SRSIZE];    // sample shift register
+  unsigned char                d_bit_sr[SRSIZE];       // binary decision shift register
+
+  static const int     OFFSET_511 = 0;         // offset to PN 511 pattern
+  static const int     LENGTH_511 = 511 + 4;   // length of PN 511 pattern (+ 4 seg sync)
+  static const int     OFFSET_2ND_63 = 578;    // offset to second PN 63 pattern
+  static const int     LENGTH_2ND_63 = 63;     // length of PN 63 pattern
+
+  static unsigned char s_511[LENGTH_511];      // PN 511 pattern
+  static unsigned char s_63[LENGTH_2ND_63];    // PN 63 pattern
+
+  inline static int wrap (int index){ return index & (SRSIZE - 1); }
+  inline static int incr (int index){ return wrap (index + 1); }
+  inline static int decr (int index){ return wrap (index - 1); }
+
+ public:
+
+  // CREATORS
+  atsci_fs_correlator_naive ();
+  ~atsci_fs_correlator_naive ();
+
+  // MANIPULATORS
+  virtual void reset ();
+  void filter (float input_sample, float *output_sample, float *output_tag);
+
+  // ACCESSORS
+
+  //! return delay in samples from input to output
+  int delay () const;
+  
+};
+
+
+#endif /* _ATSC_FS_CORRELATOR_NAIVE_H_ */
diff --git a/gr-atsc/src/lib/atsci_pnXXX.cc b/gr-atsc/src/lib/atsci_pnXXX.cc
new file mode 100644 (file)
index 0000000..cfcf87f
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_pnXXX.h>
+
+const unsigned char atsc_pn511[511] = {
+  0,0,0,0,  0,0,0,1,  0,1,1,1,  1,1,1,1,  1,1,0,0,  1,0,1,0,  1,0,1,0,  1,1,1,0,
+  0,1,1,0,  0,1,1,0,  1,0,0,0,  1,0,0,0,  1,0,0,1,  1,1,1,0,  0,0,0,1,  1,1,0,1,
+
+  0,1,1,1,  1,1,0,1,  0,0,1,1,  0,1,0,1,  0,0,1,1,  1,0,1,1,  0,0,1,1,  1,0,1,0,
+  0,1,0,0,  0,1,0,1,  1,0,0,0,  1,1,1,1,  0,0,1,0,  0,0,0,1,  0,1,0,0,  0,1,1,1,
+
+  1,1,0,0,  1,1,1,1,  0,1,0,1,  0,0,0,1,  0,1,0,0,  1,1,0,0,  0,0,1,1,  0,0,0,1,
+  0,0,0,0,  0,1,0,0,  0,0,1,1,  1,1,1,1,  0,0,0,0,  0,1,0,1,  0,1,0,0,  0,0,0,0,
+
+  1,1,0,0,  1,1,1,1,  1,1,1,0,  1,1,1,0,  1,0,1,0,  1,0,0,1,  0,1,1,0,  0,1,1,0,
+  0,0,1,1,  0,1,1,1,  0,1,1,1,  1,0,1,1,  0,1,0,0,  1,0,1,0,  0,1,0,0,  1,1,1,0,
+
+  0,1,1,1,  0,0,0,1,  0,1,1,1,  0,1,0,0,  0,0,1,1,  0,1,0,0,  1,1,1,1,  1,0,1,1,
+  0,0,0,1,  0,1,0,1,  1,0,1,1,  1,1,0,0,  1,1,0,1,  1,0,1,0,  1,1,1,0,  1,1,0,1,
+
+  1,0,0,1,  0,1,1,0,  1,1,0,1,  1,1,0,0,  1,0,0,1,  0,0,1,0,  1,1,1,0,  0,0,1,1,
+  1,0,0,1,  0,1,1,1,  1,0,1,0,  0,0,1,1,  0,1,0,1,  1,0,0,0,  0,1,0,0,  1,1,0,1,
+
+  1,1,1,1,  0,0,0,1,  0,0,1,0,  1,0,1,1,  1,1,0,0,  0,1,1,0,  0,1,0,1,  0,0,0,0,
+  1,0,0,0,  1,1,0,0,  0,0,0,1,  1,1,1,0,  1,1,1,1,  1,1,0,1,  0,1,1,0,  1,0,1,0,
+
+  1,1,0,0,  1,0,0,1,  1,0,0,1,  0,0,0,1,  1,1,0,1,  1,1,0,0,  0,0,1,0,  1,1,0,1,
+  0,0,0,0,  0,1,1,0,  1,1,0,0,  0,0,0,0,  1,0,0,1,  0,0,0,0,  0,0,0,1,  1,1,0 
+};
+
+const unsigned char atsc_pn63[63] = {
+  1,1,1,0,  0,1,0,0,  1,0,1,1,  0,1,1,1,  0,1,1,0,  0,1,1,0,  1,0,1,0,  1,1,1,1,
+  1,1,0,0,  0,0,0,1,  0,0,0,0,  1,1,0,0,  0,1,0,1,  0,0,1,1,  1,1,0,1,  0,0,0
+};
+
diff --git a/gr-atsc/src/lib/atsci_pnXXX.h b/gr-atsc/src/lib/atsci_pnXXX.h
new file mode 100644 (file)
index 0000000..0e09ae8
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+extern const unsigned char atsc_pn511[];
+extern const unsigned char atsc_pn63[];
diff --git a/gr-atsc/src/lib/atsci_randomizer.cc b/gr-atsc/src/lib/atsci_randomizer.cc
new file mode 100644 (file)
index 0000000..4a18e26
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_randomizer.h>
+#include <assert.h>
+
+unsigned char atsci_randomizer::s_output_map[1 << 14];
+bool atsci_randomizer::s_output_map_initialized_p = false;
+
+atsci_randomizer::atsci_randomizer ()
+{
+  d_state = PRELOAD_VALUE;
+
+  if (!s_output_map_initialized_p)
+    initialize_output_map ();
+}
+
+/*!
+ * \brief Generate the table used in the fast_output_map function.
+ *
+ * The table has 16K byte entries, but because of how is is used, only
+ * 256 entries end up being resident in the cache.  This seems
+ * like a good use of memory.  We can get away with a 16K table
+ * because the low two bits of the state do not affect the output
+ * function.  By shifting right those two bits we shrink the table,
+ * and also get better cache line utilization.
+ */
+void
+atsci_randomizer::initialize_output_map ()
+{
+  s_output_map_initialized_p = true;
+  
+  for (int i = 0; i < (1 << 14); i++)
+    s_output_map[i] = slow_output_map (i << 2);
+}
+
+
+void 
+atsci_randomizer::reset ()
+{
+  d_state = PRELOAD_VALUE;
+}
+
+void 
+atsci_randomizer::randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in)
+{
+  assert (in.data[0] == MPEG_SYNC_BYTE);       // confirm it's there, then drop
+
+  for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+    out.data[i] = in.data[i + 1] ^ output_and_clk ();
+}
+
+void
+atsci_randomizer::derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in)
+{
+  out.data[0] = MPEG_SYNC_BYTE;                // add sync byte to beginning of packet
+
+  for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+    out.data[i + 1] = in.data[i] ^ output_and_clk ();
+}
+
+
+unsigned char
+atsci_randomizer::slow_output_map (int st)
+{
+  int  output = 0;
+
+  if (st & 0x8000)
+    output |= 0x01;
+
+  if (st & 0x2000)
+    output |= 0x02;
+
+  if (st & 0x1000)
+    output |= 0x04;
+
+  if (st & 0x0200)
+    output |= 0x08;
+
+  if (st & 0x0020)
+    output |= 0x10;
+
+  if (st & 0x0010)
+    output |= 0x20;
+
+  if (st & 0x0008)
+    output |= 0x40;
+
+  if (st & 0x0004)
+    output |= 0x80;
+
+  return output;
+}
diff --git a/gr-atsc/src/lib/atsci_randomizer.h b/gr-atsc/src/lib/atsci_randomizer.h
new file mode 100644 (file)
index 0000000..36025d1
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001 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.
+ */
+
+#ifndef _ATSC_RANDOMIZER_H_
+#define _ATSC_RANDOMIZER_H_
+
+#include <atsc_types.h>
+
+/*! 
+ * \brief ATSC data "whitener"
+ *
+ * The data randomizer described in ATSC standard A/53B.  
+ * See figure D4 on page 54.
+ */
+
+class atsci_randomizer {
+  friend class qa_atsci_randomizer;
+  
+ public:
+  atsci_randomizer();
+
+  /*! \brief reset randomizer LFSR
+   *
+   * must be called during the Data Segment Sync interval prior to the
+   * first data segment.  I.e., the LFSR is reset prior to the first
+   * field of each VSB data frame.
+   */
+  void reset ();
+
+  //! randomize (whiten) mpeg packet and remove leading MPEG-2 sync byte
+  void randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in);
+
+  //! derandomize (de-whiten) mpeg packet and add leading MPEG-2 sync byte
+  void derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in);
+
+  unsigned int state() const { return d_state; }
+
+ private:
+  static void initialize_output_map ();
+  static unsigned char slow_output_map (int st);
+
+  static unsigned char fast_output_map (int st){
+    return s_output_map[(st & 0xb23c) >> 2]; // Magic const with 8 bits set improves cache 
+                                             // utilization.  The bits correspond to the taps
+                                            // used in output calculation.  Others may be 
+                                            // safely ignored.
+  }
+    
+  //! return current output value
+  unsigned char output (){
+    return fast_output_map (d_state);
+  }
+
+  //! clock LFSR; advance to next state.
+  void clk (){
+    if (d_state & 0x1)
+      d_state = ((d_state ^ MASK) >> 1) | 0x8000;
+    else
+      d_state = d_state >> 1;
+  }
+
+  //! return current output value and advance to next state
+  unsigned char output_and_clk (){
+    unsigned char r = output ();
+    clk ();
+    return r;
+  }
+
+  unsigned int             d_state;
+
+  static const unsigned int PRELOAD_VALUE = 0x018f; /* 0xf180 bit reversed */
+  static const unsigned int MASK = 0xa638;
+  static unsigned char             s_output_map[1 << 14];
+  static bool              s_output_map_initialized_p;
+};
+
+#endif /* _ATSC_RANDOMIZER_H_ */
diff --git a/gr-atsc/src/lib/atsci_reed_solomon.cc b/gr-atsc/src/lib/atsci_reed_solomon.cc
new file mode 100644 (file)
index 0000000..e20e76d
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_reed_solomon.h>
+#include <assert.h>
+#include <string.h>
+
+extern "C" {
+#include "rs.h"
+}
+
+static const int rs_init_symsize =     8;
+static const int rs_init_gfpoly  = 0x11d;
+static const int rs_init_fcr     =     0;      // first consecutive root
+static const int rs_init_prim    =     1;      // primitive is 1 (alpha)
+static const int rs_init_nroots  =    20;
+
+static const int N = (1 << rs_init_symsize) - 1;       // 255
+static const int K = N - rs_init_nroots;               // 235
+
+static const int amount_of_pad  = N - ATSC_MPEG_RS_ENCODED_LENGTH;       // 48
+
+atsci_reed_solomon::atsci_reed_solomon ()
+{
+  d_rs = init_rs_char (rs_init_symsize, rs_init_gfpoly,
+                      rs_init_fcr, rs_init_prim, rs_init_nroots);
+
+  assert (d_rs != 0);
+}
+
+atsci_reed_solomon::~atsci_reed_solomon ()
+{
+  if (d_rs)
+    free_rs_char (d_rs);
+  d_rs = 0;
+}
+
+void
+atsci_reed_solomon::encode (atsc_mpeg_packet_rs_encoded &out, const atsc_mpeg_packet_no_sync &in)
+{
+  unsigned char tmp[K];
+
+  assert ((int)(amount_of_pad + sizeof (in.data)) == K);
+  
+  // add missing prefix zero padding to message
+  memset (tmp, 0, amount_of_pad);
+  memcpy (&tmp[amount_of_pad], in.data, sizeof (in.data));
+
+  // copy message portion to output packet
+  memcpy (out.data, in.data, sizeof (in.data));
+
+  // now compute parity bytes and add them to tail end of output packet
+  encode_rs_char (d_rs, tmp, &out.data[sizeof (in.data)]);
+}
+
+int
+atsci_reed_solomon::decode (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in)
+{
+  unsigned char tmp[N];
+  int          ncorrections;
+
+  assert ((int)(amount_of_pad + sizeof (in.data)) == N);
+  
+  // add missing prefix zero padding to message
+  memset (tmp, 0, amount_of_pad);
+  memcpy (&tmp[amount_of_pad], in.data, sizeof (in.data));
+
+  // correct message... 
+  ncorrections = decode_rs_char (d_rs, tmp, 0, 0);
+  
+  // copy corrected message to output, skipping prefix zero padding
+  memcpy (out.data, &tmp[amount_of_pad], sizeof (out.data));
+
+  return ncorrections;
+}
diff --git a/gr-atsc/src/lib/atsci_reed_solomon.h b/gr-atsc/src/lib/atsci_reed_solomon.h
new file mode 100644 (file)
index 0000000..c9cdca9
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_REED_SOLOMON_H_
+#define _ATSC_REED_SOLOMON_H_
+
+#include <atsc_types.h>
+
+/*!
+ * \brief ATSC Reed-Solomon encoder / decoder
+ *
+ * The t=10 (207,187) code described in ATSC standard A/53B.
+ * See figure D5 on page 55.
+ */
+
+class atsci_reed_solomon {
+
+ public:
+  atsci_reed_solomon();
+  ~atsci_reed_solomon();
+
+  /*!
+   * \brief Add RS error correction encoding
+   */
+  void encode (atsc_mpeg_packet_rs_encoded &out, const atsc_mpeg_packet_no_sync &in);
+
+  /*!
+   * Decode RS encoded packet.
+   * \returns a count of corrected symbols, or -1 if the block was uncorrectible.
+   */
+  int decode (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in);
+
+ private:
+  void *d_rs;
+};
+
+#endif /* _ATSC_REED_SOLOMON_H_ */
diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine.cc b/gr-atsc/src/lib/atsci_root_raised_cosine.cc
new file mode 100644 (file)
index 0000000..9409d2b
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsc_consts.h>
+#include <atsci_root_raised_cosine.h>
+#include <gr_firdes.h>
+
+vector<float> 
+atsc_root_raised_cosine::taps (double sampling_rate)
+{
+  static const double symbol_rate = ATSC_SYMBOL_RATE/2;        // 1/2 as wide because we're designing lp filter
+  // static const int    NTAPS = 93;                   // good number
+  // static const int    NTAPS = 745;                  // better number
+  static const int    NTAPS = 279;                     // better number
+
+  return gr_firdes::root_raised_cosine (1.0, sampling_rate, symbol_rate, .115, NTAPS);
+}
diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine.h b/gr-atsc/src/lib/atsci_root_raised_cosine.h
new file mode 100644 (file)
index 0000000..cb2798a
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_RRC_H_
+#define _ATSC_RRC_H_
+
+#include <gr_fir_builder.h>
+
+class atsc_root_raised_cosine : public gr_fir_builder
+{
+public:
+  virtual std::vector<float> taps (double sampling_freq);
+};
+
+
+#endif /* _ATSC_RRC_H_ */
diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc
new file mode 100644 (file)
index 0000000..a7c427d
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_root_raised_cosine_bandpass.h>
+#include <iostream>
+#include <cmath>
+
+using std::vector;
+using std::cerr;
+using std::endl;
+
+
+vector<float> 
+atsc_root_raised_cosine_bandpass::taps (double sampling_freq)
+{
+
+  vector<float> t = atsc_root_raised_cosine::taps (sampling_freq);
+
+  cerr << "atsc_root_raised_cosine_bandpass::taps -- " << t.size () << endl;
+
+  // heterodyne the low pass coefficients up to the specified bandpass 
+  // center frequency.  Note that when we do this, the filter bandwidth
+  // is effectively twice the low pass (2.69 * 2 = 5.38) and hence
+  // matches the diagram in the ATSC spec.
+
+  double arg = 2 * M_PI * _center_freq / sampling_freq;
+  for (unsigned int i = 0; i < t.size (); i++)
+    // the factor of 2 keeps the gain of the passband normalized to 1
+    t[i] *= 2 * cos (arg * (double) i);
+
+  return t;
+}
diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h
new file mode 100644 (file)
index 0000000..00f6099
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_RRC_BANDPASS_H_
+#define _ATSC_RRC_BANDPASS_H_
+
+#include <atsci_root_raised_cosine.h>
+
+class atsc_root_raised_cosine_bandpass : public atsc_root_raised_cosine
+{
+public:
+  atsc_root_raised_cosine_bandpass (double center_freq) : _center_freq (center_freq) {}
+  virtual std::vector<float> taps (double sampling_freq);
+
+protected:
+  double       _center_freq;
+};
+
+
+#endif /* _ATSC_RRC_BANDPASS_H_ */
diff --git a/gr-atsc/src/lib/atsci_single_viterbi.cc b/gr-atsc/src/lib/atsci_single_viterbi.cc
new file mode 100644 (file)
index 0000000..f9d66ff
--- /dev/null
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <atsci_single_viterbi.h>
+#include <iostream>
+
+using std::cerr;
+using std::cout;
+
+const float atsci_single_viterbi::was_sent[32] = {
+  -7,-3,-7,-3,-7,-3,-7,-3,
+  -5,-1,-5,-1,-5,-1,-5,-1,
+  1,5,1,5,1,5,1,5,
+  3,7,3,7,3,7,3,7
+};
+
+const int atsci_single_viterbi::transition_table[32] = {
+  0,2,4,6,
+  2,0,6,4,
+  1,3,5,7,
+  3,1,7,5,
+  4,6,0,2,
+  6,4,2,0,
+  5,7,1,3,
+  7,5,3,1
+};
+
+void
+atsci_single_viterbi::reset()
+{
+  for (unsigned int i = 0; i<2; i++)
+    for (unsigned int j = 0; j<8; j++) {
+      path_metrics[i][j] = 0;
+      traceback[i][j] = 0;
+    }
+  phase = 0;
+}
+
+atsci_single_viterbi::atsci_single_viterbi()
+{
+  reset();
+}
+
+char
+atsci_single_viterbi::decode(float input)
+{
+  for (unsigned int next_state = 0; next_state < 8; next_state++) {
+    unsigned int index = next_state << 2;
+    int min_metric_symb = 0;
+    float min_metric = fabs(input - was_sent[index + 0]) +
+      path_metrics[phase][transition_table[index + 0]];
+
+    for (unsigned int symbol_sent = 1; symbol_sent < 4; symbol_sent++) 
+      if( (fabs(input-was_sent[index+symbol_sent]) + 
+          path_metrics[phase][transition_table[index+symbol_sent]])
+         < min_metric) {
+       min_metric = fabs(input-was_sent[index+symbol_sent]) + 
+         path_metrics[phase][transition_table[index+symbol_sent]];
+       min_metric_symb = symbol_sent;
+      }
+
+    path_metrics[phase^1][next_state] = min_metric;
+    traceback[phase^1][next_state] = (((unsigned long long)min_metric_symb) << 62) |
+      (traceback[phase][transition_table[index+min_metric_symb]] >> 2);
+  }
+  unsigned int best_state = 0;
+  float best_state_metric = path_metrics[phase^1][0];
+  for (unsigned int state = 1; state < 8; state++)
+    if(path_metrics[phase^1][state] < best_state_metric) {
+      best_state = state;
+      best_state_metric = path_metrics[phase^1][state];
+    }
+  if(best_state_metric > 10000) {
+    for(unsigned int state = 0; state < 8; state++)
+      path_metrics[phase^1][state] -= best_state_metric;
+    // cerr << "Resetting Path Metrics from " << best_state_metric << " to 0\n";
+  }
+  phase ^= 1;
+  return (0x3 & traceback[phase][best_state]);
+}
diff --git a/gr-atsc/src/lib/atsci_single_viterbi.h b/gr-atsc/src/lib/atsci_single_viterbi.h
new file mode 100644 (file)
index 0000000..a722a4a
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSCSINGLEVITERBI_H_
+#define _ATSCSINGLEVITERBI_H_
+
+/*!
+ * \brief single channel viterbi decoder
+ */
+class atsci_single_viterbi
+{
+  
+public:
+  atsci_single_viterbi ();
+
+  static const unsigned int TB_LEN = 32;
+
+  /*!
+   * \p INPUT ideally takes on the values +/- 1,3,5,7
+   * return is decoded dibit in the range [0, 3]
+   */
+  char decode (float input);
+
+  void reset ();
+
+  //! internal delay of decoder
+  int delay () { return TB_LEN - 1; }
+
+protected:
+  static const int transition_table[32];
+  static const float was_sent[32];
+  float path_metrics [2][8];
+  unsigned long long traceback [2][8];
+  unsigned char phase;
+};
+
+#endif 
diff --git a/gr-atsc/src/lib/atsci_slicer_agc.h b/gr-atsc/src/lib/atsci_slicer_agc.h
new file mode 100644 (file)
index 0000000..2e7d3be
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_SLICER_AGC_H_
+#define _ATSC_SLICER_AGC_H_
+
+#include <math.h>
+#include <gr_single_pole_iir.h>
+
+/*!
+ * \brief Automatic Gain Control class for atsc slicer
+ *
+ * Given perfect data, output values will be +/- {7, 5, 3, 1}
+ */
+
+class atsci_slicer_agc {
+
+ public:
+  atsci_slicer_agc () : _gain(1), dc(0.0025) {};
+
+  
+  float gain () { return _gain; }
+
+#if 1
+  float scale (float input){
+    float t = input * _gain;
+    float output = t - REFERENCE;
+    float error = REFERENCE - dc.filter (t);
+    _gain += error * RATE;
+    return output;
+  }
+#else
+  float scale(float input){
+    float avg = dc.filter(input);
+    if(fabs(avg)<.1)avg=.1;
+    _gain += _gain*.99 + .01* REFERENCE/avg;
+    return input*_gain - REFERENCE;
+  }
+#endif
+
+ protected:
+  
+  static const float                   REFERENCE = 1.25;       // pilot reference value
+  static const float                   RATE = 1.0e-5;          // adjustment rate
+  float                                        _gain;                  // current gain
+  gr_single_pole_iir<float,float,float>        dc;
+};
+
+#endif /* _ATSC_SLICER_AGC_H_ */
diff --git a/gr-atsc/src/lib/atsci_sliding_correlator.cc b/gr-atsc/src/lib/atsci_sliding_correlator.cc
new file mode 100644 (file)
index 0000000..bde8022
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#include <atsci_sliding_correlator.h>
+#include <atsci_pnXXX.h>
+
+// #define TRY_BACKWARDS
+
+/*
+ * Return the number of 1's in v.
+ * This magic code is explained wonderfully in the AMD Athlon
+ * optimization guide, pg 136.
+ */
+static inline int popcount32 (unsigned long v)
+{
+  unsigned long w = v - ((v >> 1) & 0x55555555);
+  unsigned long x = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+  unsigned long y = (x + (x >> 4)) & 0x0f0f0f0f;
+  unsigned long z = (y * 0x01010101) >> 24;
+
+  return z;
+}
+
+atsci_sliding_correlator::atsci_sliding_correlator ()
+{
+#if defined(TRY_BACKWARDS)
+  for (int i = 511 - 1; i >= 0; i--)
+    mask.shift_in (atsc_pn511[i]);
+#else
+  for (unsigned i = 0; i < 511; i++)
+    mask.shift_in (atsc_pn511[i]);
+#endif
+
+  and_mask.shift_in (0);
+  for (int i = 0; i < 511; i++)
+    and_mask.shift_in (1);
+}
+
+/*
+ * we shift in from the top of the register towards the bottom
+ *
+ * +-- bits enter here...
+ * |
+ * v
+ * block 0 | block 1 | block 2 ... | block N-1
+ *                                          |
+ *                                          +--> ... and drop out here
+ *
+ */
+inline void
+atsci_sliding_correlator::shift_reg::shift_in (int bit)
+{
+  for (int i = NSRBLOCKS - 1; i > 0; i--)
+    d[i] = ((d[i-1] & 0x1) << (srblock_bitsize - 1)) | (d[i] >> 1);
+
+  d[0] = (((srblock) bit) << (srblock_bitsize - 1)) | (d[0] >> 1);
+}
+
+int
+atsci_sliding_correlator::input_bit (int bit)
+{
+  input.shift_in (bit);
+
+  // can probably get a win by unrolling the loop, if we need to.
+  int  count = 0;
+  for (int i = 0; i < NSRBLOCKS; i++)
+    count += popcount32 ((input.d[i] ^ mask.d[i]) & and_mask.d[i]);
+
+  return count;
+}
+
diff --git a/gr-atsc/src/lib/atsci_sliding_correlator.h b/gr-atsc/src/lib/atsci_sliding_correlator.h
new file mode 100644 (file)
index 0000000..c01bc9a
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_SLIDING_CORRELATOR_H_
+#define _ATSC_SLIDING_CORRELATOR_H_
+
+#include <string.h>
+
+extern const unsigned char atsc_pn511[511];
+extern const unsigned char atsc_pn63[63];
+
+/*!
+ * \brief look for the PN 511 field sync pattern
+ */
+class atsci_sliding_correlator {
+ public:
+
+  atsci_sliding_correlator ();
+  ~atsci_sliding_correlator (){};
+
+  //! input hard decision bit, return correlation (0,511)
+  // Result is the number of wrong bits.  
+  // E.g., 0 -> perfect match; 511 -> all bits are wrong
+
+  int input_bit (int bit);
+
+  //! input sample, return correlation (0,511)
+  // Result is the number of wrong bits.  
+  // E.g., 0 -> perfect match; 511 -> all bits are wrong
+
+  int input_int (int sample){
+    return input_bit (sample < 0 ? 0 : 1);
+  }
+
+  //! input sample, return correlation (0,511)
+  // Result is the number of wrong bits.  
+  // E.g., 0 -> perfect match; 511 -> all bits are wrong
+
+  int input_float (float sample){
+    return input_bit (sample < 0 ? 0 : 1);
+  }
+
+  void reset () { input.reset (); }
+  
+ private:
+
+  typedef unsigned long        srblock;
+  static const int bits_per_char = 8;
+  static const int srblock_bitsize = sizeof (srblock) * bits_per_char;
+  static const int NSRBLOCKS = (511 + srblock_bitsize - 1) / srblock_bitsize;
+
+  class shift_reg {
+  public:
+    shift_reg ()  { reset (); }
+    void reset () { memset (d, 0, sizeof (d)); }
+    void shift_in (int bit);
+    srblock    d[NSRBLOCKS];
+  };
+
+  shift_reg    mask;           // pattern we're looking for
+  shift_reg    input;          // current input window
+  shift_reg    and_mask;       // bits to consider
+};
+
+#endif /* _ATSC_SLIDING_CORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/atsci_sssr.cc b/gr-atsc/src/lib/atsci_sssr.cc
new file mode 100644 (file)
index 0000000..dc5c01b
--- /dev/null
@@ -0,0 +1,290 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_sssr.h>
+#include <algorithm>
+#include <cmath>
+#include <cstdio>
+#include <assert.h>
+#include <atsci_diag_output.h>
+#include <gr_math.h>
+#include <stdio.h>
+
+/*
+ * ----------------------------------------------------------------
+ * Segment Integrator Pre-Processor
+ *
+ * Compute weight passed to integrator based on
+ * correlation result and ncorr_gain2
+ */
+
+inline static int
+sipp (bool digcorr_output)
+{
+  if (digcorr_output)
+    return +2;                 // positive correlation
+  else
+    return -1;                 // no correlation
+}
+
+/* 
+ * ----------------------------------------------------------------
+ * Segment Sync Integrator...
+ */
+
+static const int SSI_MIN = -16;
+static const int SSI_MAX =  15;
+
+void
+sssr::seg_sync_integrator::reset ()
+{
+  for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+    d_integrator[i] = SSI_MIN;
+}
+  
+int
+sssr::seg_sync_integrator::update (int weight, int index)
+{
+  int  t = d_integrator[index] + weight;
+  t = std::max (t, SSI_MIN);
+  t = std::min (t, SSI_MAX);
+  d_integrator[index] = t;
+
+  return t;
+}
+
+int
+sssr::seg_sync_integrator::find_max (int *v)
+{
+  int  best_value = d_integrator[0];
+  int  best_index = 0;
+  
+  for (int i = 1; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+    if (d_integrator[i] > best_value){
+      best_value = d_integrator[i];
+      best_index = i;
+    }
+
+  *v = best_value;
+  return best_index;
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Segment Sync and Symbol recovery
+ */
+
+static const int       SYMBOL_INDEX_OFFSET = 3;
+static const int       MIN_SEG_LOCK_CORRELATION_VALUE = 5;
+
+atsci_sssr::atsci_sssr ()
+  : d_debug_fp(0)
+{
+  reset ();
+  
+  if (_SSSR_DIAG_OUTPUT_){
+    const char *file = "sssr.ssout";
+    if ((d_debug_fp = fopen (file, "wb")) == 0){
+      perror (file);
+      exit (1);
+    }
+  }
+}
+
+atsci_sssr::~atsci_sssr ()
+{
+  if (d_debug_fp)
+    fclose (d_debug_fp);
+}
+
+void
+atsci_sssr::reset ()
+{
+  d_correlator.reset ();
+  d_integrator.reset ();
+  d_quad_filter.reset ();
+
+  for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+    d_quad_output[i] = 0;
+  
+  d_timing_adjust = 0;
+  d_counter = 0;
+  d_symbol_index = 0;
+  d_seg_locked = false;
+}
+
+void
+atsci_sssr::update (sssr::sample_t sample_in,   // input
+                  bool          *seg_locked,    // are we seeing segment syncs?
+                  int           *symbol_index,  // 0..831
+                  double        *timing_adjust) // how much to adjust timing
+{
+  double qo = d_quad_filter.update (sample_in);
+  d_quad_output[d_counter] = qo;
+
+  int bit = gr_signbit (sample_in) ^ 1;        // slice on sign: + => 1, - => 0
+  int corr_out = d_correlator.update (bit);
+  int weight = sipp (corr_out);
+  int corr_value = d_integrator.update (weight, d_counter);
+  int best_correlation_index = -1;
+
+  incr_symbol_index ();
+  if (incr_counter ()){                // counter just wrapped...
+    int        best_correlation_value;
+    best_correlation_index = d_integrator.find_max (&best_correlation_value);
+    d_seg_locked = best_correlation_value >= MIN_SEG_LOCK_CORRELATION_VALUE;
+    d_timing_adjust = d_quad_output[best_correlation_index];
+
+    d_symbol_index = SYMBOL_INDEX_OFFSET - 1 - best_correlation_index;
+    if (d_symbol_index < 0)
+      d_symbol_index += ATSC_DATA_SEGMENT_LENGTH;
+  }
+
+  *seg_locked = d_seg_locked;
+  *symbol_index = d_symbol_index;
+  *timing_adjust = d_timing_adjust;
+
+  if (_SSSR_DIAG_OUTPUT_){
+    float      iodata[7];
+    iodata[0] = bit;
+    iodata[1] = corr_value;
+    iodata[2] = qo;
+    iodata[3] = d_counter;
+    iodata[4] = d_symbol_index;
+    iodata[5] = best_correlation_index;
+    iodata[6] = d_timing_adjust;
+
+    if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){
+      perror ("fwrite: sssr");
+      exit (1);
+    }
+  }
+
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Interpolator control for Seg & Symbol Sync Recovery
+ */
+
+static const double    LOOP_FILTER_TAP = 0.00025;      // 0.0005 works
+static const double    ADJUSTMENT_GAIN = 1.0e-5 / (10 * ATSC_DATA_SEGMENT_LENGTH);
+  
+atsci_interpolator::atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq)
+  : d_debug_fp(0)
+{
+// Tweaked ratio from 1.8 to 1.78 to support input rate of 19.2MHz
+  assert (nominal_ratio_of_rx_clock_to_symbol_freq >= 1.78);
+  d_nominal_ratio_of_rx_clock_to_symbol_freq =
+    nominal_ratio_of_rx_clock_to_symbol_freq;
+
+  d_loop.set_taps (LOOP_FILTER_TAP);
+
+  reset ();
+
+  if (_SSSR_DIAG_OUTPUT_){
+    const char *file = "interp.ssout";
+    if ((d_debug_fp = fopen (file, "wb")) == 0){
+      perror (file);
+      exit (1);
+    }
+  }
+
+}
+
+atsci_interpolator::~atsci_interpolator ()
+{
+  if (d_debug_fp)
+    fclose (d_debug_fp);
+}
+
+void
+atsci_interpolator::reset ()
+{
+  d_w = d_nominal_ratio_of_rx_clock_to_symbol_freq;
+  d_mu = 0.5;
+  d_incr = 0;
+  d_loop.reset ();
+}
+
+bool
+atsci_interpolator::update (
+          const sssr::sample_t input_samples[],        // I: vector of samples
+          int                  nsamples,               // I: total number of samples
+          int                 *index,                  // I/O: current input index
+          double               timing_adjustment,      // I: how much to bump timing
+          sssr::sample_t      *output_sample)
+{
+  if (*index + (int) ntaps () > nsamples)
+    return false;
+
+  // FIXME Confirm that this is right.  I think it is.  It was (1-d_mu)
+  *output_sample = d_interp.interpolate (&input_samples[*index], d_mu);  
+
+  double filter_out = 0;
+  
+#if 0
+
+  filter_out = d_loop.filter (timing_adjustment);
+  d_w = d_w + ADJUSTMENT_GAIN * filter_out * 1e-3;
+
+#elif 1
+
+  filter_out = d_loop.filter (timing_adjustment);
+  d_mu = d_mu + ADJUSTMENT_GAIN * 10e3 * filter_out;
+
+#else
+
+  static const double alpha = 0.01;
+  static const double beta = alpha * alpha / 16;
+
+  double x = ADJUSTMENT_GAIN * 10e3 * timing_adjustment;
+
+  d_mu = d_mu + alpha * x;     // conceptually "phase"
+  d_w  = d_w  + beta * x;      // conceptually "frequency"
+  
+#endif
+  
+  double s = d_mu + d_w;
+  double float_incr = floor (s);
+  d_mu = s - float_incr;
+  d_incr = (int) float_incr;
+
+  assert (d_incr >= 1 && d_incr <= 3);
+  *index += d_incr;
+
+  if (_SSSR_DIAG_OUTPUT_){
+    float      iodata[6];
+    iodata[0] = timing_adjustment;
+    iodata[1] = filter_out;
+    iodata[2] = d_w;
+    iodata[3] = d_mu;
+    iodata[4] = d_incr;
+    iodata[5] = *output_sample;
+    if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){
+      perror ("fwrite: interpolate");
+      exit (1);
+    }
+  }
+
+  return true;
+}
diff --git a/gr-atsc/src/lib/atsci_sssr.h b/gr-atsc/src/lib/atsci_sssr.h
new file mode 100644 (file)
index 0000000..4555dc2
--- /dev/null
@@ -0,0 +1,240 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+/*
+ *   --- ATSC Segment and Symbol Sync Recovery ---
+ */
+
+#ifndef _ATSC_SSSR_H_
+#define _ATSC_SSSR_H_
+
+#include <atsc_consts.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <gr_single_pole_iir.h>
+#include <cstdio>
+
+/*
+ *   --- support classes for atsci_sssr ---
+ */
+
+namespace sssr {
+
+  typedef float sample_t;
+
+  // ----------------------------------------------------------------
+  //! digital correlator for 1001 and 0110 patterns
+
+  class digital_correlator {
+    int                d_sr;   // 4 bit shift register
+
+  public:
+    
+    // Constructor
+    digital_correlator () { reset (); }
+
+    // Manipulators
+
+    //! called on channel change
+    void reset () { d_sr = 0; }
+
+    //! clock bit in and return true if we've seen 1001
+
+    bool update (int bit) {
+      d_sr = ((bit & 1) << 3) | (d_sr >> 1);
+
+      return (d_sr == 0x9);    // 1001
+    }
+
+  };
+
+
+  // ----------------------------------------------------------------
+  //! segment sync integrator
+
+  class seg_sync_integrator {
+    signed char        d_integrator[ATSC_DATA_SEGMENT_LENGTH];
+    
+  public:
+
+    // Constructor
+    seg_sync_integrator () { reset (); }
+
+    // Manipulators
+
+    //! called on channel change
+    void reset ();
+    
+    //! update current tap with weight and return integrated correlation value
+    int update (int weight, int index);
+
+    //! return index of maximum correlation value
+    int find_max (int *value);
+
+  };
+  
+  // ----------------------------------------------------------------
+  //! quad filter (used to compute timing error)
+
+  class quad_filter {
+    sample_t   d_delay[4];
+
+  public:
+    // Constructor
+    quad_filter () { reset (); }
+
+    // Manipulators
+
+    //! called on channel change
+    void reset () { d_delay[0] = d_delay[1] = d_delay[2] = d_delay[3] = 0; }
+
+    double update (sample_t sample){
+      d_delay[3] = d_delay[2];
+      d_delay[2] = d_delay[1];
+      d_delay[1] = d_delay[0];
+      d_delay[0] = sample;
+
+      // the coefficients are -1,-1,+1,+1
+      return d_delay[3] + d_delay[2] - d_delay[1] - d_delay[0];
+    }
+  };
+}
+
+// ----------------------------------------------------------------
+
+/*!
+ * \brief ATSC Segment and Symbol Sync Recovery
+ *
+ * This class implements data segment sync tracking and symbol timing
+ * using the method described in "ATSC/VSB Tutorial - Receiver Technology"
+ * by Wayne E. Bretl of Zenith, pgs 41-45.
+ */
+
+class atsci_sssr {
+  sssr::digital_correlator     d_correlator;
+  sssr::seg_sync_integrator    d_integrator;
+  sssr::quad_filter            d_quad_filter;
+  double                       d_quad_output[ATSC_DATA_SEGMENT_LENGTH];
+  double                       d_timing_adjust;
+  int                          d_counter;      // free running mod 832 counter
+  int                          d_symbol_index;
+  bool                         d_seg_locked;
+  FILE                        *d_debug_fp;
+
+  
+  bool incr_counter () {
+    d_counter++;
+    if (d_counter >= ATSC_DATA_SEGMENT_LENGTH){
+      d_counter = 0;
+      return true;
+    }
+    return false;
+  }
+    
+  void incr_symbol_index () {
+    d_symbol_index++;
+    if (d_symbol_index >= ATSC_DATA_SEGMENT_LENGTH)
+      d_symbol_index = 0;
+  }
+
+public:
+
+  // Constructor
+  atsci_sssr ();
+  ~atsci_sssr ();
+
+  // Manipulators
+
+  //! call on channel change
+  void reset ();
+
+
+  /*!
+   * \brief process a single sample at the ATSC symbol rate (~10.76 MSPS)
+   *
+   * This block computes an indication of our timing error and keeps
+   * track of where the segment sync's occur.  \p timing_adjust is
+   * returned to indicate how the interpolator timing needs to be
+   * adjusted to track the transmitter's symbol timing.  If \p seg_locked
+   * is true, then \p symbol_index is the index of this sample in 
+   * the current segment.  The symbols are numbered from 0 to 831, where 
+   * symbols 0, 1, 2 and 3 correspond to the data segment sync pattern, 
+   * nominally +5, -5, -5, +5.
+   */
+
+  void update (sssr::sample_t  sample_in,      // input
+              bool           *seg_locked,      // are we seeing segment syncs?
+              int            *symbol_index,    // 0..831
+              double         *timing_adjust);  // how much to adjust timing
+
+};
+
+// ----------------------------------------------------------------
+
+/*!
+ * \brief interpolator control for segment and symbol sync recovery
+ */
+class atsci_interpolator {
+  gri_mmse_fir_interpolator    d_interp;
+  gr_single_pole_iir<float,float,float> d_loop;        // ``VCO'' loop filter
+  double                       d_nominal_ratio_of_rx_clock_to_symbol_freq; // FREQ
+  double                       d_w;    // ratio of PERIOD of Tx to Rx clocks
+  double                       d_mu;   // fractional delay [0,1]
+  int                          d_incr;         // diagnostic only
+  FILE                        *d_debug_fp;     // diagnostic only
+
+public:
+  //! \p nominal_ratio_of_rx_clock_to_symbol_freq must be >= 1.8
+  atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq);
+  ~atsci_interpolator ();
+
+  // Manipulators
+
+  //! call on channel change
+  void reset ();
+
+  /*!
+   * \brief produce next sample referenced to Tx clock
+   *
+   * If there aren't enough input_samples left to produce
+   * an output, return false, else true.
+   */
+
+  bool update (const sssr::sample_t input_samples[],   // I: vector of samples
+              int                  nsamples,           // I: total number of samples
+              int                 *index,              // I/O: current input index
+              double               timing_adjustment,  // I: how much to bump timing
+              sssr::sample_t      *output_sample);     // O: the output sample
+
+  // Accessors
+
+  // how much history we require on our input
+  unsigned ntaps () const { return d_interp.ntaps (); }
+
+  // diagnostic accessors
+  double mu ()   const { return d_mu; }
+  double w ()    const { return d_w;  }
+  int   incr () const { return d_incr; }
+  
+};
+
+#endif /* _ATSC_SSSR_H_ */
diff --git a/gr-atsc/src/lib/atsci_syminfo.h b/gr-atsc/src/lib/atsci_syminfo.h
new file mode 100644 (file)
index 0000000..a8999e7
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_SYMINFO_H_
+#define _ATSC_SYMINFO_H_
+
+namespace atsc {
+
+  static const unsigned int SI_SEGMENT_NUM_MASK       = 0x1ff;
+  static const unsigned int SI_FIELD_SYNC_SEGMENT_NUM = SI_SEGMENT_NUM_MASK;  // conceptually -1
+
+  struct syminfo {
+    unsigned int    symbol_num         : 10;   // 0..831
+    unsigned int    segment_num                :  9;   // 0..311 and SI_FIELD_SYNC_SEGMENT_NUM
+    unsigned int    field_num          :  1;   // 0..1
+    unsigned int    valid              :  1;   // contents are valid
+  };
+
+
+  static inline bool
+  tag_is_start_field_sync (syminfo tag)
+  {
+    return tag.symbol_num == 0 && tag.segment_num == SI_FIELD_SYNC_SEGMENT_NUM && tag.valid;
+  }
+
+  static inline bool
+  tag_is_start_field_sync_1 (syminfo tag)
+  {
+    return tag_is_start_field_sync (tag) && tag.field_num == 0;
+  }
+
+  static inline bool
+  tag_is_start_field_sync_2 (syminfo tag)
+  {
+    return tag_is_start_field_sync (tag) && tag.field_num == 1;
+  }
+
+}
+
+#endif /* _ATSC_SYMINFO_H_ */
diff --git a/gr-atsc/src/lib/atsci_sync_tag.h b/gr-atsc/src/lib/atsci_sync_tag.h
new file mode 100644 (file)
index 0000000..c644da3
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _ATSC_SYNC_TAG_H_
+#define _ATSC_SYNC_TAG_H_
+
+/*
+ * Constants used to communicate in the second stream passed between
+ * GrAtscFSCorrelator, GrAtscEqualizer and GrAtscFieldSyncMux.  The
+ * second stream is sample-for-sample parallel with the streaming
+ * floating point in the first stream.  The second stream provides
+ * information about alignment boundaries.
+ *
+ * These are in floating point because the current implementation
+ * requires that for a given module, all input streams share the same
+ * type and all output streams share the same type.  We'd use unsigned
+ * char otherwise.
+ */
+namespace atsc_sync_tag {
+
+  // Nothing special
+  static const float NORMAL = 0.0;
+
+  // The corresponding symbol is the first symbol of the
+  // data segment sync sequence { +5, -5, -5, +5 }
+  static const float START_SEG_SYNC = 1.0;
+
+  // The corresponding symbol is the first symbol of the
+  // field sync 1 PN511 pattern.
+  static const float START_FIELD_SYNC_1 = 2.0;
+
+  // The corresponding symbol is the first symbol of the
+  // field sync 2 PN511 pattern.
+  static const float START_FIELD_SYNC_2 = 3.0;
+};
+
+#endif /* _ATSC_SYNC_TAG_H_ */
diff --git a/gr-atsc/src/lib/atsci_trellis_encoder.cc b/gr-atsc/src/lib/atsci_trellis_encoder.cc
new file mode 100644 (file)
index 0000000..2ebccc3
--- /dev/null
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#include <atsci_trellis_encoder.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+static const int DIBITS_PER_BYTE = 4;
+
+#define SEGOF(x)       ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))
+#define SYMOF(x)       (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4)
+
+/* How many separate Trellis encoders / Viterbi decoders run in parallel */
+static const int       NCODERS = 12;
+
+#define        ENCODER_SEG_BUMP        4
+
+/* A Segment sync symbol is an 8VSB +5,-5,-5,+5 sequence that occurs at
+   the start of each 207-byte segment (including field sync segments).  */
+#define        DSEG_SYNC_SYM1  0x06    /* +5 */
+#define        DSEG_SYNC_SYM2  0x01    /* -5 */
+#define        DSEG_SYNC_SYM3  0x01    /* -5 */
+#define        DSEG_SYNC_SYM4  0x06    /* +5 */
+
+
+/* Shift counts to bit numbers (high order, low order); 9x entries unused */
+static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96};
+static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96};
+
+
+atsci_trellis_encoder::atsci_trellis_encoder ()
+{
+  debug = false;
+  reset ();
+}
+
+atsci_trellis_encoder::~atsci_trellis_encoder ()
+{
+}
+
+void
+atsci_trellis_encoder::reset ()
+{
+  for (int i = 0; i < NCODERS; i++)
+    enc[i].reset ();
+}
+
+void 
+atsci_trellis_encoder::encode (atsc_data_segment out[NCODERS],
+                             const atsc_mpeg_packet_rs_encoded in[NCODERS])
+{
+  unsigned char out_copy[OUTPUT_SIZE];
+  unsigned char in_copy[INPUT_SIZE];
+
+  assert (sizeof (in_copy) == sizeof (in[0].data) * NCODERS);
+  assert (sizeof (out_copy) == sizeof (out[0].data) * NCODERS);
+
+  // copy input into continguous temporary buffer
+  for (int i = 0; i < NCODERS; i++){
+    assert (in[i].pli.regular_seg_p ());
+    plinfo::sanity_check (in[i].pli);
+    memcpy (&in_copy[i * INPUT_SIZE/NCODERS],
+           &in[i].data[0],
+           ATSC_MPEG_RS_ENCODED_LENGTH * sizeof (in_copy[0]));
+  }
+
+  memset (out_copy, 0, sizeof (out_copy));     // FIXME, sanity check
+  
+  // do the deed...
+  encode_helper (out_copy, in_copy);
+
+  // copy output from contiguous temp buffer into final output
+  for (int i = 0; i < NCODERS; i++){
+    memcpy (&out[i].data[0],
+           &out_copy[i * OUTPUT_SIZE/NCODERS],
+           ATSC_DATA_SEGMENT_LENGTH * sizeof (out_copy[0]));
+
+    // copy pipeline info
+    out[i].pli = in[i].pli;
+
+    plinfo::sanity_check (out[i].pli);
+    assert (out[i].pli.regular_seg_p ());
+  }
+}
+
+/*
+ * This code expects contiguous arrrays.  Use it as is, it computes
+ * the correct answer.  Maybe someday, when we've run out of better
+ * things to do, rework to avoid the copying in encode.
+ */
+void 
+atsci_trellis_encoder::encode_helper (unsigned char output[OUTPUT_SIZE],
+                                    const unsigned char input[INPUT_SIZE])
+{
+  int i;
+  int encoder;
+  unsigned char trellis_buffer[NCODERS];
+  int trellis_wherefrom[NCODERS];
+  unsigned char *out, *next_out_seg;
+  int chunk;
+  int shift;
+  unsigned char dibit;
+  unsigned char symbol;
+  int skip_encoder_bump;
+
+  /* FIXME, we may want special processing here 
+     for a flag byte to keep track of which part of the field we're in? */
+
+  encoder = NCODERS - ENCODER_SEG_BUMP;
+  skip_encoder_bump = 0;
+  out = output;
+  next_out_seg = out;
+
+  for (chunk = 0;
+       chunk < INPUT_SIZE;
+       chunk += NCODERS) {
+    /* Load a new chunk of bytes into the Trellis encoder buffers.
+       They get loaded in an order that depends on where we are in the
+       segment sync progress (sigh). 
+       GRR!  When the chunk reload happens at the same time as the
+       segment boundary, we should bump the encoder NOW for the reload,
+       rather than LATER during the bitshift transition!!! */
+    if (out >= next_out_seg) {
+      encoder = (encoder + ENCODER_SEG_BUMP) % NCODERS;
+      skip_encoder_bump = 1;
+    }
+      
+    for (i = 0; i < NCODERS; i++) {
+      /* for debug */ trellis_wherefrom[encoder] = chunk+i;
+      trellis_buffer[encoder] =             input [chunk+i];
+      encoder++;
+      if (encoder >= NCODERS) encoder = 0;
+    }
+
+    for (shift = 6; shift >= 0; shift -= 2) {
+
+      /* Segment boundaries happen to occur on some bitshift transitions. */
+      if (out >= next_out_seg) {
+       /* Segment transition.  Output a data segment sync symbol, and
+          mess with the trellis encoder mux.  */
+       *out++ = DSEG_SYNC_SYM1;
+       *out++ = DSEG_SYNC_SYM2;
+       *out++ = DSEG_SYNC_SYM3;
+       *out++ = DSEG_SYNC_SYM4;
+       if (debug) printf ("SYNC SYNC SYNC SYNC\n");
+        next_out_seg = out + (SEGMENT_SIZE * DIBITS_PER_BYTE);
+
+       if (!skip_encoder_bump)
+         encoder = (encoder + ENCODER_SEG_BUMP) % NCODERS;
+       skip_encoder_bump = 0;
+      }
+
+      /* Now run each of the 12 Trellis encoders to spit out 12 symbols.
+         Each encoder takes input from the same byte of the chunk, but the
+         outputs of the encoders come out in various orders.
+         NOPE -- this is false.  The encoders take input from various
+         bytes of the chunk (which changes at segment sync time), AND
+         they also come out in various orders.  You really do have to
+         keep separate track of:  the input bytes, the encoders, and
+         the output bytes -- because they're all moving with respect to
+         each other!!!  */
+      for (i = 0; i < NCODERS; i++) {
+       dibit = 0x03 & (trellis_buffer[encoder] >> shift);
+        if (debug)
+         printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = dibit %d ",
+                 (long) SEGOF(out-output), (long) SYMOF(out-output),
+                 encoder, trellis_wherefrom[encoder],
+                 bit1[shift], bit2[shift], dibit);
+       symbol = enc[encoder].encode (dibit);
+       *out++ = symbol;
+        encoder++; if (encoder >= NCODERS) encoder = 0;
+       if (debug) printf ("sym %d\n", symbol);
+      } /* Encoders */
+    } /* Bit shifts */
+  } /* Chunks */
+  
+  /* Check up on ourselves */
+#if 0
+  assertIntsEqual (0, (INPUT_SIZE * DIBITS_PER_BYTE) % NCODERS, "not %");
+  assertIntsEqual (OUTPUT_SIZE, out - output, "outptr");
+  assertIntsEqual (NCODERS - ENCODER_SEG_BUMP, encoder, "mux sync");
+#else
+  assert (0 ==  (INPUT_SIZE * DIBITS_PER_BYTE) % NCODERS);
+  assert (OUTPUT_SIZE == out - output);
+  assert (NCODERS - ENCODER_SEG_BUMP == encoder);
+#endif
+}
+
diff --git a/gr-atsc/src/lib/atsci_trellis_encoder.h b/gr-atsc/src/lib/atsci_trellis_encoder.h
new file mode 100644 (file)
index 0000000..dc5c16d
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_TRELLIS_ENCODER_H_
+#define _ATSC_TRELLIS_ENCODER_H_
+
+#include <atsci_basic_trellis_encoder.h>
+#include <atsc_types.h>
+
+/*!
+ * \brief fancy, schmancy 12-way interleaved trellis encoder for ATSC
+ */
+
+class atsci_trellis_encoder {
+ public:
+  static const int     NCODERS = 12;
+
+  atsci_trellis_encoder ();
+  ~atsci_trellis_encoder ();
+
+  //! reset all encoder states
+  void reset ();
+
+  /*!
+   * Take 12 RS encoded, convolutionally interleaved segments and
+   * produce 12 trellis coded data segments.  We work in groups of 12
+   * because that's the smallest number of segments that composes a
+   * single full cycle of the encoder mux.
+   */
+  void encode (atsc_data_segment out[NCODERS],
+              const atsc_mpeg_packet_rs_encoded in[NCODERS]);
+
+  
+ protected:
+  static const int SEGMENT_SIZE = ATSC_MPEG_RS_ENCODED_LENGTH; // 207
+  static const int INPUT_SIZE = (SEGMENT_SIZE * 12);
+  static const int OUTPUT_SIZE = (ATSC_DATA_SEGMENT_LENGTH * 12);
+  
+  void encode_helper (unsigned char out[OUTPUT_SIZE],
+                     const unsigned char in[INPUT_SIZE]);
+
+  atsci_basic_trellis_encoder  enc[NCODERS];
+  bool                         debug;
+};
+
+
+#endif /* _ATSC_TRELLIS_ENCODER_H_ */
diff --git a/gr-atsc/src/lib/atsci_viterbi_decoder.cc b/gr-atsc/src/lib/atsci_viterbi_decoder.cc
new file mode 100644 (file)
index 0000000..5b9ae4e
--- /dev/null
@@ -0,0 +1,176 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsci_viterbi_decoder.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cmath>
+#include "atsci_viterbi_mux.cc"
+#include <string.h>
+
+
+/* How many separate Trellis encoders / Viterbi decoders run in parallel */
+static const int       NCODERS = 12;
+
+static const float     DSEG_SYNC_SYM1 =  5;
+static const float     DSEG_SYNC_SYM2 = -5;
+static const float     DSEG_SYNC_SYM3 = -5;
+static const float     DSEG_SYNC_SYM4 =  5;
+
+atsci_viterbi_decoder::atsci_viterbi_decoder ()
+{
+  debug = true;
+
+  /*
+   * These fifo's handle the alignment problem caused by the
+   * inherent decoding delay of the individual viterbi decoders.
+   * The net result is that this entire block has a pipeline latency
+   * of 12 complete segments.
+   *
+   * If anybody cares, it is possible to do it with less delay, but
+   * this approach is at least somewhat understandable...
+   */
+  
+  // the -4 is for the 4 sync symbols
+  int  fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay ();
+  for (int i = 0; i < NCODERS; i++)
+    fifo[i] = new fifo_t(fifo_size);
+
+  reset ();
+}
+
+atsci_viterbi_decoder::~atsci_viterbi_decoder ()
+{
+  for (int i = 0; i < NCODERS; i++)
+    delete fifo[i];
+}
+
+void
+atsci_viterbi_decoder::reset ()
+{
+  for (int i = 0; i < NCODERS; i++){
+    viterbi[i].reset ();
+    fifo[i]->reset ();
+  }
+}
+
+
+void
+atsci_viterbi_decoder::decode (atsc_mpeg_packet_rs_encoded out[NCODERS],
+                             const atsc_soft_data_segment in[NCODERS])
+{
+  unsigned char out_copy[OUTPUT_SIZE];
+  float        in_copy[INPUT_SIZE];
+
+  // copy input into continguous temporary buffer
+  for (int i = 0; i < NCODERS; i++){
+    assert (in[i].pli.regular_seg_p ());
+    memcpy (&in_copy[i * INPUT_SIZE/NCODERS],
+           &in[i].data[0],
+           ATSC_DATA_SEGMENT_LENGTH * sizeof (in_copy[0]));
+  }
+
+  memset (out_copy, 0, sizeof (out_copy));     // sanity check
+  
+  // do the deed...
+  decode_helper (out_copy, in_copy);
+
+  // copy output from contiguous temp buffer into final output
+  for (int i = 0; i < NCODERS; i++){
+    memcpy (&out[i].data[0],
+           &out_copy[i * OUTPUT_SIZE/NCODERS],
+           ATSC_MPEG_RS_ENCODED_LENGTH * sizeof (out_copy[0]));
+           
+           
+    // adjust pipeline info to reflect 12 segment delay
+    plinfo::delay (out[i].pli, in[i].pli, NCODERS);
+  }
+}
+
+void
+atsci_viterbi_decoder::decode_helper (unsigned char out[OUTPUT_SIZE],
+                                    const float symbols_in[INPUT_SIZE])
+{
+  int encoder;
+  unsigned int i;
+  int dbi;
+  int dbwhere;
+  int dbindex;
+  int shift;
+  unsigned char dibit;
+  float symbol;
+
+  /* Memset is not necessary if it's all working... */
+  memset (out, 0, OUTPUT_SIZE);
+
+#define VERBOSE 0
+
+#if 1
+  /* Check for sync symbols in the incoming data stream */
+  /* For now, all we do is complain to stdout.  FIXME, pass it back to
+     caller as an error/quality signal.  */
+  for (i = 0; i < sync_symbol_indices_max; i++) {
+    int j = sync_symbol_indices[i];
+    if (fabsf (symbols_in[j] - DSEG_SYNC_SYM1) > 1.0)
+      if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 1 at %d, expect %g, got %g.\n",
+                           j, DSEG_SYNC_SYM1, symbols_in[j]);
+    j++;
+    if (fabsf (symbols_in[j] - DSEG_SYNC_SYM2) > 1.0)
+      if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 2 at %d, expect %g, got %g.\n",
+                           j, DSEG_SYNC_SYM2, symbols_in[j]);
+    j++;
+    if (fabsf (symbols_in[j] - DSEG_SYNC_SYM3) > 1.0)
+      if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 3 at %d, expect %g, got %g.\n",
+                           j, DSEG_SYNC_SYM3, symbols_in[j]);
+    j++;
+    if (fabsf (symbols_in[j] - DSEG_SYNC_SYM4) > 1.0)
+      if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 4 at %d, expect %g, got %g.\n",
+                           j, DSEG_SYNC_SYM4, symbols_in[j]);
+  }
+#endif
+#undef VERBOSE
+
+  // printf ("@@@ DIBITS @@@\n");
+  
+  /* Now run each of the 12 Trellis encoders over their subset of
+     the input symbols */
+  for (encoder = 0; encoder < NCODERS; encoder++) {
+    dbi = 0;                   /* Reinitialize dibit index for new encoder */
+    fifo_t     *dibit_fifo = fifo[encoder];
+    
+    /* Feed all the incoming symbols into one encoder;
+       pump them into the relevant dibits. */
+    for (i = 0; i < enco_which_max; i++) {
+      symbol = symbols_in[enco_which_syms[encoder][i]];
+      dibit = dibit_fifo->stuff (viterbi[encoder].decode (symbol));
+      // printf ("%d\n", dibit);
+      /* Store the dibit into the output data segment */
+      dbwhere = enco_which_dibits[encoder][dbi++];
+      dbindex = dbwhere >> 3;
+      shift = dbwhere & 0x7;
+      out[dbindex] =
+       (out[dbindex] & ~(0x03 << shift)) | (dibit << shift);
+    } /* Symbols fed into one encoder */
+  } /* Encoders */
+
+  // fflush (stdout);
+}
diff --git a/gr-atsc/src/lib/atsci_viterbi_decoder.h b/gr-atsc/src/lib/atsci_viterbi_decoder.h
new file mode 100644 (file)
index 0000000..22e3c18
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_VITERBI_DECODER_H_
+#define _ATSC_VITERBI_DECODER_H_
+
+#define        USE_SIMPLE_SLICER  0
+
+#include <atsc_types.h>
+#include <interleaver_fifo.h>
+
+#if (USE_SIMPLE_SLICER)
+#include <atsci_fake_single_viterbi.h>
+typedef atsci_fake_single_viterbi      single_viterbi_t;
+#else
+#include <atsci_single_viterbi.h>
+typedef atsci_single_viterbi           single_viterbi_t;
+#endif
+
+/*!
+ * \brief fancy, schmancy 12-way interleaved viterbi decoder for ATSC
+ */
+
+class atsci_viterbi_decoder {
+public:
+  static const int     NCODERS = 12;
+
+  atsci_viterbi_decoder ();
+  ~atsci_viterbi_decoder ();
+
+  //! reset all decoder states
+  void reset ();
+
+  /*!
+   * Take 12 data segments of soft decisions (floats) and
+   * produce 12 RS encoded data segments.  We work in groups of 12
+   * because that's the smallest number of segments that composes a
+   * single full cycle of the decoder mux.
+   */
+  void decode (atsc_mpeg_packet_rs_encoded out[NCODERS],
+              const atsc_soft_data_segment in[NCODERS]);
+
+
+  
+ protected:
+  typedef interleaver_fifo<unsigned char>      fifo_t;
+
+  static const int SEGMENT_SIZE = ATSC_MPEG_RS_ENCODED_LENGTH; // 207
+  static const int OUTPUT_SIZE = (SEGMENT_SIZE * 12);
+  static const int INPUT_SIZE = (ATSC_DATA_SEGMENT_LENGTH * 12);
+  
+  void decode_helper (unsigned char out[OUTPUT_SIZE],
+                     const float in[INPUT_SIZE]);
+
+  
+  single_viterbi_t     viterbi[NCODERS];
+  fifo_t               *fifo[NCODERS]; 
+  bool                 debug;
+
+};
+
+
+
+#endif /* _ATSC_VITERBI_DECODER_H_ */
diff --git a/gr-atsc/src/lib/atsci_viterbi_gen.cc b/gr-atsc/src/lib/atsci_viterbi_gen.cc
new file mode 100644 (file)
index 0000000..ea5c3fa
--- /dev/null
@@ -0,0 +1,267 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#include <iostream>
+#include <stdio.h>
+
+using std::cerr;
+
+/*
+ * Trellis-encode a whole pile of 12 data segments for ATSC.
+ * This also includes scrambling the data among twelve Trellis encoders.
+ *
+ * Input is twelve 207-byte blocks of raw data (Reed-Solomon output that's
+ * been scrambled up by interleaving with other blocks).
+ *
+ * Output is 12 x 208 x 4 bytes, each byte containing a 3-bit symbol.
+ * The first 4 bytes are the segment sync symbol.
+ *
+    Got the first version of Trellis encoder coded.  Compiles, but I
+    didn't realize that each data segment contains an odd number of BITS!
+    The second data segment in a field starts by pulling bits out of the
+    middles of the bytes it's encoding.  You actually have to read all the
+    entries in that table on page 59 AND 60 to get it.
+
+    There's a 4-segment asymmetric pattern of bit accesses.
+    There's a 3-segment asymmetric pattern of muxing encoders.
+
+    The result is there's a 12-segment pattern that repeats throughout
+    the encoding of a field.  So this routine now encodes 12 segments at once.
+
+    This encoding system was either designed by a complete idiot or by
+    a complete genius.  It's highly complex when it could have been very
+    simple.  Now the question is whether
+    this incredible complexity buys us anything subtle and important.
+ */
+
+#define SEGMENT_SIZE   207
+#define        INPUT_SIZE      (SEGMENT_SIZE * 12)
+#define        DIBITS_PER_BYTE 4
+#define        EXTRAS          (4 * 12)        /* FIXME, sync symbols and such */
+#define        SYMBOLS_OUT     ((INPUT_SIZE * DIBITS_PER_BYTE) + EXTRAS)
+#define SEGOF(x)       ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))
+#define SYMOF(x)       (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4)
+#define        ENCODERS        12
+#define        ENCODER_SEG_BUMP        4
+
+
+/* Shift counts to bit numbers (high order, low order); 9x entries unused */
+static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96};
+static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96};
+
+/* Detailed Debugging */
+int debug_dec = 0;
+
+/* 
+ * Build indirect data structures to say which symbols go into which
+ * encoder, and then where the resulting dibits from the encoders go.
+ */
+int
+build_decode_structures (char *fileout)
+{
+  int retval = 0;
+  int i;
+  int encoder;
+  int trellis_wheredata[ENCODERS];
+  unsigned char *symp, *next_sym_seg;
+  unsigned char symbols[SYMBOLS_OUT];
+  int chunk;
+  int shift;
+  int skip_encoder_bump;
+  int *enco_syms[ENCODERS];
+  int *enco_dibits[ENCODERS];
+  int j;
+  /* The data structures we'll build and then spit out... */
+  int sync_symbol_indices[1000];
+  int sync_symbol_indices_max;
+  int enco_which_syms[ENCODERS][INPUT_SIZE];
+  int enco_which_dibits[ENCODERS][INPUT_SIZE];
+  int enco_which_max;
+  #define      BIT_PTR(int,shif) (((int) << 3) | ((shif) & 0x7))
+  /* Running indices into them as we build 'em... */
+  int *syncsyms = sync_symbol_indices;
+
+  /* Start our running pointers at the start of our per-encoder subarrays */
+  for (i = 0; i < ENCODERS; i++) {
+    enco_dibits[i] = enco_which_dibits[i];
+    enco_syms[i] = enco_which_syms[i];
+  }
+
+  encoder = ENCODERS - ENCODER_SEG_BUMP;
+  skip_encoder_bump = 0;
+  symp = symbols;
+  next_sym_seg = symp;
+
+  for (chunk = 0;
+       chunk < INPUT_SIZE;
+       chunk += ENCODERS) {
+    /* Associate data bytes with the Trellis encoders.
+       They get loaded or stored in an order that depends on where we are in the
+       segment sync progress (sigh). 
+       GRR!  When the chunk reload happens at the same time as the
+       segment boundary, we should bump the encoder NOW for the reload,
+       rather than LATER during the bitshift transition!!! */
+    if (symp >= next_sym_seg) {
+      encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS;
+      skip_encoder_bump = 1;
+    }
+      
+    /* Remember where the data bytes are going to go, once we've
+       accumulated them from the 12 interleaved decoders */
+    for (i = 0; i < ENCODERS; i++) {
+      trellis_wheredata[encoder] = chunk+i;
+      encoder++;
+      if (encoder >= ENCODERS) encoder = 0;
+    }
+
+    for (shift = 6; shift >= 0; shift -= 2) {
+
+      /* Segment boundaries happen to occur on some bitshift transitions. */
+      if (symp >= next_sym_seg) {
+       /* Segment transition.  Output a data segment sync symbol, and
+          mess with the trellis encoder mux.  */
+       *syncsyms++ = symp - symbols;
+       symp += 4;
+        next_sym_seg = symp + (SEGMENT_SIZE * DIBITS_PER_BYTE);
+
+       if (!skip_encoder_bump)
+         encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS;
+       skip_encoder_bump = 0;
+      }
+
+      /* Now run each of the 12 Trellis encoders to spit out 12 symbols.
+         Each encoder takes input from the same byte of the chunk, but the
+         outputs of the encoders come out in various orders.
+         NOPE -- this is false.  The encoders take input from various
+         bytes of the chunk (which changes at segment sync time), AND
+         they also come out in various orders.  You really do have to
+         keep separate track of:  the datasegs bytes, the encoders, and
+         the symbol bytes -- because they're all moving with respect to
+         each other!!!  */
+      for (i = 0; i < ENCODERS; i++) {
+        if (debug_dec)
+         printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = ",
+                 (long) SEGOF(symp-symbols), (long) SYMOF(symp-symbols),
+                 encoder, trellis_wheredata[encoder],
+                 bit1[shift], bit2[shift]);
+
+       /* Decoding:  Grab symbol, run through decoder, slice dibit into
+          buffer.  */
+       /* This symbol goes into this encoder next */
+       *(enco_syms[encoder]++) = symp - symbols;
+        symp++;
+       /* The next output from this encoder goes into these dibits */
+       *(enco_dibits[encoder]++) = BIT_PTR(trellis_wheredata[encoder], shift);
+
+        encoder++; if (encoder >= ENCODERS) encoder = 0;
+      } /* Encoders */
+    } /* Bit shifts */
+      
+#if 0
+    /* Now dump out the chunk of 12 data bytes that the twelve decoders have
+       accumulated. */
+  unsigned char trellis_buffer[ENCODERS];
+  unsigned char dibit;
+  unsigned char symbol;
+  int save_state;
+    for (i = 0; i < ENCODERS; i++) {
+      datasegs [trellis_wheredata[encoder]] = trellis_buffer[encoder];
+      encoder++;
+      if (encoder >= ENCODERS) encoder = 0;
+    } /* Dumping encoder bytes */
+#endif
+  } /* Chunks */
+  
+  /* Now print the resulting data structures in C++ */
+
+  if (!freopen(fileout, "w", stdout))
+    return 2;
+
+  printf ("/*\n\
+ * atsc_viterbi_mux.cc\n\
+ *\n\
+ * Data structures for knowing which symbols are fed to which\n\
+ * Viterbi decoders, and then where to put the resulting output dibits.\n\
+ *\n\
+ * Generated by 'atsc_viterbi_gen.cc'.\n\
+ */\n\n");
+  sync_symbol_indices_max = syncsyms - sync_symbol_indices;
+  printf ("const unsigned int sync_symbol_indices_max = %d;\n",
+         sync_symbol_indices_max);
+  printf ("const unsigned int sync_symbol_indices[%d] = {\n  ",
+         sync_symbol_indices_max);
+  for (i = 0; i < sync_symbol_indices_max; i++) {
+    printf ("%d,%s", sync_symbol_indices[i], (7 == i%8)? "\n  ": " ");
+  }
+  printf ("};\n\n");
+
+  enco_which_max = enco_dibits[0] - enco_which_dibits[0];
+  for (i = 0; i < ENCODERS; i++) 
+    if (enco_which_max != enco_dibits[i] - enco_which_dibits[i]) {
+      cerr << "Encoder " << i << " has different max_dibits " <<
+       enco_dibits[i] - enco_which_dibits[i] << " than " << enco_which_max;
+      retval = 3;
+    }
+
+  printf ("const unsigned int enco_which_max = %d;\n" , enco_which_max);
+
+  printf ("const unsigned int enco_which_syms[%d][%d] = {\n",
+         ENCODERS, enco_which_max);
+  for (i = 0; i < ENCODERS; i++) {
+    printf ("  /* %d */\n  {", i);
+    for (j = 0; j < enco_which_max; j++)
+      printf ("%d,%s", enco_which_syms[i][j], (7 == j%8)? "\n   ": " ");
+    printf ("},\n");
+  }
+  printf ("};\n\n");
+
+  printf ("const unsigned int enco_which_dibits[%d][%d] = {\n",
+         ENCODERS, enco_which_max);
+  for (i = 0; i < ENCODERS; i++) {
+    printf ("  /* %d */\n  {", i);
+    for (j = 0; j < enco_which_max; j++)
+      printf ("%d,%s", enco_which_dibits[i][j], (7 == j%8)? "\n   ": " ");
+    printf ("},\n");
+  }
+  printf ("};\n\n");
+  return retval;
+}
+
+int
+usage()
+{ 
+  cerr << "atsc_viterbi_gen: Usage:\n";
+  cerr << "  ./atsc_viterbi_gen -o atsc_viterbi_mux.cc\n";
+  cerr << "That's all, folks!\n";
+  return 1;
+}
+
+
+int
+main(int argc, char **argv) 
+{
+  if (argc != 3) return usage();
+  if (argv[1][0] != '-'
+   || argv[1][1] != 'o'
+   || argv[1][2] != 0   ) return usage();
+  return build_decode_structures(argv[2]);
+}
diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.cc b/gr-atsc/src/lib/atsci_vsbtx_lp.cc
new file mode 100644 (file)
index 0000000..224d29a
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <atsc_consts.h>
+#include <atsci_vsbtx_lp.h>
+#include <stdexcept>
+#include <cmath>
+#include <iostream>
+
+using std::vector;
+using std::cerr;
+using std::endl;
+
+// atsc root raised cosine filter, sampling rate = 21.52 MHz
+static const float atsc_vsbtx_lp2x[] = {
+#include "atsc_vsbtx_lp.dat"
+};
+
+#define NELEM(x) (sizeof (x) / sizeof ((x)[0]))
+
+// is a within 5% of target?
+
+static bool 
+close_enough_p (double a, double target)
+{
+  double delta = fabs (target * 0.05); //  5 percent
+
+  return fabs (target - a) <= delta;
+}
+
+vector<float> 
+atsc_vsbtx_lp::taps (double sampling_freq)
+{
+  if (close_enough_p (sampling_freq, 2 * ATSC_SYMBOL_RATE)){
+    return vector<float>(&atsc_vsbtx_lp2x[0], &atsc_vsbtx_lp2x[NELEM(atsc_vsbtx_lp2x)]);
+  }
+  else
+    throw std::out_of_range (
+     "atsc_vsbtx_lp: no pre-designed filter close enough");
+}
diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.dat b/gr-atsc/src/lib/atsci_vsbtx_lp.dat
new file mode 100644 (file)
index 0000000..448fda7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * FILTER SPECIFICATION FILE
+ * FILTER TYPE:LOW PASS                       1H
+ * PASSBAND RIPPLE IN -dB            -.0100
+ * STOPBAND RIPPLE IN -dB          -76.0000
+ * PASSBAND CUTOFF FREQUENCY    .250000     HERTZ              
+ * STOPBAND CUTOFF FREQUENCY    .360000     HERTZ              
+ * SAMPLING FREQUENCY           1.00000     HERTZ              
+ */
+/*
+ * gain of 2
+ */
+    9.23312269151211e-04,
+    8.75200144946575e-04,
+   -2.89211887866259e-03,
+    1.31580047309399e-04,
+    6.72745611518621e-03,
+   -5.82943391054869e-03,
+   -8.86140950024128e-03,
+    1.84674616903067e-02,
+    1.27039104700089e-03,
+   -3.39064113795757e-02,
+    2.52537783235312e-02,
+    3.74889532104135e-02,
+   -7.35438484698534e-02,
+   -3.70154529809952e-03,
+    1.33745657280087e-01,
+   -1.12098718993366e-01,
+   -1.84760546311736e-01,
+    5.98605459555984e-01,
+    1.20420956425369e+00,
+    5.98605459555984e-01,
+   -1.84760546311736e-01,
+   -1.12098718993366e-01,
+    1.33745657280087e-01,
+   -3.70154529809952e-03,
+   -7.35438484698534e-02,
+    3.74889532104135e-02,
+    2.52537783235312e-02,
+   -3.39064113795757e-02,
+    1.27039104700089e-03,
+    1.84674616903067e-02,
+   -8.86140950024128e-03,
+   -5.82943391054869e-03,
+    6.72745611518621e-03,
+    1.31580047309399e-04,
+   -2.89211887866259e-03,
+    8.75200144946575e-04,
+    9.23312269151211e-04
diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.h b/gr-atsc/src/lib/atsci_vsbtx_lp.h
new file mode 100644 (file)
index 0000000..7193c87
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _ATSC_VSBTX_LP_H_
+#define _ATSC_VSBTX_LP_H_
+
+#include <gr_fir_builder.h>
+
+class atsc_vsbtx_lp : public gr_fir_builder
+{
+public:
+  virtual std::vector<float> taps (double sampling_freq);
+};
+
+
+
+#endif /* _ATSC_VSBTX_LP_H_ */
diff --git a/gr-atsc/src/lib/convolutional_interleaver.h b/gr-atsc/src/lib/convolutional_interleaver.h
new file mode 100644 (file)
index 0000000..0b5ae6f
--- /dev/null
@@ -0,0 +1,126 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _CONVOLUTIONAL_INTERLEAVER_H_
+#define _CONVOLUTIONAL_INTERLEAVER_H_
+
+#include <vector>
+#include <interleaver_fifo.h>
+#include <assert.h>
+
+/*!
+ * \brief template class for generic convolutional interleaver
+ */
+
+template<class symbol_type>
+class convolutional_interleaver {
+ public:
+
+  convolutional_interleaver (bool interleave_p, int nbanks, int fifo_size_incr);
+  virtual ~convolutional_interleaver ();
+
+  //! reset interleaver (flushes contents and resets commutator)
+  void reset ();
+  
+  //! sync interleaver (resets commutator, but doesn't flush fifos)
+  void sync () { m_commutator = 0; }
+
+  //! return end to end delay in symbols (delay through concatenated interleaver / deinterleaver)
+  int end_to_end_delay ();
+
+  //! transform a single symbol
+  symbol_type transform (symbol_type input){
+    symbol_type retval = m_fifo[m_commutator]->stuff (input);
+    m_commutator++;
+    if (m_commutator >= m_nbanks)
+      m_commutator = 0;
+    return retval;
+  }
+
+  //! transform a bunch of symbols
+  void transform (symbol_type *out, const symbol_type *in, int nsymbols);
+
+protected:
+  int  m_commutator;
+  int  m_nbanks;
+  int  m_fifo_size_incr;
+  std::vector<interleaver_fifo<symbol_type> *> m_fifo;
+};
+
+template<class symbol_type>
+convolutional_interleaver<symbol_type>::convolutional_interleaver (
+                                          bool interleave_p,
+                                          int nbanks,
+                                          int fifo_size_incr)
+{
+  assert (nbanks >= 1);
+  assert (fifo_size_incr >= 1);
+
+  m_nbanks = nbanks;
+  m_fifo_size_incr = fifo_size_incr;
+
+  m_fifo.resize (nbanks);
+  
+  if (interleave_p){   // configure as interleaver
+    for (int i = 0; i < nbanks; i++)
+      m_fifo[i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr);
+  }
+  else {               // configure as de-interleaver
+    for (int i = 0; i < nbanks; i++)
+      m_fifo[nbanks - 1 - i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr);
+  }
+  sync ();
+}
+
+template<class symbol_type>
+convolutional_interleaver<symbol_type>::~convolutional_interleaver ()
+{
+  for (int i = 0; i < m_nbanks; i++)
+    delete m_fifo[i];
+}
+
+template<class symbol_type> void
+convolutional_interleaver<symbol_type>::reset ()
+{
+  sync ();
+  for (int i = 0; i < m_nbanks; i++)
+    m_fifo[i]->reset ();
+}
+
+template<class symbol_type> int
+convolutional_interleaver<symbol_type>::end_to_end_delay ()
+{
+  int m = m_nbanks * m_fifo_size_incr;
+  return m * (m_nbanks - 1);
+}
+
+template<class symbol_type> void
+convolutional_interleaver<symbol_type>::transform (symbol_type *out,
+                                                  const symbol_type *in,
+                                                  int nsymbols)
+{
+  // we may want to unroll this a couple of times...
+  for (int i = 0; i < nsymbols; i++)
+    out[i] = transform (in[i]);
+}
+
+#endif /* _CONVOLUTIONAL_INTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/create_atsci_equalizer.cc b/gr-atsc/src/lib/create_atsci_equalizer.cc
new file mode 100644 (file)
index 0000000..bc4eecf
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <create_atsci_equalizer.h>
+#include <atsci_equalizer_nop.h>
+#include <atsci_equalizer_lms.h>
+#include <atsci_equalizer_lms2.h>
+
+atsci_equalizer *
+create_atsci_equalizer_nop ()
+{
+  return new atsci_equalizer_nop ();
+}
+
+atsci_equalizer *
+create_atsci_equalizer_lms ()
+{
+  return new atsci_equalizer_lms ();
+}
+
+atsci_equalizer *
+create_atsci_equalizer_lms2 ()
+{
+  return new atsci_equalizer_lms2 ();
+}
diff --git a/gr-atsc/src/lib/create_atsci_equalizer.h b/gr-atsc/src/lib/create_atsci_equalizer.h
new file mode 100644 (file)
index 0000000..57c167f
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _CREATE_ATSC_EQUALIZER_H_
+#define _CREATE_ATSC_EQUALIZER_H_
+
+class atsci_equalizer;
+
+atsci_equalizer *create_atsci_equalizer_nop ();
+atsci_equalizer *create_atsci_equalizer_lms ();
+atsci_equalizer *create_atsci_equalizer_lms2 ();
+
+#endif /* _CREATE_ATSC_EQUALIZER_H_ */
diff --git a/gr-atsc/src/lib/create_atsci_fs_checker.cc b/gr-atsc/src/lib/create_atsci_fs_checker.cc
new file mode 100644 (file)
index 0000000..107e35c
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <create_atsci_fs_checker.h>
+#include <atsci_fs_checker_naive.h>
+
+atsci_fs_checker *
+create_atsci_fs_checker ()
+{
+  return new atsci_fs_checker_naive ();
+}
diff --git a/gr-atsc/src/lib/create_atsci_fs_checker.h b/gr-atsc/src/lib/create_atsci_fs_checker.h
new file mode 100644 (file)
index 0000000..d087450
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _CREATE_ATSC_FS_CHECKER_H_
+#define _CREATE_ATSC_FS_CHECKER_H_
+
+class atsci_fs_checker;
+
+/*!
+ * Factory that creates appropriate atsci_fs_checker
+ */
+atsci_fs_checker *create_atsci_fs_checker ();
+
+
+#endif /* _CREATE_ATSC_FS_CHECKER_H_ */
diff --git a/gr-atsc/src/lib/create_atsci_fs_correlator.cc b/gr-atsc/src/lib/create_atsci_fs_correlator.cc
new file mode 100644 (file)
index 0000000..6f65a7e
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <create_atsci_fs_correlator.h>
+#include <atsci_fs_correlator_naive.h>
+
+atsci_fs_correlator *
+create_atsci_fs_correlator ()
+{
+  return new atsci_fs_correlator_naive ();
+}
diff --git a/gr-atsc/src/lib/create_atsci_fs_correlator.h b/gr-atsc/src/lib/create_atsci_fs_correlator.h
new file mode 100644 (file)
index 0000000..9162be8
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _CREATE_ATSC_FS_CORRELATOR_H_
+#define _CREATE_ATSC_FS_CORRELATOR_H_
+
+class atsci_fs_correlator;
+
+/*!
+ * Factory that creates appropriate atsci_fs_correlator
+ */
+atsci_fs_correlator *create_atsci_fs_correlator ();
+
+
+#endif /* _CREATE_ATSC_FS_CORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/fpll_btloop_coupling.h b/gr-atsc/src/lib/fpll_btloop_coupling.h
new file mode 100644 (file)
index 0000000..e17425d
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _FPLL_BTLOOP_COUPLING_H_
+#define _FPLL_BTLOOP_COUPLING_H_
+
+/*!
+ * Magic coupling constant between GrAtscFPLL and GrAtscBitTimingLoop.
+ * Trust me, you don't want to mess with this.
+ *
+ * The agc block buried in the FPLL indirectly sets the level of the input
+ * to the bit timing loop.  The bit timing loop's convergence properties
+ * depend on the the mean amplitude of it's input.  This constant ties
+ * them together such that you can tweak the input level of the bit timing loop
+ * (somewhat) without screwing everything.
+ */
+
+static const float FPLL_BTLOOP_COUPLING_CONST = 3.125;
+
+#endif /* _FPLL_BTLOOP_COUPLING_H_ */
diff --git a/gr-atsc/src/lib/gen_encoder.py b/gr-atsc/src/lib/gen_encoder.py
new file mode 100755 (executable)
index 0000000..4356cdc
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+#
+# Copyright 2002 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 output(input, state):
+    x2 = (input >> 1) & 0x1
+    x1 = (input >> 0) & 0x1
+    s = (state >> 2) & 0x1
+    t = (state >> 1) & 0x1
+    u = (state >> 0) & 0x1
+
+    z0 = u
+    z1 = x1
+    z2 = x2 ^ s
+    return (z2 << 2) | (z1 << 1) | z0
+
+
+def next_state(input, state):
+    x2 = (input >> 1) & 0x1
+    x1 = (input >> 0) & 0x1
+    s0 = (state >> 2) & 0x1
+    t0 = (state >> 1) & 0x1
+    u0 = (state >> 0) & 0x1
+
+    s1 = x2 ^ s0
+    t1 = u0
+    u1 = t0 ^ x1
+    
+    return (s1 << 2) | (t1 << 1) | u1
+
+print "@@@ NEXT @@@"
+
+for i in range (32):
+    state = (i >> 2) & 0x7
+    input = i & 0x3
+    print next_state (input, state)
+
+
+print "@@@ OUTPUT @@@"
+
+for i in range (32):
+    state = (i >> 2) & 0x7
+    input = i & 0x3
+    print output (input, state)
+    
diff --git a/gr-atsc/src/lib/interleaver_fifo.h b/gr-atsc/src/lib/interleaver_fifo.h
new file mode 100644 (file)
index 0000000..98764af
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _INTERLEAVER_FIFO_H_
+#define _INTERLEAVER_FIFO_H_
+
+
+#include <interleaver_fifo.h>
+#include <string.h>
+#include <strings.h>
+
+/*!
+ * \brief template class for interleaver fifo
+ */
+
+template<class symbol_type>
+class interleaver_fifo {
+ public:
+
+  interleaver_fifo (unsigned int size);
+  ~interleaver_fifo ();
+
+  //! reset interleaver (flushes contents and resets commutator)
+  void reset ();
+  
+  //! stuff a symbol into the fifo and return the oldest
+  symbol_type stuff (symbol_type input){
+    if (m_size == 0)
+      return input;
+
+    symbol_type retval = m_fifo[m_position];
+    m_fifo[m_position] = input;
+    m_position++;
+    if (m_position >= m_size)
+      m_position = 0;
+
+    return retval;
+  }
+
+protected:
+  unsigned int m_size;
+  unsigned int m_position;
+  symbol_type  *m_fifo;
+};
+
+template<class symbol_type>
+interleaver_fifo<symbol_type>::interleaver_fifo (unsigned int size)
+{
+  m_size = size;
+  m_position = 0;
+  m_fifo = new symbol_type[size];
+  memset (m_fifo, 0, m_size * sizeof (symbol_type));
+}
+
+template<class symbol_type>
+interleaver_fifo<symbol_type>::~interleaver_fifo ()
+{
+  delete [] m_fifo;
+}
+
+template<class symbol_type> void
+interleaver_fifo<symbol_type>::reset ()
+{
+  m_position = 0;
+  memset (m_fifo, 0, m_size * sizeof (symbol_type));
+}
+
+#endif /* _INTERLEAVER_FIFO_H_ */
diff --git a/gr-atsc/src/lib/plinfo.cc b/gr-atsc/src/lib/plinfo.cc
new file mode 100644 (file)
index 0000000..905037b
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#include <atsc_types.h>
+#include <assert.h>
+
+void
+plinfo::delay (plinfo &out, const plinfo &in, int nsegs_of_delay)
+{
+  assert (in.regular_seg_p ());
+  assert (nsegs_of_delay >= 0);
+  
+  int  s = in.segno ();
+  if (in.in_field2_p ())
+    s += ATSC_DSEGS_PER_FIELD;
+
+  s -= nsegs_of_delay;
+  if (s < 0)
+    s += 2 * ATSC_DSEGS_PER_FIELD;
+
+  assert (0 <= s && s < 2 * ATSC_DSEGS_PER_FIELD);
+
+  if (s < ATSC_DSEGS_PER_FIELD)
+    out.set_regular_seg (false, s);                            // field 1
+  else
+    out.set_regular_seg (true, s - ATSC_DSEGS_PER_FIELD);      // field 2
+}
+
+void
+plinfo::sanity_check (const plinfo &x)
+{
+  // basic sanity checks...
+  assert (x.segno () >= 0);
+  assert (x.segno () < (unsigned) ATSC_DSEGS_PER_FIELD);
+  assert ((x.flags () & ~0x3f) == 0);
+
+  assert (x.regular_seg_p () ^ x.field_sync_p ());
+  assert ((x.segno () != 0) ^ x.first_regular_seg_p ());
+}
+
diff --git a/gr-atsc/src/lib/qa_atsci.cc b/gr-atsc/src/lib/qa_atsci.cc
new file mode 100644 (file)
index 0000000..262b528
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2002 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 class gathers together all the test cases for the atsc
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_atsci.h>
+#include <qa_atsci_randomizer.h>
+#include <qa_atsci_reed_solomon.h>
+#include <qa_interleaver_fifo.h>
+#include <qa_convolutional_interleaver.h>
+#include <qa_atsci_data_interleaver.h>
+#include <qa_atsci_basic_trellis_encoder.h>
+#include <qa_atsci_sliding_correlator.h>
+#include <qa_atsci_fake_single_viterbi.h>
+#include <qa_atsci_single_viterbi.h>
+#include <qa_atsci_trellis_encoder.h>
+#include <qa_atsci_viterbi_decoder.h>
+#include <qa_atsci_fs_correlator.h>
+#include <qa_atsci_equalizer_nop.h>
+
+CppUnit::TestSuite *
+qa_atsc::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("atsc");
+
+  s->addTest (qa_atsci_randomizer::suite ());
+  s->addTest (qa_atsci_reed_solomon::suite ());
+  s->addTest (qa_interleaver_fifo::suite ());
+  s->addTest (qa_convolutional_interleaver::suite ());
+  s->addTest (qa_atsci_data_interleaver::suite ());
+  s->addTest (qa_atsci_basic_trellis_encoder::suite ());
+  s->addTest (qa_atsci_sliding_correlator::suite ());
+  s->addTest (qa_atsci_fake_single_viterbi::suite ());
+  s->addTest (qa_atsci_single_viterbi::suite ());
+  s->addTest (qa_atsci_trellis_encoder::suite ());
+  s->addTest (qa_atsci_viterbi_decoder::suite ());
+  s->addTest (qa_atsci_fs_correlator::suite ());
+  s->addTest (qa_atsci_equalizer_nop::suite ());
+  
+  return s;
+}
diff --git a/gr-atsc/src/lib/qa_atsci.h b/gr-atsc/src/lib/qa_atsci.h
new file mode 100644 (file)
index 0000000..abf3aab
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_H_
+#define _QA_ATSC_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the dtv directory
+
+class qa_atsc {
+ public:
+  //! return suite of tests for all of dtv directory
+  static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_ATSC_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc
new file mode 100644 (file)
index 0000000..c7ed016
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_basic_trellis_encoder.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void
+qa_atsci_basic_trellis_encoder::t0 ()
+{
+  const static unsigned char in[14] = {
+    0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 2, 3
+  };
+
+  const static unsigned char expected_out[14] = {
+    0, 2, 3, 1, 1, 3, 0, 1, 2, 0, 0, 2, 5, 2
+  };
+
+  for (unsigned i = 0; i < sizeof (in); i++)
+    CPPUNIT_ASSERT_EQUAL ((int) expected_out[i], enc.encode (in[i]));
+
+  // reset encoder and test again.
+
+  enc.reset ();
+  for (unsigned i = 0; i < sizeof (in); i++)
+    CPPUNIT_ASSERT_EQUAL ((int) expected_out[i], enc.encode (in[i]));
+}
+
+
+void
+qa_atsci_basic_trellis_encoder::t1 ()
+{
+  // Print data to externally check distribution.
+  // looks OK.
+#if 0
+  srandom (27);
+
+  for (int i = 0; i < 8192; i++){
+    int        t = (random () >> 10) & 0x3;    // 2 random bits
+    printf ("%d  %d\n", t, enc.encode (t));
+  }
+#endif
+}
diff --git a/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h
new file mode 100644 (file)
index 0000000..1ac4867
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _QA_ATSC_BASIC_TRELLIS_ENCODER_H_
+#define _QA_ATSC_BASIC_TRELLIS_ENCODER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <atsci_basic_trellis_encoder.h>
+
+class qa_atsci_basic_trellis_encoder : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_atsci_basic_trellis_encoder);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_basic_trellis_encoder  enc;
+
+  void t0 ();
+  void t1 ();
+};
+
+#endif /* _QA_ATSC_BASIC_TRELLIS_ENCODER_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_data_interleaver.cc b/gr-atsc/src/lib/qa_atsci_data_interleaver.cc
new file mode 100644 (file)
index 0000000..e76a2f1
--- /dev/null
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_data_interleaver.h>
+#include <string.h>
+
+
+/*!
+ * write an easy to identify pattern into the packet
+ */
+void
+qa_atsci_data_interleaver::init_test_packet (int counter,
+                                           atsc_mpeg_packet_rs_encoded &out)
+{
+  out.data[0] = 0xf0;
+  out.data[1] = 0xff;
+  out.data[2] = (counter >> 8) & 0xff;
+  out.data[3] = counter & 0xff;
+
+  for (int i = 4; i < 205; i++)
+    out.data[i] = i;
+
+  out.data[205] = 0xa0;
+  out.data[206] = 0xaf;
+}
+
+void
+qa_atsci_data_interleaver::print_packet (FILE *fp,
+                                       int frame_number,
+                                       int field_number,
+                                       int segment_number,
+                                       const atsc_mpeg_packet_rs_encoded &in)
+{
+  fprintf (fp, "%04d:%d:%03d  ", frame_number, field_number, segment_number);
+
+  const unsigned char *p = &in.data[0];
+  for (int i = 0; i < 8; i++)
+    fprintf (fp, "%02X", p[i]);
+
+  fprintf (fp, "  ");
+  p = &in.data[8];
+  for (int i = 0; i < 8; i++)
+    fprintf (fp, "%02X", p[i]);
+
+  
+  fprintf (fp, "  ...  ");
+  p = &in.data[191];
+  for (int i = 0; i < 8; i++)
+    fprintf (fp, "%02X", p[i]);
+
+  fprintf (fp, "  ");
+  p = &in.data[199];
+  for (int i = 0; i < 8; i++)
+    fprintf (fp, "%02X", p[i]);
+
+  fprintf (fp, "\n");
+}
+
+void
+qa_atsci_data_interleaver::chk_assert (const atsc_mpeg_packet_rs_encoded &expected,
+                                     const atsc_mpeg_packet_rs_encoded &actual)
+{
+  if (expected == actual)
+    return;
+
+  FILE *fp = stderr;
+
+  fprintf (fp, "Expected: ");
+  print_packet (fp, 0, 0, 0, expected);
+
+  fprintf (fp, "Actual:   ");
+  print_packet (fp, 0, 0, 0, actual);
+
+  CPPUNIT_ASSERT (expected == actual);
+}
+
+void
+qa_atsci_data_interleaver::t0 ()
+{
+  int  counter = 0;
+  atsc_mpeg_packet_rs_encoded  in, enc, out;
+  atsc_mpeg_packet_rs_encoded  zero;
+
+  memset (&zero, 0, sizeof (zero));
+  
+  for (int frame = 0; frame < 4; frame++){
+    for (int field = 0; field < 2; field++){
+      for (int segment = 0; segment < 312; segment++, counter++){
+
+       // build test packet
+       init_test_packet (counter, in);
+       in.pli.set_regular_seg (field == 1, segment);
+
+       // interleave it
+       outbound.interleave (enc, in);
+
+       // deinterleave it
+       inbound.deinterleave (out, enc);
+
+       if (counter < 52)
+         // CPPUNIT_ASSERT (zero == out);
+         chk_assert (zero, out);
+
+       else if (counter >= 52){
+         atsc_mpeg_packet_rs_encoded expected;
+         init_test_packet (counter - 52, expected);
+         // CPPUNIT_ASSERT (expected == out);
+         chk_assert (expected, out);
+       }
+      }
+    }
+  }
+}
+
+//
+// Note, this assumes that the interleaver and deinterleaver
+// have the state left by t0.
+//
+// This test pushes crap into the interleaver, and then confirms that
+// the deinterleaver recovers.  This would be part of what you'd see
+// on a channel change.
+//
+
+void
+qa_atsci_data_interleaver::t1 ()
+{
+  int  counter = 0;
+  atsc_mpeg_packet_rs_encoded  in, enc, out;
+  atsc_mpeg_packet_rs_encoded  zero;
+
+  memset (&zero, 0, sizeof (zero));
+  
+  static const int NCRAP = 13;
+  
+  // push NCRAP segments of crap into the interleaver,
+  // but don't change the deinterleaver state
+
+  for (int i = 0; i < NCRAP; i++){
+    init_test_packet (i + 2758, in);
+    in.pli.set_regular_seg (false, i + 5);
+
+    outbound.interleave (enc, in);
+  }
+
+  // now run the normal test.
+  // we should get good segments after NCRAP + 52
+  
+  int starting_counter = 3141;
+  counter = starting_counter;
+
+  for (int frame = 0; frame < 4; frame++){
+    for (int field = 0; field < 2; field++){
+      for (int segment = 0; segment < 312; segment++, counter++){
+
+       // build test packet
+       init_test_packet (counter, in);
+       in.pli.set_regular_seg (field == 1, segment);
+
+       // interleave it
+       outbound.interleave (enc, in);
+
+       // deinterleave it
+       inbound.deinterleave (out, enc);
+
+       if (counter < starting_counter + 52 + NCRAP){
+         // don't care...
+       }
+       else if (counter >= starting_counter + 52 + NCRAP){
+         atsc_mpeg_packet_rs_encoded expected;
+         init_test_packet (counter - 52, expected);
+         // CPPUNIT_ASSERT (expected == out);
+         chk_assert (expected, out);
+       }
+      }
+    }
+  }
+}
diff --git a/gr-atsc/src/lib/qa_atsci_data_interleaver.h b/gr-atsc/src/lib/qa_atsci_data_interleaver.h
new file mode 100644 (file)
index 0000000..c5088bb
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_DATA_INTERLEAVER_H_
+#define _QA_ATSC_DATA_INTERLEAVER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdio.h>
+
+#include <atsci_data_interleaver.h>
+
+class qa_atsci_data_interleaver : public CppUnit::TestCase {
+ public:
+
+  void setUp (){
+    outbound.reset ();
+    inbound.reset ();
+  }
+
+  CPPUNIT_TEST_SUITE (qa_atsci_data_interleaver);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_data_interleaver               outbound;
+  atsci_data_deinterleaver     inbound;
+  
+  void t0 ();
+  void t1 ();
+
+  void init_test_packet (int counter, atsc_mpeg_packet_rs_encoded &out);
+  void print_packet (FILE *fp, int frame_number, int field_number, int segment_number,
+                    const atsc_mpeg_packet_rs_encoded &in);
+  void chk_assert (const atsc_mpeg_packet_rs_encoded &expected,
+                  const atsc_mpeg_packet_rs_encoded &actual);
+};
+
+
+#endif /* _QA_ATSC_DATA_INTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_equalizer_nop.cc b/gr-atsc/src/lib/qa_atsci_equalizer_nop.cc
new file mode 100644 (file)
index 0000000..85584f5
--- /dev/null
@@ -0,0 +1,247 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_atsci_equalizer_nop.h>
+#include <atsci_equalizer.h>
+#include <atsci_equalizer_nop.h>
+#include <atsci_pnXXX.h>
+#include <atsc_types.h>
+#include <cppunit/TestAssert.h>
+#include <assert.h>
+#include <iostream>
+#include <string.h>
+
+using std::cerr;
+using std::endl;
+
+
+static const int SYMBOLS_PER_FIELD = (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH;
+static const int PAD = 500;
+static const int NFIELDS = 2;
+
+static const int INPUT_SIZE = PAD + (NFIELDS * SYMBOLS_PER_FIELD);
+
+static float
+bin_map (int bit)
+{
+  return bit ? +5 : -5;
+}
+
+static void
+init_tags (atsc::syminfo *tags, int segnum, int fieldnum)
+{
+  int  i;
+
+  for (i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++){
+    tags[i].symbol_num = i;
+    tags[i].segment_num = segnum;
+    tags[i].field_num = fieldnum;
+    tags[i].valid = 1;
+  }
+}
+
+static void
+init_data_seg (float *p, atsc::syminfo *tags, int v, int segnum, int fieldnum)
+{
+  init_tags (tags, segnum, fieldnum);
+
+  int  i = 0;
+
+  p[i++] = bin_map (1);                        // data segment sync pulse
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  for (; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+    p[i] = (float) (i + v);
+}
+
+static void
+init_field_sync_tags (atsc::syminfo *tags, int fieldnum)
+{
+  init_tags (tags, atsc::SI_FIELD_SYNC_SEGMENT_NUM, fieldnum);
+}
+
+static void
+init_field_sync_common (float *p, int mask)
+                       
+{
+  int  i = 0;
+
+  p[i++] = bin_map (1);                        // data segment sync pulse
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  for (int j = 0; j < 511; j++)                // PN511
+    p[i++] = bin_map (atsc_pn511[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63, toggled on field 2
+    p[i++] = bin_map (atsc_pn63[j] ^ mask);
+  
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map (atsc_pn63[j]);
+
+  p[i++] = bin_map (0);                        // 24 bits of VSB8 mode identifiera
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (0);
+
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (1);
+
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+  p[i++] = bin_map (1);
+  p[i++] = bin_map (0);
+
+
+  for (int j = 0; j < 92; j++)         // 92 more bits
+    p[i++] = bin_map (atsc_pn63[j % 63]);
+
+  // now copy the last 12 symbols of the previous segment
+  // bogus fill
+
+  for (int j = 0; j < 12; j++)
+    p[i++] = bin_map (j & 1);
+
+  assert (i == ATSC_DATA_SEGMENT_LENGTH);
+}
+
+void
+qa_atsci_equalizer_nop::setUp ()
+{
+  eq = new atsci_equalizer_nop ();
+}
+
+void
+qa_atsci_equalizer_nop::tearDown ()
+{
+  delete eq;
+  eq = 0;
+}
+
+static void
+setup_test_data (float *data, atsc::syminfo *tags)
+{
+  int  mask = 0;
+  int  i = 0;
+
+  for (i = 0; i < PAD; i++){
+    data[i] = (float) i;
+    tags[i].symbol_num = 13 + i;
+    tags[i].segment_num = 17;
+    tags[i].field_num = 0;
+    tags[i].valid = 1;
+  }
+
+  for (int nfields = 0; nfields < NFIELDS; nfields++){
+    init_field_sync_common (&data[i], mask);
+    init_field_sync_tags (&tags[i], mask);
+    i += ATSC_DATA_SEGMENT_LENGTH;
+
+    for (int segnum = 0; segnum < 312; segnum++){
+      init_data_seg (&data[i], &tags[i], i, segnum, mask);
+      i += ATSC_DATA_SEGMENT_LENGTH;
+    }
+    mask ^= 1;
+  }
+  assert (i == INPUT_SIZE);
+}
+
+void
+qa_atsci_equalizer_nop::t0 ()
+{
+  // these are dynamically allocated because they are bigger
+  // than the default stack limit.
+
+  float         *input_data = new float[INPUT_SIZE];
+  atsc::syminfo *input_tags = new atsc::syminfo[INPUT_SIZE];
+  float         *output_data = new float[INPUT_SIZE];
+
+  try {
+
+    memset (input_data, 0, sizeof (input_data));
+    memset (input_tags, 0, sizeof (input_tags));
+    memset (output_data, 0, sizeof (output_data));
+
+    setup_test_data (input_data, input_tags);
+
+    eq->filter (input_data, input_tags,
+               output_data, INPUT_SIZE);
+
+
+    // now check that data values got copied correctly
+
+    for (int i = 0; i < INPUT_SIZE; i++){
+
+      if (input_tags[i].segment_num == atsc::SI_FIELD_SYNC_SEGMENT_NUM){
+       // ignore entire field sync data segment
+      }
+      else if (input_tags[i].symbol_num <= 3){
+       // ignore 4 symbols of data segment sync (+5, -5, -5, +5)
+      }
+      else {
+       if (output_data[i] != (float) i){
+         cerr << "output_data[" << i << "] == " << output_data[i] << endl;
+         CPPUNIT_ASSERT_DOUBLES_EQUAL ((float) i, output_data[i], 1e-6);
+       }
+      }
+    }
+
+    delete [] input_data;
+    delete [] input_tags;
+    delete [] output_data;
+  }
+
+  catch ( ... ){
+    delete [] input_data;
+    delete [] input_tags;
+    delete [] output_data;
+  }
+}
+
+void
+qa_atsci_equalizer_nop::t1 ()
+{
+  // think of another test...
+}
diff --git a/gr-atsc/src/lib/qa_atsci_equalizer_nop.h b/gr-atsc/src/lib/qa_atsci_equalizer_nop.h
new file mode 100644 (file)
index 0000000..a0d23da
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_EQUALIZER_NOP_H_
+#define _QA_ATSC_EQUALIZER_NOP_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class atsci_equalizer;
+
+class qa_atsci_equalizer_nop : public CppUnit::TestCase {
+private:
+  atsci_equalizer      *eq;
+
+public:
+  void setUp ();
+  void tearDown ();
+
+  CPPUNIT_TEST_SUITE (qa_atsci_equalizer_nop);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+private:
+
+  void t0 ();
+  void t1 ();
+
+};
+
+#endif /* _QA_ATSC_EQUALIZER_NOP_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc
new file mode 100644 (file)
index 0000000..f50f3b6
--- /dev/null
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+#include <atsci_fake_single_viterbi.h>
+#include <qa_atsci_fake_single_viterbi.h>
+#include <random.h>
+#include <string.h>
+
+
+static const int NTRIALS     =   50;
+static const int MAXERRORS   =   10;
+static const int NN          =  200;
+
+static const int MAXDIBIT    = 3;
+
+void
+qa_atsci_fake_single_viterbi::encode_block (unsigned char *out, unsigned char *in, 
+                                     unsigned int n)
+{
+  for (unsigned int i = 0; i < n; i++) {
+    out[i] = encoder.encode(in[i]);
+  }
+}
+
+
+void
+qa_atsci_fake_single_viterbi::decode_block (unsigned char *out, unsigned char *in, 
+                                     unsigned int n)
+{
+  for (unsigned int i = 0; i < n; i++) {
+    out[i] = decoder.decode ((2*in[i]-7) + noise ());
+  }
+}
+
+float
+qa_atsci_fake_single_viterbi::noise ()
+{
+#if 1
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5);;
+#else
+  return 0;
+#endif
+}
+
+void
+qa_atsci_fake_single_viterbi::t0 ()
+{
+  int                    blocklen = NN;
+  unsigned char                  in[blocklen];
+  unsigned char                  enc[blocklen];
+  unsigned char                  out[blocklen];
+  int                    decoder_errors = 0;
+  int                    delay = decoder.delay ();
+  int                    i;
+
+  // printf ("  Delay is %d.\n", delay);
+  
+  srandom (27);                // reproducable sequence of "random" values
+  
+  for (int nt = 0; nt < NTRIALS; nt++){
+
+    // load block with random data and encode
+
+    for (i = 0; i < (blocklen-delay); i++)
+      in[i] = random () & MAXDIBIT;
+    for (     ; i < blocklen; i++)
+      in[i] = 0;               /* To empty the delay buffers */
+
+    encoder.reset ();
+    encode_block (enc, in, blocklen);
+
+    decoder.reset ();
+
+    // decode the block
+    decode_block (out, enc, blocklen);
+
+    // int offset = delay/4;
+    int offset = 2;
+    bool differs = (memcmp (in+offset,
+                           out+delay+offset, blocklen-(delay+offset)));
+
+    // initial values after reset are 0
+    for (i = 0; i < delay; i++){
+      if (out[i] != 0)
+       printf ("  initial output at %i is %X, not 0\n",
+               i, out[i]);
+    }
+
+    if (differs){
+      printf ("  incorrect data, trial #%d\n", nt);
+
+      printf ("\n  Erroneous result dibits:");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       if (in[erri] != out[erri+delay])
+         printf (" %d", erri);
+      }
+      printf ("\n  In:  ");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %d", in[erri]);
+      }
+      printf ("\n  Out: ");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %d", out[erri+delay]);
+      }
+      printf ("\n  Errs:");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %c", (in[erri] != out[erri+delay])? '*': ' ');
+      }
+      printf ("\n    THIS IS A REAL PROBLEM.\n");
+      decoder_errors++;
+    }
+  }
+
+  printf ("  Summary: %d decoder errors out of %d trials.\n",
+         decoder_errors, NTRIALS);
+
+  CPPUNIT_ASSERT (decoder_errors == 0);
+}
+
diff --git a/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h
new file mode 100644 (file)
index 0000000..60a8d96
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_FAKE_SINGLE_VITERBI_H
+#define _QA_ATSC_FAKE_SINGLE_VITERBI_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <atsci_fake_single_viterbi.h>
+#include <atsci_basic_trellis_encoder.h>
+
+class qa_atsci_fake_single_viterbi : public CppUnit::TestCase {
+ private:
+  atsci_fake_single_viterbi    decoder;
+  atsci_basic_trellis_encoder  encoder;
+  
+  CPPUNIT_TEST_SUITE (qa_atsci_fake_single_viterbi);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t0 ();
+
+  void encode_block(unsigned char *out, unsigned char *in, unsigned n);
+  void decode_block(unsigned char *out, unsigned char *in, unsigned n);
+  float noise ();
+
+};
+
+#endif /* _QA_ATSC_FAKE_SINGLE_VITERBI_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_fs_correlator.cc b/gr-atsc/src/lib/qa_atsci_fs_correlator.cc
new file mode 100644 (file)
index 0000000..ebfc564
--- /dev/null
@@ -0,0 +1,255 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_atsci_fs_correlator.h>
+#include <atsci_fs_correlator.h>
+#include <create_atsci_fs_correlator.h>
+#include <atsci_sync_tag.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <atsci_pnXXX.h>
+#include <atsc_types.h>
+#include <cppunit/TestAssert.h>
+#include <assert.h>
+#include <random.h>
+
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+
+static float
+bin_map (int bit)
+{
+  return bit ? +5 : -5;
+}
+
+static void
+init_field_sync_common (float *p, int mask)
+                       
+{
+  int  i = 0;
+
+  p[i++] = bin_map(1);                 // data segment sync pulse
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+
+  for (int j = 0; j < 511; j++)                // PN511
+    p[i++] = bin_map(atsc_pn511[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map(atsc_pn63[j]);
+
+  for (int j = 0; j < 63; j++)         // PN63, toggled on field 2
+    p[i++] = bin_map(atsc_pn63[j] ^ mask);
+  
+  for (int j = 0; j < 63; j++)         // PN63
+    p[i++] = bin_map(atsc_pn63[j]);
+
+  p[i++] = bin_map(0);                 // 24 bits of VSB8 mode identifiera
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(0);
+
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(1);
+
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+  p[i++] = bin_map(1);
+  p[i++] = bin_map(0);
+
+
+  for (int j = 0; j < 92; j++)         // 92 more bits
+    p[i++] = bin_map(atsc_pn63[j % 63]);
+
+  // now copy the last 12 symbols of the previous segment
+  // bogus pad for this test...
+
+  for (int j = 0; j < 12; j++)
+    p[i++] = bin_map(j & 1);
+
+  assert (i == ATSC_DATA_SEGMENT_LENGTH);
+}
+
+inline static void
+init_field_sync_1 (float *s)
+{
+  init_field_sync_common (s, 0);
+}
+
+inline static void
+init_field_sync_2 (float *s)
+{
+  init_field_sync_common (s, 1);
+}
+
+static void
+cause_errors (float *p, int nerrs1, int nerrs2)
+{
+  static const int offset1 =   4;      // offset to PN 511
+  static const int offset2 = 578;      // offset to 2nd PN 63
+
+  for (int i = 0; i < nerrs1; i++){    // flip nerrs1 bits in PN 511
+    p[i + offset1] = -p[i + offset1];
+  }
+
+  for (int i = 0; i < nerrs2; i++){    // flip nerrs2 bits in PN 63
+    p[i + offset2] = -p[i + offset2];
+  }
+}
+
+
+void
+qa_atsci_fs_correlator::setUp ()
+{
+  fsc = create_atsci_fs_correlator ();
+}
+
+void
+qa_atsci_fs_correlator::tearDown ()
+{
+  delete fsc;
+  fsc = 0;
+}
+
+
+// check sample fifo
+
+void
+qa_atsci_fs_correlator::t0 ()
+{
+  int  delay = fsc->delay ();
+  int  i;
+  float        output_sample, output_tag;
+
+  for (i = 0; i < delay; i++){
+    fsc->filter ((float) i, &output_sample, &output_tag);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, output_sample, 1e-6);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6);
+  }
+
+  for (; i < delay + 5000; i++){
+    fsc->filter ((float) i, &output_sample, &output_tag);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL ((float) (i - delay), output_sample, 1e-6);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6);
+  }
+}
+
+void
+qa_atsci_fs_correlator::util (int which_field, int nerrs1, int nerrs2)
+{
+  static const int PAD = 303;
+  static const int ISIZE = 4096;
+  int  delay = fsc->delay ();
+  float        output_sample, output_tag;
+  int  i;
+  float        input[ISIZE];
+
+  fsc->reset ();       // known starting conditions
+  
+  // build input
+  
+  for (i = 0; i < PAD; i++)
+    input[i] = uniform () * 7;
+
+  init_field_sync_common (&input[i], which_field);
+  cause_errors (&input[i], nerrs1, nerrs2);
+  i += ATSC_DATA_SEGMENT_LENGTH;
+
+  for (; i < ISIZE; i++)
+    input[i] = uniform () * 7;
+
+  // run the input and check
+  
+  for (i = 0; i < ISIZE; i++){
+    fsc->filter (input[i], &output_sample, &output_tag);
+    if (i == delay + PAD){     // should be field sync
+      if (which_field == 0)
+       CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::START_FIELD_SYNC_1, output_tag, 1e-6);
+      else
+       CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::START_FIELD_SYNC_2, output_tag, 1e-6);
+    }
+    else {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6);
+    }
+  }
+}
+
+
+void
+qa_atsci_fs_correlator::t1 ()
+{
+  util (0, 0, 0);
+}
+
+void
+qa_atsci_fs_correlator::t2 ()
+{
+  util (1, 0, 0);
+}
+
+void
+qa_atsci_fs_correlator::t3 ()
+{
+  for (int nerrs1 = 0; nerrs1 < 20; nerrs1++){
+    for (int nerrs2 = 0; nerrs2 < 5; nerrs2++){
+      util (0, nerrs1, nerrs2);
+    }
+  }
+}
+
+void
+qa_atsci_fs_correlator::t4 ()
+{
+  for (int nerrs1 = 0; nerrs1 < 5; nerrs1++){
+    for (int nerrs2 = 0; nerrs2 < 5; nerrs2++){
+      util (1, nerrs1, nerrs2);
+    }
+  }
+}
+
diff --git a/gr-atsc/src/lib/qa_atsci_fs_correlator.h b/gr-atsc/src/lib/qa_atsci_fs_correlator.h
new file mode 100644 (file)
index 0000000..9d984d9
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _QA_ATSC_FS_CORRELATOR_H_
+#define _QA_ATSC_FS_CORRELATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class atsci_fs_correlator;
+
+class qa_atsci_fs_correlator : public CppUnit::TestCase {
+private:
+  atsci_fs_correlator  *fsc;
+  
+ public:
+
+  void setUp ();
+  void tearDown ();
+
+  CPPUNIT_TEST_SUITE (qa_atsci_fs_correlator);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST (t4);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void util (int which_field, int nerr1, int nerr2);
+  
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+  void t4 ();
+};
+
+#endif /* _QA_ATSC_FS_CORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_randomizer.cc b/gr-atsc/src/lib/qa_atsci_randomizer.cc
new file mode 100644 (file)
index 0000000..b2d0bde
--- /dev/null
@@ -0,0 +1,145 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_atsci_randomizer.h>
+
+#include <cppunit/TestAssert.h>
+#include <string.h>
+
+static unsigned int expected_initial_states[] = {
+  0x018f,
+  0xd3db,
+  0xbaf1,
+  0x8e64,
+  0x4732,
+  0x2399,
+  0xc2d0,
+  0x6168
+};
+
+static unsigned char expected_initial_values[] = {
+  0xc0,
+  0x6d,
+  0x3f,
+  0x99,
+  0x38,
+  0x6a,
+  0x29,
+  0x52
+};
+
+#define        NELEMENTS(ary) ((sizeof (ary)) / sizeof (ary[0]))
+
+void
+qa_atsci_randomizer::t0_compare_output_maps ()
+{
+  for (int i = 0; i < 0x10000; i++){
+    unsigned char slow = atsci_randomizer::slow_output_map(i);
+    unsigned char fast = atsci_randomizer::fast_output_map(i);
+    CPPUNIT_ASSERT_EQUAL (slow, fast);
+  }
+}
+
+void
+qa_atsci_randomizer::t1_initial_states ()
+{
+  // LFSR should start with expected states
+
+  for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){
+    unsigned int got = randomizer.state();
+    randomizer.clk ();
+    CPPUNIT_ASSERT_EQUAL (expected_initial_states[i], got);
+  }
+}
+
+void
+qa_atsci_randomizer::t2_initial_values ()
+{
+  // LFSR should start with expected values
+
+  for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){
+    unsigned char got = randomizer.output_and_clk ();
+    CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got);
+  }
+}
+
+void
+qa_atsci_randomizer::t3_reset ()
+{
+  // LFSR should start with expected values
+
+  for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){
+    unsigned char got = randomizer.output_and_clk ();
+    CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got);
+  }
+
+  randomizer.reset (); // reset LFSR
+  
+  // and now should repeat expected values
+
+  for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){
+    unsigned char got = randomizer.output_and_clk ();
+    CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got);
+  }
+}
+
+void
+qa_atsci_randomizer::t4_high_level ()
+{
+  static const int     N = 5;
+
+  atsc_mpeg_packet             in[N];
+  atsc_mpeg_packet_no_sync     middle[N];
+  atsc_mpeg_packet             out[N];
+  
+  memset (in, 0, sizeof (in));
+  memset (middle, 0, sizeof (middle));
+  memset (out, 0, sizeof (out));
+
+  // setup input test data
+
+  int  counter = 0xff;
+  for (int n = 0; n < N; n++){
+    in[n].data[0] = MPEG_SYNC_BYTE;
+    for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+      in[n].data[i + 1] = counter++;
+  }
+
+  // randomize N packets
+
+  for (int n = 0; n < N; n++)
+    randomizer.randomize (middle[n], in[n]);
+
+  // reset LFSR and derandomize N packets
+
+  randomizer.reset (); // reset LFSR
+
+  for (int n = 0; n < N; n++)
+    randomizer.derandomize (out[n], middle[n]);
+
+  // compare packets
+
+  for (int n = 0; n < N; n++){
+    CPPUNIT_ASSERT (in[n] == out[n]);
+  }
+}
+
diff --git a/gr-atsc/src/lib/qa_atsci_randomizer.h b/gr-atsc/src/lib/qa_atsci_randomizer.h
new file mode 100644 (file)
index 0000000..f1b1a1b
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+#ifndef _QA_ATSC_RANDOMIZER_H_
+#define _QA_ATSC_RANDOMIZER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <atsci_randomizer.h>
+
+class qa_atsci_randomizer : public CppUnit::TestCase {
+ private:
+  atsci_randomizer     randomizer;
+  
+ public:
+
+  void setUp (){
+    // nop
+  }
+
+  void tearDown (){
+    // nop
+  }
+
+  CPPUNIT_TEST_SUITE (qa_atsci_randomizer);
+  CPPUNIT_TEST (t0_compare_output_maps);
+  CPPUNIT_TEST (t1_initial_states);
+  CPPUNIT_TEST (t2_initial_values);
+  CPPUNIT_TEST (t3_reset);
+  CPPUNIT_TEST (t4_high_level);
+  CPPUNIT_TEST_SUITE_END ();
+
+
+ private:
+  void t0_compare_output_maps ();
+  void t1_initial_states ();
+  void t2_initial_values ();
+  void t3_reset ();
+  void t4_high_level ();
+  
+};
+
+#endif /* _QA_ATSC_RANDOMIZER_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_reed_solomon.cc b/gr-atsc/src/lib/qa_atsci_reed_solomon.cc
new file mode 100644 (file)
index 0000000..b08c8af
--- /dev/null
@@ -0,0 +1,115 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <atsci_reed_solomon.h>
+#include <qa_atsci_reed_solomon.h>
+#include <string.h>
+
+
+static const int NROOTS      =   20;
+static const int NTRIALS     =  100;
+static const int NN         = ATSC_MPEG_RS_ENCODED_LENGTH;
+
+void
+qa_atsci_reed_solomon::t0_reed_solomon ()
+{
+  atsc_mpeg_packet_no_sync     in;
+  atsc_mpeg_packet_rs_encoded          enc;
+  atsc_mpeg_packet_no_sync     out;
+  int                    derrors;
+  int                    errlocs[NN];
+  int                    errval;
+  int                    errloc;
+  int                    decoder_errors = 0;
+
+  for (int nt = 0; nt < NTRIALS; nt++){
+
+    // test up to the error correction capacity of the code
+    for (int errors = 0; errors <= NROOTS*2; errors++){
+
+      // load block with random data and encode
+
+      for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+       in.data[i] = random () & 0xff;
+
+      rs.encode (enc, in);
+
+      memset (errlocs, 0, sizeof (errlocs));
+
+      for (int i = 0; i < errors; i++){
+
+       do {
+         errval = random () & 0xff;
+       } while (errval == 0);  // error value must be non-zero
+
+       do {
+         errloc = random () % NN;
+       } while (errlocs[errloc] != 0);         // must not choose the same location twice
+
+       errlocs[errloc] = 1;
+
+       enc.data[errloc] ^= errval;             // cause the error
+      }
+
+      // decode the errored block
+      derrors = rs.decode (out, enc);
+
+      if (errors <= NROOTS/2) {
+       // We should have handled all these errors and corrected them.
+       if (derrors != errors){
+         fprintf (stderr, "  decoder says %d errors, true number is %d\n", derrors, errors);
+         decoder_errors++;
+       }
+
+       if (in != out){
+         fprintf (stderr, "  uncorrected errors!\n");
+         decoder_errors++;
+       }
+      } else {
+       // We have been given more errors than we could cope with.  Make
+       // sure that we detect these errors.  Complain if we get incorrect
+       // block but don't say it's incorrect.
+       bool differs = (in != out);
+
+       if (differs && (derrors < 0)) {
+         // Reported uncorrectable error accurately
+       } else if (differs) {
+         fprintf (stderr,
+                  "  decoder found %d of %d errors, but incorrect block\n",
+                  derrors, errors);
+       } else {
+         fprintf (stderr, "  decoder corrected %d of %d errors unexpectedly\n",
+                  derrors, errors);
+       }
+      }
+    }
+  }
+
+  CPPUNIT_ASSERT (decoder_errors == 0);
+}
diff --git a/gr-atsc/src/lib/qa_atsci_reed_solomon.h b/gr-atsc/src/lib/qa_atsci_reed_solomon.h
new file mode 100644 (file)
index 0000000..22f1743
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_REED_SOLOMON_H_
+#define _QA_ATSC_REED_SOLOMON_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <atsci_reed_solomon.h>
+
+class qa_atsci_reed_solomon : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_atsci_reed_solomon);
+  CPPUNIT_TEST (t0_reed_solomon);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_reed_solomon   rs;
+
+  void t0_reed_solomon ();
+};
+
+#endif /* _QA_ATSC_REED_SOLOMON_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_single_viterbi.cc b/gr-atsc/src/lib/qa_atsci_single_viterbi.cc
new file mode 100644 (file)
index 0000000..d7c2909
--- /dev/null
@@ -0,0 +1,284 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <atsci_single_viterbi.h>
+#include <qa_atsci_single_viterbi.h>
+#include <random.h>
+#include <string.h>
+
+
+static const int NTRIALS     =   50;
+static const int MAXERRORS   =   10;
+static const int NN          =  200;
+
+static const int MAXDIBIT    = 3;
+
+void
+qa_atsci_single_viterbi::encode_block (unsigned char *out, unsigned char *in, 
+                                     unsigned int n)
+{
+  for (unsigned int i = 0; i < n; i++) {
+    out[i] = encoder.encode(in[i]);
+  }
+}
+
+
+void
+qa_atsci_single_viterbi::decode_block (unsigned char *out, unsigned char *in, 
+                                     unsigned int n, float noise_factor)
+{
+  for (unsigned int i = 0; i < n; i++) {
+    out[i] = decoder.decode((2*in[i]-7) + noise () * noise_factor);
+  }
+}
+
+float
+qa_atsci_single_viterbi::noise ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+void
+qa_atsci_single_viterbi::t0 ()
+{
+  int                    blocklen = NN;
+  unsigned char                  in[blocklen];
+  unsigned char                  enc[blocklen];
+  unsigned char                  out[blocklen];
+  int                    decoder_errors = 0;
+  int                    delay = decoder.delay ();
+  int                    i;
+
+  // printf ("  Delay is %d.\n", delay);
+  
+  srandom (27);                // reproducable sequence of "random" values
+  
+  for (int nt = 0; nt < NTRIALS; nt++){
+
+    // load block with random data and encode
+
+    for (i = 0; i < (blocklen-delay); i++)
+      in[i] = random () & MAXDIBIT;
+    for (     ; i < blocklen; i++)
+      in[i] = 0;               /* To empty the delay buffers */
+
+    encoder.reset ();
+    encode_block (enc, in, blocklen);
+
+    decoder.reset ();
+
+    // decode the block
+    decode_block (out, enc, blocklen, 1.0);
+
+    // int offset = delay/4;
+    int offset = 2;
+    bool differs = (memcmp (in+offset,
+                           out+delay+offset, blocklen-(delay+offset)));
+
+    // initial values after reset are 0
+    for (i = 0; i < delay; i++){
+      if (out[i] != 0)
+       printf ("  initial output at %i is %X, not 0\n",
+               i, out[i]);
+    }
+
+    if (differs){
+      printf ("  incorrect data\n");
+
+      printf ("\n  Erroneous result dibits:");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       if (in[erri] != out[erri+delay])
+         printf (" %d", erri);
+      }
+      printf ("\n  In:  ");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %d", in[erri]);
+      }
+      printf ("\n  Out: ");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %d", out[erri+delay]);
+      }
+      printf ("\n  Errs:");
+      for (int erri = 0; erri < (NN-delay); erri++) {
+       printf (" %c", (in[erri] != out[erri+delay])? '*': ' ');
+      }
+      printf ("\n    THIS IS A REAL PROBLEM.\n");
+      decoder_errors++;
+    }
+  }
+
+  printf ("  Summary: %d decoder errors out of %d trials.\n",
+         decoder_errors, NTRIALS);
+
+  CPPUNIT_ASSERT (decoder_errors == 0);
+}
+
+void
+qa_atsci_single_viterbi::t1 ()
+{
+  int                    blocklen = NN;
+  unsigned char                  in[blocklen];
+  unsigned char                  enc[blocklen];
+  unsigned char                  out[blocklen];
+  int                    errlocs[NN];
+  int                    errval;
+  int                    errloc;
+  int                    decoder_errors = 0;
+  int                    delay = decoder.delay ();
+  int                    i;
+
+  // printf ("  Delay is %d.\n", delay);
+  
+  srandom (1);         // reproducable sequence of "random" values
+  
+  for (int nt = 0; nt < NTRIALS; nt++){
+
+    // test up to the error correction capacity of the code
+    for (int errors = 0; errors <= MAXERRORS; errors++){
+
+      // load block with random data and encode
+
+      for (i = 0; i < (blocklen-delay); i++)
+       in[i] = random () & MAXDIBIT;
+      for (     ; i < blocklen; i++)
+       in[i] = 0;              /* To empty the delay buffers */
+
+      encoder.reset ();
+      encode_block (enc, in, blocklen);
+
+      // Now generate 0 to N errors in the encoded symbols.
+      //
+      //  If we restrict ourselves to damaging the low-order bit,
+      //  our decoder finds and fixes the vast majority of errors.
+      //
+      //  If we munge any or all of the three bits of the symbol,
+      //  our decoder frequently gets the wrong data even with a single
+      //  error.
+      //  
+      //  Let's see what it can do with just the two low-order bits.
+      //
+      // ALSO:  Don't let any error be within 12 spots of another
+      //  error.  This simulates the muxed behavior.
+
+      memset (errlocs, 0, sizeof (errlocs));
+
+      for (int j = 0; j < errors; j++){
+
+       do {
+         // errval = random () & 3;  // FIXME:  1;   // FIXME: MAXSYM;
+         errval = random () & 1;  // FIXME:  1;   // FIXME: MAXSYM;
+       } while (errval == 0);  // error value must be non-zero
+
+       // Don't insert errors in the first delay slot, since we
+       // don't have valid history to correct them.  Also, don't
+       // insert burst errors (adjacent errors), or errors within 2,
+       // since we can't reliably correct them.  Also we must not choose 
+       // the same location twice when inserting an error.
+
+       do {
+         errloc = random () % NN;
+       } while (errloc < delay || errlocs[errloc] != 0
+                || (errloc > 0 && errlocs[errloc-1] != 0)
+                || (errloc > 1 && errlocs[errloc-2] != 0)
+                || (errloc < (NN-1) && errlocs[errloc+1] != 0)
+                || (errloc < (NN-2) && errlocs[errloc+2] != 0));
+
+       errlocs[errloc] = 1;
+
+       enc[errloc] ^= errval;          // cause the error
+      }
+
+      // decode the errored block
+      decoder.reset ();
+      decode_block (out, enc, blocklen, 0.5);
+
+      // int offset = delay/4;
+      int offset = 2;
+      bool differs = (memcmp (in+offset,
+                             out+delay+offset, blocklen-(delay+offset)));
+
+      // initial values after reset are 0
+      for (i = 0; i < delay; i++){
+       if (out[i] != 0)
+         printf ("  initial output at %i is %X, not 0\n",
+                 i, out[i]);
+      }
+
+      if (differs){
+       printf ("  %2d errors introduced, %scorrect data\n",
+                errors, differs? "in": "");
+
+       // FIXME, should we be able to tell how many errs too?
+        if (differs) {
+         const int ERRTOL = 12;                /* Or relate to delay? */
+         int shouldfix = 1;
+         int lasti = -ERRTOL;
+
+         printf (  "  Inserted errors:        ");
+         for (int erri = 0; erri < NN; erri++) {
+           if (errlocs[erri]) {
+             printf (" %d", erri);
+             // if (erri < lasti+ERRTOL)
+             //   shouldfix = 0;
+             lasti = erri;
+           }
+         }
+         printf ("\n  Erroneous result dibits:");
+         for (int erri = 0; erri < (NN-delay); erri++) {
+           if (in[erri] != out[erri+delay])
+             printf (" %d", erri);
+         }
+         printf ("\n  In:  ");
+         for (int erri = 0; erri < (NN-delay); erri++) {
+             printf (" %d", in[erri]);
+         }
+         printf ("\n  Out: ");
+         for (int erri = 0; erri < (NN-delay); erri++) {
+             printf (" %d", out[erri+delay]);
+         }
+         printf ("\n  Errs:");
+         for (int erri = 0; erri < (NN-delay); erri++) {
+           printf (" %c", (in[erri] != out[erri+delay])? '*': ' ');
+         }
+         if (shouldfix)
+           printf ("\n    THIS IS A REAL PROBLEM.\n");
+         else
+           printf ("\n    BUT THAT'S OK since errors are too close.\n");
+         if (shouldfix)
+            decoder_errors++;
+       }
+      }
+    }
+  }
+
+  printf ("  Summary: %d decoder errors out of %d trials.\n",
+         decoder_errors, (MAXERRORS*NTRIALS));
+
+  CPPUNIT_ASSERT (decoder_errors <= (MAXERRORS*NTRIALS) * .1);
+}
diff --git a/gr-atsc/src/lib/qa_atsci_single_viterbi.h b/gr-atsc/src/lib/qa_atsci_single_viterbi.h
new file mode 100644 (file)
index 0000000..057c29e
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_SINGLE_VITERBI_H
+#define _QA_ATSC_SINGLE_VITERBI_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <atsci_single_viterbi.h>
+#include <atsci_basic_trellis_encoder.h>
+
+class qa_atsci_single_viterbi : public CppUnit::TestCase {
+ private:
+  atsci_single_viterbi         decoder;
+  atsci_basic_trellis_encoder  encoder;
+  
+  CPPUNIT_TEST_SUITE (qa_atsci_single_viterbi);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t0 ();
+  void t1 ();
+
+  void encode_block(unsigned char *out, unsigned char *in, unsigned n);
+  void decode_block(unsigned char *out, unsigned char *in, unsigned n, float noise_factor);
+  float noise ();
+
+};
+
+#endif /* _QA_ATSC_SINGLE_VITERBI_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_sliding_correlator.cc b/gr-atsc/src/lib/qa_atsci_sliding_correlator.cc
new file mode 100644 (file)
index 0000000..0c5d987
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_sliding_correlator.h>
+#include <cstdio>
+
+void
+qa_atsci_sliding_correlator::t0 ()
+{
+
+#if 0
+  int  count = 0;
+  int  i;
+  for (i = 0; i < 100; i++)
+    printf ("%6d: %3d\n", count++, corr.input_bit (i & 1));
+
+  for (i = 0; i < 511; i++)
+    printf ("%6d: %3d\n", count++, corr.input_bit (atsc_pn511[i]));
+
+  for (i = 0; i < 100; i++)
+    printf ("%6d: %3d\n", count++, corr.input_bit ((i & 2) != 0));
+
+  for (i = 0; i < 511; i++)
+    printf ("%6d: %3d\n", count++, corr.input_bit (atsc_pn511[i] ^ 1));
+
+  for (i = 0; i < 100; i++)
+    printf ("%6d: %3d\n", count++,
+           corr.input_bit (atsc_pn511[i] ^ atsc_pn511[i+31]));
+#endif
+
+}
diff --git a/gr-atsc/src/lib/qa_atsci_sliding_correlator.h b/gr-atsc/src/lib/qa_atsci_sliding_correlator.h
new file mode 100644 (file)
index 0000000..6e74173
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_SLIDING_CORRELATOR_H_
+#define _QA_ATSC_SLIDING_CORRELATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdio.h>
+
+#include <atsci_sliding_correlator.h>
+
+class qa_atsci_sliding_correlator : public CppUnit::TestCase {
+
+ public:
+
+  void setUp (void) 
+  {
+    corr.reset ();
+  }
+
+  CPPUNIT_TEST_SUITE (qa_atsci_sliding_correlator);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_sliding_correlator     corr;
+  
+  void t0 ();
+};
+
+
+#endif /* _QA_ATSC_SLIDING_CORRELATOR_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder.cc b/gr-atsc/src/lib/qa_atsci_trellis_encoder.cc
new file mode 100644 (file)
index 0000000..390776e
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_trellis_encoder.h>
+#include <cstdio>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+static const int NCODERS = atsci_trellis_encoder::NCODERS;
+
+void
+qa_atsci_trellis_encoder::t0 ()
+{
+#if 0          // generate i/o test data for t1
+
+  atsc_mpeg_packet_rs_encoded  in[NCODERS];
+  atsc_data_segment            out[NCODERS];
+
+  
+  memset (in,  0, sizeof (in));
+  memset (out, 0, sizeof (out));
+
+  srandom (1);
+
+  printf ("@@@ INPUT @@@\n");
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (in[i].data); j++){
+      int t = (random () >> 8) & 0xff; // 8 random bits
+      in[i].data[j] = t;
+      printf ("%d\n", t);
+    }
+  }
+  
+  enc.reset ();
+  enc.encode (out, in);
+
+  printf ("@@@ OUTPUT @@@\n");
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (out[i].data); j++){
+       printf ("%d\n", out[i].data[j]);
+    }
+  }
+#endif
+}
+
+void
+qa_atsci_trellis_encoder::t1 ()
+{
+  atsc_mpeg_packet_rs_encoded  in[NCODERS];
+  atsc_data_segment            expected_out[NCODERS];
+  atsc_data_segment            actual_out[NCODERS];
+  static const unsigned char   raw_input[NCODERS * NELEM (in[0].data)] = {
+#include "qa_atsci_trellis_encoder_t1_input.dat"
+  };
+  static const unsigned char   raw_output[NCODERS * NELEM (expected_out[0].data)] = {
+#include "qa_atsci_trellis_encoder_t1_output.dat"
+  };
+
+
+  // load up input
+  const unsigned char *r = &raw_input[0];
+  for (int i = 0; i < NCODERS; i++){
+    in[i].pli.set_regular_seg (false, i);
+    for (unsigned int j = 0; j < NELEM (in[i].data); j++){
+      in[i].data[j] = *r++;
+    }
+  }
+
+  // load up expected output
+  r = &raw_output[0];
+  for (int i = 0; i < NCODERS; i++){
+    expected_out[i].pli.set_regular_seg (false, i);
+    for (unsigned int j = 0; j < NELEM (expected_out[i].data); j++){
+      expected_out[i].data[j] = *r++;
+    }
+  }
+
+  memset (&actual_out, 0, sizeof (actual_out));                // ensure zero
+
+  enc.reset ();
+  enc.encode (actual_out, in);                         // trellis code test data
+
+  for (int i = 0; i < NCODERS; i++){                   // check the result
+    CPPUNIT_ASSERT (expected_out[i] == actual_out[i]);
+    CPPUNIT_ASSERT (expected_out[i].pli == actual_out[i].pli);
+  }
+}
diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder.h b/gr-atsc/src/lib/qa_atsci_trellis_encoder.h
new file mode 100644 (file)
index 0000000..42b3323
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_TRELLIS_ENCODER_H_
+#define _QA_ATSC_TRELLIS_ENCODER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdio.h>
+
+#include <atsci_trellis_encoder.h>
+
+class qa_atsci_trellis_encoder : public CppUnit::TestCase {
+
+ public:
+
+  void setUp (void) 
+  {
+    enc.reset ();
+  }
+
+  CPPUNIT_TEST_SUITE (qa_atsci_trellis_encoder);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_trellis_encoder        enc;
+  
+  void t0 ();
+  void t1 ();
+};
+
+
+#endif /* _QA_ATSC_TRELLIS_ENCODER_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat
new file mode 100644 (file)
index 0000000..e6109dd
--- /dev/null
@@ -0,0 +1,2484 @@
+69,
+35,
+152,
+72,
+220,
+92,
+148,
+88,
+31,
+124,
+88,
+215,
+65,
+30,
+169,
+225,
+0,
+98,
+8,
+39,
+35,
+233,
+205,
+67,
+15,
+37,
+249,
+114,
+194,
+215,
+196,
+7,
+251,
+93,
+80,
+215,
+186,
+228,
+48,
+217,
+97,
+137,
+177,
+163,
+168,
+90,
+132,
+168,
+189,
+140,
+208,
+224,
+118,
+158,
+36,
+134,
+196,
+29,
+248,
+134,
+245,
+189,
+141,
+240,
+26,
+221,
+200,
+212,
+194,
+248,
+173,
+35,
+130,
+95,
+198,
+42,
+185,
+74,
+211,
+119,
+215,
+164,
+88,
+78,
+66,
+124,
+212,
+6,
+154,
+204,
+141,
+143,
+137,
+27,
+127,
+164,
+249,
+72,
+120,
+187,
+64,
+38,
+222,
+195,
+133,
+165,
+237,
+63,
+240,
+193,
+183,
+199,
+101,
+15,
+21,
+168,
+140,
+233,
+175,
+38,
+182,
+60,
+182,
+64,
+87,
+53,
+228,
+80,
+126,
+93,
+11,
+191,
+132,
+234,
+130,
+10,
+143,
+112,
+74,
+127,
+49,
+2,
+71,
+150,
+18,
+93,
+63,
+158,
+71,
+238,
+197,
+253,
+43,
+123,
+62,
+130,
+177,
+35,
+211,
+47,
+129,
+223,
+238,
+6,
+202,
+112,
+17,
+89,
+224,
+91,
+217,
+17,
+94,
+33,
+168,
+112,
+126,
+231,
+14,
+197,
+214,
+212,
+195,
+1,
+79,
+1,
+132,
+1,
+36,
+87,
+48,
+165,
+55,
+30,
+172,
+1,
+143,
+189,
+90,
+112,
+24,
+52,
+130,
+119,
+85,
+42,
+231,
+211,
+18,
+246,
+153,
+232,
+202,
+92,
+234,
+26,
+93,
+110,
+27,
+130,
+197,
+75,
+40,
+253,
+106,
+212,
+254,
+250,
+145,
+89,
+106,
+170,
+141,
+236,
+33,
+227,
+23,
+9,
+183,
+41,
+255,
+80,
+18,
+201,
+172,
+252,
+227,
+10,
+107,
+255,
+141,
+49,
+74,
+181,
+46,
+181,
+138,
+44,
+175,
+27,
+133,
+26,
+198,
+19,
+6,
+232,
+246,
+29,
+241,
+174,
+71,
+240,
+254,
+90,
+185,
+171,
+87,
+157,
+182,
+194,
+157,
+67,
+243,
+232,
+248,
+34,
+157,
+130,
+78,
+77,
+158,
+212,
+103,
+100,
+231,
+110,
+76,
+222,
+140,
+61,
+140,
+211,
+46,
+138,
+46,
+232,
+54,
+133,
+133,
+236,
+72,
+35,
+47,
+59,
+11,
+40,
+94,
+168,
+171,
+172,
+246,
+74,
+128,
+93,
+174,
+104,
+204,
+251,
+70,
+88,
+57,
+210,
+44,
+103,
+93,
+90,
+79,
+148,
+223,
+213,
+129,
+39,
+248,
+177,
+99,
+4,
+217,
+193,
+172,
+133,
+110,
+162,
+207,
+239,
+0,
+126,
+87,
+205,
+121,
+158,
+37,
+179,
+113,
+81,
+27,
+207,
+171,
+107,
+99,
+139,
+65,
+228,
+178,
+58,
+149,
+22,
+62,
+111,
+216,
+234,
+244,
+70,
+141,
+195,
+54,
+142,
+66,
+141,
+91,
+187,
+44,
+129,
+111,
+157,
+210,
+138,
+108,
+126,
+245,
+208,
+9,
+55,
+180,
+188,
+113,
+74,
+211,
+175,
+185,
+171,
+154,
+174,
+242,
+40,
+114,
+40,
+183,
+180,
+182,
+19,
+112,
+226,
+148,
+223,
+128,
+103,
+106,
+237,
+229,
+96,
+189,
+239,
+151,
+114,
+172,
+8,
+189,
+127,
+184,
+118,
+43,
+83,
+37,
+29,
+123,
+151,
+70,
+50,
+76,
+252,
+69,
+188,
+223,
+218,
+156,
+96,
+65,
+6,
+77,
+39,
+102,
+11,
+23,
+254,
+125,
+195,
+7,
+59,
+67,
+191,
+178,
+111,
+18,
+215,
+141,
+142,
+111,
+211,
+192,
+187,
+208,
+6,
+119,
+176,
+225,
+19,
+16,
+34,
+26,
+94,
+74,
+128,
+105,
+97,
+127,
+231,
+37,
+134,
+35,
+104,
+69,
+213,
+215,
+88,
+172,
+101,
+230,
+27,
+56,
+167,
+214,
+9,
+174,
+78,
+185,
+143,
+98,
+202,
+178,
+124,
+40,
+253,
+253,
+146,
+94,
+124,
+122,
+131,
+2,
+157,
+236,
+72,
+114,
+196,
+161,
+31,
+41,
+136,
+58,
+98,
+47,
+17,
+107,
+222,
+96,
+37,
+110,
+194,
+239,
+32,
+63,
+24,
+29,
+60,
+170,
+124,
+185,
+37,
+0,
+188,
+195,
+237,
+4,
+53,
+178,
+165,
+84,
+219,
+45,
+143,
+62,
+93,
+161,
+169,
+60,
+1,
+206,
+170,
+196,
+190,
+203,
+4,
+214,
+232,
+65,
+129,
+101,
+250,
+166,
+102,
+182,
+105,
+83,
+186,
+159,
+5,
+96,
+244,
+225,
+142,
+132,
+31,
+236,
+37,
+201,
+40,
+39,
+152,
+210,
+236,
+86,
+157,
+240,
+44,
+134,
+49,
+173,
+235,
+44,
+83,
+81,
+226,
+189,
+165,
+157,
+93,
+170,
+254,
+81,
+140,
+141,
+213,
+171,
+121,
+251,
+117,
+161,
+35,
+13,
+116,
+16,
+99,
+17,
+0,
+144,
+152,
+50,
+61,
+132,
+95,
+145,
+214,
+66,
+79,
+123,
+223,
+172,
+38,
+222,
+254,
+178,
+107,
+211,
+94,
+229,
+207,
+212,
+134,
+242,
+225,
+251,
+2,
+69,
+12,
+3,
+214,
+164,
+54,
+20,
+40,
+149,
+165,
+254,
+215,
+245,
+122,
+183,
+162,
+160,
+150,
+160,
+83,
+1,
+116,
+177,
+230,
+67,
+133,
+109,
+54,
+103,
+104,
+56,
+173,
+117,
+60,
+131,
+26,
+115,
+151,
+67,
+9,
+61,
+65,
+224,
+50,
+188,
+152,
+212,
+92,
+46,
+116,
+175,
+48,
+232,
+97,
+23,
+44,
+231,
+132,
+98,
+78,
+237,
+155,
+251,
+98,
+215,
+126,
+124,
+74,
+22,
+191,
+83,
+83,
+1,
+52,
+133,
+189,
+205,
+90,
+26,
+252,
+207,
+202,
+45,
+183,
+43,
+68,
+228,
+19,
+201,
+70,
+98,
+182,
+225,
+93,
+25,
+185,
+220,
+150,
+4,
+243,
+86,
+88,
+70,
+88,
+141,
+203,
+21,
+90,
+38,
+48,
+87,
+245,
+250,
+132,
+173,
+38,
+200,
+145,
+57,
+145,
+215,
+156,
+72,
+185,
+250,
+98,
+114,
+215,
+248,
+119,
+202,
+78,
+207,
+16,
+166,
+92,
+220,
+188,
+183,
+2,
+237,
+14,
+247,
+231,
+146,
+164,
+14,
+91,
+53,
+72,
+237,
+13,
+228,
+53,
+199,
+222,
+151,
+57,
+181,
+144,
+177,
+127,
+222,
+128,
+143,
+133,
+220,
+107,
+66,
+147,
+109,
+47,
+162,
+101,
+23,
+52,
+9,
+37,
+143,
+63,
+110,
+125,
+77,
+82,
+179,
+20,
+49,
+75,
+78,
+230,
+219,
+255,
+102,
+186,
+127,
+246,
+64,
+92,
+98,
+130,
+240,
+208,
+177,
+146,
+53,
+200,
+198,
+63,
+238,
+86,
+127,
+92,
+212,
+204,
+175,
+135,
+224,
+224,
+210,
+47,
+199,
+173,
+46,
+45,
+104,
+174,
+36,
+168,
+10,
+134,
+42,
+250,
+86,
+220,
+141,
+139,
+165,
+83,
+203,
+148,
+170,
+74,
+241,
+126,
+22,
+160,
+6,
+247,
+128,
+216,
+38,
+72,
+134,
+85,
+117,
+238,
+3,
+153,
+151,
+13,
+32,
+194,
+8,
+118,
+158,
+149,
+2,
+68,
+233,
+205,
+217,
+148,
+23,
+202,
+19,
+46,
+106,
+25,
+38,
+235,
+241,
+76,
+51,
+120,
+162,
+169,
+103,
+165,
+66,
+254,
+179,
+98,
+192,
+188,
+217,
+95,
+82,
+219,
+164,
+59,
+169,
+125,
+208,
+193,
+71,
+227,
+239,
+177,
+252,
+22,
+157,
+238,
+98,
+208,
+102,
+5,
+121,
+206,
+170,
+188,
+204,
+94,
+31,
+141,
+26,
+248,
+237,
+108,
+212,
+146,
+168,
+125,
+15,
+120,
+62,
+87,
+91,
+46,
+9,
+88,
+68,
+166,
+70,
+167,
+118,
+173,
+172,
+240,
+124,
+87,
+172,
+72,
+181,
+203,
+214,
+207,
+196,
+196,
+59,
+152,
+86,
+228,
+21,
+102,
+92,
+84,
+190,
+183,
+131,
+199,
+16,
+199,
+110,
+86,
+110,
+229,
+4,
+27,
+213,
+128,
+114,
+129,
+201,
+39,
+77,
+160,
+247,
+17,
+100,
+51,
+169,
+187,
+23,
+191,
+33,
+115,
+20,
+223,
+43,
+151,
+167,
+59,
+94,
+21,
+146,
+205,
+251,
+150,
+233,
+208,
+23,
+91,
+82,
+224,
+131,
+159,
+129,
+122,
+177,
+229,
+173,
+91,
+160,
+196,
+27,
+194,
+56,
+47,
+162,
+99,
+198,
+74,
+159,
+37,
+95,
+49,
+243,
+91,
+200,
+220,
+43,
+223,
+55,
+126,
+192,
+187,
+29,
+65,
+53,
+207,
+39,
+226,
+42,
+200,
+167,
+69,
+138,
+223,
+116,
+45,
+67,
+59,
+119,
+226,
+97,
+215,
+20,
+84,
+50,
+221,
+48,
+94,
+188,
+104,
+220,
+125,
+35,
+249,
+191,
+89,
+200,
+230,
+60,
+243,
+175,
+227,
+56,
+57,
+195,
+173,
+103,
+7,
+233,
+222,
+234,
+74,
+181,
+254,
+158,
+232,
+219,
+207,
+70,
+152,
+56,
+34,
+22,
+92,
+28,
+213,
+181,
+229,
+188,
+241,
+216,
+107,
+213,
+17,
+165,
+153,
+190,
+12,
+160,
+167,
+235,
+139,
+242,
+161,
+138,
+144,
+137,
+101,
+96,
+208,
+254,
+152,
+242,
+20,
+244,
+14,
+234,
+170,
+243,
+167,
+155,
+204,
+19,
+113,
+221,
+184,
+11,
+156,
+197,
+171,
+68,
+177,
+55,
+54,
+82,
+193,
+199,
+220,
+39,
+39,
+172,
+37,
+192,
+158,
+58,
+180,
+173,
+37,
+94,
+161,
+204,
+250,
+109,
+224,
+108,
+75,
+153,
+119,
+232,
+94,
+35,
+45,
+15,
+90,
+99,
+98,
+27,
+43,
+62,
+66,
+83,
+234,
+104,
+20,
+137,
+162,
+201,
+54,
+200,
+39,
+215,
+149,
+34,
+69,
+117,
+142,
+144,
+14,
+6,
+121,
+109,
+41,
+166,
+125,
+131,
+10,
+223,
+159,
+53,
+29,
+225,
+137,
+8,
+74,
+157,
+145,
+237,
+102,
+200,
+181,
+142,
+159,
+74,
+177,
+229,
+192,
+64,
+118,
+207,
+70,
+239,
+60,
+111,
+149,
+185,
+243,
+160,
+153,
+146,
+214,
+182,
+116,
+95,
+191,
+190,
+253,
+80,
+171,
+99,
+25,
+97,
+242,
+185,
+172,
+163,
+158,
+108,
+228,
+20,
+59,
+42,
+4,
+120,
+154,
+154,
+49,
+141,
+58,
+202,
+32,
+16,
+129,
+149,
+112,
+65,
+83,
+109,
+146,
+255,
+209,
+171,
+96,
+196,
+100,
+13,
+103,
+2,
+121,
+76,
+23,
+181,
+118,
+28,
+45,
+17,
+183,
+95,
+158,
+241,
+42,
+191,
+2,
+172,
+84,
+115,
+237,
+168,
+224,
+127,
+168,
+178,
+42,
+8,
+118,
+142,
+22,
+222,
+145,
+143,
+42,
+169,
+69,
+160,
+197,
+114,
+177,
+124,
+210,
+80,
+110,
+252,
+16,
+113,
+168,
+101,
+228,
+149,
+13,
+197,
+20,
+181,
+119,
+63,
+190,
+237,
+206,
+212,
+203,
+95,
+100,
+245,
+9,
+169,
+150,
+207,
+28,
+72,
+76,
+238,
+153,
+186,
+234,
+169,
+44,
+146,
+14,
+17,
+40,
+28,
+214,
+61,
+209,
+77,
+125,
+144,
+59,
+75,
+100,
+6,
+171,
+200,
+252,
+180,
+114,
+147,
+131,
+142,
+219,
+207,
+124,
+117,
+138,
+102,
+31,
+183,
+249,
+45,
+200,
+34,
+74,
+158,
+96,
+27,
+236,
+221,
+172,
+39,
+40,
+16,
+46,
+212,
+217,
+43,
+136,
+75,
+190,
+11,
+217,
+154,
+219,
+85,
+15,
+102,
+188,
+46,
+29,
+182,
+92,
+229,
+217,
+166,
+131,
+57,
+194,
+112,
+22,
+110,
+151,
+63,
+127,
+197,
+19,
+88,
+241,
+156,
+163,
+175,
+168,
+125,
+73,
+131,
+211,
+88,
+233,
+143,
+135,
+7,
+70,
+227,
+236,
+31,
+138,
+112,
+88,
+77,
+224,
+111,
+187,
+120,
+174,
+59,
+62,
+194,
+147,
+47,
+94,
+55,
+222,
+6,
+180,
+40,
+138,
+135,
+129,
+116,
+23,
+8,
+123,
+93,
+236,
+103,
+125,
+118,
+216,
+213,
+195,
+184,
+69,
+127,
+49,
+244,
+187,
+111,
+182,
+78,
+158,
+21,
+134,
+125,
+27,
+59,
+165,
+165,
+195,
+38,
+25,
+218,
+47,
+149,
+56,
+27,
+252,
+181,
+146,
+213,
+139,
+86,
+142,
+208,
+213,
+191,
+196,
+145,
+46,
+123,
+223,
+205,
+144,
+102,
+75,
+171,
+161,
+240,
+81,
+101,
+23,
+107,
+64,
+70,
+0,
+120,
+98,
+253,
+46,
+244,
+210,
+185,
+74,
+96,
+138,
+32,
+32,
+78,
+177,
+79,
+201,
+145,
+28,
+89,
+248,
+103,
+5,
+154,
+88,
+87,
+255,
+112,
+195,
+63,
+183,
+196,
+184,
+25,
+193,
+230,
+14,
+148,
+160,
+89,
+245,
+42,
+122,
+21,
+121,
+43,
+100,
+67,
+189,
+129,
+157,
+182,
+233,
+162,
+80,
+65,
+250,
+80,
+178,
+190,
+143,
+105,
+130,
+72,
+131,
+67,
+47,
+145,
+216,
+208,
+235,
+205,
+251,
+101,
+227,
+116,
+145,
+71,
+183,
+78,
+201,
+84,
+4,
+178,
+247,
+85,
+244,
+242,
+165,
+166,
+176,
+53,
+16,
+50,
+126,
+147,
+118,
+173,
+37,
+78,
+125,
+16,
+28,
+120,
+117,
+0,
+237,
+6,
+71,
+164,
+85,
+17,
+249,
+90,
+195,
+240,
+175,
+184,
+227,
+85,
+94,
+147,
+138,
+110,
+197,
+8,
+2,
+60,
+182,
+39,
+139,
+51,
+55,
+167,
+172,
+173,
+167,
+153,
+179,
+239,
+62,
+9,
+1,
+55,
+99,
+196,
+40,
+19,
+124,
+12,
+104,
+219,
+159,
+243,
+74,
+101,
+251,
+76,
+161,
+178,
+115,
+44,
+230,
+171,
+212,
+146,
+88,
+124,
+44,
+12,
+108,
+107,
+21,
+109,
+163,
+121,
+50,
+204,
+140,
+175,
+216,
+244,
+138,
+119,
+232,
+213,
+221,
+228,
+33,
+127,
+150,
+149,
+172,
+124,
+64,
+129,
+15,
+153,
+253,
+59,
+166,
+105,
+167,
+187,
+215,
+74,
+53,
+9,
+22,
+193,
+184,
+238,
+182,
+67,
+102,
+158,
+24,
+68,
+130,
+58,
+195,
+24,
+207,
+111,
+149,
+16,
+240,
+164,
+170,
+238,
+224,
+80,
+88,
+135,
+12,
+47,
+209,
+65,
+57,
+232,
+2,
+242,
+215,
+185,
+53,
+62,
+87,
+78,
+130,
+218,
+136,
+69,
+243,
+87,
+181,
+136,
+104,
+166,
+44,
+18,
+148,
+13,
+99,
+237,
+148,
+111,
+28,
+102,
+176,
+86,
+79,
+179,
+72,
+38,
+109,
+125,
+100,
+197,
+203,
+231,
+159,
+83,
+44,
+146,
+171,
+226,
+27,
+20,
+137,
+72,
+39,
+29,
+85,
+138,
+10,
+234,
+249,
+39,
+81,
+170,
+125,
+160,
+94,
+197,
+198,
+203,
+67,
+43,
+145,
+15,
+18,
+48,
+98,
+63,
+195,
+14,
+34,
+222,
+35,
+171,
+39,
+74,
+201,
+125,
+212,
+212,
+103,
+206,
+251,
+185,
+121,
+121,
+89,
+215,
+63,
+32,
+163,
+130,
+75,
+52,
+145,
+94,
+101,
+244,
+158,
+40,
+3,
+192,
+7,
+38,
+107,
+47,
+113,
+52,
+172,
+69,
+8,
+20,
+20,
+4,
+205,
+141,
+126,
+38,
+101,
+189,
+71,
+9,
+64,
+147,
+62,
+210,
+241,
+163,
+198,
+143,
+204,
+202,
+80,
+212,
+241,
+187,
+4,
+98,
+240,
+176,
+168,
+249,
+197,
+188,
+254,
+146,
+73,
+124,
+185,
+175,
+57,
+1,
+184,
+122,
+148,
+246,
+76,
+134,
+154,
+19,
+21,
+102,
+222,
+102,
+59,
+207,
+33,
+63,
+49,
+18,
+240,
+218,
+11,
+181,
+150,
+9,
+72,
+224,
+134,
+2,
+143,
+192,
+3,
+71,
+58,
+151,
+62,
+135,
+29,
+216,
+154,
+51,
+63,
+120,
+153,
+123,
+72,
+187,
+187,
+122,
+206,
+171,
+84,
+218,
+97,
+234,
+228,
+169,
+203,
+106,
+172,
+90,
+42,
+175,
+162,
+101,
+71,
+224,
+236,
+101,
+185,
+135,
+153,
+248,
+0,
+51,
+116,
+72,
+238,
+47,
+194,
+189,
+218,
+22,
+151,
+60,
+1,
+123,
+230,
+204,
+230,
+146,
+38,
+17,
+66,
+200,
+118,
+137,
+169,
+99,
+239,
+98,
+234,
+136,
+91,
+234,
+187,
+208,
+51,
+170,
+255,
+245,
+103,
+218,
+11,
+255,
+22,
+12,
+123,
+252,
+217,
+97,
+142,
+255,
+115,
+208,
+200,
+234,
+90,
+114,
+77,
+73,
+212,
+56,
+209,
+48,
+35,
+141,
+0,
+86,
+55,
+0,
+75,
+159,
+218,
+87,
+159,
+240,
+100,
+26,
+237,
+61,
+124,
+124,
+61,
+239,
+77,
+6,
+218,
+167,
+120,
+39,
+241,
+77,
+96,
+195,
+125,
+132,
+80,
+126,
+218,
+136,
+126,
+38,
+40,
+88,
+126,
+199,
+73,
+226,
+225,
+55,
+32,
+94,
+179,
+94,
+78,
+1,
+100,
+40,
+168,
+220,
+80,
+154,
+41,
+177,
+93,
+167,
+53,
+173,
+37,
+16,
+54,
+164,
+55,
+94,
+253,
+181,
+37,
+70,
+152,
+7,
+126,
+184,
+102,
+50,
+22,
+180,
+51,
+123,
+221,
+220,
+87,
+46,
+118,
+129,
+223,
+211,
+41,
+20,
+129,
+78,
+37,
+183,
+243,
+92,
+21,
+240,
+17,
+59,
+55,
+169,
+67,
+181,
+98,
+170,
+231,
+121,
+94,
+27,
+244,
+60,
+247,
+76,
+106,
+109,
+206,
+73,
+64,
+247,
+94,
+193,
+70,
+131,
+121,
+57,
+223,
+143,
+41,
+241,
+203,
+97,
+155,
+14,
+23,
+253,
+184,
+255,
+119,
+23,
+26,
+108,
+83,
+17,
+184,
+190,
+127,
+135,
+7,
+191,
+126,
+102,
+129,
+196,
+233,
+251,
+254,
+200,
+138,
+40,
+186,
+85,
+137,
+85,
+100,
+160,
+83,
+29,
+159,
+202,
+53,
+185,
+54,
+137,
+203,
+239,
+71,
+74,
+119,
+79,
+10,
+245,
+181,
+140,
+186,
+158,
+135,
+184,
+103,
+18,
+224,
+33,
+103,
+106,
+118,
+204,
+10,
+201,
+234,
+170,
+147,
+31,
+99,
+202,
+168,
+47,
+186,
+239,
+121,
+50,
+62,
+131,
+39,
+243,
+15,
+225,
+146,
+151,
+154,
+249,
+169,
+123,
+26,
+17,
+229,
+145,
+221,
+239,
+90,
+199,
+153,
+238,
+230,
+253,
+185,
+142,
+44,
+116,
+126,
+166,
+166,
+189,
+41,
+206,
+176,
+57,
+176,
+67,
+208,
+74,
+60,
+121,
+197,
+87,
+138,
+170,
+232,
+104,
+154,
+67,
+48,
+52,
+50,
+22,
+49,
+236,
+165,
+94,
+96,
+36,
+4,
+7,
+225,
+46,
+213,
+146,
+104,
+133,
+213,
+57,
+207,
+18,
+178,
+149,
+105,
+61,
+63,
+82,
+166,
+218,
+150,
+214,
+14,
+200,
+237,
+64,
+180,
+147,
+159,
+21,
+183,
+164,
+28,
+152,
+210,
+241,
+42,
+59,
+118,
+0,
+116,
+70,
+18,
diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat
new file mode 100644 (file)
index 0000000..175d482
--- /dev/null
@@ -0,0 +1,9984 @@
+6,
+1,
+1,
+6,
+2,
+0,
+4,
+2,
+6,
+2,
+4,
+2,
+0,
+2,
+2,
+6,
+1,
+4,
+6,
+1,
+7,
+3,
+6,
+3,
+2,
+7,
+3,
+7,
+2,
+4,
+1,
+4,
+3,
+7,
+7,
+5,
+7,
+3,
+5,
+7,
+2,
+2,
+0,
+5,
+0,
+4,
+5,
+5,
+3,
+0,
+5,
+2,
+3,
+1,
+5,
+2,
+1,
+7,
+5,
+5,
+0,
+7,
+3,
+2,
+1,
+2,
+0,
+4,
+0,
+1,
+5,
+1,
+5,
+1,
+0,
+1,
+1,
+6,
+5,
+4,
+1,
+1,
+1,
+3,
+4,
+5,
+7,
+0,
+3,
+1,
+6,
+6,
+0,
+5,
+1,
+6,
+3,
+7,
+7,
+7,
+0,
+0,
+2,
+7,
+7,
+3,
+7,
+4,
+7,
+6,
+6,
+3,
+1,
+5,
+7,
+3,
+5,
+2,
+4,
+4,
+2,
+6,
+6,
+2,
+6,
+6,
+1,
+0,
+5,
+2,
+7,
+6,
+4,
+3,
+5,
+2,
+2,
+6,
+3,
+5,
+1,
+7,
+5,
+3,
+2,
+3,
+4,
+7,
+5,
+3,
+0,
+2,
+3,
+1,
+1,
+5,
+5,
+2,
+1,
+1,
+2,
+5,
+7,
+2,
+4,
+1,
+7,
+1,
+0,
+2,
+0,
+5,
+4,
+7,
+5,
+5,
+5,
+5,
+4,
+1,
+5,
+5,
+3,
+1,
+0,
+4,
+5,
+6,
+6,
+7,
+7,
+7,
+4,
+0,
+1,
+1,
+4,
+1,
+3,
+2,
+6,
+0,
+5,
+0,
+3,
+1,
+7,
+5,
+2,
+0,
+2,
+5,
+3,
+3,
+1,
+1,
+1,
+2,
+2,
+5,
+7,
+7,
+0,
+4,
+3,
+7,
+3,
+2,
+3,
+6,
+4,
+7,
+7,
+5,
+0,
+5,
+4,
+0,
+0,
+4,
+0,
+7,
+4,
+0,
+2,
+1,
+4,
+2,
+5,
+7,
+7,
+2,
+7,
+3,
+0,
+1,
+6,
+7,
+4,
+6,
+6,
+7,
+5,
+3,
+5,
+6,
+4,
+4,
+7,
+2,
+2,
+5,
+0,
+2,
+1,
+3,
+5,
+0,
+2,
+5,
+7,
+2,
+3,
+4,
+4,
+2,
+1,
+0,
+1,
+0,
+3,
+2,
+0,
+3,
+7,
+5,
+0,
+3,
+7,
+3,
+7,
+4,
+3,
+2,
+1,
+3,
+4,
+0,
+6,
+1,
+6,
+7,
+6,
+0,
+2,
+1,
+0,
+6,
+7,
+5,
+1,
+5,
+4,
+6,
+6,
+2,
+4,
+6,
+5,
+2,
+1,
+0,
+2,
+1,
+2,
+2,
+3,
+1,
+4,
+0,
+6,
+3,
+7,
+1,
+4,
+7,
+5,
+5,
+5,
+0,
+6,
+4,
+4,
+7,
+6,
+0,
+6,
+4,
+4,
+4,
+5,
+3,
+3,
+0,
+4,
+2,
+6,
+3,
+1,
+3,
+3,
+3,
+1,
+5,
+7,
+2,
+0,
+0,
+5,
+5,
+4,
+1,
+3,
+7,
+3,
+3,
+2,
+1,
+6,
+2,
+6,
+1,
+7,
+1,
+6,
+2,
+4,
+4,
+6,
+0,
+3,
+1,
+2,
+7,
+5,
+5,
+6,
+0,
+5,
+1,
+1,
+7,
+5,
+4,
+5,
+0,
+5,
+7,
+3,
+0,
+6,
+2,
+6,
+3,
+7,
+5,
+4,
+7,
+5,
+0,
+5,
+6,
+6,
+2,
+6,
+6,
+2,
+2,
+1,
+3,
+7,
+1,
+5,
+1,
+1,
+7,
+1,
+4,
+6,
+0,
+6,
+0,
+0,
+0,
+7,
+4,
+0,
+1,
+4,
+0,
+5,
+0,
+6,
+3,
+3,
+7,
+6,
+1,
+7,
+5,
+3,
+2,
+4,
+2,
+3,
+7,
+3,
+3,
+6,
+0,
+5,
+7,
+7,
+5,
+1,
+1,
+5,
+6,
+2,
+0,
+3,
+3,
+7,
+6,
+4,
+0,
+6,
+6,
+3,
+4,
+2,
+7,
+5,
+3,
+2,
+6,
+5,
+7,
+6,
+2,
+2,
+4,
+3,
+7,
+7,
+0,
+6,
+3,
+0,
+3,
+1,
+1,
+4,
+4,
+7,
+6,
+4,
+1,
+1,
+3,
+7,
+6,
+4,
+6,
+0,
+4,
+0,
+6,
+7,
+2,
+0,
+0,
+7,
+0,
+5,
+0,
+0,
+4,
+1,
+3,
+5,
+6,
+7,
+1,
+4,
+2,
+6,
+4,
+0,
+0,
+6,
+1,
+1,
+3,
+5,
+0,
+7,
+3,
+4,
+0,
+4,
+4,
+2,
+1,
+5,
+7,
+7,
+5,
+3,
+5,
+4,
+2,
+4,
+0,
+3,
+7,
+3,
+2,
+4,
+6,
+0,
+1,
+6,
+3,
+2,
+2,
+1,
+0,
+0,
+6,
+1,
+2,
+7,
+1,
+5,
+7,
+7,
+7,
+3,
+7,
+3,
+3,
+4,
+5,
+3,
+1,
+0,
+6,
+3,
+1,
+6,
+1,
+3,
+3,
+3,
+2,
+4,
+5,
+5,
+4,
+6,
+1,
+0,
+7,
+6,
+0,
+7,
+2,
+5,
+7,
+2,
+0,
+6,
+5,
+0,
+6,
+0,
+1,
+4,
+7,
+6,
+6,
+0,
+0,
+5,
+3,
+0,
+2,
+6,
+2,
+1,
+5,
+4,
+0,
+2,
+6,
+2,
+6,
+2,
+7,
+1,
+4,
+4,
+5,
+6,
+2,
+7,
+7,
+6,
+4,
+3,
+5,
+4,
+6,
+7,
+3,
+5,
+7,
+1,
+7,
+7,
+6,
+3,
+1,
+1,
+3,
+3,
+4,
+4,
+5,
+1,
+0,
+1,
+5,
+6,
+1,
+4,
+1,
+6,
+7,
+3,
+7,
+1,
+7,
+3,
+6,
+0,
+3,
+5,
+1,
+0,
+3,
+5,
+6,
+7,
+3,
+6,
+4,
+2,
+0,
+0,
+1,
+0,
+2,
+5,
+0,
+6,
+2,
+4,
+4,
+1,
+1,
+1,
+1,
+4,
+2,
+3,
+4,
+6,
+2,
+4,
+4,
+6,
+0,
+2,
+1,
+6,
+3,
+0,
+6,
+1,
+1,
+2,
+6,
+2,
+3,
+0,
+3,
+5,
+7,
+1,
+7,
+0,
+0,
+5,
+5,
+5,
+5,
+2,
+2,
+4,
+4,
+4,
+7,
+7,
+3,
+0,
+4,
+4,
+3,
+3,
+6,
+7,
+3,
+5,
+2,
+7,
+7,
+7,
+5,
+3,
+6,
+5,
+5,
+1,
+3,
+4,
+2,
+2,
+0,
+5,
+6,
+7,
+6,
+1,
+4,
+1,
+0,
+1,
+7,
+2,
+1,
+3,
+2,
+4,
+3,
+5,
+3,
+7,
+3,
+6,
+5,
+6,
+1,
+1,
+6,
+7,
+7,
+7,
+5,
+4,
+3,
+0,
+7,
+3,
+4,
+4,
+3,
+5,
+6,
+0,
+1,
+1,
+6,
+4,
+0,
+3,
+1,
+7,
+1,
+1,
+0,
+3,
+1,
+4,
+4,
+0,
+5,
+2,
+4,
+3,
+7,
+3,
+2,
+1,
+5,
+3,
+6,
+0,
+2,
+2,
+3,
+6,
+2,
+2,
+5,
+3,
+5,
+1,
+5,
+4,
+6,
+5,
+3,
+2,
+6,
+6,
+2,
+4,
+5,
+3,
+0,
+0,
+3,
+0,
+2,
+7,
+1,
+7,
+4,
+3,
+1,
+2,
+7,
+0,
+3,
+5,
+0,
+1,
+4,
+1,
+6,
+3,
+5,
+4,
+3,
+0,
+6,
+4,
+0,
+5,
+5,
+3,
+7,
+4,
+1,
+4,
+4,
+4,
+0,
+7,
+0,
+3,
+0,
+0,
+1,
+1,
+5,
+2,
+3,
+4,
+0,
+7,
+4,
+2,
+5,
+3,
+3,
+4,
+1,
+3,
+1,
+6,
+6,
+2,
+6,
+6,
+6,
+7,
+2,
+5,
+7,
+5,
+7,
+3,
+5,
+2,
+3,
+1,
+4,
+2,
+2,
+6,
+4,
+1,
+2,
+5,
+4,
+5,
+7,
+0,
+2,
+6,
+1,
+4,
+1,
+7,
+6,
+5,
+1,
+0,
+2,
+7,
+1,
+3,
+0,
+0,
+2,
+4,
+5,
+3,
+4,
+7,
+6,
+7,
+2,
+3,
+5,
+0,
+4,
+1,
+4,
+4,
+5,
+1,
+5,
+2,
+0,
+0,
+2,
+4,
+2,
+0,
+1,
+1,
+6,
+1,
+6,
+0,
+2,
+5,
+2,
+2,
+3,
+5,
+6,
+6,
+0,
+3,
+0,
+2,
+1,
+0,
+3,
+5,
+3,
+0,
+4,
+2,
+6,
+2,
+4,
+5,
+6,
+1,
+7,
+2,
+0,
+7,
+0,
+3,
+3,
+6,
+6,
+0,
+0,
+0,
+0,
+6,
+3,
+3,
+4,
+1,
+7,
+3,
+7,
+7,
+4,
+3,
+5,
+7,
+7,
+0,
+2,
+3,
+4,
+7,
+1,
+1,
+0,
+5,
+4,
+1,
+6,
+3,
+5,
+6,
+5,
+0,
+5,
+3,
+6,
+7,
+1,
+5,
+2,
+5,
+6,
+2,
+2,
+7,
+5,
+4,
+1,
+6,
+2,
+3,
+1,
+7,
+4,
+7,
+4,
+3,
+1,
+7,
+0,
+6,
+6,
+2,
+0,
+2,
+4,
+5,
+0,
+4,
+1,
+3,
+1,
+3,
+7,
+4,
+5,
+2,
+2,
+3,
+0,
+5,
+5,
+2,
+4,
+3,
+7,
+0,
+2,
+3,
+3,
+6,
+2,
+6,
+3,
+4,
+5,
+0,
+4,
+2,
+2,
+5,
+5,
+0,
+5,
+4,
+2,
+4,
+2,
+7,
+3,
+7,
+3,
+7,
+7,
+2,
+2,
+2,
+6,
+2,
+6,
+1,
+3,
+1,
+1,
+2,
+4,
+7,
+4,
+1,
+1,
+1,
+7,
+5,
+6,
+1,
+5,
+0,
+3,
+5,
+0,
+4,
+6,
+2,
+5,
+5,
+6,
+5,
+5,
+4,
+5,
+3,
+0,
+5,
+0,
+0,
+1,
+3,
+5,
+3,
+1,
+2,
+1,
+2,
+2,
+6,
+6,
+4,
+1,
+0,
+2,
+4,
+5,
+5,
+1,
+4,
+3,
+6,
+5,
+4,
+7,
+1,
+0,
+5,
+5,
+6,
+5,
+0,
+5,
+3,
+6,
+0,
+6,
+4,
+6,
+4,
+1,
+6,
+1,
+4,
+1,
+7,
+4,
+0,
+6,
+3,
+1,
+1,
+5,
+3,
+5,
+0,
+7,
+6,
+0,
+0,
+3,
+7,
+6,
+6,
+5,
+5,
+5,
+6,
+4,
+0,
+4,
+0,
+3,
+0,
+6,
+2,
+3,
+7,
+7,
+5,
+3,
+0,
+6,
+2,
+2,
+5,
+1,
+1,
+6,
+4,
+6,
+2,
+3,
+4,
+1,
+3,
+2,
+2,
+4,
+6,
+0,
+7,
+0,
+4,
+0,
+2,
+2,
+7,
+5,
+4,
+5,
+4,
+6,
+1,
+0,
+6,
+5,
+1,
+6,
+6,
+0,
+6,
+0,
+2,
+3,
+5,
+0,
+3,
+0,
+2,
+5,
+2,
+7,
+5,
+3,
+3,
+3,
+5,
+4,
+7,
+7,
+4,
+4,
+3,
+5,
+2,
+3,
+7,
+2,
+5,
+6,
+0,
+5,
+4,
+7,
+5,
+5,
+6,
+0,
+2,
+2,
+7,
+3,
+1,
+7,
+2,
+5,
+7,
+7,
+1,
+5,
+2,
+5,
+2,
+7,
+0,
+6,
+3,
+3,
+6,
+0,
+4,
+4,
+5,
+0,
+0,
+0,
+1,
+2,
+3,
+0,
+2,
+3,
+3,
+7,
+2,
+1,
+6,
+7,
+0,
+7,
+2,
+7,
+5,
+7,
+1,
+7,
+4,
+4,
+3,
+3,
+1,
+1,
+6,
+7,
+6,
+0,
+1,
+0,
+6,
+7,
+1,
+6,
+4,
+3,
+7,
+0,
+6,
+7,
+5,
+7,
+3,
+7,
+3,
+4,
+1,
+4,
+1,
+1,
+5,
+1,
+7,
+5,
+1,
+4,
+4,
+2,
+4,
+1,
+1,
+4,
+4,
+3,
+6,
+3,
+3,
+7,
+3,
+7,
+3,
+6,
+7,
+3,
+7,
+0,
+0,
+0,
+4,
+5,
+1,
+7,
+7,
+2,
+2,
+3,
+1,
+7,
+6,
+7,
+7,
+7,
+7,
+0,
+6,
+5,
+6,
+0,
+1,
+5,
+5,
+1,
+7,
+6,
+2,
+7,
+0,
+0,
+7,
+3,
+7,
+5,
+0,
+5,
+6,
+0,
+4,
+3,
+0,
+5,
+5,
+5,
+6,
+3,
+1,
+1,
+6,
+4,
+6,
+4,
+0,
+0,
+7,
+1,
+2,
+4,
+6,
+1,
+5,
+4,
+7,
+3,
+4,
+1,
+0,
+3,
+3,
+5,
+6,
+7,
+4,
+2,
+1,
+5,
+2,
+0,
+7,
+6,
+1,
+0,
+1,
+0,
+1,
+3,
+7,
+3,
+1,
+3,
+3,
+6,
+5,
+5,
+2,
+3,
+6,
+7,
+4,
+0,
+4,
+5,
+2,
+7,
+3,
+0,
+4,
+7,
+2,
+6,
+5,
+7,
+3,
+3,
+6,
+5,
+2,
+5,
+2,
+2,
+3,
+4,
+0,
+7,
+3,
+6,
+5,
+1,
+0,
+2,
+1,
+4,
+3,
+4,
+3,
+2,
+0,
+4,
+6,
+5,
+6,
+6,
+4,
+0,
+4,
+0,
+7,
+0,
+3,
+4,
+0,
+1,
+1,
+5,
+3,
+4,
+7,
+4,
+2,
+4,
+7,
+0,
+6,
+7,
+6,
+6,
+6,
+1,
+1,
+6,
+0,
+0,
+4,
+4,
+7,
+6,
+6,
+4,
+5,
+0,
+1,
+2,
+4,
+0,
+1,
+4,
+3,
+4,
+1,
+2,
+7,
+6,
+5,
+5,
+6,
+6,
+4,
+2,
+4,
+6,
+2,
+7,
+2,
+7,
+1,
+2,
+3,
+1,
+7,
+3,
+5,
+1,
+4,
+1,
+4,
+1,
+7,
+4,
+1,
+0,
+7,
+7,
+4,
+2,
+0,
+7,
+6,
+1,
+2,
+2,
+1,
+5,
+4,
+2,
+5,
+6,
+4,
+6,
+7,
+1,
+2,
+7,
+5,
+6,
+1,
+0,
+0,
+7,
+0,
+6,
+5,
+3,
+1,
+5,
+7,
+2,
+4,
+0,
+7,
+3,
+6,
+3,
+1,
+2,
+4,
+7,
+6,
+1,
+3,
+4,
+3,
+6,
+1,
+3,
+5,
+0,
+7,
+2,
+2,
+4,
+1,
+4,
+2,
+2,
+0,
+4,
+3,
+6,
+7,
+2,
+3,
+1,
+3,
+4,
+2,
+7,
+3,
+1,
+6,
+3,
+0,
+3,
+7,
+2,
+0,
+2,
+1,
+3,
+1,
+6,
+6,
+3,
+3,
+5,
+0,
+2,
+3,
+1,
+6,
+6,
+3,
+2,
+3,
+4,
+7,
+5,
+7,
+7,
+5,
+4,
+4,
+4,
+2,
+1,
+7,
+1,
+4,
+5,
+7,
+5,
+7,
+5,
+6,
+4,
+0,
+6,
+6,
+6,
+5,
+5,
+4,
+5,
+4,
+0,
+1,
+4,
+2,
+2,
+2,
+4,
+4,
+3,
+5,
+7,
+3,
+3,
+2,
+0,
+3,
+7,
+7,
+4,
+7,
+4,
+6,
+0,
+3,
+7,
+4,
+6,
+7,
+1,
+7,
+2,
+3,
+3,
+6,
+5,
+4,
+6,
+4,
+3,
+0,
+5,
+6,
+7,
+6,
+5,
+5,
+2,
+3,
+0,
+6,
+3,
+1,
+5,
+0,
+7,
+4,
+3,
+4,
+6,
+1,
+6,
+5,
+2,
+6,
+3,
+6,
+4,
+4,
+4,
+3,
+3,
+5,
+3,
+0,
+6,
+6,
+4,
+3,
+3,
+4,
+3,
+7,
+1,
+7,
+5,
+7,
+5,
+5,
+5,
+1,
+3,
+6,
+5,
+6,
+1,
+2,
+3,
+1,
+6,
+6,
+0,
+3,
+2,
+5,
+5,
+4,
+3,
+2,
+0,
+1,
+4,
+4,
+1,
+4,
+6,
+0,
+5,
+4,
+4,
+7,
+1,
+3,
+2,
+4,
+4,
+1,
+1,
+5,
+5,
+6,
+7,
+7,
+6,
+0,
+5,
+4,
+7,
+2,
+6,
+2,
+7,
+1,
+1,
+2,
+0,
+5,
+4,
+0,
+1,
+0,
+6,
+2,
+6,
+4,
+1,
+6,
+2,
+6,
+7,
+0,
+5,
+2,
+7,
+3,
+0,
+7,
+3,
+3,
+7,
+6,
+1,
+6,
+5,
+3,
+7,
+7,
+0,
+1,
+2,
+7,
+5,
+5,
+5,
+3,
+5,
+5,
+6,
+0,
+4,
+5,
+4,
+0,
+7,
+2,
+1,
+3,
+5,
+1,
+4,
+7,
+4,
+3,
+6,
+3,
+0,
+4,
+3,
+2,
+1,
+7,
+2,
+1,
+2,
+0,
+7,
+5,
+7,
+4,
+6,
+4,
+3,
+0,
+5,
+3,
+7,
+3,
+3,
+1,
+7,
+4,
+2,
+2,
+4,
+3,
+6,
+2,
+1,
+5,
+0,
+7,
+2,
+0,
+7,
+7,
+7,
+3,
+2,
+6,
+1,
+5,
+5,
+4,
+6,
+4,
+3,
+3,
+5,
+6,
+7,
+1,
+1,
+1,
+0,
+1,
+5,
+4,
+2,
+2,
+1,
+0,
+5,
+4,
+7,
+1,
+5,
+6,
+6,
+6,
+6,
+4,
+1,
+0,
+1,
+5,
+6,
+1,
+6,
+0,
+4,
+3,
+5,
+0,
+3,
+4,
+1,
+2,
+0,
+1,
+2,
+6,
+0,
+1,
+6,
+0,
+6,
+0,
+5,
+4,
+0,
+5,
+3,
+5,
+0,
+5,
+4,
+2,
+2,
+2,
+5,
+0,
+4,
+5,
+1,
+6,
+6,
+7,
+4,
+3,
+7,
+7,
+5,
+0,
+4,
+1,
+3,
+0,
+7,
+0,
+0,
+5,
+5,
+1,
+1,
+6,
+6,
+7,
+0,
+4,
+3,
+1,
+2,
+3,
+5,
+7,
+1,
+3,
+1,
+2,
+3,
+2,
+4,
+0,
+3,
+4,
+1,
+2,
+1,
+7,
+0,
+0,
+1,
+5,
+7,
+5,
+1,
+5,
+5,
+6,
+7,
+4,
+1,
+2,
+7,
+0,
+3,
+2,
+5,
+4,
+3,
+5,
+0,
+5,
+6,
+7,
+2,
+5,
+6,
+4,
+7,
+5,
+6,
+4,
+7,
+6,
+6,
+7,
+0,
+0,
+4,
+6,
+6,
+4,
+4,
+3,
+7,
+4,
+7,
+0,
+4,
+3,
+2,
+5,
+0,
+5,
+6,
+5,
+0,
+4,
+5,
+7,
+0,
+3,
+3,
+0,
+0,
+2,
+7,
+1,
+5,
+2,
+5,
+5,
+2,
+2,
+5,
+7,
+6,
+6,
+3,
+1,
+0,
+7,
+5,
+1,
+3,
+0,
+3,
+7,
+3,
+1,
+2,
+3,
+3,
+5,
+7,
+7,
+5,
+6,
+4,
+2,
+1,
+6,
+6,
+2,
+5,
+7,
+2,
+4,
+1,
+5,
+3,
+0,
+1,
+6,
+1,
+0,
+5,
+0,
+6,
+3,
+5,
+6,
+7,
+4,
+3,
+7,
+4,
+0,
+5,
+3,
+1,
+5,
+1,
+4,
+0,
+2,
+0,
+1,
+5,
+2,
+7,
+3,
+4,
+1,
+3,
+0,
+3,
+3,
+5,
+5,
+4,
+3,
+2,
+6,
+1,
+5,
+4,
+6,
+5,
+3,
+2,
+7,
+5,
+5,
+6,
+0,
+0,
+7,
+7,
+7,
+1,
+0,
+4,
+2,
+6,
+5,
+7,
+0,
+7,
+0,
+1,
+1,
+3,
+7,
+0,
+6,
+6,
+5,
+5,
+2,
+1,
+5,
+1,
+7,
+0,
+3,
+0,
+5,
+1,
+3,
+3,
+3,
+5,
+4,
+3,
+0,
+5,
+0,
+4,
+0,
+2,
+2,
+4,
+3,
+7,
+7,
+6,
+7,
+6,
+5,
+0,
+3,
+4,
+0,
+3,
+2,
+2,
+5,
+2,
+5,
+6,
+6,
+0,
+7,
+4,
+4,
+1,
+4,
+2,
+3,
+1,
+1,
+5,
+0,
+6,
+4,
+6,
+6,
+7,
+0,
+5,
+6,
+4,
+1,
+2,
+4,
+1,
+1,
+7,
+7,
+0,
+6,
+0,
+4,
+3,
+3,
+0,
+2,
+4,
+6,
+5,
+5,
+1,
+3,
+3,
+6,
+1,
+1,
+6,
+3,
+3,
+4,
+3,
+7,
+4,
+3,
+3,
+4,
+1,
+4,
+2,
+5,
+3,
+0,
+6,
+6,
+1,
+4,
+6,
+0,
+3,
+3,
+3,
+7,
+2,
+4,
+2,
+6,
+0,
+5,
+6,
+4,
+6,
+7,
+7,
+2,
+6,
+0,
+7,
+5,
+7,
+2,
+7,
+0,
+0,
+0,
+6,
+2,
+7,
+4,
+1,
+6,
+5,
+2,
+7,
+6,
+2,
+7,
+6,
+5,
+5,
+4,
+3,
+4,
+7,
+1,
+4,
+1,
+5,
+5,
+5,
+0,
+1,
+4,
+6,
+6,
+0,
+2,
+5,
+2,
+6,
+3,
+2,
+1,
+1,
+2,
+6,
+5,
+1,
+0,
+4,
+0,
+0,
+0,
+6,
+2,
+7,
+3,
+5,
+4,
+6,
+2,
+5,
+0,
+0,
+5,
+7,
+4,
+6,
+5,
+2,
+7,
+6,
+3,
+2,
+4,
+0,
+2,
+3,
+4,
+6,
+7,
+2,
+5,
+5,
+7,
+2,
+0,
+4,
+2,
+6,
+6,
+3,
+4,
+3,
+5,
+2,
+0,
+7,
+6,
+6,
+7,
+2,
+5,
+7,
+7,
+5,
+1,
+6,
+7,
+3,
+5,
+1,
+1,
+5,
+0,
+6,
+3,
+7,
+7,
+3,
+3,
+4,
+2,
+6,
+7,
+4,
+7,
+0,
+2,
+6,
+0,
+1,
+2,
+5,
+6,
+0,
+2,
+5,
+5,
+4,
+0,
+2,
+3,
+7,
+2,
+6,
+5,
+0,
+4,
+4,
+1,
+2,
+6,
+5,
+3,
+2,
+1,
+0,
+0,
+2,
+2,
+1,
+3,
+1,
+5,
+2,
+4,
+0,
+0,
+0,
+5,
+5,
+7,
+6,
+0,
+0,
+4,
+2,
+1,
+6,
+3,
+4,
+6,
+0,
+3,
+6,
+3,
+7,
+5,
+3,
+2,
+7,
+3,
+0,
+6,
+3,
+6,
+7,
+3,
+5,
+2,
+5,
+0,
+1,
+0,
+0,
+7,
+3,
+0,
+3,
+6,
+7,
+4,
+1,
+4,
+5,
+5,
+2,
+5,
+2,
+4,
+6,
+2,
+2,
+2,
+5,
+0,
+7,
+0,
+3,
+5,
+6,
+2,
+0,
+3,
+4,
+3,
+5,
+0,
+6,
+1,
+1,
+5,
+7,
+1,
+2,
+3,
+0,
+7,
+1,
+0,
+0,
+0,
+7,
+7,
+5,
+2,
+5,
+2,
+4,
+6,
+1,
+2,
+2,
+1,
+0,
+6,
+5,
+4,
+4,
+0,
+4,
+0,
+7,
+5,
+5,
+6,
+5,
+2,
+3,
+4,
+7,
+0,
+6,
+6,
+6,
+6,
+0,
+0,
+2,
+3,
+6,
+4,
+1,
+6,
+7,
+7,
+0,
+2,
+1,
+0,
+2,
+3,
+4,
+2,
+5,
+7,
+1,
+7,
+0,
+1,
+2,
+6,
+1,
+4,
+0,
+7,
+7,
+3,
+3,
+4,
+0,
+6,
+0,
+1,
+6,
+3,
+2,
+7,
+6,
+0,
+2,
+5,
+4,
+2,
+0,
+0,
+4,
+7,
+5,
+6,
+2,
+7,
+6,
+2,
+6,
+3,
+2,
+1,
+0,
+4,
+4,
+4,
+1,
+5,
+7,
+4,
+5,
+7,
+3,
+0,
+0,
+3,
+1,
+6,
+2,
+1,
+3,
+0,
+2,
+0,
+5,
+3,
+4,
+5,
+0,
+1,
+0,
+7,
+2,
+6,
+0,
+5,
+5,
+3,
+2,
+7,
+3,
+0,
+6,
+0,
+0,
+3,
+0,
+4,
+7,
+6,
+1,
+2,
+1,
+5,
+1,
+7,
+4,
+7,
+2,
+3,
+6,
+6,
+2,
+0,
+5,
+6,
+2,
+1,
+6,
+2,
+5,
+3,
+2,
+3,
+0,
+2,
+3,
+6,
+2,
+7,
+1,
+4,
+4,
+2,
+7,
+7,
+4,
+3,
+6,
+5,
+1,
+6,
+6,
+2,
+1,
+6,
+1,
+4,
+0,
+5,
+2,
+2,
+6,
+4,
+4,
+5,
+4,
+3,
+3,
+5,
+6,
+3,
+7,
+0,
+0,
+4,
+2,
+4,
+3,
+1,
+2,
+6,
+3,
+0,
+5,
+4,
+6,
+4,
+3,
+7,
+7,
+7,
+4,
+0,
+7,
+7,
+1,
+2,
+7,
+6,
+1,
+7,
+6,
+6,
+0,
+4,
+4,
+3,
+5,
+3,
+3,
+5,
+3,
+2,
+4,
+2,
+2,
+6,
+1,
+6,
+7,
+1,
+4,
+0,
+0,
+4,
+6,
+1,
+1,
+1,
+6,
+0,
+6,
+3,
+3,
+5,
+3,
+6,
+5,
+4,
+2,
+0,
+6,
+0,
+2,
+4,
+5,
+2,
+1,
+5,
+2,
+7,
+4,
+5,
+1,
+2,
+3,
+7,
+7,
+6,
+5,
+4,
+6,
+7,
+6,
+6,
+2,
+5,
+7,
+5,
+6,
+7,
+7,
+5,
+3,
+6,
+7,
+4,
+2,
+4,
+4,
+7,
+6,
+3,
+6,
+6,
+1,
+6,
+1,
+6,
+5,
+3,
+1,
+6,
+1,
+0,
+0,
+4,
+7,
+1,
+1,
+1,
+4,
+3,
+6,
+6,
+4,
+1,
+0,
+6,
+2,
+6,
+5,
+4,
+5,
+6,
+0,
+5,
+1,
+4,
+6,
+7,
+6,
+2,
+5,
+1,
+0,
+4,
+2,
+2,
+2,
+7,
+5,
+7,
+7,
+5,
+7,
+6,
+3,
+0,
+1,
+4,
+0,
+1,
+4,
+2,
+7,
+0,
+4,
+6,
+5,
+0,
+2,
+6,
+2,
+7,
+1,
+2,
+0,
+7,
+7,
+7,
+3,
+6,
+2,
+3,
+3,
+6,
+2,
+1,
+7,
+3,
+1,
+3,
+2,
+3,
+7,
+1,
+1,
+6,
+6,
+4,
+1,
+4,
+1,
+0,
+2,
+5,
+7,
+5,
+7,
+3,
+5,
+5,
+3,
+1,
+5,
+5,
+7,
+5,
+2,
+1,
+0,
+7,
+4,
+0,
+2,
+6,
+1,
+0,
+5,
+3,
+0,
+7,
+7,
+4,
+7,
+5,
+2,
+6,
+7,
+7,
+5,
+4,
+0,
+2,
+1,
+3,
+5,
+6,
+7,
+3,
+2,
+7,
+5,
+3,
+6,
+2,
+3,
+7,
+5,
+0,
+5,
+1,
+0,
+2,
+1,
+3,
+1,
+7,
+6,
+0,
+1,
+0,
+7,
+1,
+2,
+6,
+1,
+6,
+0,
+3,
+2,
+3,
+5,
+0,
+6,
+7,
+1,
+1,
+1,
+0,
+7,
+0,
+3,
+1,
+7,
+6,
+0,
+6,
+4,
+6,
+7,
+2,
+7,
+3,
+7,
+5,
+4,
+1,
+6,
+6,
+5,
+6,
+6,
+1,
+6,
+7,
+0,
+6,
+1,
+1,
+6,
+1,
+4,
+1,
+0,
+4,
+6,
+2,
+5,
+1,
+1,
+6,
+7,
+2,
+3,
+6,
+2,
+3,
+3,
+2,
+4,
+1,
+0,
+6,
+1,
+2,
+5,
+6,
+1,
+1,
+7,
+7,
+5,
+7,
+3,
+3,
+5,
+7,
+7,
+7,
+0,
+3,
+2,
+1,
+4,
+2,
+3,
+1,
+3,
+7,
+0,
+7,
+1,
+4,
+2,
+1,
+5,
+0,
+0,
+5,
+0,
+4,
+3,
+0,
+4,
+1,
+5,
+3,
+2,
+0,
+5,
+5,
+7,
+5,
+1,
+7,
+3,
+0,
+6,
+2,
+2,
+4,
+6,
+3,
+3,
+0,
+7,
+7,
+7,
+5,
+6,
+6,
+1,
+6,
+6,
+6,
+6,
+3,
+6,
+6,
+6,
+0,
+5,
+5,
+2,
+7,
+3,
+2,
+2,
+5,
+2,
+4,
+6,
+7,
+6,
+2,
+0,
+5,
+5,
+3,
+7,
+3,
+7,
+2,
+5,
+5,
+6,
+0,
+4,
+3,
+7,
+5,
+3,
+4,
+7,
+3,
+0,
+3,
+5,
+2,
+2,
+4,
+0,
+3,
+6,
+7,
+0,
+3,
+7,
+2,
+6,
+3,
+5,
+3,
+7,
+4,
+0,
+1,
+7,
+6,
+3,
+0,
+6,
+5,
+4,
+7,
+7,
+3,
+2,
+3,
+1,
+2,
+2,
+0,
+3,
+5,
+5,
+4,
+4,
+1,
+1,
+4,
+5,
+7,
+4,
+0,
+1,
+1,
+0,
+5,
+5,
+3,
+4,
+5,
+3,
+3,
+4,
+6,
+3,
+3,
+3,
+2,
+2,
+4,
+1,
+2,
+0,
+0,
+2,
+1,
+2,
+6,
+3,
+2,
+0,
+1,
+0,
+2,
+5,
+3,
+7,
+6,
+2,
+2,
+6,
+3,
+6,
+6,
+3,
+3,
+4,
+5,
+3,
+0,
+5,
+7,
+4,
+1,
+5,
+2,
+7,
+7,
+3,
+3,
+0,
+6,
+0,
+5,
+4,
+3,
+0,
+1,
+0,
+0,
+5,
+2,
+5,
+5,
+5,
+1,
+0,
+4,
+5,
+4,
+5,
+1,
+5,
+0,
+2,
+6,
+2,
+7,
+6,
+1,
+2,
+7,
+0,
+0,
+5,
+4,
+6,
+2,
+2,
+0,
+7,
+0,
+4,
+5,
+1,
+1,
+1,
+4,
+3,
+3,
+7,
+5,
+1,
+5,
+6,
+3,
+4,
+0,
+1,
+0,
+7,
+3,
+7,
+4,
+1,
+0,
+7,
+0,
+7,
+5,
+3,
+4,
+0,
+2,
+2,
+3,
+5,
+3,
+5,
+5,
+7,
+0,
+4,
+0,
+5,
+4,
+0,
+3,
+3,
+3,
+3,
+2,
+4,
+5,
+7,
+6,
+6,
+4,
+4,
+0,
+6,
+4,
+6,
+0,
+7,
+0,
+5,
+3,
+2,
+6,
+0,
+1,
+2,
+5,
+6,
+4,
+5,
+5,
+1,
+1,
+7,
+7,
+0,
+2,
+3,
+4,
+1,
+6,
+1,
+0,
+5,
+3,
+1,
+1,
+0,
+4,
+7,
+5,
+0,
+1,
+1,
+5,
+7,
+2,
+7,
+1,
+4,
+0,
+4,
+4,
+7,
+0,
+3,
+4,
+6,
+6,
+0,
+1,
+6,
+2,
+5,
+1,
+5,
+1,
+6,
+7,
+6,
+7,
+7,
+1,
+1,
+3,
+2,
+0,
+5,
+4,
+6,
+1,
+7,
+7,
+1,
+7,
+2,
+7,
+2,
+1,
+1,
+5,
+1,
+5,
+1,
+4,
+3,
+2,
+6,
+2,
+5,
+0,
+7,
+4,
+0,
+7,
+3,
+5,
+0,
+4,
+5,
+2,
+6,
+3,
+4,
+7,
+5,
+2,
+2,
+4,
+3,
+0,
+2,
+5,
+6,
+3,
+1,
+5,
+2,
+4,
+2,
+1,
+1,
+2,
+2,
+6,
+5,
+6,
+4,
+3,
+4,
+6,
+1,
+0,
+7,
+7,
+3,
+4,
+6,
+0,
+1,
+2,
+0,
+1,
+2,
+5,
+0,
+3,
+1,
+2,
+2,
+4,
+4,
+4,
+4,
+4,
+4,
+6,
+5,
+0,
+7,
+1,
+5,
+4,
+1,
+6,
+6,
+1,
+6,
+0,
+2,
+3,
+4,
+6,
+4,
+0,
+2,
+3,
+7,
+2,
+3,
+4,
+2,
+7,
+1,
+2,
+7,
+2,
+6,
+5,
+5,
+0,
+7,
+2,
+5,
+4,
+6,
+3,
+7,
+3,
+7,
+1,
+3,
+0,
+2,
+1,
+4,
+5,
+2,
+5,
+2,
+1,
+1,
+3,
+4,
+4,
+4,
+6,
+1,
+4,
+1,
+7,
+6,
+5,
+7,
+0,
+3,
+0,
+6,
+2,
+6,
+7,
+6,
+2,
+1,
+3,
+4,
+5,
+7,
+4,
+3,
+3,
+4,
+5,
+0,
+4,
+6,
+6,
+7,
+6,
+0,
+0,
+7,
+1,
+4,
+7,
+0,
+2,
+4,
+2,
+7,
+2,
+7,
+2,
+6,
+1,
+6,
+2,
+6,
+7,
+6,
+1,
+0,
+3,
+1,
+3,
+2,
+3,
+5,
+2,
+3,
+1,
+1,
+6,
+3,
+1,
+5,
+5,
+3,
+4,
+4,
+7,
+1,
+5,
+6,
+4,
+3,
+3,
+5,
+5,
+1,
+7,
+7,
+1,
+7,
+1,
+2,
+2,
+6,
+6,
+3,
+1,
+1,
+1,
+7,
+3,
+0,
+5,
+1,
+1,
+0,
+2,
+2,
+1,
+7,
+7,
+6,
+6,
+5,
+1,
+2,
+0,
+2,
+1,
+2,
+3,
+2,
+0,
+0,
+6,
+6,
+5,
+6,
+1,
+7,
+6,
+3,
+4,
+4,
+7,
+6,
+7,
+4,
+1,
+3,
+6,
+1,
+2,
+3,
+1,
+4,
+7,
+5,
+5,
+0,
+1,
+3,
+2,
+1,
+5,
+6,
+2,
+4,
+4,
+6,
+7,
+4,
+3,
+4,
+3,
+5,
+0,
+2,
+2,
+0,
+5,
+6,
+4,
+0,
+0,
+1,
+7,
+1,
+5,
+7,
+5,
+6,
+0,
+1,
+7,
+2,
+3,
+2,
+6,
+7,
+2,
+5,
+2,
+1,
+3,
+0,
+5,
+5,
+5,
+6,
+0,
+6,
+0,
+5,
+2,
+2,
+5,
+3,
+1,
+2,
+3,
+3,
+6,
+2,
+0,
+1,
+7,
+2,
+1,
+1,
+7,
+0,
+2,
+1,
+5,
+1,
+6,
+3,
+3,
+3,
+7,
+5,
+6,
+4,
+2,
+7,
+6,
+2,
+1,
+4,
+0,
+7,
+4,
+5,
+6,
+2,
+5,
+2,
+4,
+0,
+6,
+5,
+3,
+2,
+5,
+7,
+7,
+3,
+0,
+4,
+0,
+6,
+4,
+2,
+6,
+1,
+1,
+6,
+7,
+3,
+7,
+2,
+0,
+5,
+6,
+0,
+3,
+4,
+6,
+0,
+2,
+2,
+3,
+3,
+0,
+6,
+5,
+2,
+2,
+6,
+6,
+3,
+0,
+0,
+4,
+7,
+6,
+2,
+4,
+7,
+4,
+5,
+7,
+5,
+2,
+2,
+7,
+2,
+5,
+1,
+3,
+1,
+6,
+0,
+3,
+5,
+5,
+3,
+1,
+4,
+4,
+2,
+3,
+1,
+3,
+1,
+0,
+1,
+2,
+3,
+7,
+6,
+7,
+4,
+2,
+1,
+1,
+0,
+5,
+3,
+4,
+4,
+0,
+7,
+5,
+2,
+2,
+1,
+5,
+3,
+6,
+6,
+6,
+1,
+7,
+5,
+7,
+1,
+5,
+5,
+5,
+5,
+4,
+6,
+5,
+4,
+3,
+7,
+0,
+6,
+0,
+3,
+7,
+3,
+0,
+3,
+2,
+5,
+2,
+4,
+3,
+4,
+5,
+4,
+6,
+6,
+0,
+1,
+2,
+4,
+6,
+7,
+1,
+2,
+6,
+3,
+2,
+2,
+2,
+7,
+1,
+3,
+5,
+1,
+5,
+1,
+6,
+1,
+5,
+7,
+7,
+0,
+2,
+3,
+0,
+3,
+1,
+6,
+7,
+3,
+6,
+5,
+3,
+3,
+2,
+6,
+5,
+2,
+3,
+0,
+3,
+2,
+4,
+3,
+4,
+3,
+1,
+2,
+2,
+6,
+6,
+6,
+4,
+2,
+0,
+2,
+3,
+4,
+6,
+7,
+0,
+7,
+6,
+3,
+1,
+5,
+4,
+2,
+5,
+3,
+0,
+7,
+2,
+7,
+7,
+5,
+0,
+6,
+4,
+7,
+3,
+5,
+4,
+4,
+3,
+0,
+5,
+5,
+1,
+2,
+4,
+1,
+0,
+7,
+6,
+5,
+7,
+7,
+1,
+5,
+6,
+7,
+6,
+5,
+3,
+6,
+1,
+6,
+0,
+3,
+1,
+3,
+4,
+5,
+1,
+7,
+7,
+6,
+4,
+6,
+5,
+0,
+3,
+0,
+2,
+1,
+4,
+0,
+4,
+5,
+3,
+1,
+4,
+3,
+4,
+1,
+5,
+7,
+5,
+1,
+7,
+0,
+3,
+6,
+5,
+1,
+3,
+4,
+4,
+2,
+0,
+6,
+1,
+5,
+4,
+4,
+6,
+1,
+7,
+7,
+3,
+6,
+1,
+2,
+1,
+6,
+7,
+0,
+6,
+7,
+2,
+7,
+1,
+7,
+4,
+3,
+7,
+2,
+3,
+2,
+3,
+4,
+0,
+0,
+5,
+3,
+1,
+7,
+6,
+7,
+6,
+3,
+7,
+7,
+6,
+7,
+5,
+0,
+6,
+2,
+2,
+1,
+2,
+5,
+4,
+7,
+5,
+3,
+5,
+7,
+4,
+6,
+5,
+3,
+1,
+3,
+7,
+4,
+2,
+0,
+1,
+1,
+0,
+5,
+0,
+0,
+0,
+4,
+3,
+5,
+2,
+7,
+3,
+1,
+4,
+0,
+3,
+3,
+1,
+3,
+2,
+6,
+3,
+3,
+6,
+5,
+0,
+1,
+7,
+3,
+4,
+7,
+2,
+4,
+3,
+0,
+6,
+3,
+2,
+6,
+4,
+2,
+5,
+6,
+7,
+0,
+0,
+7,
+3,
+4,
+5,
+6,
+7,
+2,
+0,
+2,
+7,
+6,
+1,
+1,
+3,
+5,
+4,
+7,
+7,
+3,
+5,
+7,
+4,
+7,
+6,
+7,
+6,
+0,
+7,
+3,
+4,
+1,
+4,
+3,
+5,
+7,
+0,
+6,
+2,
+3,
+5,
+6,
+1,
+3,
+3,
+2,
+2,
+6,
+6,
+0,
+3,
+7,
+1,
+2,
+6,
+2,
+1,
+6,
+0,
+2,
+3,
+4,
+7,
+2,
+1,
+5,
+2,
+4,
+5,
+7,
+0,
+5,
+1,
+4,
+4,
+2,
+7,
+6,
+7,
+6,
+3,
+3,
+0,
+2,
+5,
+2,
+5,
+1,
+2,
+0,
+7,
+5,
+0,
+4,
+6,
+6,
+1,
+5,
+2,
+6,
+0,
+4,
+0,
+4,
+5,
+7,
+3,
+5,
+7,
+4,
+4,
+0,
+0,
+2,
+3,
+7,
+4,
+1,
+1,
+2,
+2,
+3,
+4,
+2,
+6,
+3,
+7,
+3,
+3,
+7,
+7,
+2,
+4,
+7,
+0,
+7,
+3,
+7,
+6,
+4,
+5,
+6,
+0,
+1,
+2,
+2,
+2,
+1,
+3,
+4,
+4,
+7,
+1,
+2,
+5,
+4,
+3,
+6,
+7,
+5,
+4,
+3,
+6,
+1,
+3,
+5,
+0,
+1,
+3,
+1,
+1,
+5,
+3,
+7,
+1,
+1,
+0,
+4,
+1,
+2,
+0,
+6,
+5,
+3,
+5,
+2,
+6,
+3,
+7,
+1,
+2,
+2,
+3,
+6,
+3,
+4,
+3,
+6,
+6,
+4,
+1,
+0,
+2,
+7,
+7,
+7,
+2,
+7,
+6,
+5,
+1,
+1,
+1,
+5,
+5,
+5,
+4,
+7,
+2,
+7,
+4,
+6,
+0,
+6,
+7,
+4,
+0,
+1,
+1,
+4,
+5,
+0,
+2,
+0,
+7,
+0,
+6,
+7,
+5,
+3,
+6,
+5,
+0,
+5,
+5,
+0,
+3,
+4,
+6,
+5,
+6,
+4,
+2,
+2,
+1,
+6,
+0,
+4,
+0,
+4,
+7,
+7,
+6,
+7,
+5,
+0,
+0,
+2,
+7,
+2,
+5,
+6,
+1,
+0,
+1,
+7,
+6,
+6,
+7,
+5,
+3,
+1,
+2,
+5,
+1,
+3,
+0,
+0,
+0,
+7,
+3,
+6,
+6,
+2,
+6,
+4,
+5,
+1,
+5,
+3,
+0,
+5,
+6,
+0,
+4,
+2,
+7,
+3,
+1,
+1,
+6,
+3,
+0,
+5,
+0,
+0,
+0,
+1,
+5,
+5,
+7,
+5,
+2,
+4,
+4,
+3,
+0,
+2,
+6,
+4,
+5,
+1,
+0,
+1,
+7,
+1,
+6,
+0,
+2,
+7,
+7,
+3,
+5,
+3,
+5,
+5,
+5,
+2,
+1,
+7,
+1,
+5,
+3,
+5,
+1,
+6,
+0,
+1,
+3,
+6,
+6,
+5,
+6,
+7,
+2,
+5,
+7,
+4,
+7,
+5,
+2,
+1,
+4,
+5,
+6,
+2,
+6,
+3,
+4,
+4,
+5,
+1,
+0,
+6,
+2,
+3,
+7,
+0,
+5,
+2,
+1,
+0,
+7,
+5,
+2,
+4,
+3,
+2,
+5,
+0,
+6,
+6,
+2,
+2,
+6,
+3,
+1,
+6,
+7,
+4,
+1,
+2,
+2,
+5,
+6,
+7,
+0,
+0,
+6,
+1,
+4,
+0,
+5,
+1,
+3,
+0,
+3,
+3,
+4,
+5,
+4,
+2,
+3,
+6,
+1,
+4,
+3,
+5,
+1,
+6,
+6,
+1,
+1,
+6,
+5,
+7,
+7,
+7,
+6,
+4,
+7,
+0,
+2,
+6,
+4,
+6,
+1,
+5,
+6,
+7,
+0,
+7,
+4,
+4,
+1,
+6,
+4,
+1,
+3,
+3,
+6,
+6,
+4,
+7,
+3,
+6,
+0,
+5,
+4,
+2,
+4,
+4,
+1,
+4,
+6,
+2,
+5,
+7,
+5,
+0,
+4,
+2,
+3,
+5,
+6,
+0,
+1,
+2,
+1,
+3,
+4,
+7,
+2,
+5,
+3,
+4,
+4,
+6,
+2,
+7,
+1,
+4,
+3,
+7,
+7,
+0,
+2,
+7,
+4,
+5,
+0,
+7,
+3,
+3,
+3,
+4,
+1,
+5,
+4,
+1,
+6,
+0,
+6,
+4,
+2,
+5,
+4,
+7,
+1,
+0,
+4,
+1,
+1,
+5,
+3,
+5,
+0,
+1,
+1,
+7,
+5,
+1,
+2,
+5,
+6,
+2,
+5,
+0,
+6,
+5,
+0,
+4,
+7,
+4,
+7,
+5,
+2,
+0,
+3,
+5,
+5,
+7,
+3,
+1,
+0,
+5,
+5,
+3,
+1,
+4,
+2,
+6,
+0,
+4,
+7,
+0,
+3,
+4,
+1,
+2,
+4,
+6,
+2,
+6,
+1,
+7,
+6,
+7,
+1,
+3,
+3,
+4,
+5,
+3,
+7,
+7,
+4,
+7,
+6,
+1,
+1,
+5,
+0,
+6,
+6,
+1,
+1,
+7,
+1,
+4,
+3,
+5,
+1,
+5,
+1,
+3,
+0,
+5,
+5,
+2,
+0,
+5,
+3,
+7,
+7,
+7,
+2,
+5,
+6,
+1,
+7,
+6,
+1,
+0,
+6,
+2,
+6,
+2,
+4,
+7,
+7,
+3,
+0,
+7,
+6,
+5,
+2,
+6,
+6,
+2,
+2,
+0,
+5,
+2,
+5,
+1,
+2,
+6,
+7,
+1,
+1,
+5,
+5,
+1,
+5,
+0,
+6,
+3,
+5,
+0,
+5,
+6,
+0,
+6,
+4,
+4,
+1,
+4,
+2,
+0,
+2,
+2,
+1,
+6,
+7,
+2,
+7,
+7,
+1,
+0,
+3,
+3,
+2,
+5,
+1,
+7,
+1,
+7,
+7,
+1,
+7,
+6,
+3,
+3,
+7,
+6,
+7,
+5,
+3,
+1,
+4,
+7,
+0,
+5,
+0,
+6,
+5,
+4,
+0,
+3,
+4,
+3,
+1,
+4,
+3,
+4,
+1,
+6,
+3,
+6,
+7,
+6,
+3,
+2,
+4,
+7,
+3,
+5,
+0,
+1,
+6,
+1,
+3,
+4,
+7,
+2,
+1,
+3,
+4,
+0,
+5,
+6,
+0,
+2,
+2,
+0,
+0,
+7,
+6,
+6,
+1,
+3,
+6,
+6,
+6,
+6,
+2,
+6,
+7,
+3,
+0,
+4,
+0,
+5,
+4,
+7,
+7,
+7,
+7,
+3,
+3,
+6,
+2,
+2,
+1,
+7,
+0,
+1,
+1,
+5,
+3,
+7,
+4,
+6,
+3,
+5,
+2,
+4,
+2,
+7,
+5,
+1,
+4,
+0,
+7,
+3,
+3,
+0,
+4,
+7,
+5,
+2,
+3,
+5,
+1,
+3,
+1,
+5,
+0,
+5,
+4,
+1,
+4,
+0,
+4,
+3,
+0,
+7,
+7,
+7,
+1,
+2,
+2,
+3,
+7,
+4,
+7,
+0,
+7,
+0,
+4,
+4,
+0,
+0,
+1,
+0,
+7,
+0,
+1,
+1,
+1,
+1,
+3,
+5,
+3,
+6,
+4,
+1,
+2,
+2,
+3,
+6,
+1,
+6,
+1,
+0,
+3,
+1,
+1,
+2,
+4,
+5,
+4,
+4,
+7,
+0,
+5,
+1,
+0,
+6,
+4,
+0,
+4,
+0,
+1,
+6,
+6,
+4,
+1,
+0,
+1,
+0,
+1,
+2,
+6,
+3,
+2,
+1,
+2,
+2,
+5,
+3,
+2,
+0,
+2,
+7,
+5,
+3,
+4,
+2,
+7,
+3,
+1,
+5,
+0,
+0,
+2,
+5,
+4,
+0,
+2,
+0,
+3,
+1,
+5,
+5,
+0,
+2,
+3,
+5,
+7,
+7,
+3,
+4,
+6,
+3,
+3,
+5,
+6,
+3,
+1,
+7,
+5,
+7,
+3,
+4,
+0,
+2,
+0,
+5,
+5,
+5,
+1,
+0,
+5,
+2,
+0,
+6,
+6,
+6,
+3,
+1,
+6,
+7,
+7,
+3,
+5,
+4,
+7,
+7,
+7,
+7,
+7,
+7,
+4,
+4,
+6,
+7,
+1,
+6,
+5,
+3,
+7,
+1,
+4,
+6,
+4,
+1,
+6,
+0,
+7,
+5,
+1,
+0,
+0,
+3,
+7,
+2,
+6,
+6,
+7,
+3,
+2,
+0,
+7,
+1,
+5,
+2,
+3,
+5,
+5,
+6,
+3,
+7,
+0,
+5,
+2,
+0,
+2,
+2,
+0,
+2,
+6,
+3,
+6,
+0,
+2,
+0,
+6,
+5,
+0,
+1,
+7,
+2,
+0,
+7,
+6,
+5,
+5,
+1,
+5,
+6,
+4,
+0,
+3,
+5,
+4,
+0,
+3,
+0,
+2,
+4,
+4,
+2,
+4,
+3,
+2,
+6,
+0,
+1,
+7,
+5,
+0,
+1,
+1,
+3,
+2,
+3,
+6,
+4,
+0,
+0,
+2,
+4,
+4,
+4,
+0,
+5,
+5,
+4,
+1,
+6,
+4,
+1,
+4,
+7,
+0,
+3,
+3,
+1,
+6,
+3,
+2,
+7,
+4,
+4,
+0,
+5,
+4,
+1,
+7,
+7,
+2,
+3,
+2,
+1,
+2,
+1,
+4,
+7,
+4,
+3,
+4,
+4,
+7,
+0,
+1,
+7,
+7,
+4,
+6,
+6,
+4,
+2,
+1,
+7,
+5,
+5,
+0,
+0,
+3,
+5,
+7,
+0,
+6,
+6,
+4,
+5,
+3,
+4,
+5,
+3,
+6,
+6,
+3,
+4,
+1,
+1,
+7,
+5,
+0,
+7,
+2,
+7,
+2,
+4,
+0,
+0,
+2,
+2,
+7,
+3,
+3,
+7,
+2,
+6,
+1,
+4,
+3,
+0,
+2,
+0,
+6,
+2,
+3,
+4,
+3,
+2,
+0,
+0,
+7,
+6,
+7,
+6,
+6,
+2,
+6,
+5,
+5,
+5,
+7,
+6,
+0,
+5,
+7,
+5,
+7,
+5,
+2,
+4,
+1,
+6,
+3,
+3,
+7,
+2,
+6,
+0,
+3,
+6,
+3,
+1,
+5,
+6,
+6,
+5,
+7,
+4,
+4,
+7,
+6,
+4,
+3,
+2,
+7,
+1,
+2,
+5,
+6,
+6,
+2,
+1,
+0,
+2,
+4,
+0,
+0,
+0,
+1,
+7,
+4,
+5,
+5,
+3,
+6,
+5,
+1,
+4,
+3,
+1,
+6,
+2,
+0,
+2,
+2,
+4,
+1,
+0,
+4,
+2,
+1,
+6,
+6,
+1,
+1,
+6,
+4,
+7,
+4,
+5,
+7,
+1,
+5,
+0,
+2,
+0,
+0,
+0,
+4,
+5,
+5,
+2,
+5,
+6,
+7,
+2,
+5,
+0,
+2,
+2,
+6,
+1,
+6,
+2,
+3,
+6,
+4,
+7,
+6,
+6,
+1,
+5,
+5,
+5,
+2,
+3,
+6,
+5,
+3,
+3,
+4,
+1,
+4,
+6,
+6,
+5,
+1,
+5,
+6,
+6,
+3,
+2,
+4,
+6,
+3,
+4,
+4,
+1,
+6,
+3,
+1,
+6,
+4,
+4,
+0,
+2,
+7,
+6,
+4,
+5,
+4,
+6,
+6,
+3,
+7,
+4,
+0,
+3,
+4,
+3,
+6,
+1,
+0,
+2,
+6,
+1,
+5,
+4,
+6,
+5,
+3,
+7,
+1,
+7,
+0,
+1,
+5,
+5,
+3,
+2,
+1,
+3,
+7,
+4,
+2,
+0,
+2,
+0,
+0,
+3,
+0,
+7,
+0,
+2,
+0,
+7,
+6,
+1,
+5,
+3,
+7,
+6,
+5,
+5,
+5,
+0,
+3,
+1,
+7,
+4,
+6,
+7,
+7,
+0,
+2,
+1,
+4,
+4,
+7,
+1,
+7,
+1,
+0,
+2,
+2,
+2,
+2,
+1,
+1,
+0,
+0,
+1,
+4,
+6,
+6,
+4,
+0,
+1,
+1,
+1,
+6,
+6,
+1,
+5,
+7,
+0,
+7,
+0,
+4,
+4,
+2,
+5,
+6,
+7,
+4,
+5,
+1,
+6,
+3,
+6,
+6,
+1,
+0,
+3,
+7,
+1,
+1,
+1,
+7,
+5,
+2,
+5,
+3,
+0,
+0,
+4,
+5,
+3,
+6,
+1,
+6,
+0,
+0,
+2,
+5,
+7,
+2,
+5,
+7,
+4,
+4,
+1,
+4,
+7,
+0,
+2,
+7,
+7,
+3,
+4,
+0,
+3,
+0,
+3,
+0,
+3,
+4,
+5,
+0,
+0,
+3,
+3,
+3,
+7,
+6,
+6,
+6,
+4,
+2,
+6,
+5,
+7,
+2,
+7,
+5,
+4,
+1,
+6,
+1,
+7,
+7,
+2,
+0,
+1,
+0,
+2,
+7,
+5,
+2,
+1,
+6,
+7,
+1,
+3,
+5,
+1,
+6,
+0,
+2,
+6,
+4,
+2,
+6,
+2,
+3,
+5,
+6,
+1,
+1,
+0,
+0,
+6,
+2,
+2,
+1,
+0,
+2,
+7,
+0,
+7,
+2,
+4,
+0,
+1,
+5,
+7,
+0,
+2,
+6,
+4,
+2,
+2,
+4,
+0,
+4,
+4,
+6,
+7,
+7,
+7,
+5,
+7,
+3,
+6,
+6,
+4,
+0,
+1,
+2,
+4,
+3,
+3,
+6,
+5,
+5,
+5,
+3,
+4,
+6,
+4,
+7,
+1,
+6,
+6,
+6,
+3,
+5,
+6,
+1,
+2,
+3,
+5,
+7,
+2,
+0,
+2,
+7,
+6,
+1,
+0,
+1,
+3,
+7,
+2,
+4,
+4,
+0,
+3,
+7,
+0,
+1,
+0,
+1,
+1,
+0,
+4,
+7,
+4,
+0,
+1,
+0,
+4,
+7,
+2,
+3,
+3,
+1,
+2,
+3,
+0,
+6,
+7,
+1,
+6,
+2,
+7,
+6,
+4,
+6,
+1,
+6,
+4,
+7,
+6,
+2,
+3,
+2,
+1,
+6,
+1,
+4,
+0,
+2,
+0,
+3,
+6,
+0,
+5,
+5,
+7,
+3,
+4,
+2,
+7,
+1,
+2,
+0,
+1,
+6,
+5,
+2,
+0,
+5,
+3,
+5,
+3,
+0,
+1,
+1,
+0,
+7,
+5,
+6,
+7,
+5,
+5,
+2,
+4,
+5,
+6,
+0,
+3,
+5,
+3,
+5,
+1,
+5,
+1,
+4,
+1,
+6,
+4,
+5,
+3,
+3,
+2,
+4,
+7,
+1,
+1,
+4,
+0,
+2,
+6,
+2,
+6,
+2,
+6,
+7,
+6,
+5,
+5,
+6,
+1,
+3,
+7,
+6,
+0,
+6,
+1,
+1,
+4,
+5,
+1,
+3,
+2,
+1,
+3,
+5,
+2,
+7,
+6,
+3,
+6,
+7,
+7,
+7,
+6,
+5,
+2,
+4,
+7,
+7,
+0,
+4,
+3,
+2,
+6,
+6,
+5,
+3,
+0,
+1,
+1,
+2,
+6,
+7,
+7,
+2,
+0,
+6,
+4,
+4,
+2,
+0,
+7,
+2,
+5,
+3,
+6,
+5,
+0,
+7,
+3,
+5,
+3,
+3,
+4,
+7,
+0,
+2,
+0,
+6,
+4,
+5,
+5,
+6,
+1,
+7,
+3,
+3,
+7,
+4,
+6,
+4,
+6,
+7,
+5,
+2,
+3,
+2,
+1,
+2,
+1,
+2,
+7,
+2,
+3,
+6,
+7,
+7,
+4,
+6,
+3,
+0,
+7,
+7,
+1,
+5,
+5,
+6,
+0,
+7,
+3,
+5,
+4,
+4,
+2,
+5,
+1,
+2,
+5,
+1,
+1,
+4,
+7,
+2,
+1,
+0,
+0,
+1,
+3,
+2,
+1,
+2,
+6,
+7,
+2,
+4,
+2,
+2,
+0,
+3,
+4,
+5,
+7,
+2,
+0,
+1,
+6,
+2,
+2,
+3,
+6,
+4,
+7,
+0,
+2,
+3,
+0,
+7,
+5,
+5,
+5,
+7,
+1,
+7,
+1,
+7,
+6,
+5,
+6,
+0,
+4,
+2,
+6,
+6,
+0,
+7,
+1,
+7,
+7,
+3,
+5,
+3,
+1,
+2,
+4,
+6,
+5,
+6,
+7,
+4,
+7,
+6,
+6,
+1,
+6,
+3,
+0,
+7,
+2,
+0,
+0,
+5,
+6,
+2,
+4,
+3,
+0,
+3,
+6,
+3,
+4,
+2,
+3,
+0,
+0,
+7,
+6,
+2,
+0,
+6,
+7,
+0,
+6,
+5,
+1,
+5,
+4,
+3,
+7,
+4,
+2,
+0,
+3,
+7,
+5,
+6,
+5,
+0,
+4,
+0,
+5,
+6,
+3,
+6,
+6,
+7,
+4,
+0,
+3,
+7,
+6,
+1,
+7,
+7,
+7,
+7,
+6,
+6,
+5,
+2,
+2,
+3,
+5,
+6,
+2,
+1,
+6,
+1,
+5,
+4,
+4,
+7,
+4,
+6,
+0,
+2,
+2,
+7,
+4,
+5,
+4,
+6,
+5,
+1,
+4,
+2,
+7,
+3,
+1,
+0,
+0,
+3,
+5,
+1,
+4,
+1,
+0,
+3,
+1,
+1,
+4,
+3,
+4,
+2,
+0,
+0,
+5,
+3,
+4,
+3,
+7,
+5,
+5,
+3,
+2,
+4,
+1,
+5,
+0,
+0,
+2,
+0,
+4,
+7,
+6,
+2,
+7,
+4,
+4,
+4,
+1,
+7,
+1,
+7,
+1,
+4,
+2,
+4,
+1,
+4,
+1,
+5,
+0,
+1,
+2,
+3,
+2,
+7,
+1,
+6,
+1,
+6,
+1,
+1,
+6,
+3,
+0,
+4,
+2,
+7,
+6,
+7,
+7,
+4,
+4,
+2,
+5,
+4,
+0,
+7,
+3,
+6,
+2,
+3,
+4,
+2,
+3,
+0,
+2,
+7,
+2,
+1,
+5,
+6,
+7,
+0,
+5,
+7,
+3,
+2,
+4,
+3,
+3,
+5,
+5,
+3,
+3,
+1,
+2,
+3,
+6,
+1,
+4,
+0,
+7,
+3,
+5,
+5,
+4,
+2,
+6,
+0,
+6,
+0,
+6,
+3,
+4,
+4,
+5,
+7,
+1,
+2,
+3,
+5,
+3,
+3,
+3,
+5,
+5,
+7,
+3,
+6,
+0,
+5,
+3,
+0,
+5,
+3,
+5,
+7,
+6,
+1,
+4,
+4,
+1,
+6,
+2,
+5,
+1,
+2,
+7,
+4,
+6,
+3,
+1,
+0,
+4,
+0,
+6,
+0,
+3,
+2,
+2,
+1,
+1,
+0,
+6,
+0,
+7,
+6,
+1,
+5,
+2,
+1,
+6,
+4,
+2,
+1,
+2,
+0,
+3,
+7,
+4,
+4,
+0,
+0,
+1,
+3,
+0,
+6,
+3,
+2,
+2,
+1,
+7,
+1,
+0,
+3,
+4,
+3,
+4,
+0,
+5,
+3,
+4,
+3,
+1,
+2,
+0,
+5,
+3,
+2,
+2,
+6,
+5,
+5,
+4,
+0,
+1,
+0,
+4,
+7,
+3,
+0,
+1,
+3,
+3,
+1,
+4,
+5,
+1,
+0,
+2,
+4,
+4,
+0,
+4,
+5,
+6,
+3,
+0,
+4,
+7,
+6,
+7,
+7,
+5,
+6,
+3,
+3,
+2,
+2,
+6,
+7,
+0,
+7,
+1,
+7,
+2,
+7,
+5,
+0,
+7,
+4,
+1,
+3,
+3,
+5,
+7,
+4,
+0,
+5,
+1,
+7,
+1,
+6,
+0,
+2,
+1,
+7,
+6,
+3,
+4,
+5,
+7,
+7,
+7,
+7,
+7,
+0,
+3,
+2,
+2,
+5,
+6,
+7,
+4,
+0,
+2,
+7,
+3,
+6,
+4,
+4,
+5,
+5,
+5,
+6,
+5,
+7,
+6,
+6,
+6,
+3,
+1,
+0,
+2,
+3,
+6,
+6,
+6,
+5,
+7,
+6,
+6,
+1,
+2,
+2,
+0,
+2,
+4,
+5,
+4,
+1,
+3,
+7,
+5,
+5,
+2,
+5,
+0,
+2,
+4,
+4,
+6,
+5,
+2,
+1,
+4,
+7,
+3,
+4,
+0,
+3,
+6,
+3,
+3,
+7,
+6,
+5,
+1,
+4,
+7,
+7,
+2,
+7,
+3,
+1,
+7,
+4,
+7,
+3,
+2,
+3,
+2,
+5,
+7,
+0,
+3,
+5,
+0,
+3,
+1,
+2,
+2,
+5,
+2,
+5,
+5,
+1,
+2,
+5,
+7,
+1,
+3,
+4,
+3,
+5,
+7,
+7,
+3,
+6,
+4,
+5,
+1,
+1,
+0,
+0,
+3,
+7,
+3,
+6,
+0,
+2,
+0,
+5,
+7,
+3,
+3,
+2,
+2,
+4,
+4,
+0,
+1,
+1,
+6,
+5,
+6,
+4,
+7,
+1,
+2,
+7,
+7,
+4,
+6,
+0,
+3,
+1,
+2,
+7,
+6,
+4,
+5,
+7,
+3,
+4,
+4,
+1,
+5,
+7,
+5,
+7,
+6,
+7,
+4,
+0,
+0,
+4,
+4,
+6,
+3,
+0,
+4,
+6,
+3,
+5,
+1,
+7,
+3,
+0,
+4,
+2,
+2,
+1,
+3,
+6,
+5,
+3,
+4,
+1,
+3,
+0,
+0,
+1,
+4,
+0,
+5,
+5,
+5,
+4,
+1,
+5,
+4,
+4,
+4,
+6,
+4,
+5,
+5,
+2,
+3,
+1,
+4,
+1,
+1,
+6,
+2,
+0,
+2,
+6,
+1,
+0,
+2,
+2,
+3,
+7,
+2,
+1,
+1,
+6,
+7,
+2,
+7,
+6,
+6,
+6,
+1,
+6,
+6,
+2,
+6,
+3,
+1,
+1,
+4,
+5,
+7,
+3,
+1,
+4,
+7,
+0,
+6,
+7,
+5,
+0,
+5,
+2,
+1,
+1,
+5,
+6,
+3,
+0,
+1,
+6,
+7,
+5,
+4,
+2,
+1,
+3,
+1,
+5,
+6,
+6,
+4,
+0,
+2,
+6,
+7,
+7,
+7,
+0,
+1,
+2,
+4,
+5,
+5,
+6,
+6,
+2,
+7,
+7,
+2,
+3,
+5,
+4,
+6,
+4,
+2,
+1,
+3,
+7,
+4,
+0,
+6,
+1,
+1,
+2,
+3,
+1,
+4,
+4,
+3,
+5,
+1,
+3,
+1,
+7,
+1,
+1,
+1,
+6,
+6,
+1,
+2,
+3,
+4,
+3,
+6,
+4,
+3,
+4,
+7,
+4,
+1,
+6,
+0,
+4,
+7,
+2,
+4,
+5,
+2,
+7,
+4,
+6,
+4,
+6,
+0,
+7,
+7,
+6,
+0,
+4,
+4,
+1,
+7,
+1,
+1,
+3,
+6,
+5,
+0,
+3,
+6,
+3,
+2,
+5,
+7,
+6,
+0,
+5,
+5,
+1,
+1,
+1,
+5,
+1,
+1,
+3,
+6,
+6,
+7,
+7,
+0,
+7,
+4,
+5,
+2,
+7,
+4,
+2,
+2,
+3,
+3,
+2,
+1,
+4,
+5,
+1,
+2,
+2,
+5,
+6,
+5,
+3,
+2,
+4,
+4,
+3,
+2,
+7,
+5,
+2,
+0,
+7,
+0,
+2,
+6,
+6,
+5,
+1,
+0,
+2,
+4,
+1,
+5,
+3,
+1,
+2,
+7,
+5,
+6,
+3,
+4,
+4,
+1,
+2,
+6,
+4,
+0,
+5,
+3,
+4,
+0,
+6,
+6,
+6,
+4,
+6,
+4,
+5,
+1,
+6,
+6,
+3,
+4,
+2,
+7,
+7,
+3,
+3,
+4,
+4,
+6,
+0,
+2,
+5,
+6,
+7,
+1,
+7,
+1,
+1,
+4,
+7,
+2,
+2,
+3,
+3,
+1,
+7,
+5,
+0,
+7,
+3,
+4,
+5,
+1,
+7,
+5,
+6,
+4,
+0,
+1,
+7,
+6,
+0,
+2,
+5,
+2,
+5,
+3,
+0,
+3,
+5,
+3,
+1,
+6,
+5,
+3,
+1,
+2,
+5,
+4,
+6,
+3,
+6,
+6,
+7,
+3,
+0,
+3,
+3,
+5,
+7,
+5,
+1,
+4,
+6,
+6,
+0,
+1,
+3,
+4,
+0,
+2,
+4,
+2,
+2,
+1,
+5,
+1,
+3,
+3,
+1,
+5,
+7,
+0,
+7,
+0,
+4,
+2,
+4,
+2,
+7,
+4,
+3,
+4,
+1,
+0,
+1,
+6,
+2,
+2,
+3,
+4,
+0,
+5,
+0,
+1,
+5,
+6,
+1,
+3,
+7,
+3,
+1,
+2,
+5,
+0,
+7,
+6,
+7,
+7,
+5,
+1,
+5,
+7,
+6,
+1,
+1,
+6,
+1,
+0,
+6,
+7,
+5,
+1,
+1,
+6,
+3,
+7,
+0,
+5,
+7,
+0,
+4,
+0,
+7,
+7,
+7,
+4,
+0,
+5,
+3,
+0,
+0,
+0,
+4,
+1,
+2,
+4,
+2,
+6,
+1,
+5,
+1,
+5,
+3,
+0,
+2,
+0,
+6,
+3,
+4,
+5,
+0,
+7,
+3,
+0,
+1,
+6,
+5,
+1,
+3,
+3,
+2,
+2,
+7,
+6,
+0,
+1,
+1,
+1,
+0,
+0,
+1,
+2,
+5,
+2,
+3,
+6,
+7,
+0,
+3,
+2,
+1,
+5,
+5,
+6,
+6,
+3,
+4,
+3,
+1,
+5,
+6,
+4,
+2,
+2,
+7,
+1,
+0,
+3,
+1,
+1,
+1,
+0,
+6,
+4,
+0,
+6,
+6,
+6,
+0,
+4,
+4,
+5,
+3,
+3,
+1,
+0,
+2,
+5,
+6,
+6,
+4,
+1,
+7,
+3,
+0,
+3,
+4,
+0,
+3,
+2,
+3,
+7,
+4,
+0,
+1,
+0,
+5,
+0,
+5,
+2,
+7,
+4,
+3,
+5,
+6,
+5,
+3,
+3,
+0,
+3,
+4,
+5,
+0,
+6,
+4,
+7,
+1,
+2,
+2,
+1,
+7,
+1,
+3,
+4,
+7,
+7,
+3,
+2,
+2,
+0,
+2,
+7,
+5,
+5,
+3,
+3,
+7,
+5,
+7,
+0,
+4,
+0,
+5,
+2,
+3,
+5,
+0,
+3,
+6,
+7,
+2,
+6,
+2,
+4,
+6,
+0,
+4,
+1,
+5,
+4,
+2,
+0,
+0,
+5,
+5,
+6,
+6,
+4,
+7,
+5,
+6,
+3,
+7,
+3,
+2,
+0,
+6,
+3,
+5,
+2,
+5,
+1,
+0,
+3,
+7,
+1,
+3,
+7,
+2,
+7,
+2,
+1,
+1,
+7,
+6,
+0,
+4,
+5,
+3,
+5,
+1,
+6,
+4,
+0,
+7,
+2,
+1,
+3,
+7,
+5,
+0,
+1,
+2,
+6,
+4,
+1,
+0,
+6,
+0,
+5,
+7,
+1,
+5,
+3,
+6,
+7,
+0,
+4,
+5,
+1,
+5,
+3,
+4,
+3,
+4,
+6,
+7,
+7,
+4,
+1,
+0,
+2,
+4,
+2,
+1,
+2,
+1,
+6,
+3,
+2,
+2,
+2,
+1,
+4,
+1,
+2,
+4,
+6,
+4,
+7,
+0,
+0,
+1,
+0,
+4,
+6,
+2,
+1,
+1,
+3,
+5,
+3,
+3,
+2,
+4,
+0,
+1,
+5,
+6,
+2,
+4,
+3,
+4,
+4,
+3,
+5,
+3,
+6,
+6,
+6,
+5,
+0,
+5,
+2,
+5,
+3,
+0,
+4,
+7,
+5,
+0,
+4,
+4,
+2,
+2,
+4,
+2,
+1,
+1,
+1,
+6,
+0,
+4,
+0,
+3,
+1,
+0,
+4,
+6,
+1,
+6,
+0,
+2,
+1,
+0,
+2,
+7,
+4,
+0,
+0,
+3,
+7,
+0,
+5,
+5,
+6,
+6,
+7,
+6,
+3,
+2,
+6,
+7,
+6,
+6,
+2,
+0,
+6,
+7,
+7,
+4,
+1,
+7,
+7,
+6,
+0,
+5,
+6,
+7,
+3,
+3,
+6,
+0,
+5,
+3,
+7,
+6,
+2,
+2,
+1,
+1,
+5,
+4,
+0,
+4,
+7,
+2,
+4,
+5,
+7,
+4,
+6,
+3,
+7,
+7,
+2,
+2,
+4,
+0,
+1,
+0,
+7,
+4,
+0,
+2,
+6,
+3,
+5,
+3,
+3,
+4,
+4,
+1,
+4,
+2,
+2,
+2,
+0,
+6,
+6,
+3,
+7,
+4,
+5,
+0,
+1,
+3,
+1,
+7,
+2,
+6,
+2,
+6,
+2,
+4,
+2,
+5,
+6,
+1,
+2,
+1,
+3,
+5,
+5,
+4,
+0,
+2,
+0,
+4,
+6,
+1,
+2,
+1,
+5,
+6,
+4,
+0,
+0,
+1,
+0,
+1,
+1,
+5,
+7,
+7,
+1,
+4,
+5,
+4,
+0,
+0,
+2,
+2,
+4,
+3,
+5,
+6,
+7,
+6,
+0,
+4,
+6,
+1,
+7,
+4,
+3,
+6,
+7,
+4,
+4,
+7,
+1,
+4,
+5,
+0,
+3,
+0,
+3,
+4,
+6,
+0,
+7,
+5,
+2,
+6,
+6,
+1,
+0,
+0,
+6,
+0,
+0,
+6,
+5,
+5,
+0,
+7,
+6,
+2,
+7,
+6,
+2,
+2,
+2,
+3,
+7,
+1,
+0,
+5,
+5,
+0,
+7,
+7,
+5,
+5,
+3,
+3,
+2,
+3,
+0,
+1,
+4,
+6,
+2,
+1,
+2,
+0,
+7,
+6,
+2,
+6,
+6,
+3,
+3,
+7,
+6,
+5,
+0,
+1,
+4,
+4,
+3,
+6,
+3,
+0,
+7,
+5,
+5,
+5,
+2,
+6,
+3,
+0,
+1,
+7,
+1,
+7,
+0,
+1,
+6,
+3,
+5,
+2,
+1,
+4,
+1,
+5,
+3,
+1,
+1,
+3,
+2,
+4,
+0,
+7,
+7,
+0,
+7,
+1,
+2,
+7,
+0,
+4,
+7,
+3,
+5,
+3,
+4,
+6,
+2,
+3,
+0,
+0,
+3,
+5,
+5,
+1,
+0,
+4,
+7,
+3,
+6,
+0,
+4,
+7,
+1,
+0,
+5,
+1,
+1,
+7,
+7,
+1,
+1,
+5,
+6,
+7,
+5,
+5,
+5,
+1,
+4,
+7,
+0,
+7,
+2,
+0,
+1,
+2,
+3,
+0,
+3,
+1,
+3,
+2,
+3,
+2,
+0,
+1,
+2,
+6,
+4,
+7,
+4,
+1,
+5,
+4,
+3,
+2,
+6,
+2,
+4,
+5,
+7,
+3,
+7,
+3,
+5,
+0,
+0,
+5,
+5,
+4,
+0,
+4,
+5,
+2,
+3,
+2,
+5,
+6,
+1,
+4,
+4,
+4,
+6,
+7,
+7,
+4,
+2,
+4,
+3,
+5,
+4,
+3,
+3,
+6,
+3,
+5,
+6,
+6,
+6,
+6,
+4,
+2,
+5,
+7,
+1,
+5,
+1,
+3,
+6,
+1,
+1,
+1,
+3,
+6,
+6,
+2,
+3,
+0,
+1,
+6,
+5,
+4,
+4,
+0,
+3,
+3,
+0,
+0,
+4,
+7,
+1,
+6,
+4,
+3,
+7,
+1,
+0,
+5,
+0,
+0,
+5,
+5,
+1,
+1,
+1,
+3,
+7,
+4,
+5,
+5,
+2,
+0,
+2,
+5,
+1,
+4,
+6,
+2,
+0,
+7,
+4,
+5,
+5,
+4,
+6,
+5,
+7,
+7,
+4,
+4,
+1,
+1,
+5,
+3,
+0,
+4,
+5,
+7,
+0,
+5,
+2,
+6,
+6,
+1,
+6,
+2,
+3,
+2,
+2,
+2,
+3,
+6,
+1,
+1,
+6,
+3,
+2,
+4,
+5,
+1,
+6,
+4,
+5,
+7,
+5,
+7,
+2,
+6,
+3,
+4,
+1,
+6,
+3,
+4,
+7,
+2,
+0,
+3,
+5,
+6,
+3,
+0,
+5,
+6,
+7,
+0,
+6,
+6,
+3,
+6,
+2,
+3,
+0,
+6,
+3,
+3,
+4,
+4,
+6,
+7,
+5,
+0,
+4,
+5,
+5,
+1,
+4,
+5,
+3,
+0,
+7,
+1,
+5,
+4,
+6,
+3,
+4,
+6,
+3,
+1,
+5,
+6,
+5,
+5,
+7,
+0,
+5,
+4,
+3,
+6,
+5,
+3,
+5,
+1,
+1,
+7,
+6,
+6,
+2,
+1,
+1,
+1,
+1,
+2,
+1,
+4,
+5,
+0,
+4,
+1,
+4,
+4,
+5,
+4,
+7,
+4,
+5,
+3,
+5,
+3,
+6,
+0,
+2,
+7,
+3,
+1,
+4,
+0,
+1,
+7,
+1,
+3,
+3,
+1,
+1,
+7,
+4,
+4,
+1,
+6,
+1,
+4,
+3,
+2,
+7,
+0,
+6,
+0,
+3,
+5,
+2,
+3,
+1,
+3,
+6,
+0,
+0,
+5,
+4,
+3,
+5,
+6,
+4,
+5,
+1,
+1,
+6,
+4,
+7,
+2,
+4,
+3,
+7,
+2,
+6,
+5,
+1,
+7,
+5,
+4,
+1,
+6,
+0,
+4,
+2,
+1,
+1,
+5,
+1,
+6,
+2,
+2,
+7,
+1,
+0,
+3,
+2,
+2,
+2,
+3,
+1,
+2,
+4,
+1,
+0,
+2,
+4,
+7,
+5,
+2,
+2,
+6,
+1,
+5,
+6,
+6,
+3,
+0,
+6,
+6,
+0,
+5,
+7,
+4,
+3,
+2,
+1,
+4,
+5,
+4,
+1,
+4,
+3,
+2,
+7,
+0,
+4,
+2,
+6,
+6,
+3,
+0,
+2,
+6,
+1,
+0,
+2,
+0,
+1,
+5,
+0,
+1,
+4,
+0,
+2,
+5,
+1,
+4,
+2,
+4,
+4,
+4,
+6,
+0,
+1,
+4,
+5,
+6,
+5,
+4,
+5,
+6,
+7,
+3,
+3,
+5,
+4,
+4,
+2,
+2,
+1,
+2,
+4,
+1,
+3,
+7,
+3,
+2,
+5,
+2,
+0,
+5,
+7,
+3,
+3,
+4,
+6,
+2,
+4,
+2,
+4,
+7,
+2,
+0,
+0,
+1,
+1,
+1,
+2,
+2,
+7,
+5,
+1,
+3,
+3,
+5,
+7,
+1,
+7,
+4,
+7,
+3,
+3,
+0,
+6,
+6,
+5,
+4,
+7,
+7,
+2,
+7,
+1,
+7,
+2,
+7,
+2,
+2,
+7,
+5,
+2,
+2,
+2,
+1,
+1,
+2,
+6,
+7,
+1,
+5,
+6,
+2,
+4,
+6,
+5,
+1,
+7,
+6,
+5,
+4,
+4,
+0,
+0,
+0,
+2,
+5,
+6,
+3,
+0,
+3,
+2,
+5,
+5,
+5,
+4,
+2,
+3,
+6,
+2,
+0,
+7,
+1,
+0,
+0,
+4,
+6,
+4,
+7,
+1,
+4,
+3,
+7,
+7,
+7,
+4,
+1,
+5,
+6,
+2,
+5,
+7,
+0,
+3,
+1,
+4,
+4,
+4,
+6,
+4,
+7,
+3,
+1,
+6,
+2,
+0,
+1,
+7,
+5,
+2,
+6,
+5,
+1,
+7,
+1,
+6,
+5,
+7,
+3,
+1,
+2,
+3,
+5,
+2,
+1,
+6,
+1,
+5,
+6,
+7,
+2,
+3,
+6,
+5,
+6,
+4,
+7,
+2,
+1,
+0,
+2,
+0,
+2,
+6,
+5,
+7,
+0,
+2,
+2,
+7,
+1,
+7,
+7,
+5,
+7,
+2,
+4,
+4,
+4,
+3,
+2,
+5,
+3,
+5,
+3,
+6,
+5,
+7,
+1,
+7,
+4,
+7,
+3,
+7,
+6,
+3,
+4,
+4,
+5,
+7,
+4,
+3,
+0,
+2,
+1,
+0,
+2,
+6,
+3,
+2,
+7,
+0,
+7,
+4,
+2,
+0,
+7,
+1,
+1,
+6,
+7,
+3,
+0,
+5,
+3,
+5,
+7,
+2,
+6,
+0,
+6,
+7,
+0,
+3,
+3,
+2,
+4,
+6,
+5,
+1,
+6,
+3,
+4,
+3,
+1,
+2,
+7,
+2,
+5,
+2,
+1,
+4,
+7,
+7,
+4,
+6,
+2,
+0,
+2,
+5,
+0,
+7,
+3,
+1,
+1,
+2,
+2,
+6,
+0,
+0,
+4,
+0,
+1,
+1,
+4,
+0,
+1,
+4,
+7,
+7,
+6,
+6,
+4,
+1,
+2,
+5,
+7,
+3,
+1,
+6,
+5,
+5,
+1,
+1,
+2,
+4,
+2,
+3,
+7,
+1,
+1,
+1,
+7,
+1,
+0,
+0,
+3,
+5,
+7,
+0,
+2,
+7,
+1,
+2,
+2,
+3,
+5,
+3,
+7,
+4,
+1,
+7,
+4,
+0,
+3,
+0,
+0,
+4,
+2,
+3,
+0,
+5,
+5,
+7,
+0,
+1,
+4,
+0,
+4,
+1,
+2,
+2,
+3,
+0,
+3,
+6,
+4,
+6,
+1,
+4,
+0,
+4,
+7,
+0,
+5,
+5,
+0,
+2,
+6,
+6,
+6,
+6,
+0,
+5,
+5,
+0,
+1,
+6,
+3,
+3,
+3,
+7,
+6,
+7,
+0,
+4,
+1,
+0,
+3,
+2,
+5,
+1,
+3,
+1,
+5,
+7,
+2,
+3,
+5,
+6,
+2,
+7,
+3,
+5,
+0,
+3,
+4,
+2,
+1,
+3,
+7,
+7,
+6,
+3,
+2,
+7,
+3,
+4,
+7,
+6,
+0,
+4,
+4,
+3,
+1,
+2,
+2,
+6,
+5,
+5,
+3,
+1,
+5,
+7,
+5,
+0,
+4,
+0,
+3,
+2,
+3,
+6,
+0,
+2,
+2,
+1,
+2,
+3,
+3,
+6,
+7,
+3,
+2,
+6,
+5,
+6,
+4,
+3,
+0,
+3,
+3,
+5,
+0,
+7,
+6,
+7,
+2,
+7,
+4,
+4,
+4,
+4,
+0,
+2,
+7,
+6,
+5,
+3,
+4,
+1,
+0,
+3,
+2,
+5,
+1,
+4,
+7,
+4,
+0,
+6,
+6,
+1,
+0,
+3,
+3,
+0,
+2,
+4,
+4,
+0,
+7,
+2,
+7,
+3,
+0,
+6,
+1,
+5,
+2,
+4,
+3,
+2,
+7,
+1,
+3,
+2,
+2,
+2,
+7,
+6,
+1,
+6,
+5,
+3,
+2,
+6,
+0,
+2,
+7,
+1,
+4,
+4,
+4,
+7,
+1,
+3,
+4,
+2,
+3,
+3,
+3,
+2,
+3,
+2,
+1,
+5,
+7,
+4,
+0,
+5,
+7,
+3,
+0,
+0,
+5,
+3,
+4,
+5,
+6,
+5,
+4,
+6,
+0,
+6,
+6,
+1,
+1,
+6,
+7,
+3,
+6,
+0,
+0,
+2,
+3,
+0,
+1,
+2,
+3,
+7,
+5,
+6,
+5,
+7,
+2,
+3,
+3,
+6,
+2,
+3,
+6,
+6,
+7,
+2,
+2,
+3,
+1,
+5,
+4,
+5,
+0,
+1,
+2,
+6,
+0,
+3,
+6,
+2,
+6,
+1,
+3,
+2,
+4,
+1,
+3,
+3,
+7,
+1,
+5,
+6,
+4,
+5,
+3,
+4,
+6,
+1,
+7,
+5,
+3,
+3,
+0,
+7,
+4,
+3,
+4,
+4,
+3,
+7,
+6,
+1,
+0,
+0,
+1,
+3,
+2,
+2,
+5,
+0,
+7,
+4,
+0,
+3,
+1,
+3,
+0,
+4,
+5,
+6,
+2,
+4,
+4,
+1,
+0,
+4,
+2,
+5,
+7,
+7,
+6,
+3,
+6,
+6,
+7,
+6,
+2,
+3,
+0,
+5,
+3,
+1,
+2,
+3,
+5,
+5,
+7,
+6,
+1,
+5,
+0,
+7,
+6,
+7,
+7,
+6,
+6,
+6,
+0,
+7,
+2,
+3,
+6,
+6,
+2,
+0,
+3,
+6,
+6,
+0,
+7,
+5,
+0,
+4,
+1,
+2,
+3,
+1,
+6,
+3,
+3,
+4,
+5,
+3,
+2,
+5,
+4,
+3,
+5,
+0,
+0,
+3,
+3,
+0,
+3,
+6,
+7,
+2,
+3,
+7,
+5,
+1,
+6,
+6,
+4,
+0,
+0,
+0,
+3,
+6,
+7,
+2,
+7,
+2,
+3,
+2,
+7,
+0,
+3,
+4,
+4,
+3,
+0,
+6,
+2,
+6,
+7,
+5,
+1,
+2,
+1,
+6,
+3,
+5,
+7,
+1,
+0,
+1,
+6,
+0,
+3,
+3,
+5,
+7,
+1,
+1,
+5,
+0,
+4,
+6,
+6,
+1,
+2,
+5,
+1,
+7,
+3,
+3,
+1,
+5,
+0,
+0,
+7,
+4,
+2,
+7,
+1,
+4,
+6,
+6,
+1,
+0,
+0,
+4,
+7,
+7,
+3,
+4,
+1,
+3,
+6,
+2,
+7,
+1,
+4,
+4,
+0,
+3,
+7,
+7,
+3,
+3,
+7,
+1,
+4,
+6,
+2,
+2,
+1,
+0,
+0,
+5,
+0,
+6,
+5,
+0,
+1,
+6,
+5,
+3,
+4,
+5,
+7,
+7,
+5,
+6,
+3,
+5,
+4,
+7,
+6,
+5,
+7,
+2,
+3,
+2,
+0,
+3,
+6,
+0,
+3,
+1,
+0,
+1,
+1,
+4,
+4,
+2,
+1,
+7,
+4,
+3,
+7,
+7,
+0,
+7,
+3,
+4,
+3,
+5,
+2,
+0,
+0,
+5,
+6,
+6,
+6,
+0,
+6,
+6,
+5,
+6,
+0,
+1,
+0,
+7,
+6,
+6,
+5,
+5,
+0,
+3,
+5,
+2,
+4,
+0,
+2,
+2,
+7,
+7,
+2,
+4,
+6,
+7,
+1,
+5,
+4,
+3,
+7,
+4,
+1,
+3,
+0,
+5,
+5,
+0,
+5,
+6,
+6,
+5,
+5,
+0,
+5,
+2,
+6,
+0,
+0,
+5,
+1,
+4,
+3,
+5,
+1,
+4,
+1,
+4,
+5,
+5,
+3,
+0,
+5,
+2,
+7,
+3,
+5,
+4,
+1,
+0,
+2,
+6,
+1,
+1,
+1,
+1,
+2,
+0,
+3,
+0,
+5,
+6,
+4,
+2,
+7,
+6,
+1,
+4,
+6,
+1,
+4,
+2,
+3,
+1,
+2,
+5,
+4,
+2,
+1,
+7,
+5,
+6,
+5,
+1,
+6,
+4,
+7,
+6,
+1,
+5,
+7,
+3,
+2,
+2,
+6,
+4,
+0,
+1,
+3,
+0,
+2,
+4,
+4,
+6,
+4,
+7,
+2,
+7,
+2,
+2,
+6,
+4,
+6,
+7,
+7,
+0,
+6,
+7,
+5,
+7,
+3,
+4,
+0,
+0,
+1,
+1,
+5,
+2,
+5,
+2,
+2,
+0,
+7,
+0,
+2,
+2,
+6,
+5,
+7,
+3,
+6,
+2,
+6,
+5,
+2,
+4,
+7,
+7,
+2,
+1,
+0,
+1,
+6,
+3,
+1,
+0,
+0,
+6,
+1,
+1,
+7,
+7,
+1,
+5,
+3,
+7,
+4,
+5,
+2,
+1,
+7,
+3,
+3,
+0,
+6,
+3,
+3,
+2,
+7,
+6,
+7,
+2,
+0,
+4,
+2,
+3,
+0,
+0,
+0,
+4,
+1,
+0,
+1,
+0,
+7,
+1,
+0,
+5,
+2,
+7,
+3,
+4,
+3,
+6,
+7,
+4,
+5,
+6,
+6,
+3,
+1,
+7,
+1,
+2,
+6,
+5,
+2,
+0,
+3,
+4,
+1,
+0,
+0,
+4,
+5,
+7,
+0,
+6,
+2,
+2,
+4,
+4,
+2,
+1,
+7,
+5,
+1,
+5,
+2,
+6,
+3,
+5,
+1,
+2,
+2,
+4,
+7,
+4,
+1,
+5,
+1,
+5,
+3,
+4,
+4,
+5,
+5,
+7,
+4,
+3,
+7,
+3,
+2,
+2,
+2,
+1,
+1,
+0,
+0,
+1,
+5,
+1,
+6,
+0,
+2,
+0,
+6,
+4,
+4,
+1,
+1,
+5,
+2,
+1,
+4,
+5,
+5,
+2,
+3,
+1,
+7,
+2,
+0,
+5,
+0,
+7,
+4,
+2,
+0,
+3,
+5,
+4,
+7,
+4,
+5,
+5,
+0,
+0,
+0,
+2,
+3,
+5,
+3,
+7,
+2,
+4,
+6,
+7,
+2,
+1,
+6,
+3,
+1,
+1,
+0,
+7,
+4,
+4,
+4,
+4,
+7,
+2,
+1,
+3,
+5,
+1,
+5,
+2,
+4,
+2,
+4,
+1,
+1,
+2,
+0,
+0,
+7,
+5,
+4,
+2,
+2,
+1,
+6,
+6,
+3,
+5,
+7,
+7,
+6,
+1,
+7,
+3,
+5,
+6,
+5,
+4,
+2,
+0,
+3,
+3,
+4,
+3,
+7,
+3,
+6,
+2,
+0,
+0,
+2,
+3,
+2,
+6,
+0,
+4,
+2,
+4,
+2,
+1,
+7,
+6,
+3,
+5,
+4,
+0,
+0,
+1,
+2,
+7,
+3,
+0,
+5,
+1,
+1,
+3,
+6,
+2,
+2,
+6,
+5,
+7,
+3,
+7,
+1,
+6,
+1,
+2,
+5,
+7,
+3,
+6,
+0,
+0,
+4,
+1,
+1,
+6,
+1,
+0,
+2,
+3,
+3,
+3,
+5,
+1,
+1,
+7,
+7,
+5,
+1,
+2,
+0,
+2,
+2,
+1,
+0,
+2,
+2,
+6,
+2,
+0,
+7,
+7,
+0,
+6,
+0,
+3,
+3,
+6,
+4,
+4,
+0,
+5,
+0,
+7,
+0,
+7,
+2,
+0,
+1,
+5,
+4,
+0,
+2,
+0,
+7,
+0,
+0,
+5,
+5,
+5
diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc
new file mode 100644 (file)
index 0000000..4632ec4
--- /dev/null
@@ -0,0 +1,178 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_viterbi_decoder.h>
+#include <qa_atsci_trellis_encoder.h>
+#include <cstdio>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+static const int NCODERS = atsci_viterbi_decoder::NCODERS;
+
+#if 0
+static void
+map_to_soft_symbols (atsc_soft_data_segment &out,
+                    const atsc_data_segment &in)
+{
+  for (unsigned int i = 0; i < NELEM (in.data); i++){
+    out.data[i] = in.data[i] * 2 - 7;
+  }
+}
+#endif
+
+static void
+pad_decoder_input (atsc_soft_data_segment out[NCODERS])
+{
+  memset (out,  0, sizeof (out));
+
+  // add data segment sync
+  for (int i = 0; i < NCODERS; i++){
+    out[i].data[0] =  5;
+    out[i].data[1] = -5;
+    out[i].data[2] = -5;
+    out[i].data[3] =  5;
+    out[i].pli.set_regular_seg (false, i);
+  }
+}
+
+void
+qa_atsci_viterbi_decoder::t0 ()
+{
+#if 0
+  atsci_trellis_encoder                enc;
+  atsc_mpeg_packet_rs_encoded  encoder_in[NCODERS];
+  atsc_data_segment            encoder_out[NCODERS];
+  atsc_soft_data_segment       decoder_in[NCODERS];
+  atsc_soft_data_segment       decoder_in_pad[NCODERS];
+  atsc_mpeg_packet_rs_encoded  decoder_out[NCODERS];
+  atsc_mpeg_packet_rs_encoded  decoder_out_pad[NCODERS];
+
+  
+  memset (encoder_in,      0, sizeof (encoder_in));
+  memset (encoder_out,     0, sizeof (encoder_out));
+  memset (decoder_out_pad, 0, sizeof (decoder_out_pad));
+
+  srandom (1);
+
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){
+      int t = (random () >> 8) & 0xff; // 8 random bits
+      encoder_in[i].data[j] = t;
+    }
+  }
+  
+  fflush (stdout);
+  printf ("@@@ ENCODER INPUT @@@\n");
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){
+       printf ("%d\n", encoder_in[i].data[j]);
+    }
+  }
+
+  enc.reset ();
+  enc.encode (encoder_out, encoder_in);
+
+  printf ("@@@ ENCODER OUTPUT @@@\n");
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (encoder_out[i].data); j++){
+       printf ("%d\n", encoder_out[i].data[j]);
+    }
+  }
+
+  for (int i = 0; i < NCODERS; i++)
+    map_to_soft_symbols (decoder_in[i], encoder_out[i]);
+
+  viterbi.reset ();
+
+  // this has only the previous (non-existant) output
+  viterbi.decode (decoder_out_pad, decoder_in);        
+
+  // now we'll see the real output
+  pad_decoder_input (decoder_in_pad);
+  viterbi.decode (decoder_out, decoder_in_pad);
+
+  printf ("@@@ DECODER OUTPUT @@@\n");
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (decoder_out[i].data); j++){
+       printf ("%d\n", decoder_out[i].data[j]);
+    }
+  }
+  fflush (stdout);
+#endif
+}
+
+void
+qa_atsci_viterbi_decoder::t1 ()
+{
+  atsc_soft_data_segment       decoder_in[NCODERS];
+  atsc_soft_data_segment       decoder_in_pad[NCODERS];
+  atsc_mpeg_packet_rs_encoded  decoder_out[NCODERS];
+  atsc_mpeg_packet_rs_encoded  decoder_out_pad[NCODERS];
+  atsc_mpeg_packet_rs_encoded  expected_out[NCODERS];
+  static const float           raw_input[NCODERS * NELEM (decoder_in[0].data)] = {
+#include "qa_atsci_viterbi_decoder_t1_input.dat"
+  };
+  static const unsigned char   raw_output[NCODERS * NELEM (expected_out[0].data)] = {
+#include "qa_atsci_viterbi_decoder_t1_output.dat"
+  };
+
+
+  // load up input
+  const float *ri = &raw_input[0];
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (decoder_in[i].data); j++){
+      decoder_in[i].data[j] = *ri++;
+    }
+    decoder_in[i].pli.set_regular_seg (false, i);
+  }
+
+  // load up expected output
+  const unsigned char *ro = &raw_output[0];
+  for (int i = 0; i < NCODERS; i++){
+    for (unsigned int j = 0; j < NELEM (expected_out[i].data); j++){
+      expected_out[i].data[j] = *ro++;
+    }
+    expected_out[i].pli.set_regular_seg (false, i);
+  }
+
+  viterbi.reset ();
+
+  // this has only the previous (non-existant) output
+  viterbi.decode (decoder_out_pad, decoder_in);        
+
+  // now we'll see the real output
+  pad_decoder_input (decoder_in_pad);
+  viterbi.decode (decoder_out, decoder_in_pad);
+
+  for (int i = 0; i < NCODERS; i++){                   // check the result
+    CPPUNIT_ASSERT (expected_out[i] == decoder_out[i]);
+  }
+}
diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder.h b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.h
new file mode 100644 (file)
index 0000000..3e74d2b
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_ATSC_VITERBI_DECODER_H_
+#define _QA_ATSC_VITERBI_DECODER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <stdio.h>
+#include <atsci_viterbi_decoder.h>
+
+class qa_atsci_viterbi_decoder : public CppUnit::TestCase {
+
+ public:
+
+  void setUp (void) 
+  {
+    viterbi.reset ();
+  }
+
+  CPPUNIT_TEST_SUITE (qa_atsci_viterbi_decoder);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  atsci_viterbi_decoder        viterbi;
+  
+  void t0 ();
+  void t1 ();
+};
+
+
+#endif /* _QA_ATSC_VITERBI_DECODER_H_ */
diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat
new file mode 100644 (file)
index 0000000..b2f356c
--- /dev/null
@@ -0,0 +1,9984 @@
+  5 + -0.863407,
+ -5 + 0.630254,
+ -5 + 0.766777,
+  5 + -0.587788,
+ -3 + 0.197374,
+ -7 + -0.928392,
+  1 + 0.846137,
+ -3 + -0.148515,
+  5 + 0.20529,
+ -3 + 0.957658,
+  1 + 0.712777,
+ -3 + -0.783731,
+ -7 + -0.649688,
+ -3 + 0.364183,
+ -3 + 0.766379,
+  5 + -0.254228,
+ -5 + 0.265344,
+  1 + -0.0926997,
+  5 + -0.729882,
+ -5 + -0.946608,
+  7 + 0.941424,
+ -1 + 0.00502258,
+  5 + 0.353994,
+ -1 + -0.431315,
+ -3 + 0.802947,
+  7 + 0.0174765,
+ -1 + 0.107732,
+  7 + -0.426013,
+ -3 + 0.179269,
+  1 + -0.334729,
+ -5 + 0.363112,
+  1 + -0.793512,
+ -1 + -0.386831,
+  7 + -0.469307,
+  7 + -0.592471,
+  3 + -0.0650877,
+  7 + 0.465307,
+ -1 + 0.0575076,
+  3 + 0.804467,
+  7 + 0.766673,
+ -3 + 0.177288,
+ -3 + 0.254259,
+ -7 + 0.0933109,
+  3 + -0.132741,
+ -7 + 0.226975,
+  1 + 0.805,
+  3 + 0.474327,
+  3 + -0.147847,
+ -1 + 0.3179,
+ -7 + -0.141455,
+  3 + 0.322113,
+ -3 + 0.633945,
+ -1 + -0.950742,
+ -5 + -0.39542,
+  3 + -0.0594983,
+ -3 + -0.772717,
+ -5 + 0.545784,
+  7 + 0.398416,
+  3 + -0.673597,
+  3 + -0.790352,
+ -7 + -0.544624,
+  7 + -0.633903,
+ -1 + -0.908654,
+ -3 + -0.311397,
+ -5 + 0.662512,
+ -3 + -0.135222,
+ -7 + 0.366291,
+  1 + -0.741085,
+ -7 + -0.29157,
+ -5 + -0.673842,
+  3 + 0.776452,
+ -5 + -0.0937042,
+  3 + 0.683802,
+ -5 + -0.722854,
+ -7 + 0.0347072,
+ -5 + 0.40685,
+ -5 + 0.31874,
+  5 + -0.947299,
+  3 + -0.955457,
+  1 + 0.742103,
+ -5 + -0.535021,
+ -5 + -0.67394,
+ -5 + -0.108192,
+ -1 + -0.968649,
+  1 + 0.445698,
+  3 + -0.476884,
+  7 + 0.566045,
+ -7 + -0.137864,
+ -1 + -0.190159,
+ -5 + -0.0220287,
+  5 + 0.307356,
+  5 + 0.917233,
+ -7 + 0.320761,
+  3 + -0.789388,
+ -5 + 0.117822,
+  5 + -0.604396,
+ -1 + 0.552753,
+  7 + -0.446649,
+  7 + -0.810118,
+  7 + -0.658175,
+ -7 + 0.553164,
+ -7 + -0.344854,
+ -3 + 0.280593,
+  7 + -0.884303,
+  7 + 0.720506,
+ -1 + -0.987799,
+  7 + 0.793155,
+  1 + -0.850125,
+  7 + 0.115369,
+  5 + 0.544406,
+  5 + -0.276058,
+ -1 + -0.231108,
+ -5 + 0.376881,
+  3 + -0.559075,
+  7 + -0.915446,
+ -1 + -0.460641,
+  3 + 0.818044,
+ -3 + -0.991244,
+  1 + 0.420497,
+  1 + 0.485863,
+ -3 + -0.376003,
+  5 + -0.350986,
+  5 + 0.430744,
+ -3 + 0.463798,
+  5 + 0.42518,
+  5 + -0.290836,
+ -5 + -0.691567,
+ -7 + 0.824346,
+  3 + 0.450636,
+ -3 + 0.043629,
+  7 + 0.316293,
+  5 + -0.120924,
+  1 + 0.726472,
+ -1 + -0.543775,
+  3 + 0.933344,
+ -3 + 0.132114,
+ -3 + -0.310619,
+  5 + 0.911921,
+ -1 + -0.497207,
+  3 + -0.637383,
+ -5 + -0.732262,
+  7 + 0.107649,
+  3 + 0.520015,
+ -1 + 0.157455,
+ -3 + -0.894858,
+ -1 + 0.0945327,
+  1 + -0.691426,
+  7 + 0.144207,
+  3 + 0.445607,
+ -1 + 0.255407,
+ -7 + 0.306034,
+ -3 + -0.371352,
+ -1 + 0.124452,
+ -5 + 0.359695,
+ -5 + -0.888643,
+  3 + 0.290357,
+  3 + -0.0254667,
+ -3 + 0.407853,
+ -5 + 0.679174,
+ -5 + 0.0575717,
+ -3 + 0.137283,
+  3 + 0.729587,
+  7 + 0.31509,
+ -3 + -0.348804,
+  1 + 0.57604,
+ -5 + 0.345748,
+  7 + -0.327496,
+ -5 + -0.425651,
+ -7 + 0.140657,
+ -3 + 0.238764,
+ -7 + -0.143133,
+  3 + 0.337288,
+  1 + 0.959842,
+  7 + -0.977864,
+  3 + -0.317419,
+  3 + -0.198654,
+  3 + 0.955435,
+  3 + -0.23876,
+  1 + -0.88292,
+ -5 + -0.511151,
+  3 + 0.779996,
+  3 + -0.443377,
+ -1 + -0.192438,
+ -5 + 0.811447,
+ -7 + 0.634155,
+  1 + -0.762404,
+  3 + 0.731365,
+  5 + 0.783236,
+  5 + -0.307317,
+  7 + 0.482175,
+  7 + -0.539608,
+  7 + -0.775192,
+  1 + -0.560785,
+ -7 + 0.206625,
+ -5 + -0.038118,
+ -5 + -0.228189,
+  1 + 0.462362,
+ -5 + 0.72833,
+ -1 + 0.622996,
+ -3 + 0.998274,
+  5 + 0.142163,
+ -7 + 0.618011,
+  3 + 0.122273,
+ -7 + -0.483532,
+ -1 + -0.854097,
+ -5 + 0.108088,
+  7 + -0.193228,
+  3 + 0.648767,
+ -3 + -0.656924,
+ -7 + -0.991222,
+ -3 + -0.25652,
+  3 + -0.269033,
+ -1 + 0.324665,
+ -1 + 0.107827,
+ -5 + -0.0475933,
+ -5 + -0.99274,
+ -5 + -0.30318,
+ -3 + -0.747831,
+ -3 + -0.203781,
+  3 + -0.010757,
+  7 + 0.0734757,
+  7 + -0.761203,
+ -7 + 0.389509,
+  1 + -0.25976,
+ -1 + 0.965806,
+  7 + 0.526324,
+ -1 + -0.298331,
+ -3 + 0.410725,
+ -1 + 0.00752225,
+  5 + -0.455632,
+  1 + -0.884761,
+  7 + 0.602377,
+  7 + 0.555917,
+  3 + -0.160695,
+ -7 + -0.567533,
+  3 + 0.758232,
+  1 + -0.587694,
+ -7 + 0.414466,
+ -7 + -0.652491,
+  1 + 0.0124494,
+ -7 + 0.389889,
+  7 + 0.227003,
+  1 + 0.242753,
+ -7 + 0.913462,
+ -3 + 0.691642,
+ -5 + 0.75989,
+  1 + -0.596777,
+ -3 + -0.752662,
+  3 + -0.108642,
+  7 + -0.60189,
+  7 + 0.511322,
+ -3 + -0.24478,
+  7 + -0.849058,
+ -1 + -0.845527,
+ -7 + -0.572068,
+ -5 + -0.661012,
+  5 + -0.701889,
+  7 + 0.822228,
+  1 + -0.00200901,
+  5 + -0.71468,
+  5 + 0.691151,
+  7 + 0.561903,
+  3 + -0.527991,
+ -1 + -0.867353,
+  3 + -0.728324,
+  5 + -0.813234,
+  1 + -0.966217,
+  1 + 0.0669532,
+  7 + 0.905965,
+ -3 + -0.937283,
+ -3 + 0.774056,
+  3 + -0.384885,
+ -7 + 0.175322,
+ -3 + 0.309913,
+ -5 + 0.251167,
+ -1 + 0.381753,
+  3 + 0.00625176,
+ -7 + 0.56373,
+ -3 + 0.63392,
+  3 + 0.762169,
+  7 + 0.0347039,
+ -3 + -0.935108,
+ -1 + -0.114944,
+  1 + -0.424213,
+  1 + 0.0317198,
+ -3 + 0.2139,
+ -5 + 0.0530905,
+ -7 + -0.36603,
+ -5 + -0.851717,
+ -7 + 0.414219,
+ -1 + -0.397429,
+ -3 + -0.995697,
+ -7 + -0.328063,
+ -1 + -0.604664,
+  7 + -0.45941,
+  3 + 0.718596,
+ -7 + -0.377836,
+ -1 + 0.915331,
+  7 + -0.730175,
+ -1 + -0.51083,
+  7 + -0.923481,
+  1 + 0.102495,
+ -1 + 0.1293,
+ -3 + 0.812872,
+ -5 + 0.066343,
+ -1 + -0.578684,
+  1 + 0.926482,
+ -7 + 0.10389,
+  5 + -0.462554,
+ -5 + -0.108,
+  5 + -0.471902,
+  7 + -0.34884,
+  5 + 0.719192,
+ -7 + -0.763765,
+ -3 + 0.257366,
+ -5 + -0.623314,
+ -7 + 0.0467943,
+  5 + -0.646451,
+  7 + 0.54531,
+  3 + -0.955682,
+ -5 + -0.432122,
+  3 + -0.886357,
+  1 + 0.088559,
+  5 + -0.975894,
+  5 + -0.105386,
+ -3 + 0.0978638,
+  1 + -0.199998,
+  5 + 0.0380346,
+  3 + 0.427315,
+ -3 + 0.214304,
+ -5 + -0.566543,
+ -7 + -0.380715,
+ -3 + -0.877135,
+ -5 + 0.267701,
+ -3 + -0.03107,
+ -3 + 0.595488,
+ -1 + 0.322574,
+ -5 + 0.559362,
+  1 + -0.0401364,
+ -7 + 0.528057,
+  5 + -0.319427,
+ -1 + 0.357237,
+  7 + 0.222854,
+ -5 + -0.432566,
+  1 + -0.998243,
+  7 + 0.742835,
+  3 + -0.182255,
+  3 + -0.471161,
+  3 + 0.606823,
+ -7 + 0.974148,
+  5 + -0.667598,
+  1 + -0.811568,
+  1 + -0.936551,
+  7 + -0.530943,
+  5 + 0.908057,
+ -7 + 0.895185,
+  5 + 0.711135,
+  1 + -0.95896,
+  1 + 0.83532,
+  1 + 0.14732,
+  3 + 0.90921,
+ -1 + -0.30945,
+ -1 + -0.869543,
+ -7 + -0.360646,
+  1 + 0.357157,
+ -3 + -0.514692,
+  5 + 0.896144,
+ -1 + -0.196886,
+ -5 + -0.319624,
+ -1 + -0.472977,
+ -1 + -0.784624,
+ -1 + -0.281646,
+ -5 + -0.559682,
+  3 + 0.391078,
+  7 + 0.306199,
+ -3 + 0.962734,
+ -7 + -0.11162,
+ -7 + 0.357581,
+  3 + 0.0805047,
+  3 + -0.922337,
+  1 + 0.232492,
+ -5 + -0.574144,
+ -1 + 0.710829,
+  7 + -0.284843,
+ -1 + 0.831973,
+ -1 + -0.336799,
+ -3 + -0.745866,
+ -5 + -0.645711,
+  5 + 0.0646029,
+ -3 + 0.252552,
+  5 + -0.48003,
+ -5 + 0.299438,
+  7 + 0.738929,
+ -5 + 0.40337,
+  5 + 0.605547,
+ -3 + -0.525722,
+  1 + -0.326724,
+  1 + -0.515053,
+  5 + 0.261516,
+ -7 + 0.320474,
+ -1 + -0.521487,
+ -5 + 0.903239,
+ -3 + -0.403525,
+  7 + 0.0639151,
+  3 + 0.359482,
+  3 + 0.823776,
+  5 + 0.0387504,
+ -7 + 0.109849,
+  3 + -0.097467,
+ -5 + -0.832645,
+ -5 + 0.526237,
+  7 + 0.438123,
+  3 + -0.519244,
+  1 + -0.0476922,
+  3 + 0.191197,
+ -7 + -0.534928,
+  3 + 0.462164,
+  7 + -0.895527,
+ -1 + 0.473474,
+ -7 + 0.146189,
+  5 + -0.179909,
+ -3 + -0.285322,
+  5 + 0.613479,
+ -1 + -0.0315166,
+  7 + 0.698841,
+  3 + -0.774282,
+  1 + 0.818017,
+  7 + -0.932623,
+  3 + 0.0664446,
+ -7 + 0.06308,
+  3 + -0.519814,
+  5 + -0.576546,
+  5 + -0.267179,
+ -3 + -0.837482,
+  5 + -0.255068,
+  5 + -0.0568383,
+ -3 + 0.888405,
+ -3 + -0.366288,
+ -5 + -0.552696,
+ -1 + 0.541689,
+  7 + -0.0454361,
+ -5 + 0.608489,
+  3 + -0.922755,
+ -5 + 0.406846,
+ -5 + -0.506253,
+  7 + -0.688017,
+ -5 + 0.776949,
+  1 + -0.378568,
+  5 + -0.727209,
+ -7 + 0.613322,
+  5 + 0.962756,
+ -7 + -0.893482,
+ -7 + -0.987528,
+ -7 + 0.456806,
+  7 + 0.786419,
+  1 + 0.034181,
+ -7 + 0.790939,
+ -5 + -0.0300588,
+  1 + 0.1652,
+ -7 + -0.481907,
+  3 + 0.0991387,
+ -7 + -0.564886,
+  5 + 0.85039,
+ -1 + 0.812973,
+ -1 + -0.407522,
+  7 + -0.952524,
+  5 + 0.765642,
+ -5 + -0.337741,
+  7 + 0.957819,
+  3 + -0.899041,
+ -1 + -0.671052,
+ -3 + 0.983954,
+  1 + -0.89124,
+ -3 + 0.0940522,
+ -1 + 0.611417,
+  7 + -0.937967,
+ -1 + 0.941416,
+ -1 + -0.359601,
+  5 + 0.747211,
+ -7 + -0.111301,
+  3 + -0.640113,
+  7 + 0.0550081,
+  7 + -0.189345,
+  3 + 0.214366,
+ -5 + 0.135666,
+ -5 + 0.226602,
+  3 + -0.410662,
+  5 + -0.843728,
+ -3 + -0.371912,
+ -7 + -0.989917,
+ -1 + 0.690856,
+ -1 + 0.0420038,
+  7 + 0.00959448,
+  5 + -0.815518,
+  1 + 0.430825,
+ -7 + 0.609881,
+  5 + -0.688188,
+  5 + -0.60674,
+ -1 + 0.0334734,
+  1 + 0.722216,
+ -3 + 0.285942,
+  7 + 0.519757,
+  3 + -0.27104,
+ -1 + 0.509289,
+ -3 + -0.81976,
+  5 + 0.481086,
+  3 + -0.974128,
+  7 + -0.337838,
+  5 + 0.962801,
+ -3 + -0.798452,
+ -3 + 0.457351,
+  1 + 0.103281,
+ -1 + -0.0256317,
+  7 + 0.802218,
+  7 + 0.689228,
+ -7 + -0.276751,
+  5 + 0.404102,
+ -1 + -0.860859,
+ -7 + -0.0371287,
+ -1 + 0.370437,
+ -5 + -0.616334,
+ -5 + -0.758392,
+  1 + -0.454585,
+  1 + -0.137519,
+  7 + -0.261276,
+  5 + 0.558348,
+  1 + -0.948463,
+ -5 + 0.523879,
+ -5 + 0.555652,
+ -1 + 0.840325,
+  7 + 0.279812,
+  5 + 0.617966,
+  1 + 0.192231,
+  5 + 0.132018,
+ -7 + -0.11959,
+  1 + -0.894721,
+ -7 + -0.504819,
+  5 + -0.419666,
+  7 + -0.391328,
+ -3 + -0.24103,
+ -7 + -0.852627,
+ -7 + 0.990221,
+  7 + 0.822151,
+ -7 + 0.170617,
+  3 + 0.614475,
+ -7 + 0.446277,
+ -7 + -0.371819,
+  1 + 0.831829,
+ -5 + 0.0787276,
+ -1 + -0.684313,
+  3 + -0.611736,
+  5 + 0.472613,
+  7 + 0.730033,
+ -5 + -0.811217,
+  1 + -0.760817,
+ -3 + 0.268843,
+  5 + 0.584456,
+  1 + 0.823053,
+ -7 + 0.80804,
+ -7 + 0.457053,
+  5 + -0.577104,
+ -5 + -0.224893,
+ -5 + -0.107738,
+ -1 + -0.51484,
+  3 + -0.198893,
+ -7 + 0.278753,
+  7 + 0.502244,
+ -1 + 0.0510433,
+  1 + -0.402208,
+ -7 + 0.343478,
+  1 + -0.901047,
+  1 + 0.369701,
+ -3 + -0.944263,
+ -5 + 0.386476,
+  3 + -0.954781,
+  7 + -0.688498,
+  7 + -0.365083,
+  3 + -0.776885,
+ -1 + -0.598649,
+  3 + -0.87102,
+  1 + 0.975515,
+ -3 + -0.467838,
+  1 + 0.466075,
+ -7 + 0.271324,
+ -1 + 0.978247,
+  7 + 0.112029,
+ -1 + 0.601593,
+ -3 + -0.412666,
+  1 + -0.601096,
+  5 + -0.0684049,
+ -7 + 0.552019,
+ -5 + 0.313324,
+  5 + -0.836011,
+ -1 + 0.528016,
+ -3 + 0.284965,
+ -3 + 0.700575,
+ -5 + 0.0874079,
+ -7 + -0.0126598,
+ -7 + -0.276119,
+  5 + -0.218603,
+ -5 + -0.0014039,
+ -3 + 0.189325,
+  7 + 0.429569,
+ -5 + 0.837003,
+  3 + 0.703335,
+  7 + -0.216503,
+  7 + 0.0920741,
+  7 + 0.750109,
+ -1 + -0.322132,
+  7 + -0.128556,
+ -1 + 0.00373274,
+ -1 + -0.17115,
+  1 + 0.264227,
+  3 + 0.988822,
+ -1 + 0.0243255,
+ -5 + 0.605084,
+ -7 + 0.295968,
+  5 + 0.873413,
+ -1 + 0.434273,
+ -5 + -0.781778,
+  5 + -0.0426681,
+ -5 + 0.167692,
+ -1 + -0.334183,
+ -1 + 0.07798,
+ -1 + -0.297114,
+ -3 + 0.816338,
+  1 + -0.611242,
+  3 + -0.423656,
+  3 + -0.432077,
+  1 + -0.145807,
+  5 + 0.10632,
+ -5 + 0.756861,
+ -7 + -0.931971,
+  7 + -0.397063,
+  5 + 0.283628,
+ -7 + 0.721398,
+  7 + 0.348194,
+ -3 + -0.33922,
+  3 + 0.412108,
+  7 + 0.510752,
+ -3 + -0.263234,
+ -7 + 0.485708,
+  5 + 0.573377,
+  3 + 0.244824,
+ -7 + 0.756185,
+  5 + -0.981843,
+ -7 + 0.890249,
+ -5 + -0.785723,
+  1 + 0.429159,
+  7 + 0.891205,
+  5 + -0.310018,
+  5 + -0.0331806,
+ -7 + 0.567766,
+ -7 + -0.172382,
+  3 + -0.0973954,
+ -1 + -0.726783,
+ -7 + 0.86626,
+ -3 + 0.640023,
+  5 + -0.104726,
+ -3 + -0.213919,
+ -5 + -0.131563,
+  3 + 0.108026,
+  1 + 0.426832,
+ -7 + 0.631181,
+ -3 + -0.911012,
+  5 + 0.232769,
+ -3 + -0.124074,
+  5 + -0.263584,
+ -3 + 0.246066,
+  7 + 0.833384,
+ -5 + -0.798822,
+  1 + -0.281957,
+  1 + -0.527281,
+  3 + 0.918325,
+  5 + -0.872591,
+ -3 + 0.987781,
+  7 + -0.724259,
+  7 + 0.73749,
+  5 + -0.179643,
+  1 + -0.480496,
+ -1 + -0.0747694,
+  3 + -0.162109,
+  1 + 0.655518,
+  5 + 0.815859,
+  7 + -0.422858,
+ -1 + 0.19599,
+  3 + -0.601651,
+  7 + -0.598413,
+ -5 + -0.951473,
+  7 + 0.684015,
+  7 + 0.121945,
+  5 + 0.330604,
+ -1 + 0.800472,
+ -5 + -0.892743,
+ -5 + -0.0700532,
+ -1 + 0.143832,
+ -1 + 0.713388,
+  1 + -0.253503,
+  1 + -0.0462767,
+  3 + 0.140933,
+ -5 + 0.94534,
+ -7 + 0.665662,
+ -5 + 0.207102,
+  3 + -0.327194,
+  5 + 0.110171,
+ -5 + 0.225803,
+  1 + -0.900872,
+ -5 + 0.0169889,
+  5 + 0.152721,
+  7 + 0.125242,
+ -1 + 0.63948,
+  7 + 0.0639926,
+ -5 + -0.869524,
+  7 + -0.160608,
+ -1 + -0.465428,
+  5 + -0.2185,
+ -7 + -0.465846,
+ -1 + 0.0973919,
+  3 + 0.450568,
+ -5 + -0.451587,
+ -7 + -0.83918,
+ -1 + 0.709855,
+  3 + -0.86862,
+  5 + 0.676479,
+  7 + -0.125049,
+ -1 + -0.191198,
+  5 + -0.925049,
+  1 + -0.521026,
+ -3 + -0.0364143,
+ -7 + 0.600769,
+ -7 + 0.164072,
+ -5 + 0.416589,
+ -7 + -0.595857,
+ -3 + 0.220567,
+  3 + 0.0636474,
+ -7 + 0.644101,
+  5 + -0.775524,
+ -3 + -0.192748,
+  1 + 0.0538391,
+  1 + 0.29524,
+ -5 + 0.882538,
+ -5 + -0.816844,
+ -5 + 0.862396,
+ -5 + 0.314402,
+  1 + -0.392808,
+ -3 + 0.651255,
+ -1 + -0.231968,
+  1 + 0.738021,
+  5 + 0.84997,
+ -3 + 0.186296,
+  1 + 0.741231,
+  1 + -0.177977,
+  5 + 0.522434,
+ -7 + 0.597047,
+ -3 + 0.0266608,
+ -5 + -0.152547,
+  5 + -0.579447,
+ -1 + -0.357272,
+ -7 + -0.497293,
+  5 + 0.869424,
+ -5 + -0.0230876,
+ -5 + -0.132476,
+ -3 + 0.936738,
+  5 + 0.558816,
+ -3 + -0.0384813,
+ -1 + 0.483534,
+ -7 + 0.867384,
+ -1 + 0.42158,
+  3 + 0.420513,
+  7 + -0.0754159,
+ -5 + -0.379954,
+  7 + 0.769618,
+ -7 + 0.340938,
+ -7 + -0.869991,
+  3 + 0.830734,
+  3 + 0.94181,
+  3 + -0.130749,
+  3 + 0.517635,
+ -3 + -0.252298,
+ -3 + -0.0496521,
+  1 + 0.684225,
+  1 + 0.172965,
+  1 + 0.417296,
+  7 + -0.466398,
+  7 + -0.114508,
+ -1 + -0.109476,
+ -7 + 0.00148834,
+  1 + 0.0949139,
+  1 + 0.432791,
+ -1 + -0.240929,
+ -1 + 0.652485,
+  5 + -0.217385,
+  7 + -0.8724,
+ -1 + 0.387098,
+  3 + -0.444865,
+ -3 + 0.184706,
+  7 + -0.730551,
+  7 + 0.754565,
+  7 + -0.604301,
+  3 + -0.119371,
+ -1 + -0.28214,
+  5 + 0.143776,
+  3 + 0.957703,
+  3 + -0.104371,
+ -5 + -0.261664,
+ -1 + 0.495793,
+  1 + -0.734588,
+ -3 + 0.628134,
+ -3 + 0.817538,
+ -7 + 0.361645,
+  3 + 0.162489,
+  5 + -0.536024,
+  7 + -0.486136,
+  5 + -0.776124,
+ -5 + -0.629988,
+  1 + -0.0367843,
+ -5 + -0.493533,
+ -7 + -0.725222,
+ -5 + 0.492433,
+  7 + 0.288113,
+ -3 + -0.784857,
+ -5 + 0.824698,
+ -1 + -0.545993,
+ -3 + -0.306256,
+  1 + -0.877171,
+ -1 + 0.567034,
+  3 + -0.440337,
+ -1 + 0.14643,
+  7 + -0.755017,
+ -1 + -0.832763,
+  5 + -0.498979,
+  3 + 0.763625,
+  5 + 0.566975,
+ -5 + 0.0534092,
+ -5 + -0.963171,
+  5 + 0.0216508,
+  7 + 0.597324,
+  7 + -0.441571,
+  7 + 0.0347587,
+  3 + 0.983787,
+  1 + 0.188113,
+ -1 + -0.171194,
+ -7 + -0.641733,
+  7 + 0.36138,
+ -1 + -0.566453,
+  1 + 0.882606,
+  1 + 0.61524,
+ -1 + -0.773541,
+  3 + 0.153026,
+  5 + -0.621578,
+ -7 + -0.904904,
+ -5 + 0.0406272,
+ -5 + 0.415864,
+  5 + -0.60085,
+  1 + 0.727596,
+ -7 + -0.0860673,
+ -1 + -0.785685,
+ -5 + -0.889453,
+  7 + -0.141489,
+ -5 + 0.04296,
+ -5 + 0.564742,
+ -7 + -0.12966,
+ -1 + 0.841196,
+ -5 + 0.71528,
+  1 + -0.104704,
+  1 + -0.263372,
+ -7 + 0.680698,
+  3 + 0.756433,
+ -3 + -0.200798,
+  1 + 0.027729,
+ -1 + -0.464512,
+  7 + -0.60066,
+ -1 + 0.104495,
+ -3 + 0.713626,
+ -5 + -0.776119,
+  3 + 0.168751,
+ -1 + -0.905566,
+  5 + -0.955254,
+ -7 + -0.407108,
+ -3 + 0.170629,
+ -3 + -0.453202,
+ -1 + -0.907515,
+  5 + -0.210368,
+ -3 + -0.98412,
+ -3 + -0.798125,
+  3 + -0.414919,
+ -1 + -0.236897,
+  3 + -0.491091,
+ -5 + -0.77713,
+  3 + 0.230108,
+  1 + -0.796737,
+  5 + -0.26121,
+  3 + 0.397635,
+ -1 + 0.85451,
+ -3 + -0.393889,
+  5 + 0.983874,
+  5 + 0.942163,
+ -3 + 0.74394,
+  1 + 0.242709,
+  3 + -0.779053,
+ -1 + 0.341856,
+ -7 + -0.116747,
+ -7 + -0.640877,
+ -1 + -0.318128,
+ -7 + 0.00367009,
+ -3 + 0.617172,
+  7 + -0.204651,
+ -5 + 0.0780388,
+  7 + 0.626396,
+  1 + -0.638141,
+ -1 + -0.882934,
+ -5 + -0.704026,
+ -3 + 0.851265,
+  7 + 0.0141939,
+ -7 + 0.611678,
+ -1 + 0.341055,
+  3 + -0.405282,
+ -7 + 0.993071,
+ -5 + -0.0799289,
+  1 + -0.967094,
+ -5 + -0.893374,
+  5 + -0.606802,
+ -1 + -0.296088,
+  3 + 0.578082,
+  1 + 0.630626,
+ -1 + -0.256433,
+ -7 + 0.023755,
+  5 + -0.565901,
+  1 + -0.87536,
+ -7 + 0.591114,
+  3 + -0.0151382,
+  3 + -0.218575,
+ -1 + -0.571426,
+  7 + -0.817884,
+  1 + -0.105616,
+ -5 + 0.226052,
+  1 + -0.197419,
+  1 + -0.804454,
+  1 + -0.957871,
+ -7 + 0.869702,
+  7 + -0.118016,
+ -7 + 0.231177,
+ -1 + 0.143965,
+ -7 + -0.544014,
+ -7 + -0.125394,
+ -5 + 0.66333,
+ -5 + 0.0453925,
+  3 + -0.445539,
+ -3 + -0.841133,
+ -1 + 0.406819,
+  1 + 0.066009,
+ -7 + -0.141267,
+  7 + 0.20172,
+  1 + -0.397711,
+ -3 + -0.341991,
+  3 + -0.66472,
+ -1 + 0.1133,
+ -1 + -0.0874664,
+  1 + 0.460378,
+ -5 + 0.833044,
+ -1 + 0.694845,
+ -5 + -0.814154,
+  5 + 0.190124,
+  5 + 0.90168,
+ -3 + 0.150333,
+  5 + -0.832164,
+  5 + -0.623571,
+  5 + 0.116979,
+  7 + -0.623282,
+ -3 + 0.724953,
+  3 + -0.656996,
+  7 + 0.0645319,
+  3 + 0.0895726,
+  7 + -0.776726,
+ -1 + 0.318608,
+  3 + 0.0496206,
+ -3 + 0.0368759,
+ -1 + 0.555521,
+ -5 + -0.673436,
+  1 + 0.0103849,
+ -3 + 0.0743446,
+ -3 + -0.259726,
+  5 + 0.0216708,
+  1 + 0.769972,
+ -5 + -0.441797,
+ -3 + 0.719177,
+  3 + 0.576816,
+  1 + -0.95444,
+  3 + 0.385715,
+  7 + 0.215961,
+ -7 + -0.0887377,
+ -3 + 0.9093,
+  5 + 0.231244,
+ -5 + 0.878044,
+  1 + 0.237768,
+ -5 + -0.224173,
+  7 + 0.115184,
+  5 + -0.507669,
+  3 + -0.4694,
+ -5 + -0.559494,
+ -7 + 0.256493,
+ -3 + 0.691867,
+  7 + 0.760056,
+ -5 + -0.0235437,
+ -1 + -0.491056,
+ -7 + -0.632234,
+ -7 + 0.688073,
+ -3 + 0.448912,
+  1 + 0.806255,
+  3 + 0.174302,
+ -1 + 0.924295,
+  1 + -0.0079971,
+  7 + 0.585534,
+  5 + -0.106368,
+  7 + -0.647104,
+ -3 + -0.232442,
+ -1 + 0.103303,
+  3 + -0.545308,
+ -7 + 0.171427,
+  1 + -0.150061,
+ -5 + 0.124142,
+  1 + 0.609533,
+  1 + -0.51341,
+  3 + 0.372706,
+ -5 + 0.406665,
+  3 + -0.277069,
+ -3 + 0.316304,
+ -7 + -0.233404,
+ -7 + 0.0158354,
+ -3 + -0.376876,
+  1 + -0.914291,
+ -3 + -0.819444,
+ -7 + 0.566109,
+ -5 + -0.582836,
+ -5 + -0.839922,
+  5 + 0.186932,
+ -5 + -0.675285,
+  5 + -0.957952,
+ -7 + -0.784832,
+ -3 + 0.403649,
+  3 + 0.798144,
+ -3 + -0.880645,
+ -3 + 0.528126,
+ -1 + -0.657318,
+  3 + 0.890482,
+  5 + -0.46684,
+  5 + -0.566931,
+ -7 + 0.81062,
+ -1 + -0.0238388,
+ -7 + -0.377402,
+ -3 + -0.21429,
+ -5 + -0.505753,
+ -7 + -0.951982,
+ -1 + -0.515628,
+  3 + -0.871026,
+ -1 + -0.838789,
+ -7 + -0.725925,
+  1 + 0.77047,
+ -3 + 0.858867,
+  5 + 0.600752,
+ -3 + 0.0665514,
+  1 + -0.317725,
+  3 + -0.843704,
+  5 + 0.219384,
+ -5 + -0.586559,
+  7 + -0.240551,
+ -3 + -0.209033,
+ -7 + 0.493641,
+  7 + 0.152856,
+ -7 + -0.597324,
+ -1 + -0.276392,
+ -1 + 0.831608,
+  5 + 0.470546,
+  5 + 0.330143,
+ -7 + 0.642262,
+ -7 + 0.977435,
+ -7 + 0.313444,
+ -7 + -0.10048,
+  5 + 0.563594,
+ -1 + -0.186187,
+ -1 + -0.365659,
+  1 + -0.837578,
+ -5 + 0.140403,
+  7 + -0.78022,
+ -1 + 0.844668,
+  7 + 0.375148,
+  7 + -0.0498808,
+  1 + 0.40211,
+ -1 + 0.744509,
+  3 + 0.079077,
+  7 + 0.296291,
+  7 + -0.27219,
+ -7 + -0.660157,
+ -3 + 0.915867,
+ -1 + 0.102478,
+  1 + -0.851214,
+  7 + -0.634492,
+ -5 + -0.253903,
+ -5 + -0.598679,
+ -7 + -0.223802,
+  3 + 0.0226067,
+  1 + 0.696982,
+ -5 + -0.0351859,
+  5 + -0.481739,
+ -1 + -0.00746336,
+  3 + 0.416315,
+  5 + 0.321218,
+  3 + -0.283638,
+ -7 + 0.752743,
+  3 + -0.774599,
+ -1 + 0.30598,
+  5 + -0.0478183,
+  7 + 0.791332,
+ -5 + -0.235768,
+  3 + 0.292966,
+ -3 + 0.414722,
+  3 + -0.665212,
+  5 + -0.710929,
+ -3 + -0.588074,
+ -3 + 0.331691,
+  7 + 0.882629,
+  3 + -0.550038,
+  1 + -0.957022,
+ -5 + 0.990136,
+  5 + -0.558498,
+ -3 + -0.842342,
+ -1 + 0.000248163,
+ -5 + 0.131952,
+  7 + -0.167911,
+  1 + -0.425364,
+  7 + -0.372087,
+  1 + 0.526899,
+ -1 + -0.638801,
+ -5 + -0.386877,
+  7 + 0.871863,
+ -7 + 0.459965,
+  5 + -0.165079,
+  5 + 0.296509,
+ -3 + 0.833452,
+ -7 + 0.744527,
+ -3 + 0.626609,
+  1 + -0.814472,
+  3 + 0.998261,
+ -7 + 0.270782,
+  1 + -0.904688,
+ -5 + 0.723069,
+ -1 + -0.664172,
+ -5 + -0.019654,
+ -1 + 0.757106,
+  7 + 0.780875,
+  1 + -0.898937,
+  3 + -0.485577,
+ -3 + -0.140519,
+ -3 + -0.240458,
+ -1 + 0.353802,
+ -7 + -0.918099,
+  3 + -0.32276,
+  3 + 0.672086,
+ -3 + -0.335273,
+  1 + -0.999146,
+ -1 + -0.630338,
+  7 + -0.544571,
+ -7 + 0.470793,
+ -3 + -0.581126,
+ -1 + 0.135819,
+ -1 + 0.0451301,
+  5 + 0.479837,
+ -3 + 0.172697,
+  5 + 0.796663,
+ -1 + -0.566894,
+  1 + 0.470888,
+  3 + 0.0653015,
+ -7 + 0.792323,
+  1 + -0.867727,
+ -3 + 0.829587,
+ -3 + -0.740408,
+  3 + -0.830687,
+  3 + 0.957641,
+ -7 + -0.423364,
+  3 + -0.893497,
+  1 + -0.853771,
+ -3 + 0.92187,
+  1 + -0.929865,
+ -3 + 0.198643,
+  7 + 0.961747,
+ -1 + -0.431994,
+  7 + 0.35683,
+ -1 + -0.871135,
+  7 + 0.727451,
+  7 + 0.458093,
+ -3 + 0.22682,
+ -3 + -0.827643,
+ -3 + -0.189953,
+  5 + -0.688236,
+ -3 + -0.294562,
+  5 + -0.903106,
+ -5 + 0.444196,
+ -1 + 0.2121,
+ -5 + -0.214493,
+ -5 + -0.392994,
+ -3 + 0.665017,
+  1 + 0.269187,
+  7 + -0.745741,
+  1 + -0.185388,
+ -5 + -0.795616,
+ -5 + -0.989525,
+ -5 + -0.0291574,
+  7 + 0.577641,
+  3 + -0.98546,
+  5 + 0.696809,
+ -5 + 0.649647,
+  3 + -0.401609,
+ -7 + 0.29181,
+ -1 + -0.336865,
+  3 + -0.279985,
+ -7 + 0.819639,
+  1 + -0.69903,
+  5 + -0.956345,
+ -3 + 0.917636,
+  3 + -0.539845,
+  3 + -0.58337,
+  5 + 0.0319712,
+  3 + -0.682523,
+  3 + -0.160175,
+  1 + -0.707552,
+  3 + -0.197245,
+ -1 + 0.583643,
+ -7 + 0.128135,
+  3 + 0.240791,
+ -7 + -0.289134,
+ -7 + 0.955084,
+ -5 + 0.495007,
+ -1 + 0.955188,
+  3 + 0.523281,
+ -1 + 0.468672,
+ -5 + -0.467838,
+ -3 + 0.654833,
+ -5 + 0.85963,
+ -3 + 0.532693,
+ -3 + -0.11304,
+  5 + 0.947132,
+  5 + 0.395143,
+  1 + -0.114501,
+ -5 + 0.275912,
+ -7 + -0.816982,
+ -3 + 0.280537,
+  1 + -0.290476,
+  3 + 0.753207,
+  3 + -0.37078,
+ -5 + -0.73641,
+  1 + 0.720629,
+ -1 + 0.61751,
+  5 + -0.114619,
+  3 + -0.509509,
+  1 + 0.349672,
+  7 + 0.426544,
+ -5 + -0.567438,
+ -7 + -0.52387,
+  3 + -0.376306,
+  3 + -0.49252,
+  5 + 0.441628,
+  3 + 0.703002,
+ -7 + 0.62187,
+  3 + 0.754402,
+ -1 + -0.344451,
+  5 + -0.0148834,
+ -7 + 0.449515,
+  5 + 0.230859,
+  1 + 0.724024,
+  5 + 0.190704,
+  1 + -0.69348,
+ -5 + 0.586233,
+  5 + 0.0794267,
+ -5 + -0.631736,
+  1 + 0.105417,
+ -5 + 0.136263,
+  7 + -0.642064,
+  1 + 0.0430542,
+ -7 + -0.41497,
+  5 + 0.775936,
+ -1 + 0.687085,
+ -5 + 0.925474,
+ -5 + 0.0990985,
+  3 + -0.277763,
+ -1 + 0.299999,
+  3 + 0.392572,
+ -7 + -0.546367,
+  7 + 0.403084,
+  5 + -0.0418944,
+ -7 + 0.446579,
+ -7 + 0.372017,
+ -1 + 0.459786,
+  7 + -0.0032825,
+  5 + 0.189248,
+  5 + -0.155126,
+  3 + 0.53685,
+  3 + 0.933272,
+  3 + -0.384181,
+  5 + 0.204225,
+  1 + -0.327539,
+ -7 + 0.348723,
+  1 + -0.685387,
+ -7 + -0.750799,
+ -1 + -0.627168,
+ -7 + 0.610837,
+  5 + -0.957175,
+ -3 + 0.834856,
+ -1 + 0.528653,
+  7 + -0.780567,
+  7 + 0.0884855,
+  3 + 0.648985,
+ -1 + 0.218943,
+ -7 + 0.832075,
+  5 + 0.811807,
+ -3 + -0.685713,
+ -3 + -0.296578,
+  3 + 0.000125931,
+ -5 + -0.996983,
+ -5 + -0.193044,
+  5 + -0.0545228,
+  1 + 0.893854,
+  5 + 0.97836,
+ -3 + -0.748222,
+ -1 + 0.196022,
+  1 + 0.163083,
+ -5 + -0.180233,
+ -1 + 0.209452,
+ -3 + 0.744591,
+ -3 + -0.1817,
+  1 + -0.447565,
+  5 + 0.528624,
+ -7 + -0.692082,
+  7 + -0.428345,
+ -7 + 0.0934917,
+  1 + 0.678237,
+ -7 + -0.298993,
+ -3 + 0.654322,
+ -3 + -0.942614,
+  7 + 0.783697,
+  3 + 0.395035,
+  1 + -0.372332,
+  3 + -0.859733,
+  1 + 0.4468,
+  5 + 0.822121,
+ -5 + 0.201003,
+ -7 + -0.74061,
+  5 + -0.568736,
+  3 + 0.904994,
+ -5 + 0.325172,
+  5 + 0.292775,
+  5 + 0.511914,
+ -7 + 0.675604,
+  5 + 0.907106,
+ -7 + 0.676053,
+ -3 + -0.64883,
+ -1 + -0.451512,
+  3 + -0.841985,
+ -7 + 0.0817016,
+ -1 + 0.111568,
+ -7 + -0.594469,
+ -3 + -0.844349,
+  3 + -0.26745,
+ -3 + -0.559703,
+  7 + 0.53067,
+  3 + -0.256771,
+ -1 + -0.170001,
+ -1 + -0.775529,
+ -1 + -0.456536,
+  3 + -0.998071,
+  1 + 0.941052,
+  7 + 0.130878,
+  7 + 0.838738,
+  1 + 0.856186,
+  1 + 0.846151,
+ -1 + -0.737487,
+  3 + -0.76553,
+ -3 + 0.222,
+ -1 + -0.387758,
+  7 + -0.269319,
+ -3 + 0.0668951,
+  3 + 0.731949,
+  5 + -0.741075,
+ -7 + -0.219907,
+  3 + 0.487581,
+  1 + -0.973969,
+  7 + 0.639967,
+  3 + 0.809232,
+  3 + -0.642748,
+  5 + -0.453162,
+ -7 + -0.474022,
+ -3 + -0.631836,
+ -3 + 0.0981818,
+  7 + 0.684498,
+ -1 + -0.654845,
+ -5 + -0.612608,
+  7 + 0.610862,
+ -3 + -0.369351,
+  3 + -0.261936,
+  7 + -0.814926,
+  7 + 0.390131,
+ -5 + 0.531136,
+  3 + 0.974289,
+ -3 + -0.111925,
+  3 + 0.376471,
+ -3 + -0.941562,
+  7 + -0.410982,
+ -7 + 0.875953,
+  5 + -0.448872,
+ -1 + -0.806028,
+ -1 + -0.814961,
+  5 + 0.395374,
+ -7 + 0.814904,
+  1 + 0.383855,
+  1 + -0.252184,
+  3 + 0.524843,
+ -7 + -0.233859,
+ -7 + 0.764495,
+ -7 + 0.817705,
+ -5 + 0.641853,
+ -3 + -0.758414,
+ -1 + -0.260464,
+ -7 + -0.240351,
+ -3 + 0.0476139,
+ -1 + -0.220685,
+ -1 + -0.993293,
+  7 + 0.627481,
+ -3 + -0.950516,
+ -5 + -0.0848613,
+  5 + 0.670037,
+  7 + 0.825011,
+ -7 + 0.111405,
+  7 + 0.0703245,
+ -3 + 0.177663,
+  7 + -0.739343,
+  3 + -0.673892,
+  7 + -0.947279,
+ -5 + 0.732764,
+  7 + -0.807932,
+  1 + -0.494108,
+  1 + 0.611574,
+ -1 + 0.205265,
+ -1 + -0.485118,
+ -5 + 0.0552847,
+ -5 + -0.176059,
+  5 + 0.00244508,
+  7 + -0.773636,
+  5 + 0.951496,
+ -7 + 0.525518,
+ -5 + 0.968101,
+ -7 + 0.10137,
+  5 + -0.4487,
+  7 + 0.215142,
+ -5 + -0.162651,
+  5 + -0.520808,
+  1 + -0.89087,
+ -1 + -0.804296,
+  7 + -0.341382,
+ -7 + 0.793131,
+  5 + -0.724335,
+  7 + 0.0832606,
+  3 + -0.819473,
+  7 + -0.613928,
+ -1 + -0.975915,
+  7 + 0.555494,
+ -1 + -0.753698,
+  1 + -0.570132,
+ -5 + -0.00221921,
+  1 + 0.010534,
+ -5 + -0.825051,
+ -5 + 0.528378,
+  3 + 0.559274,
+ -5 + 0.826081,
+  7 + -0.349553,
+  3 + 0.36511,
+ -5 + -0.881283,
+  1 + 0.833997,
+  1 + 0.00815386,
+ -3 + -0.820684,
+  1 + 0.952573,
+ -5 + 0.378794,
+ -5 + 0.465909,
+  1 + -0.166333,
+  1 + 0.0746185,
+ -1 + 0.431021,
+  5 + 0.266922,
+ -1 + 0.339902,
+ -1 + 0.372874,
+  7 + -0.0149696,
+ -1 + 0.0317811,
+  7 + -0.691387,
+ -1 + 0.929823,
+  5 + -0.295751,
+  7 + -0.851862,
+ -1 + 0.33382,
+  7 + -0.589562,
+ -7 + -0.217095,
+ -7 + 0.115214,
+ -7 + 0.220949,
+  1 + 0.800567,
+  3 + -0.251049,
+ -5 + -0.626753,
+  7 + -0.450723,
+  7 + 0.22979,
+ -3 + -0.342451,
+ -3 + 0.997709,
+ -1 + 0.582385,
+ -5 + 0.191317,
+  7 + -0.873862,
+  5 + 0.213097,
+  7 + -0.762892,
+  7 + 0.954305,
+  7 + 0.188828,
+  7 + 0.931783,
+ -7 + -0.839115,
+  5 + -0.738813,
+  3 + 0.926841,
+  5 + 0.399905,
+ -7 + 0.0123429,
+ -5 + 0.545699,
+  3 + -0.661568,
+  3 + -0.261673,
+ -5 + -0.81428,
+  7 + 0.866628,
+  5 + -0.048188,
+ -3 + 0.165017,
+  7 + -0.698899,
+ -7 + 0.0783355,
+ -7 + 0.693822,
+  7 + 0.726706,
+ -1 + 0.148921,
+  7 + -0.685703,
+  3 + 0.548864,
+ -7 + -0.878148,
+  3 + 0.205964,
+  5 + -0.271077,
+ -7 + -0.15239,
+  1 + -0.949635,
+ -1 + 0.961041,
+ -7 + 0.0868696,
+  3 + -0.361298,
+  3 + 0.624626,
+  3 + -0.0838945,
+  5 + 0.132301,
+ -1 + 0.192646,
+ -5 + -0.579731,
+ -5 + -0.101051,
+  5 + 0.870131,
+  1 + 0.535988,
+  5 + 0.255953,
+  1 + 0.314134,
+ -7 + 0.762894,
+ -7 + 0.127185,
+  7 + -0.222042,
+ -5 + -0.529038,
+ -3 + 0.231572,
+  1 + 0.788721,
+  5 + -0.891869,
+ -5 + -0.472732,
+  3 + -0.0128941,
+  1 + -0.623197,
+  7 + -0.490687,
+ -1 + -0.441505,
+  1 + -0.0410075,
+ -5 + 0.847264,
+ -7 + -0.371955,
+ -1 + 0.41401,
+ -1 + -0.742,
+  3 + 0.0546079,
+  5 + -0.529726,
+  7 + -0.0630406,
+  1 + 0.196568,
+ -3 + 0.488722,
+ -5 + -0.357116,
+  3 + -0.179397,
+ -3 + 0.358234,
+ -7 + 0.821111,
+  7 + -0.634397,
+  5 + -0.490498,
+ -5 + -0.103393,
+ -7 + -0.996996,
+ -5 + 0.358586,
+ -7 + 0.785637,
+ -5 + 0.46574,
+ -1 + -0.714036,
+  7 + 0.73281,
+ -1 + -0.980125,
+ -5 + 0.152175,
+ -1 + -0.468575,
+ -1 + -0.154831,
+  5 + -0.257122,
+  3 + -0.414745,
+  3 + 0.663051,
+ -3 + 0.787162,
+ -1 + 0.773088,
+  5 + -0.0174988,
+  7 + 0.348241,
+  1 + 0.856018,
+ -7 + -0.177525,
+  1 + 0.409387,
+  3 + 0.0205055,
+ -3 + 0.212273,
+  7 + -0.35314,
+ -1 + 0.253691,
+ -7 + 0.988757,
+  1 + 0.915514,
+  7 + -0.0632796,
+ -3 + -0.0794022,
+  5 + 0.905145,
+  3 + -0.678132,
+  7 + 0.842035,
+ -1 + 0.189324,
+ -1 + 0.431813,
+  5 + 0.855323,
+  3 + -0.285528,
+ -3 + -0.740299,
+  3 + 0.526598,
+ -3 + -0.807057,
+ -3 + -0.907001,
+ -1 + 0.673215,
+  1 + -0.806326,
+ -7 + -0.0179321,
+  7 + 0.0822508,
+ -1 + 0.850969,
+  5 + 0.18839,
+  3 + -0.692543,
+ -5 + 0.064437,
+ -7 + -0.112983,
+ -3 + -0.0709171,
+ -5 + 0.327346,
+  1 + -0.595314,
+ -1 + 0.878245,
+  1 + 0.291632,
+ -1 + -0.922109,
+ -3 + -0.872261,
+ -7 + -0.212876,
+  1 + -0.348517,
+  5 + -0.24286,
+  3 + 0.777443,
+  5 + 0.00615786,
+  5 + 0.834023,
+  1 + -0.590069,
+ -7 + 0.653321,
+  1 + -0.234737,
+ -7 + 0.664936,
+  7 + 0.411378,
+ -7 + -0.88205,
+ -1 + -0.855369,
+  1 + 0.377919,
+ -7 + -0.456485,
+ -5 + -0.949986,
+ -5 + -0.0158651,
+  3 + 0.535672,
+ -1 + -0.687636,
+  1 + 0.736756,
+  7 + -0.696999,
+  1 + 0.847792,
+ -3 + -0.349274,
+  1 + -0.544481,
+  7 + 0.608189,
+ -7 + 0.608384,
+  5 + -0.323123,
+  7 + -0.947181,
+  5 + 0.753829,
+  5 + -0.573138,
+  5 + -0.485321,
+ -5 + 0.480423,
+ -5 + -0.371829,
+  5 + -0.853753,
+ -7 + 0.878959,
+ -7 + 0.0642654,
+  1 + 0.680307,
+  1 + 0.291632,
+  7 + -0.853807,
+  5 + 0.644158,
+  5 + -0.355364,
+  1 + 0.190966,
+  3 + -0.294411,
+ -7 + -0.67303,
+ -5 + -0.965702,
+ -3 + 0.55212,
+  1 + -0.804562,
+ -7 + -0.494127,
+ -5 + -0.983771,
+  1 + -0.133138,
+ -1 + -0.607814,
+  1 + -0.742387,
+ -5 + -0.411707,
+ -3 + -0.816862,
+  7 + 0.426785,
+  5 + -0.089001,
+  3 + -0.966127,
+  3 + -0.784032,
+  5 + -0.356036,
+  5 + 0.475987,
+  1 + 0.970457,
+ -3 + 0.678356,
+  1 + -0.430618,
+  5 + 0.942241,
+ -3 + -0.913966,
+  7 + -0.730373,
+ -3 + 0.640682,
+  7 + -0.024488,
+ -5 + 0.462632,
+ -3 + -0.609614,
+ -1 + -0.482857,
+ -5 + 0.535506,
+  7 + 0.821051,
+ -1 + 0.793945,
+  3 + -0.0835013,
+ -5 + -0.393026,
+  1 + -0.415528,
+ -5 + 0.182819,
+  1 + -0.561988,
+ -5 + -0.417262,
+  7 + 0.708211,
+  1 + -0.207354,
+ -5 + -0.844518,
+ -7 + 0.604461,
+  7 + 0.787027,
+  7 + 0.763122,
+  1 + 0.300372,
+ -3 + -0.0203687,
+ -7 + -0.500432,
+  7 + -0.5601,
+  5 + -0.682225,
+ -5 + -0.547398,
+ -3 + 0.769381,
+ -3 + 0.750163,
+ -5 + -0.820679,
+  3 + 0.236003,
+  1 + -0.316465,
+ -3 + 0.802262,
+  3 + -0.399964,
+  5 + -0.166494,
+  1 + 0.776745,
+  5 + 0.716541,
+  7 + -0.251088,
+ -5 + -0.42548,
+ -3 + -0.761153,
+  7 + -0.0766243,
+  3 + -0.180629,
+  5 + -0.166458,
+ -5 + -0.833394,
+ -7 + 0.0297446,
+ -7 + -0.362676,
+  7 + -0.644897,
+ -7 + 0.283366,
+  5 + -0.665628,
+  3 + -0.488068,
+ -1 + -0.902438,
+ -5 + -0.355751,
+  3 + -0.419479,
+  7 + -0.370073,
+ -3 + 0.480753,
+  1 + -0.420338,
+ -7 + -0.24157,
+  7 + 0.207747,
+ -1 + -0.777488,
+  5 + 0.341417,
+ -1 + -0.33618,
+ -5 + 0.598459,
+ -3 + -0.280681,
+  1 + -0.0398586,
+  7 + 0.717195,
+  5 + 0.431427,
+ -5 + -0.839676,
+ -1 + -0.74745,
+  1 + 0.73193,
+ -1 + 0.729311,
+  5 + 0.561066,
+ -5 + -0.670177,
+ -1 + -0.254041,
+  3 + 0.0451663,
+ -7 + -0.160697,
+  7 + 0.13319,
+ -3 + 0.360953,
+ -3 + 0.264897,
+  1 + -0.566809,
+ -5 + 0.291045,
+  1 + -0.573798,
+ -3 + 0.854987,
+ -3 + -0.973763,
+ -7 + -0.958898,
+  1 + -0.945093,
+ -1 + -0.72672,
+  5 + 0.814473,
+  7 + -0.794704,
+ -3 + 0.229887,
+ -1 + 0.801239,
+ -5 + 0.531782,
+ -1 + 0.247072,
+  1 + -0.179189,
+ -3 + 0.401884,
+  7 + 0.236019,
+ -1 + 0.725281,
+ -5 + 0.74655,
+  5 + -0.427725,
+ -1 + 0.967868,
+ -7 + -0.432802,
+ -1 + 0.541378,
+  7 + -0.555299,
+ -3 + 0.166895,
+ -7 + 0.921733,
+ -3 + 0.840396,
+ -5 + -0.602658,
+ -1 + -0.189227,
+ -5 + 0.605957,
+  5 + -0.525512,
+  5 + 0.433278,
+ -1 + 0.554043,
+ -1 + 0.353735,
+  3 + -0.493134,
+ -7 + 0.86014,
+ -3 + 0.543759,
+ -1 + 0.248284,
+ -5 + -0.502769,
+  5 + -0.984136,
+  5 + 0.407552,
+ -1 + 0.869081,
+ -3 + -0.7676,
+ -1 + 0.940972,
+  1 + -0.511719,
+  7 + 0.870979,
+  3 + -0.0582847,
+  7 + -0.628254,
+  7 + -0.780393,
+  3 + -0.227097,
+  1 + -0.738505,
+  1 + 0.364707,
+  1 + -0.522339,
+ -3 + -0.123359,
+ -5 + 0.911237,
+  7 + -0.856169,
+ -5 + 0.878138,
+  1 + -0.761068,
+  3 + 0.341228,
+  7 + 0.0689835,
+  3 + -0.15808,
+  7 + -0.138551,
+  3 + 0.368672,
+  5 + -0.617489,
+  1 + 0.404668,
+ -7 + -0.699522,
+  5 + -0.997434,
+  5 + 0.36597,
+  5 + 0.785275,
+  3 + -0.231849,
+  3 + -0.0999933,
+  1 + -0.109,
+  3 + -0.686237,
+  1 + -0.902631,
+ -7 + 0.51259,
+ -5 + 0.0942837,
+  1 + 0.708383,
+ -3 + -0.861124,
+ -3 + -0.179481,
+ -3 + 0.779682,
+  1 + -0.493657,
+  1 + -0.418592,
+ -1 + 0.856146,
+  3 + -0.0875076,
+  7 + -0.483033,
+ -1 + 0.646554,
+ -1 + 0.974864,
+ -3 + -0.841565,
+ -7 + 0.228352,
+ -1 + -0.0205758,
+  7 + -0.359954,
+  7 + 0.314803,
+  1 + -0.357785,
+  7 + 0.751935,
+  1 + 0.215695,
+  5 + -0.190122,
+ -7 + 0.428353,
+ -1 + -0.890184,
+  7 + 0.122886,
+  1 + -0.557184,
+  5 + -0.556109,
+  7 + 0.828952,
+ -5 + -0.989435,
+  7 + 0.830655,
+ -3 + -0.217279,
+ -1 + -0.835888,
+ -1 + 0.254548,
+  5 + 0.523081,
+  3 + 0.584681,
+  1 + -0.0839997,
+  5 + -0.186458,
+  1 + 0.0540011,
+ -1 + 0.274899,
+ -7 + 0.116505,
+  3 + 0.723544,
+  5 + 0.136319,
+  7 + -0.419947,
+  5 + 0.476982,
+  3 + 0.243726,
+  3 + 0.0739162,
+ -3 + -0.028526,
+ -1 + -0.915011,
+ -7 + 0.764662,
+  5 + -0.449836,
+ -1 + 0.54113,
+ -5 + 0.435229,
+  3 + 0.0290581,
+ -7 + -0.416793,
+  7 + 0.733392,
+  1 + -0.222058,
+ -1 + -0.70491,
+  1 + -0.738726,
+  5 + 0.467214,
+ -5 + -0.820001,
+  5 + -0.100838,
+  3 + -0.867579,
+ -3 + 0.682739,
+  5 + -0.418042,
+ -1 + 0.451298,
+  5 + 0.494458,
+  1 + -0.849409,
+  1 + -0.69703,
+  1 + 0.852578,
+ -1 + -0.781506,
+ -1 + 0.477606,
+  3 + -0.215093,
+ -1 + 0.741802,
+ -7 + 0.574622,
+  5 + 0.855315,
+  5 + 0.655386,
+  1 + -0.0553299,
+ -1 + -0.801709,
+ -1 + 0.610893,
+  1 + -0.996069,
+ -1 + -0.632696,
+  7 + 0.337866,
+ -5 + -0.444426,
+  7 + 0.557502,
+  3 + 0.171951,
+  7 + 0.0341445,
+  3 + 0.332677,
+  3 + 0.169284,
+  3 + -0.273138,
+ -5 + 0.31627,
+ -1 + -0.456444,
+  5 + -0.892569,
+  3 + 0.936689,
+  5 + -0.406369,
+ -5 + 0.589934,
+ -3 + -0.20777,
+ -1 + 0.757187,
+ -5 + 0.629676,
+  5 + 0.365524,
+  5 + 0.289739,
+ -7 + -0.182101,
+ -1 + 0.784527,
+ -3 + 0.382947,
+  3 + -0.380673,
+  3 + -0.748491,
+  1 + 0.642036,
+ -1 + 0.423028,
+ -3 + -0.740949,
+ -7 + 0.0430477,
+ -5 + 0.916659,
+  1 + -0.858744,
+  1 + 0.354461,
+ -5 + 0.197777,
+  1 + 0.132034,
+  5 + -0.935967,
+ -7 + 0.920792,
+  3 + -0.456423,
+  1 + -0.288826,
+  1 + -0.600615,
+  7 + -0.975289,
+ -5 + -0.259924,
+ -1 + -0.640925,
+ -3 + 0.531508,
+  1 + 0.560676,
+  1 + -0.36099,
+ -5 + 0.122059,
+ -5 + -0.701523,
+  3 + -0.620508,
+  3 + -0.918876,
+  5 + -0.716268,
+  7 + -0.885677,
+  7 + -0.812334,
+  5 + -0.427292,
+ -7 + -0.543744,
+  3 + -0.917745,
+  1 + 0.285421,
+  7 + -0.938258,
+ -3 + 0.845977,
+  5 + -0.817096,
+ -3 + -0.81931,
+  7 + 0.384529,
+ -5 + 0.923807,
+ -5 + -0.835286,
+ -3 + 0.495043,
+ -7 + 0.610036,
+  3 + 0.691557,
+  1 + 0.262664,
+ -7 + 0.312157,
+ -5 + -0.629477,
+ -7 + -0.396994,
+  5 + -0.749666,
+ -3 + -0.693143,
+  5 + 0.427751,
+  1 + 0.18179,
+ -5 + 0.994096,
+  5 + -0.868472,
+ -3 + -0.000652722,
+  5 + -0.826959,
+  7 + 0.810413,
+ -7 + 0.624387,
+  3 + -0.0808038,
+ -3 + 0.766962,
+  7 + -0.576073,
+ -1 + 0.549271,
+ -7 + -0.831344,
+  7 + -0.693934,
+ -1 + 0.494453,
+ -1 + 0.201426,
+  7 + 0.722833,
+  5 + -0.156928,
+ -5 + 0.470001,
+  5 + 0.928162,
+  3 + 0.282769,
+ -1 + 0.914984,
+  7 + 0.453746,
+  7 + 0.641607,
+ -7 + -0.00260904,
+ -5 + -0.1964,
+ -3 + 0.251894,
+  7 + 0.528101,
+  3 + 0.110567,
+  3 + 0.589285,
+  3 + -0.820993,
+ -1 + 0.933257,
+  3 + 0.400226,
+  3 + 0.307276,
+  5 + -0.485213,
+ -7 + 0.442066,
+  1 + -0.967156,
+  3 + 0.725474,
+  1 + -0.699786,
+ -7 + 0.506006,
+  7 + 0.513752,
+ -3 + -0.55039,
+ -5 + 0.997721,
+ -1 + 0.875475,
+  3 + 0.935239,
+ -5 + 0.114364,
+  1 + -0.956559,
+  7 + -0.360408,
+  1 + 0.198951,
+ -1 + -0.202082,
+  5 + 0.6909,
+ -1 + 0.530785,
+ -7 + 0.117763,
+  1 + -0.671653,
+ -1 + -0.301334,
+ -3 + -0.0852486,
+ -5 + 0.24372,
+  7 + -0.937574,
+ -3 + 0.970979,
+ -5 + -0.307326,
+ -3 + 0.755383,
+ -7 + -0.0614709,
+  7 + -0.354787,
+  3 + -0.195025,
+  7 + -0.294593,
+  1 + 0.679208,
+  5 + 0.876946,
+  1 + 0.896838,
+ -1 + 0.343962,
+ -7 + -0.0557097,
+  3 + 0.335734,
+ -1 + 0.00658689,
+  7 + -0.707898,
+ -1 + 0.355665,
+ -1 + -0.598976,
+ -5 + -0.591982,
+  7 + -0.485165,
+  1 + -0.624015,
+ -3 + -0.545053,
+ -3 + -0.584821,
+  1 + -0.748295,
+ -1 + 0.603633,
+  5 + -0.281878,
+ -3 + 0.887608,
+ -5 + -0.701604,
+  3 + 0.583568,
+ -7 + -0.987855,
+  7 + 0.0166069,
+ -3 + 0.156798,
+ -7 + 0.693214,
+  7 + 0.197865,
+  7 + 0.461644,
+  7 + -0.751676,
+ -1 + 0.989154,
+ -3 + -0.828416,
+  5 + 0.478627,
+ -5 + -0.225786,
+  3 + 0.146553,
+  3 + 0.242108,
+  1 + -0.991743,
+  5 + -0.23658,
+  1 + 0.712781,
+ -1 + -0.320432,
+ -1 + -0.272036,
+  3 + 0.601587,
+  5 + -0.176224,
+  7 + -0.599448,
+ -5 + 0.821199,
+ -5 + -0.650962,
+ -5 + 0.54749,
+ -7 + 0.846249,
+ -5 + 0.895817,
+  3 + -0.368985,
+  1 + -0.479081,
+ -3 + 0.780251,
+ -3 + 0.30783,
+ -5 + -0.0721856,
+ -7 + -0.0359803,
+  3 + -0.559485,
+  1 + 0.296459,
+  7 + 0.19517,
+ -5 + -0.686891,
+  3 + 0.126611,
+  5 + -0.0218955,
+  5 + -0.0897653,
+  5 + -0.476869,
+  5 + -0.36738,
+  1 + -0.905938,
+ -5 + 0.769578,
+ -7 + -0.911913,
+ -5 + 0.243897,
+  3 + 0.688956,
+  5 + 0.278523,
+ -5 + 0.119666,
+  5 + -0.0967183,
+ -7 + -0.925501,
+  1 + -0.609733,
+ -1 + 0.538315,
+  3 + -0.49403,
+ -7 + 0.00403903,
+ -1 + 0.422778,
+  1 + -0.676254,
+ -5 + -0.495082,
+ -3 + 0.887213,
+ -7 + -0.210539,
+ -5 + 0.802399,
+ -3 + -0.205944,
+  5 + -0.684772,
+ -7 + 0.844196,
+ -5 + -0.69577,
+  5 + -0.822575,
+ -7 + -0.158769,
+  5 + 0.942987,
+ -7 + -0.739025,
+  3 + 0.791325,
+  1 + -0.931093,
+ -7 + -0.8201,
+  3 + -0.732275,
+ -1 + 0.945871,
+  3 + -0.891814,
+ -7 + 0.0258538,
+  3 + 0.892123,
+  1 + -0.880949,
+ -3 + -0.633805,
+ -3 + -0.709181,
+ -3 + -0.383623,
+  3 + -0.150093,
+ -7 + -0.117931,
+  1 + -0.307017,
+  3 + 0.380702,
+ -5 + -0.594801,
+  5 + -0.43212,
+  5 + 0.920089,
+  7 + -0.804395,
+  1 + -0.918654,
+ -1 + -0.904769,
+  7 + -0.78175,
+  7 + 0.322011,
+  3 + -0.294538,
+ -7 + 0.930585,
+  1 + -0.477718,
+ -5 + -0.989844,
+ -1 + 0.902946,
+ -7 + -0.350604,
+  7 + 0.126035,
+ -7 + -0.920143,
+ -7 + 0.851657,
+  3 + -0.136341,
+  3 + 0.593154,
+ -5 + -0.803969,
+ -5 + 0.503475,
+  5 + 0.0188022,
+  5 + 0.631931,
+  7 + 0.91577,
+ -7 + -0.549304,
+  1 + -0.723671,
+ -1 + -0.305956,
+ -5 + 0.74761,
+ -3 + 0.355676,
+ -1 + 0.855675,
+  3 + 0.613764,
+  7 + 0.700543,
+ -5 + -0.132191,
+ -1 + -0.0646009,
+ -5 + 0.590769,
+ -3 + -0.49326,
+ -1 + 0.216807,
+ -3 + -0.946063,
+  1 + 0.186966,
+ -7 + 0.790963,
+ -1 + 0.45715,
+  1 + 0.743977,
+ -5 + -0.136574,
+ -3 + -0.888679,
+ -5 + -0.732167,
+  7 + -0.397459,
+ -7 + -0.0469681,
+ -7 + 0.615953,
+ -5 + 0.439568,
+  3 + 0.273846,
+  7 + 0.314949,
+  3 + 0.911291,
+ -5 + -0.453662,
+  3 + 0.80863,
+  3 + -0.0106643,
+  5 + 0.607597,
+  7 + 0.356758,
+  1 + -0.6931,
+ -5 + 0.371134,
+ -3 + -0.711628,
+  7 + 0.944743,
+ -7 + 0.202408,
+ -1 + 0.728236,
+ -3 + 0.684351,
+  3 + -0.40255,
+  1 + -0.186503,
+ -1 + 0.0150248,
+  3 + 0.185297,
+ -7 + 0.36002,
+  3 + 0.750152,
+  5 + -0.381467,
+  7 + 0.334737,
+ -3 + 0.0568684,
+  3 + -0.567396,
+  5 + -0.995164,
+  1 + 0.602424,
+  7 + 0.0454783,
+  3 + 0.516061,
+  5 + -0.199994,
+  1 + 0.737877,
+  7 + 0.411311,
+  5 + -0.853456,
+  5 + -0.121685,
+  7 + -0.507778,
+ -7 + 0.152738,
+ -7 + 0.094981,
+  1 + -0.681713,
+  5 + 0.442789,
+  5 + 0.973592,
+  1 + -0.323444,
+  1 + 0.863931,
+ -1 + 0.396984,
+  7 + 0.249854,
+  1 + 0.807021,
+  7 + 0.644638,
+ -7 + -0.422386,
+  1 + 0.0698824,
+ -1 + 0.24009,
+ -3 + -0.406826,
+  3 + -0.997362,
+ -7 + -0.410919,
+  3 + 0.0102449,
+  5 + -0.495212,
+  3 + 0.260833,
+ -7 + -0.397034,
+  1 + -0.379961,
+  3 + 0.483326,
+  7 + -0.909255,
+ -7 + 0.950334,
+ -1 + -0.970264,
+ -1 + 0.276129,
+ -7 + -0.0553154,
+ -7 + 0.322334,
+ -3 + -0.902084,
+  7 + 0.29514,
+ -5 + 0.864139,
+  3 + 0.925323,
+ -3 + 0.338491,
+  3 + -0.0651398,
+  3 + 0.912289,
+ -3 + 0.52022,
+ -3 + -0.709139,
+  3 + -0.742856,
+  7 + 0.565104,
+  5 + 0.894589,
+  5 + -0.556394,
+ -1 + -0.864631,
+ -5 + 0.794986,
+ -7 + -0.869075,
+  7 + 0.774674,
+  3 + 0.428512,
+ -5 + 0.839244,
+ -1 + 0.357717,
+ -7 + 0.199788,
+ -1 + -0.458671,
+  7 + 0.526558,
+ -1 + -0.318607,
+ -5 + 0.630471,
+ -3 + -0.441537,
+ -1 + -0.580994,
+ -1 + 0.690485,
+  3 + -0.547178,
+  7 + 0.0732123,
+  7 + -0.552486,
+  3 + -0.133145,
+  5 + -0.933638,
+  1 + 0.255392,
+ -3 + -0.280157,
+ -5 + -0.150034,
+  5 + -0.122912,
+  5 + 0.941452,
+ -3 + 0.188547,
+  3 + -0.211247,
+  7 + 0.946076,
+ -3 + 0.92071,
+  1 + 0.972226,
+ -5 + 0.852144,
+  3 + 0.377145,
+ -1 + 0.413943,
+ -7 + 0.439598,
+ -5 + -0.13615,
+  5 + 0.171454,
+ -5 + 0.845844,
+ -7 + 0.783942,
+  3 + -0.618869,
+ -7 + 0.760145,
+  5 + -0.0578561,
+ -1 + -0.582842,
+  3 + -0.155049,
+  5 + -0.220217,
+  7 + -0.73738,
+  1 + -0.767926,
+ -1 + -0.1484,
+  7 + 0.834785,
+  1 + 0.101825,
+ -7 + -0.449194,
+  3 + 0.11657,
+ -1 + 0.904672,
+ -5 + 0.054498,
+  3 + 0.924094,
+ -5 + -0.0965653,
+  1 + -0.613703,
+ -7 + 0.4126,
+ -3 + 0.584113,
+ -7 + 0.159096,
+ -5 + -0.485646,
+  3 + -0.0365765,
+ -3 + -0.417187,
+  7 + 0.916336,
+ -1 + 0.725319,
+  1 + 0.494014,
+ -5 + -0.532621,
+ -1 + 0.646111,
+ -7 + -0.417253,
+ -1 + -0.0992868,
+ -1 + 0.654899,
+  3 + -0.444689,
+  3 + 0.800794,
+  1 + -0.112122,
+ -1 + -0.712385,
+ -3 + 0.166391,
+  5 + 0.314575,
+ -5 + 0.950806,
+  3 + -0.44719,
+  1 + -0.175398,
+  5 + -0.225897,
+  3 + 0.258122,
+ -1 + -0.571683,
+ -3 + 0.745108,
+  7 + -0.489975,
+  3 + 0.869279,
+  3 + -0.536627,
+  5 + -0.828879,
+ -7 + -0.62512,
+ -7 + -0.456803,
+  7 + 0.142581,
+  7 + -0.220935,
+  7 + 0.012534,
+ -5 + -0.681989,
+ -7 + 0.622798,
+  1 + -0.557702,
+ -3 + 0.482869,
+  5 + 0.197984,
+  3 + 0.934018,
+  7 + -0.094445,
+ -7 + 0.325073,
+  7 + 0.917923,
+ -7 + 0.17338,
+ -5 + -0.354761,
+ -5 + 0.71292,
+ -1 + -0.877613,
+  7 + -0.857628,
+ -7 + 0.5547,
+  5 + 0.819892,
+  5 + 0.550559,
+  3 + -0.0277248,
+  3 + 0.0711193,
+ -3 + -0.0491096,
+ -5 + -0.860672,
+  3 + -0.0807872,
+ -5 + 0.651853,
+  7 + 0.104082,
+ -7 + 0.236164,
+ -1 + -0.330286,
+ -7 + -0.480073,
+  3 + 0.406925,
+ -5 + -0.518305,
+ -1 + -0.605615,
+ -1 + 0.381587,
+ -1 + -0.11044,
+  3 + -0.160278,
+  1 + -0.304637,
+ -1 + -0.527384,
+ -7 + 0.882399,
+  3 + -0.777911,
+ -7 + -0.0419154,
+  1 + -0.719173,
+ -7 + 0.936713,
+ -3 + -0.751213,
+ -3 + 0.441754,
+  1 + -0.0637285,
+ -1 + 0.375699,
+  7 + -0.153902,
+  7 + -0.792171,
+  5 + 0.655847,
+  7 + 0.882999,
+  5 + 0.0812634,
+  3 + 0.546496,
+ -7 + -0.223494,
+ -1 + -0.356427,
+  1 + 0.310918,
+ -7 + 0.571231,
+ -1 + 0.798337,
+ -3 + 0.598408,
+ -3 + 0.72025,
+  3 + 0.51356,
+ -3 + -0.167374,
+  3 + 0.240713,
+  5 + 0.933577,
+  5 + 0.267443,
+ -7 + 0.853163,
+  7 + 0.751923,
+  1 + -0.76546,
+  1 + -0.464537,
+ -5 + -0.307334,
+  1 + 0.78241,
+ -3 + -0.998566,
+ -1 + 0.35207,
+ -5 + 0.427847,
+ -5 + 0.110459,
+  3 + 0.834955,
+ -7 + 0.254993,
+  5 + 0.368997,
+  1 + 0.697111,
+  5 + 0.458215,
+  5 + 0.0957664,
+  7 + -0.97862,
+ -7 + -0.615026,
+  3 + 0.859467,
+  5 + -0.306685,
+  1 + 0.305295,
+ -5 + 0.093081,
+ -3 + 0.673005,
+  1 + 0.985715,
+ -5 + -0.944994,
+ -5 + 0.817741,
+  7 + -0.898887,
+  7 + -0.742699,
+ -7 + 0.298725,
+  5 + -0.180113,
+ -7 + 0.18706,
+  1 + 0.185461,
+ -1 + -0.522394,
+ -1 + -0.117225,
+ -7 + -0.143794,
+ -3 + -0.273471,
+  1 + 0.139797,
+  5 + -0.265773,
+  3 + 0.427259,
+  3 + -0.869272,
+ -5 + -0.144366,
+ -1 + 0.337665,
+ -1 + 0.171026,
+  5 + -0.79788,
+ -5 + 0.192947,
+ -5 + -0.311556,
+  5 + 0.785642,
+ -1 + -0.505434,
+ -1 + 0.233518,
+  1 + 0.420173,
+ -1 + 0.163412,
+  7 + 0.605216,
+  1 + -0.593143,
+ -1 + -0.957213,
+ -1 + -0.515973,
+  1 + 0.525257,
+ -5 + 0.446536,
+  1 + 0.486375,
+ -3 + -0.5737,
+  3 + -0.217493,
+ -1 + 0.517623,
+ -7 + 0.920525,
+  5 + 0.365421,
+  5 + 0.00848039,
+ -5 + 0.153402,
+  1 + 0.13929,
+  5 + 0.977456,
+ -7 + 0.22807,
+ -1 + -0.119464,
+ -1 + -0.351284,
+ -1 + -0.991155,
+  7 + 0.889795,
+ -3 + 0.691846,
+  1 + -0.746596,
+ -3 + 0.586713,
+  5 + 0.596188,
+ -7 + -0.477961,
+  3 + -0.620132,
+  5 + -0.0775085,
+  1 + -0.165338,
+  5 + -0.211165,
+  7 + -0.0470844,
+  7 + -0.748061,
+ -3 + -0.810057,
+  5 + -0.196284,
+ -7 + 0.0831261,
+  7 + 0.823358,
+  3 + -0.628647,
+  7 + 0.576381,
+ -3 + -0.347779,
+  7 + 0.223497,
+ -7 + -0.526754,
+ -7 + 0.806814,
+ -7 + -0.725776,
+  5 + -0.793048,
+ -3 + -0.678268,
+  7 + -0.718848,
+  1 + 0.914832,
+ -5 + 0.808905,
+  5 + 0.664148,
+  3 + -0.151127,
+ -3 + -0.289634,
+  7 + 0.276275,
+  5 + 0.0411116,
+ -3 + 0.180697,
+  7 + -0.957571,
+  5 + -0.931349,
+  3 + 0.346197,
+  3 + 0.855933,
+  1 + -0.9529,
+ -1 + -0.687524,
+  1 + 0.393423,
+  7 + 0.946512,
+ -5 + 0.361563,
+  1 + 0.197133,
+ -5 + 0.313557,
+  3 + -0.932788,
+  3 + -0.342819,
+  3 + 0.07439,
+ -7 + 0.703045,
+ -5 + -0.37896,
+  1 + -0.175719,
+  5 + 0.223835,
+  5 + -0.516742,
+ -7 + 0.791386,
+ -3 + 0.594912,
+  3 + 0.917958,
+ -3 + -0.550284,
+  5 + 0.161439,
+ -1 + 0.308031,
+ -3 + 0.129603,
+ -5 + -0.755601,
+ -5 + -0.0725142,
+ -3 + 0.900576,
+  5 + -0.0439364,
+  3 + -0.571107,
+ -5 + -0.696274,
+ -7 + -0.101347,
+  1 + 0.364593,
+ -7 + -0.428825,
+ -7 + 0.723648,
+ -7 + -0.196055,
+  5 + -0.466505,
+ -3 + 0.906948,
+  7 + 0.869376,
+ -1 + 0.965839,
+  3 + -0.279962,
+  1 + 0.734883,
+  5 + 0.829225,
+ -3 + 0.931521,
+  3 + 0.362365,
+ -7 + 0.797885,
+ -7 + 0.497423,
+  3 + 0.776487,
+  7 + 0.636682,
+  1 + 0.285877,
+  5 + 0.662518,
+  3 + -0.273415,
+ -3 + -0.609258,
+  7 + -0.621225,
+  5 + 0.795938,
+ -1 + 0.330694,
+ -3 + 0.690014,
+  1 + -0.493836,
+ -7 + 0.308625,
+ -3 + -0.948984,
+ -1 + -0.553156,
+  1 + -0.561592,
+  5 + 0.835248,
+  7 + -0.722998,
+ -3 + -0.147382,
+  3 + -0.986829,
+  3 + -0.428939,
+  7 + -0.486681,
+ -3 + -0.512164,
+ -7 + -0.849359,
+  1 + 0.169338,
+ -3 + 0.794093,
+  5 + -0.54137,
+  5 + -0.526859,
+ -1 + 0.452928,
+  1 + -0.42493,
+ -1 + 0.121008,
+  3 + 0.227603,
+ -3 + -0.933629,
+ -7 + -0.176661,
+  7 + -0.444884,
+  5 + 0.0810715,
+  5 + -0.139102,
+  7 + -0.726052,
+ -3 + 0.342913,
+  3 + -0.586903,
+  7 + 0.619812,
+  7 + 0.513767,
+  3 + 0.179749,
+ -5 + 0.28388,
+  5 + 0.494988,
+  7 + -0.697871,
+ -1 + 0.320561,
+  3 + 0.336703,
+ -5 + 0.277044,
+ -5 + 0.637778,
+  3 + -0.778878,
+ -7 + 0.563479,
+  5 + 0.933587,
+ -1 + -0.0155785,
+  7 + 0.967945,
+  7 + -0.441443,
+ -1 + 0.476776,
+ -1 + 0.784109,
+  1 + 0.282272,
+ -3 + 0.120237,
+  5 + 0.909491,
+  7 + 0.0166548,
+  1 + 0.0874624,
+  7 + -0.943263,
+ -7 + 0.404136,
+ -3 + -0.425458,
+  5 + -0.279096,
+ -7 + 0.297659,
+ -5 + -0.909941,
+ -3 + 0.417617,
+  3 + 0.541595,
+  5 + 0.553146,
+ -7 + -0.758788,
+ -3 + 0.810651,
+  3 + 0.824127,
+  3 + -0.860216,
+  1 + -0.301784,
+ -7 + 0.774392,
+ -3 + -0.409294,
+ -1 + -0.233762,
+  7 + -0.169785,
+ -3 + 0.0785076,
+  5 + 0.612462,
+  3 + -0.436439,
+ -7 + 0.879343,
+  1 + 0.639467,
+  1 + 0.052389,
+ -5 + -0.0166562,
+ -3 + 0.341038,
+  5 + -0.828713,
+  3 + 0.794875,
+ -1 + 0.45125,
+ -3 + 0.681263,
+ -5 + 0.420113,
+ -7 + -0.367513,
+ -7 + 0.706676,
+ -3 + -0.494458,
+ -3 + -0.834332,
+ -5 + -0.683485,
+ -1 + -0.0354494,
+ -5 + -0.604827,
+  3 + 0.413222,
+ -3 + 0.275839,
+  1 + 0.456946,
+ -7 + -0.171177,
+ -7 + -0.518215,
+ -7 + 0.0480101,
+  3 + -0.543404,
+  3 + 0.634555,
+  7 + 0.509344,
+  5 + 0.032606,
+ -7 + 0.847702,
+ -7 + -0.382019,
+  1 + -0.893403,
+ -3 + 0.0839257,
+ -5 + -0.605519,
+  5 + -0.398689,
+ -1 + 0.777001,
+  1 + 0.557634,
+  5 + -0.203117,
+ -7 + 0.388056,
+ -1 + -0.841352,
+  5 + 0.571447,
+ -1 + 0.540101,
+  7 + 0.707744,
+  3 + 0.0310338,
+ -1 + -0.222217,
+ -3 + 0.878539,
+  7 + 0.0656955,
+ -1 + 0.579365,
+ -7 + 0.77745,
+  5 + -0.330132,
+ -1 + -0.181327,
+  5 + -0.936911,
+  7 + -0.28417,
+ -1 + 0.184943,
+  3 + 0.470113,
+ -3 + -0.668268,
+  3 + 0.443922,
+ -7 + -0.254059,
+ -5 + -0.998164,
+ -7 + -0.293805,
+ -7 + 0.0910158,
+  7 + 0.692813,
+ -1 + -0.0799075,
+ -7 + 0.721993,
+ -1 + 0.385094,
+  5 + -0.00619203,
+  7 + 0.552784,
+  1 + -0.596967,
+ -5 + -0.00704482,
+  1 + -0.110811,
+  3 + 0.121887,
+  3 + 0.674047,
+ -3 + 0.170743,
+  3 + 0.760664,
+ -3 + 0.42977,
+  1 + 0.315997,
+  5 + 0.154003,
+ -3 + 0.369766,
+ -3 + 0.646692,
+ -3 + -0.0673465,
+  3 + -0.0560396,
+ -7 + 0.138723,
+  7 + -0.0105182,
+ -7 + -0.742613,
+ -1 + -0.0661037,
+  3 + 0.00532501,
+  5 + -0.755478,
+ -3 + 0.363332,
+ -7 + -0.299669,
+ -1 + 0.27668,
+  1 + -0.117032,
+ -1 + -0.0241725,
+  3 + 0.0823766,
+ -7 + -0.207114,
+  5 + -0.0581861,
+ -5 + 0.689536,
+ -5 + -0.206481,
+  3 + -0.457966,
+  7 + -0.489086,
+ -5 + 0.467335,
+ -3 + -0.360001,
+ -1 + -0.138445,
+ -7 + -0.914763,
+  7 + 0.588969,
+ -5 + 0.283839,
+ -7 + 0.959326,
+ -7 + -0.67792,
+ -7 + -0.334574,
+  7 + 0.370579,
+  7 + -0.171007,
+  3 + -0.868796,
+ -3 + -0.319757,
+  3 + -0.879288,
+ -3 + -0.435152,
+  1 + -0.700487,
+  5 + -0.313853,
+ -5 + 0.0436639,
+ -3 + -0.579779,
+ -3 + -0.778584,
+ -5 + -0.789192,
+ -7 + -0.0165036,
+  5 + -0.746662,
+  3 + 0.423599,
+  1 + -0.896458,
+  1 + 0.884175,
+ -7 + -0.861808,
+  1 + 0.0740701,
+ -7 + 0.338526,
+  7 + 0.292062,
+  3 + 0.948647,
+  3 + -0.473585,
+  5 + -0.420246,
+  3 + -0.949748,
+ -3 + -0.593698,
+ -1 + -0.996076,
+  1 + -0.862255,
+  7 + 0.137548,
+ -7 + -0.28388,
+  5 + 0.534124,
+  5 + 0.434866,
+  5 + 0.139012,
+  5 + -0.468484,
+ -7 + 0.740186,
+ -7 + -0.376626,
+ -3 + -0.183861,
+ -1 + 0.669948,
+  5 + 0.859722,
+  1 + -0.138174,
+ -5 + -0.573832,
+  5 + -0.940617,
+  7 + -0.267174,
+  7 + -0.3461,
+ -7 + -0.741914,
+ -3 + -0.322358,
+ -5 + 0.718059,
+ -7 + -0.97611,
+ -3 + 0.154576,
+ -1 + -0.183644,
+  1 + -0.575116,
+ -3 + 0.825954,
+  3 + -0.751385,
+  7 + -0.607166,
+ -5 + -0.500472,
+  7 + 0.882115,
+ -7 + 0.0493956,
+ -5 + 0.362625,
+ -3 + 0.492293,
+  5 + 0.389105,
+ -5 + 0.800949,
+  1 + 0.94705,
+ -7 + -0.377441,
+  7 + 0.351678,
+  7 + -0.44366,
+ -1 + 0.320667,
+ -1 + 0.752543,
+  1 + 0.969968,
+ -7 + 0.0223379,
+  5 + -0.91498,
+ -7 + -0.172866,
+ -5 + -0.173087,
+  5 + 0.996417,
+ -1 + -0.490241,
+ -3 + 0.91821,
+  7 + -0.563976,
+  5 + -0.485962,
+ -7 + 0.892581,
+ -3 + -0.460805,
+  3 + 0.941525,
+  1 + -0.174042,
+ -3 + 0.838862,
+ -7 + -0.156077,
+ -7 + 0.466488,
+  1 + -0.724364,
+  7 + 0.587571,
+  3 + -0.274185,
+  5 + -0.514854,
+ -3 + 0.254629,
+  7 + -0.291446,
+  5 + -0.0912776,
+ -3 + -0.54812,
+  5 + -0.0964439,
+ -1 + -0.952324,
+ -3 + 0.477252,
+ -5 + -0.75421,
+ -7 + -0.536212,
+  1 + 0.97589,
+  1 + -0.534707,
+  1 + -0.610279,
+ -5 + -0.380512,
+  3 + -0.213305,
+  7 + 0.951862,
+  1 + 0.514467,
+  3 + -0.52728,
+  7 + -0.107415,
+ -1 + 0.530744,
+ -7 + -0.780547,
+ -7 + 0.601507,
+ -1 + -0.884028,
+ -5 + 0.295033,
+  5 + 0.216542,
+ -3 + 0.803556,
+ -5 + 0.408551,
+ -1 + 0.0640241,
+ -7 + 0.337687,
+ -3 + 0.973948,
+ -7 + -0.112561,
+  3 + 0.497891,
+ -1 + -0.360651,
+  1 + 0.429832,
+  3 + 0.599578,
+ -7 + 0.62018,
+ -5 + 0.00679079,
+ -7 + 0.214149,
+  7 + 0.840447,
+ -3 + -0.167543,
+  5 + 0.0564775,
+ -7 + 0.824302,
+  3 + 0.0793194,
+  3 + 0.999321,
+ -1 + -0.446545,
+ -3 + 0.703463,
+  7 + 0.991686,
+ -1 + -0.894842,
+ -7 + -0.011711,
+  5 + 0.280148,
+ -7 + 0.854388,
+ -7 + -0.187445,
+ -1 + 0.594443,
+ -7 + 0.933654,
+  1 + 0.297684,
+  7 + 0.305794,
+  5 + -0.871352,
+ -5 + -0.415714,
+ -3 + -0.437484,
+ -5 + 0.425868,
+  3 + 0.413091,
+ -5 + 0.413299,
+  7 + -0.94675,
+  1 + 0.403995,
+  7 + 0.792962,
+ -3 + -0.663822,
+ -1 + 0.782255,
+  5 + 0.740358,
+  5 + 0.64335,
+ -3 + -0.677456,
+ -7 + 0.318753,
+  3 + 0.637624,
+  5 + 0.716802,
+ -3 + 0.506525,
+ -5 + -0.0154431,
+  5 + -0.413524,
+ -3 + -0.97805,
+  3 + -0.715193,
+ -1 + 0.855351,
+ -3 + -0.547344,
+ -1 + 0.707832,
+ -7 + -0.100186,
+ -3 + 0.1044,
+ -1 + 0.834975,
+  5 + 0.950804,
+ -3 + -0.146867,
+  7 + -0.922332,
+ -5 + 0.361724,
+  1 + -0.376783,
+  1 + -0.979652,
+ -3 + -0.860688,
+  7 + -0.0470151,
+  7 + -0.29374,
+  1 + -0.820914,
+ -1 + -0.811114,
+  5 + -0.585238,
+  3 + 0.0997306,
+ -5 + -0.789875,
+  5 + -0.240234,
+  5 + -0.795669,
+ -3 + 0.834812,
+ -5 + -0.0813862,
+  5 + -0.154017,
+ -5 + 0.414384,
+  1 + 0.878358,
+ -7 + -0.0818945,
+  3 + -0.239543,
+ -3 + -0.203324,
+ -3 + -0.921207,
+  5 + 0.69081,
+  1 + -0.727172,
+  1 + 0.287061,
+  3 + 0.216088,
+  1 + -0.47675,
+ -1 + 0.679726,
+ -1 + 0.147156,
+  3 + 0.785956,
+  5 + -0.0128753,
+ -1 + -0.198679,
+  7 + 0.16421,
+ -7 + -0.41241,
+ -7 + 0.785757,
+  1 + 0.502945,
+ -3 + -0.611199,
+  1 + 0.589565,
+ -1 + -0.0650551,
+ -5 + -0.575992,
+ -3 + -0.744359,
+  5 + -0.856259,
+ -1 + 0.95337,
+ -7 + 0.285215,
+  3 + -0.692112,
+  1 + 0.427753,
+  5 + -0.771773,
+  1 + 0.469569,
+ -1 + -0.428564,
+  7 + 0.465778,
+  7 + -0.468184,
+  7 + 0.958522,
+  1 + -0.129728,
+ -7 + 0.48096,
+  7 + -0.127209,
+  7 + -0.725595,
+ -5 + -0.100204,
+ -3 + 0.231591,
+  7 + 0.54961,
+  5 + 0.714396,
+ -5 + -0.891057,
+  7 + 0.0990063,
+  5 + -0.0485793,
+  5 + 0.350462,
+ -7 + 0.683771,
+  1 + -0.69861,
+  1 + 0.0453779,
+ -1 + -0.609794,
+  3 + -0.30366,
+ -1 + -0.0804034,
+ -1 + -0.119469,
+  3 + 0.0833771,
+ -1 + 0.365207,
+ -3 + 0.569098,
+  1 + 0.122556,
+ -3 + 0.383273,
+ -3 + 0.873332,
+  5 + -0.992991,
+ -5 + -0.888515,
+  5 + 0.0792137,
+  7 + -0.949043,
+ -5 + -0.311345,
+  1 + 0.129391,
+ -7 + 0.514229,
+ -7 + -0.889496,
+  1 + -0.188848,
+  5 + -0.47186,
+ -5 + -0.0947434,
+ -5 + -0.860318,
+ -5 + 0.240262,
+  5 + -0.855161,
+ -7 + -0.682376,
+  5 + -0.268279,
+ -1 + 0.574063,
+ -1 + -0.607989,
+  3 + 0.563884,
+ -1 + -0.28172,
+  5 + 0.889506,
+  3 + 0.961434,
+  1 + 0.701135,
+ -3 + -0.36667,
+ -7 + -0.665516,
+  5 + -0.982884,
+ -7 + -0.444751,
+ -3 + -0.0457394,
+  1 + 0.686493,
+  3 + -0.763344,
+ -3 + -0.969778,
+ -5 + 0.557193,
+  3 + -0.70817,
+ -3 + -0.0794386,
+  7 + -0.674222,
+  1 + 0.776054,
+  3 + 0.0315101,
+ -5 + 0.629314,
+ -3 + 0.0376186,
+ -1 + 0.363226,
+  7 + -0.829763,
+  7 + -0.252856,
+  5 + -0.622667,
+  3 + -0.409799,
+  1 + 0.33154,
+  5 + 0.731536,
+  7 + 0.702268,
+  5 + 0.926338,
+  5 + 0.843521,
+ -3 + -0.505366,
+  3 + 0.034738,
+  7 + 0.935227,
+  3 + -0.633068,
+  5 + 0.612473,
+  7 + -0.0785781,
+  7 + -0.209858,
+  3 + -0.519326,
+ -1 + -0.900059,
+  5 + 0.167903,
+  7 + -0.237923,
+  1 + 0.568017,
+ -3 + 0.338209,
+  1 + -0.262908,
+  1 + 0.0486361,
+  7 + 0.05413,
+  5 + -0.900298,
+ -1 + 0.13673,
+  5 + 0.256166,
+  5 + 0.302061,
+ -5 + 0.399097,
+  5 + -0.379186,
+ -5 + 0.623826,
+  5 + -0.436995,
+  3 + 0.15716,
+ -1 + -0.839201,
+ -5 + -0.0482146,
+  5 + -0.580043,
+ -5 + -0.276397,
+ -7 + -0.224163,
+ -7 + 0.569099,
+  1 + 0.112961,
+  7 + 0.695617,
+ -5 + -0.985498,
+ -5 + 0.624633,
+ -5 + -0.698944,
+  1 + 0.290597,
+ -1 + 0.492301,
+  5 + -0.873225,
+  5 + 0.517916,
+  1 + -0.739614,
+ -5 + -0.118872,
+ -7 + 0.429263,
+  5 + -0.374059,
+ -3 + -0.196779,
+  5 + 0.845428,
+  3 + -0.825515,
+  1 + -0.324621,
+  3 + -0.321085,
+  5 + 0.659568,
+ -7 + 0.507627,
+  3 + -0.762506,
+ -5 + 0.0177499,
+  1 + -0.969493,
+  5 + -0.989013,
+  7 + 0.639013,
+  5 + -0.293451,
+ -3 + -0.399314,
+  3 + -0.164182,
+ -5 + -0.0115777,
+ -7 + 0.728109,
+  1 + 0.0601385,
+ -3 + 0.53905,
+ -3 + 0.557821,
+ -3 + 0.267226,
+  7 + 0.484006,
+  3 + -0.462906,
+  7 + 0.593879,
+  7 + 0.70928,
+  3 + 0.783019,
+  7 + -0.390819,
+  5 + 0.447453,
+ -1 + -0.327203,
+ -7 + -0.249398,
+ -5 + -0.100986,
+  1 + -0.155282,
+ -7 + -0.798511,
+ -5 + -0.415777,
+  1 + 0.971724,
+ -3 + -0.087326,
+  7 + 0.946116,
+ -7 + -0.681513,
+  1 + -0.564743,
+  5 + 0.939016,
+  3 + -0.437047,
+ -7 + -0.551414,
+ -3 + 0.489793,
+  5 + -0.535763,
+ -3 + -0.98994,
+  7 + 0.192269,
+ -5 + 0.802636,
+ -3 + 0.335588,
+ -7 + -0.346334,
+  7 + 0.710128,
+  7 + 0.359396,
+  7 + 0.167325,
+ -1 + -0.359781,
+  5 + -0.450043,
+ -3 + -0.399062,
+ -1 + 0.220616,
+ -1 + -0.713507,
+  5 + -0.323577,
+ -3 + -0.324612,
+ -5 + -0.0478501,
+  7 + 0.0652244,
+ -1 + 0.694262,
+ -5 + 0.234324,
+ -1 + 0.684074,
+ -3 + 0.885926,
+ -1 + 0.709219,
+  7 + -0.403976,
+ -5 + 0.0613845,
+ -5 + 0.578585,
+  5 + 0.531759,
+  5 + -0.823466,
+  1 + 0.885001,
+ -5 + 0.678863,
+  1 + 0.235131,
+ -5 + 0.741793,
+ -7 + 0.831432,
+ -3 + 0.524304,
+  3 + -0.740704,
+  7 + 0.507732,
+  3 + -0.0357639,
+  7 + 0.863181,
+ -1 + 0.576264,
+  3 + 0.516363,
+  3 + -0.764998,
+ -1 + -0.362159,
+ -5 + 0.197446,
+  3 + -0.446453,
+  3 + 0.981725,
+  7 + 0.0734841,
+  3 + 0.256196,
+ -3 + -0.77722,
+ -5 + 0.791577,
+ -7 + 0.402091,
+  7 + 0.553504,
+  1 + -0.93853,
+ -7 + 0.584471,
+ -3 + -0.437479,
+  5 + 0.997935,
+ -5 + 0.682598,
+ -7 + 0.641139,
+  3 + -0.732735,
+ -1 + 0.930625,
+ -7 + -0.488808,
+  7 + -0.985779,
+  7 + 0.526349,
+  1 + 0.412067,
+  7 + 0.405549,
+  3 + 0.95903,
+ -3 + 0.304788,
+  5 + -0.344784,
+  7 + -0.707093,
+  7 + 0.508233,
+  3 + 0.704947,
+  1 + 0.790839,
+ -7 + -0.789173,
+ -3 + -0.320104,
+ -5 + -0.0990607,
+ -1 + -0.181266,
+  3 + 0.413149,
+  5 + -0.445842,
+  7 + 0.114297,
+ -1 + -0.0193645,
+ -3 + -0.630197,
+  7 + 0.549956,
+  3 + 0.832843,
+ -1 + 0.709999,
+  5 + 0.35154,
+ -3 + 0.488788,
+ -1 + -0.367693,
+  7 + 0.81898,
+  3 + -0.977579,
+ -7 + 0.677679,
+  3 + 0.0798718,
+ -5 + -0.361776,
+ -7 + 0.029239,
+ -3 + 0.752219,
+ -5 + 0.36909,
+ -1 + -0.845805,
+ -5 + 0.552649,
+  7 + -0.320622,
+  5 + -0.0791636,
+ -7 + 0.155842,
+ -5 + -0.383591,
+ -7 + -0.921708,
+  7 + 0.262659,
+ -5 + -0.311854,
+ -3 + 0.909658,
+  5 + 0.220908,
+ -5 + -0.24149,
+  5 + 0.424055,
+ -7 + -0.115968,
+ -1 + -0.837231,
+ -3 + -0.943953,
+ -1 + -0.501246,
+  3 + -0.30943,
+ -7 + 0.726022,
+  5 + 0.468604,
+  7 + -0.536298,
+ -5 + 0.180367,
+ -5 + 0.478635,
+ -5 + -0.983354,
+ -7 + 0.948823,
+  7 + -0.964671,
+ -7 + 0.83219,
+ -1 + -0.00482819,
+ -5 + 0.910779,
+  7 + 0.0379913,
+  5 + 0.958815,
+ -7 + 0.37621,
+  5 + -0.348852,
+  1 + 0.251557,
+  5 + 0.421582,
+  7 + 0.100173,
+ -3 + -0.343514,
+  7 + 0.866663,
+ -1 + 0.442026,
+  7 + 0.0442502,
+  3 + -0.617214,
+  1 + -0.743735,
+ -5 + 0.458965,
+  5 + -0.572788,
+  5 + 0.040819,
+  3 + -0.445056,
+  5 + -0.58016,
+  5 + 0.386475,
+ -5 + 0.470098,
+  5 + -0.00197146,
+  7 + -0.614743,
+ -7 + 0.632339,
+  5 + -0.445174,
+ -5 + -0.462788,
+ -5 + 0.994442,
+  5 + -0.0414883,
+ -5 + 0.882532,
+  1 + 0.694469,
+ -5 + -0.36298,
+ -7 + 0.836014,
+  1 + 0.247427,
+  5 + -0.623588,
+ -3 + 0.509161,
+  3 + -0.0136789,
+ -5 + 0.551708,
+ -5 + 0.714889,
+  5 + 0.948555,
+  7 + -0.542934,
+ -3 + 0.284379,
+ -1 + 0.445103,
+  5 + -0.302788,
+ -3 + 0.782427,
+ -1 + -0.137974,
+ -1 + 0.874363,
+ -3 + -0.450784,
+  1 + -0.962429,
+ -5 + 0.938102,
+ -7 + -0.879492,
+  5 + 0.666352,
+ -5 + 0.146655,
+ -3 + 0.505806,
+  3 + -0.90168,
+  5 + -0.00662362,
+ -5 + 0.401645,
+ -5 + 0.516729,
+  7 + -0.325518,
+  7 + -0.670081,
+  3 + -0.898185,
+  7 + 0.725776,
+ -1 + -0.519448,
+ -1 + 0.101936,
+  3 + -0.800607,
+  7 + -0.407942,
+  7 + -0.249011,
+  7 + 0.974777,
+ -7 + 0.984282,
+ -1 + 0.177661,
+ -3 + 0.165499,
+ -5 + -0.145106,
+  1 + 0.092101,
+ -3 + -0.287475,
+ -1 + -0.160128,
+ -5 + 0.20695,
+ -1 + 0.278086,
+  7 + 0.376328,
+ -7 + 0.854766,
+  7 + 0.242705,
+ -5 + -0.623362,
+  1 + -0.755314,
+ -3 + -0.498729,
+ -5 + -0.742776,
+  3 + -0.17839,
+ -7 + -0.141452,
+ -7 + 0.0890251,
+  3 + -0.761854,
+ -7 + 0.316197,
+  1 + 0.531921,
+ -1 + 0.763375,
+ -7 + 0.398482,
+  1 + -0.930327,
+ -5 + 0.559533,
+  3 + -0.782727,
+ -1 + -0.809251,
+ -3 + -0.827661,
+ -7 + -0.790187,
+  3 + 0.886559,
+  3 + -0.312838,
+  7 + -0.205646,
+  3 + 0.538917,
+ -5 + -0.151619,
+  7 + -0.498444,
+ -1 + -0.777891,
+ -7 + 0.709902,
+  5 + -0.842215,
+ -3 + -0.0873613,
+ -3 + 0.88423,
+  1 + 0.50133,
+  5 + 0.87654,
+ -1 + 0.775389,
+ -1 + 0.274183,
+ -7 + -0.1128,
+  7 + 0.129837,
+  7 + -0.138116,
+  7 + 0.697651,
+  3 + -0.363404,
+  5 + -0.51758,
+  5 + 0.276224,
+ -5 + -0.843988,
+  5 + 0.965171,
+  5 + -0.433201,
+  5 + 0.77057,
+  5 + -0.347871,
+ -1 + -0.337877,
+  5 + 0.0192994,
+  5 + -0.00149202,
+  5 + -0.705596,
+ -7 + 0.848062,
+  3 + -0.780618,
+  3 + 0.33526,
+ -3 + -0.0251735,
+  7 + -0.148926,
+ -1 + -0.655041,
+ -3 + -0.559493,
+ -3 + -0.604536,
+  3 + -0.0386967,
+ -3 + 0.830413,
+  1 + -0.428,
+  5 + -0.0231212,
+  7 + -0.199671,
+  5 + -0.396984,
+ -3 + 0.687779,
+ -7 + -0.126673,
+  3 + -0.14281,
+  3 + -0.663755,
+ -1 + 0.590741,
+  7 + -0.259138,
+ -1 + 0.36915,
+  7 + -0.193918,
+ -3 + 0.074994,
+  3 + 0.0734893,
+  3 + -0.87442,
+  5 + -0.277579,
+ -7 + 0.874191,
+  1 + 0.603273,
+ -1 + -0.933543,
+  7 + 0.952655,
+  3 + -0.0753299,
+ -1 + -0.0547395,
+  1 + 0.298926,
+  7 + 0.89666,
+ -1 + -0.169361,
+ -7 + -0.0164988,
+ -1 + 0.536616,
+  3 + 0.123214,
+ -3 + -0.686119,
+ -3 + 0.207928,
+  1 + 0.690104,
+ -7 + -0.840309,
+ -1 + 0.22515,
+  5 + -0.848586,
+  7 + -0.266778,
+ -7 + -0.573275,
+ -1 + 0.792824,
+  7 + -0.984161,
+ -3 + -0.188004,
+  5 + -0.461688,
+ -1 + -0.62303,
+  3 + -0.513087,
+ -1 + -0.0713464,
+  7 + -0.4341,
+  1 + 0.791935,
+ -7 + -0.216476,
+ -5 + -0.472753,
+  7 + 0.887405,
+  5 + -0.629382,
+ -1 + 0.960013,
+ -7 + -0.225607,
+  5 + -0.783357,
+  3 + 0.238133,
+  1 + -0.939504,
+  7 + 0.300807,
+  7 + 0.714341,
+ -1 + 0.0662017,
+ -3 + 0.709742,
+ -1 + 0.80212,
+ -5 + 0.78005,
+ -3 + 0.252241,
+ -3 + -0.848605,
+ -7 + -0.928371,
+ -1 + 0.6205,
+  3 + -0.355202,
+  3 + -0.884526,
+  1 + 0.766157,
+  1 + -0.48066,
+ -5 + 0.148214,
+ -5 + 0.416083,
+  1 + 0.141582,
+  3 + 0.954276,
+  7 + -0.598539,
+  1 + 0.302432,
+ -7 + -0.302829,
+ -5 + 0.365095,
+ -5 + 0.291996,
+ -7 + -0.853708,
+  3 + -0.27352,
+  3 + 0.544414,
+ -1 + -0.459018,
+  1 + 0.184556,
+  3 + -0.52332,
+ -1 + -0.191827,
+ -1 + 0.670293,
+  1 + 0.519123,
+  5 + 0.841211,
+ -1 + -0.940759,
+ -1 + -0.251439,
+ -1 + 0.695483,
+ -3 + 0.557767,
+ -3 + 0.26932,
+  1 + 0.0599606,
+ -5 + -0.731488,
+ -3 + -0.559606,
+ -7 + -0.161615,
+ -7 + -0.269363,
+ -3 + 0.700813,
+ -5 + -0.598768,
+ -3 + 0.805228,
+  5 + -0.856961,
+ -1 + -0.385613,
+ -3 + -0.323487,
+ -7 + 0.411967,
+ -5 + 0.21551,
+ -7 + 0.010317,
+ -3 + 0.573196,
+  3 + -0.360943,
+ -1 + 0.564722,
+  7 + 0.0449874,
+  5 + -0.230872,
+ -3 + -0.394789,
+ -3 + 0.992717,
+  5 + 0.241152,
+ -1 + -0.849168,
+  5 + 0.828781,
+  5 + -0.408953,
+ -1 + -0.289148,
+ -1 + 0.222295,
+  1 + -0.537086,
+  3 + 0.306834,
+ -1 + -0.585661,
+ -7 + 0.538775,
+  3 + -0.204193,
+  7 + -0.77022,
+  1 + -0.540422,
+ -5 + 0.104483,
+  3 + 0.0113785,
+ -3 + 0.358089,
+  7 + 0.83108,
+  7 + -0.810261,
+ -1 + 0.0540461,
+ -1 + 0.87434,
+ -7 + -0.379698,
+  5 + -0.722662,
+ -7 + -0.587491,
+  3 + -0.152501,
+  1 + -0.137736,
+ -1 + 0.137048,
+ -7 + -0.993715,
+ -5 + -0.817584,
+ -7 + 0.192652,
+ -7 + 0.965716,
+  3 + -0.497121,
+ -3 + -0.583623,
+  3 + 0.724106,
+  3 + 0.906286,
+  3 + 0.369401,
+ -5 + -0.333858,
+ -7 + 0.201107,
+  1 + -0.481391,
+  3 + 0.214079,
+  1 + -0.634333,
+  3 + 0.32668,
+ -5 + 0.438198,
+  3 + 0.0183425,
+ -7 + -0.854446,
+ -3 + -0.749623,
+  5 + 0.260525,
+ -3 + -0.246166,
+  7 + -0.256046,
+  5 + -0.0506104,
+ -5 + -0.546944,
+ -3 + 0.70895,
+  7 + 0.671615,
+ -7 + -0.178744,
+ -7 + -0.296848,
+  3 + -0.786894,
+  1 + 0.486466,
+  5 + 0.984005,
+ -3 + 0.755768,
+ -3 + 0.60431,
+ -7 + -0.658241,
+  7 + -0.99308,
+ -7 + 0.730603,
+  1 + -0.147345,
+  3 + -0.914348,
+ -5 + 0.176437,
+ -5 + -0.883513,
+ -5 + -0.746214,
+  1 + 0.599807,
+ -1 + -0.826388,
+ -1 + -0.231019,
+  7 + -0.427187,
+  3 + 0.436418,
+ -5 + -0.0296006,
+  3 + 0.342193,
+  5 + -0.02255,
+ -1 + 0.332447,
+  1 + 0.627013,
+ -7 + -0.257934,
+ -5 + -0.61819,
+ -7 + 0.660406,
+  7 + -0.749068,
+ -1 + -0.826357,
+  7 + 0.259934,
+  1 + 0.624619,
+ -5 + -0.409846,
+ -7 + 0.175771,
+  7 + 0.841248,
+ -7 + -0.182872,
+  7 + 0.728087,
+  3 + -0.272224,
+ -1 + 0.694387,
+  1 + 0.87123,
+ -7 + -0.36121,
+ -3 + 0.231829,
+ -3 + -0.288232,
+ -1 + 0.860921,
+  3 + -0.667815,
+ -1 + -0.9711,
+  3 + -0.778314,
+  3 + -0.298502,
+  7 + 0.460686,
+ -7 + -0.972103,
+  1 + -0.791205,
+ -7 + -0.527057,
+  3 + 0.680872,
+  1 + 0.854739,
+ -7 + -0.673826,
+ -1 + 0.137268,
+ -1 + 0.333986,
+ -1 + 0.901741,
+ -1 + -0.202348,
+ -3 + -0.774122,
+  1 + 0.589625,
+  3 + -0.849021,
+  7 + -0.456618,
+  5 + 0.567717,
+  5 + -0.636284,
+  1 + 0.365766,
+  1 + -0.511727,
+ -7 + 0.166757,
+  5 + 0.919885,
+  1 + -0.642062,
+  5 + -0.296797,
+ -7 + -0.385574,
+  7 + 0.591877,
+ -7 + 0.436025,
+  3 + 0.451077,
+ -1 + -0.716762,
+ -3 + 0.374155,
+  5 + 0.337632,
+ -7 + 0.723804,
+ -5 + 0.383933,
+ -3 + -0.0862489,
+  3 + 0.990362,
+  5 + 0.133119,
+  1 + -0.12971,
+  3 + 0.044241,
+  3 + -0.964742,
+ -5 + 0.702827,
+ -5 + 0.52507,
+  7 + 0.813182,
+  7 + 0.456129,
+ -7 + -0.564425,
+ -3 + 0.681494,
+ -1 + 0.503007,
+  1 + 0.488921,
+ -5 + -0.978964,
+  5 + -0.978504,
+ -5 + 0.458051,
+ -7 + 0.0654869,
+  3 + -0.245564,
+ -1 + -0.337528,
+ -5 + -0.55446,
+ -5 + 0.273099,
+ -7 + 0.215733,
+  1 + -0.138924,
+  7 + -0.219671,
+  3 + -0.887201,
+ -7 + -0.516248,
+ -5 + -0.396037,
+ -5 + 0.818756,
+  3 + -0.712209,
+  7 + -0.282743,
+ -3 + 0.707385,
+  7 + 0.359774,
+ -5 + -0.845302,
+  1 + -0.1686,
+ -7 + -0.483578,
+  1 + 0.720247,
+  1 + 0.626128,
+  7 + -0.2298,
+ -7 + -0.491252,
+ -1 + 0.568972,
+  1 + 0.348875,
+  5 + -0.21767,
+  5 + -0.844788,
+ -7 + 0.212711,
+ -5 + -0.728646,
+  5 + -0.257998,
+ -3 + 0.91577,
+  3 + -0.356945,
+ -5 + -0.727851,
+  3 + -0.839908,
+ -5 + -0.87513,
+  5 + 0.492427,
+  7 + 0.859239,
+  5 + 0.63738,
+  7 + -0.567552,
+  7 + -0.311746,
+ -5 + -0.293624,
+ -5 + -0.0892278,
+ -1 + 0.68692,
+ -3 + -0.584071,
+ -7 + -0.368564,
+  3 + 0.685985,
+  1 + -0.443952,
+  5 + -0.799968,
+ -5 + 0.849293,
+  7 + 0.419622,
+  7 + -0.719699,
+ -5 + 0.776349,
+  7 + 0.353652,
+ -3 + -0.957607,
+  7 + -0.233657,
+ -3 + 0.110137,
+ -5 + -0.825374,
+ -5 + 0.936229,
+  3 + 0.611605,
+ -5 + 0.598961,
+  3 + 0.914424,
+ -5 + 0.185668,
+  1 + -0.506371,
+ -1 + 0.19368,
+ -3 + 0.135954,
+  5 + 0.0317122,
+ -3 + 0.926598,
+  3 + 0.841409,
+ -7 + -0.995628,
+  7 + -0.516938,
+  1 + -0.327213,
+ -7 + -0.988622,
+  7 + 0.0436381,
+ -1 + -0.736482,
+  3 + 0.0252206,
+ -7 + -0.999107,
+  1 + 0.287324,
+  3 + -0.710148,
+ -3 + -0.863982,
+  5 + -0.110109,
+ -1 + -0.382303,
+  1 + -0.00955381,
+  7 + 0.574434,
+  3 + 0.772632,
+ -3 + 0.427061,
+ -3 + -0.47615,
+  1 + 0.159639,
+ -1 + 0.0973485,
+ -7 + 0.670094,
+ -3 + 0.66009,
+  3 + -0.966069,
+  5 + 0.729848,
+ -1 + -0.165828,
+ -5 + -0.991247,
+  3 + -0.796155,
+ -3 + -0.665567,
+  1 + 0.705734,
+ -3 + -0.0729422,
+ -5 + 0.569012,
+ -5 + 0.532164,
+ -3 + 0.114169,
+ -3 + -0.79896,
+  5 + -0.434429,
+  3 + 0.0409003,
+  5 + -0.656138,
+  1 + 0.80331,
+ -1 + -0.832592,
+  1 + -0.512036,
+  5 + 0.821594,
+ -5 + 0.153262,
+ -7 + 0.742653,
+  7 + 0.775938,
+  7 + 0.794682,
+ -1 + 0.436735,
+  1 + 0.232814,
+  5 + 0.173647,
+ -7 + 0.0346826,
+ -5 + -0.764013,
+ -3 + 0.414464,
+ -7 + -0.107918,
+ -5 + -0.909358,
+ -3 + -0.855809,
+  3 + 0.321112,
+ -7 + -0.853217,
+ -1 + 0.240779,
+ -5 + 0.308181,
+ -3 + -0.101137,
+ -3 + 0.0592809,
+  1 + -0.475771,
+  1 + -0.805118,
+  1 + -0.497502,
+  1 + 0.0533702,
+  1 + 0.256822,
+  1 + 0.943496,
+  5 + 0.195682,
+  3 + 0.84158,
+ -7 + 0.691885,
+  7 + 0.702398,
+ -5 + -0.0240126,
+  3 + 0.0729154,
+  1 + 0.683697,
+ -5 + 0.261411,
+  5 + 0.953329,
+  5 + -0.728981,
+ -5 + -0.635009,
+  5 + -0.630682,
+ -7 + 0.122834,
+ -3 + 0.959923,
+ -1 + 0.374435,
+  1 + 0.720612,
+  5 + 0.664998,
+  1 + 0.00891615,
+ -7 + 0.432124,
+ -3 + 0.0339184,
+ -1 + -0.257549,
+  7 + 0.584476,
+ -3 + 0.0935045,
+ -1 + -0.804627,
+  1 + -0.992967,
+ -3 + 0.538947,
+  7 + 0.180181,
+ -5 + -0.90103,
+ -3 + -0.368599,
+  7 + 0.775146,
+ -3 + -0.990663,
+  5 + -0.991429,
+  3 + 0.229796,
+  3 + 0.933547,
+ -7 + 0.629628,
+  7 + -0.128119,
+ -3 + 0.993864,
+  3 + -0.518632,
+  1 + 0.431409,
+  5 + 0.162359,
+ -1 + 0.340156,
+  7 + 0.99834,
+ -1 + -0.37602,
+  7 + 0.798388,
+ -5 + -0.977304,
+ -1 + -0.714549,
+ -7 + 0.371461,
+ -3 + 0.429763,
+ -5 + -0.176519,
+  1 + 0.130875,
+  3 + -0.192991,
+ -3 + 0.926126,
+  3 + -0.756796,
+ -3 + 0.0799201,
+ -5 + -0.885874,
+ -5 + -0.922719,
+ -1 + 0.788957,
+  1 + 0.876735,
+  1 + 0.505541,
+  1 + 0.0568082,
+  5 + -0.546276,
+ -5 + 0.987925,
+  1 + 0.559679,
+ -5 + 0.240393,
+  7 + 0.460363,
+  5 + 0.194578,
+  3 + 0.987203,
+  7 + 0.781711,
+ -7 + -0.0489823,
+ -1 + -0.776679,
+ -7 + -0.496617,
+  5 + -0.488827,
+ -3 + -0.501392,
+  5 + 0.703741,
+  7 + -0.0924905,
+  5 + -0.948555,
+ -3 + -0.508697,
+ -5 + -0.211705,
+ -1 + -0.0656021,
+  1 + 0.526428,
+  3 + 0.977313,
+  7 + 0.717488,
+  1 + 0.987358,
+ -1 + -0.492118,
+ -1 + 0.765235,
+  1 + -0.576154,
+  3 + 0.52365,
+ -7 + 0.253303,
+  1 + -0.492177,
+  5 + 0.865942,
+  5 + 0.977195,
+  7 + 0.161001,
+  5 + -0.907593,
+ -7 + -0.557902,
+ -7 + 0.825849,
+  7 + -0.120301,
+ -5 + 0.531996,
+  1 + 0.80755,
+  7 + 0.969872,
+ -7 + -0.738685,
+ -3 + 0.636749,
+  1 + -0.655666,
+ -3 + 0.999979,
+  7 + -0.843387,
+ -3 + 0.693217,
+  7 + 0.615595,
+ -3 + -0.585734,
+  5 + -0.349962,
+ -5 + -0.708827,
+  5 + 0.767043,
+ -3 + -0.561155,
+  5 + 0.0547506,
+  7 + -0.00058388,
+  5 + 0.683614,
+ -5 + 0.933133,
+ -7 + -0.705963,
+ -1 + 0.432718,
+ -5 + -0.745574,
+ -1 + 0.578781,
+ -3 + 0.265256,
+ -1 + -0.723166,
+  3 + -0.609362,
+ -3 + 0.897704,
+ -1 + 0.630349,
+ -5 + 0.582721,
+ -5 + -0.0955401,
+  5 + -0.235266,
+ -1 + 0.829279,
+ -5 + -0.824548,
+  3 + -0.803079,
+  3 + -0.505004,
+ -1 + -0.492252,
+  1 + -0.92866,
+  1 + -0.193727,
+  7 + 0.855165,
+ -5 + -0.409258,
+  3 + 0.483943,
+  5 + -0.711778,
+  1 + -0.291856,
+ -1 + -0.309453,
+ -1 + -0.961907,
+  3 + 0.239915,
+  3 + 0.333033,
+ -5 + -0.520074,
+  7 + 0.80808,
+  7 + -0.392463,
+ -5 + -0.268562,
+  7 + 0.963694,
+ -5 + -0.27416,
+ -3 + 0.136372,
+ -3 + -0.533467,
+  5 + 0.0336407,
+  5 + 0.269954,
+ -1 + 0.481331,
+ -5 + 0.883264,
+ -5 + 0.917248,
+ -5 + 0.841082,
+  7 + -0.272449,
+ -1 + 0.612493,
+ -7 + -0.0456689,
+  3 + -0.468522,
+ -5 + -0.783857,
+ -5 + -0.963398,
+ -7 + 0.0600612,
+ -3 + 0.80801,
+ -3 + -0.969476,
+ -5 + 0.949233,
+  7 + -0.954761,
+  7 + -0.0774834,
+  5 + -0.245508,
+  5 + 0.345368,
+  3 + -0.476338,
+ -5 + -0.322511,
+ -3 + 0.450538,
+ -7 + -0.678719,
+ -3 + -0.172123,
+ -5 + -0.209171,
+ -3 + -0.420884,
+ -1 + 0.00383168,
+ -3 + -0.312955,
+ -7 + -0.0884187,
+ -7 + 0.201349,
+  5 + -0.601248,
+  5 + -0.413319,
+  3 + -0.246626,
+  5 + 0.977104,
+ -5 + 0.0133906,
+  7 + 0.349431,
+  5 + 0.216145,
+ -1 + -0.529927,
+  1 + -0.249291,
+  1 + 0.658874,
+  7 + 0.43074,
+  5 + 0.124815,
+  7 + -0.553229,
+  1 + 0.116857,
+ -5 + 0.734356,
+ -1 + -0.647581,
+  5 + -0.323226,
+ -5 + -0.810003,
+ -3 + 0.822276,
+ -1 + -0.591676,
+ -5 + -0.434047,
+  1 + 0.15821,
+  7 + 0.165069,
+  3 + 0.253866,
+  3 + 0.973848,
+ -7 + 0.713996,
+ -5 + 0.215808,
+ -1 + 0.0812883,
+ -3 + 0.846565,
+ -5 + -0.947667,
+  3 + 0.409641,
+  5 + -0.385462,
+ -3 + 0.787733,
+  1 + 0.844418,
+  1 + 0.349241,
+  5 + -0.586969,
+  7 + 0.257519,
+  1 + -0.315586,
+ -1 + -0.327033,
+  1 + 0.767669,
+ -1 + -0.292183,
+  3 + 0.389264,
+ -7 + 0.339534,
+ -3 + 0.477526,
+ -3 + 0.11475,
+ -7 + -0.119439,
+  3 + 0.406966,
+  5 + 0.419678,
+  1 + 0.76062,
+ -7 + 0.536916,
+ -7 + -0.510681,
+ -5 + 0.905296,
+  7 + 0.13423,
+ -5 + 0.748596,
+  3 + -0.431882,
+  7 + 0.33909,
+  3 + 0.341309,
+  5 + -0.172616,
+ -7 + -0.778667,
+ -5 + -0.984483,
+  7 + 0.04289,
+ -3 + 0.791158,
+ -1 + -0.606419,
+ -3 + 0.939034,
+  5 + -0.688122,
+  7 + -0.0797096,
+ -3 + -0.176378,
+  3 + -0.200208,
+ -3 + 0.539966,
+ -5 + 0.55811,
+ -1 + -0.965644,
+ -7 + -0.62776,
+  3 + -0.327998,
+  3 + -0.518732,
+  3 + 0.713363,
+  5 + 0.082287,
+ -7 + -0.799949,
+  5 + -0.144101,
+ -7 + -0.416404,
+  3 + 0.926589,
+ -3 + -0.0426248,
+ -3 + 0.823828,
+  3 + -0.899492,
+ -1 + 0.925421,
+ -5 + -0.987104,
+ -3 + -0.667032,
+ -1 + -0.376583,
+ -1 + 0.776434,
+  5 + 0.838315,
+ -3 + -0.411202,
+ -7 + -0.918427,
+ -5 + 0.627889,
+  7 + -0.542975,
+ -3 + -0.0689918,
+ -5 + -0.55104,
+ -5 + 0.829815,
+  7 + 0.466128,
+ -7 + -0.910729,
+ -3 + 0.587943,
+ -5 + -0.989778,
+  3 + 0.429693,
+ -5 + 0.363276,
+  5 + 0.48865,
+ -1 + 0.462889,
+ -1 + 0.933537,
+ -1 + -0.237365,
+  7 + -0.503287,
+  3 + 0.898831,
+  5 + -0.88925,
+  1 + 0.491187,
+ -3 + 0.819494,
+  7 + -0.841093,
+  5 + -0.172405,
+ -3 + 0.296082,
+ -5 + 0.230588,
+  1 + -0.135964,
+ -7 + -0.24852,
+  7 + 0.779819,
+  1 + -0.0197039,
+  3 + 0.690689,
+  5 + 0.201188,
+ -3 + 0.316178,
+  3 + -0.790151,
+ -3 + 0.353513,
+  1 + 0.482168,
+ -7 + 0.5088,
+  5 + -0.619387,
+  3 + -0.572638,
+ -1 + 0.737113,
+ -3 + -0.330907,
+  3 + -0.642647,
+  7 + -0.587751,
+  7 + 0.705296,
+ -1 + 0.765705,
+ -7 + 0.342622,
+  1 + -0.443867,
+ -7 + 0.64285,
+  5 + 0.119933,
+  1 + 0.146719,
+ -3 + 0.808331,
+  5 + 0.362826,
+ -5 + 0.649288,
+ -5 + -0.919914,
+  5 + 0.530805,
+  7 + 0.836641,
+ -1 + -0.33567,
+  7 + -0.814941,
+ -3 + 0.521328,
+ -7 + -0.0633902,
+  3 + 0.637973,
+  5 + -0.448024,
+ -7 + 0.529787,
+ -1 + 0.158647,
+  1 + -0.343875,
+  5 + 0.862299,
+ -7 + 0.269423,
+ -3 + 0.205924,
+ -3 + 0.543444,
+ -1 + -0.0442747,
+ -1 + -0.514346,
+ -7 + -0.538346,
+  5 + -0.134437,
+  3 + -0.242908,
+ -3 + 0.960616,
+ -3 + 0.613265,
+  5 + -0.578398,
+  5 + -0.196621,
+ -1 + 0.99966,
+ -7 + -0.206926,
+ -7 + 0.149597,
+  1 + -0.618079,
+  7 + -0.779085,
+  5 + 0.78756,
+ -3 + -0.461424,
+  1 + -0.8271,
+  7 + -0.779893,
+  1 + -0.034591,
+  3 + -0.618594,
+  7 + -0.508509,
+  3 + 0.858569,
+ -3 + -0.292217,
+ -3 + 0.638647,
+  7 + 0.429429,
+ -3 + 0.0850469,
+  3 + 0.840684,
+ -5 + -0.361285,
+ -1 + -0.0439304,
+ -5 + -0.464768,
+  5 + 0.814776,
+ -7 + 0.838205,
+ -1 + 0.932473,
+  3 + 0.0800499,
+  3 + 0.430625,
+ -1 + -0.379486,
+ -5 + 0.566269,
+  1 + -0.191075,
+  1 + 0.426799,
+ -3 + -0.865195,
+ -1 + -0.286844,
+ -5 + -0.347813,
+ -1 + 0.254653,
+ -5 + -0.0217081,
+ -7 + 0.712565,
+ -5 + 0.626585,
+ -3 + 0.407399,
+ -1 + -0.495544,
+  7 + 0.988263,
+  5 + 0.752268,
+  7 + -0.57751,
+  1 + -0.699522,
+ -3 + -0.559222,
+ -5 + -0.142211,
+ -5 + -0.984406,
+ -7 + 0.478908,
+  3 + -0.492842,
+ -1 + -0.75382,
+  1 + 0.00969996,
+  1 + -0.893656,
+ -7 + 0.928332,
+  7 + -0.310557,
+  3 + -0.203997,
+ -3 + -0.119623,
+ -3 + 0.23919,
+ -5 + 0.89898,
+  3 + -0.000236075,
+ -1 + -0.75715,
+  5 + -0.946444,
+  5 + 0.830343,
+  5 + 0.170209,
+ -5 + 0.0682683,
+  7 + 0.490712,
+  3 + 0.0912319,
+  7 + -0.939061,
+ -5 + -0.27871,
+  3 + 0.292512,
+  3 + 0.7815,
+  3 + 0.780423,
+  3 + -0.995218,
+  1 + -0.971244,
+  5 + 0.863878,
+  3 + 0.605471,
+  1 + 0.615707,
+ -1 + -0.430001,
+  7 + 0.137532,
+ -7 + 0.420738,
+  5 + -0.511889,
+ -7 + -0.894203,
+ -1 + -0.442678,
+  7 + 0.58245,
+ -1 + -0.302989,
+ -7 + 0.046658,
+ -1 + 0.213312,
+ -3 + -0.40466,
+  3 + 0.119842,
+ -3 + -0.209236,
+  1 + 0.489636,
+ -1 + 0.0750853,
+  1 + -0.138393,
+  3 + 0.197677,
+  1 + 0.801,
+  5 + -0.737093,
+  5 + 0.0908536,
+ -7 + -0.604504,
+ -5 + 0.56203,
+ -3 + 0.309546,
+  1 + -0.966521,
+  5 + 0.977852,
+  7 + 0.73063,
+ -5 + -0.256762,
+ -3 + -0.431265,
+  5 + 0.661912,
+ -1 + 0.865871,
+ -3 + 0.10026,
+ -3 + 0.979883,
+ -3 + -0.50973,
+  7 + -0.387004,
+ -5 + 0.872216,
+ -1 + -0.552574,
+  3 + -0.00281111,
+ -5 + -0.433458,
+  3 + 0.228333,
+ -5 + -0.784953,
+  5 + 0.571488,
+ -5 + -0.107047,
+  3 + 0.598395,
+  7 + -0.209076,
+  7 + 0.968037,
+ -7 + 0.133602,
+ -3 + 0.197601,
+ -1 + -0.737348,
+ -7 + -0.0987225,
+ -1 + -0.680374,
+ -5 + 0.902133,
+  5 + -0.065214,
+  7 + 0.820436,
+ -1 + -0.994703,
+  5 + 0.928257,
+  3 + 0.387782,
+ -1 + -0.867014,
+ -1 + -0.343716,
+ -3 + -0.0119044,
+  5 + -0.882348,
+  3 + -0.349223,
+ -3 + -0.423901,
+ -1 + -0.358375,
+ -7 + 0.877898,
+ -1 + -0.0346012,
+ -3 + -0.731243,
+  1 + -0.0103546,
+ -1 + -0.662776,
+  1 + 0.486511,
+ -1 + -0.0129122,
+ -5 + 0.0121863,
+ -3 + 0.550817,
+ -3 + 0.0375324,
+  5 + 0.371006,
+  5 + -0.111812,
+  5 + 0.963243,
+  1 + 0.36354,
+ -3 + -0.0390213,
+ -7 + -0.512331,
+ -3 + 0.530897,
+ -1 + -0.961326,
+  1 + -0.128698,
+  5 + -0.0345879,
+  7 + -0.724934,
+ -7 + -0.990395,
+  7 + -0.0956077,
+  5 + 0.998217,
+ -1 + -0.38503,
+ -5 + 0.431693,
+  3 + -0.322315,
+  1 + -0.520076,
+ -3 + -0.403514,
+  3 + -0.638799,
+ -1 + -0.665616,
+ -7 + 0.866326,
+  7 + -0.314543,
+ -3 + -0.752403,
+  7 + 0.180847,
+  7 + -0.924565,
+  3 + 0.431162,
+ -7 + -0.844134,
+  5 + -0.621084,
+  1 + 0.678683,
+  7 + -0.643627,
+ -1 + 0.464485,
+  3 + 0.311484,
+  1 + 0.61938,
+  1 + -0.362697,
+ -1 + -0.545854,
+ -7 + -0.693428,
+  3 + -0.162961,
+  3 + 0.362332,
+ -5 + -0.0418496,
+ -3 + -0.790282,
+  1 + -0.362329,
+ -5 + -0.679632,
+ -7 + 0.193632,
+  7 + 0.169699,
+  5 + -0.0276975,
+  3 + 0.145423,
+  7 + -0.526892,
+  7 + 0.23963,
+ -5 + -0.0191274,
+  3 + 0.267953,
+  5 + -0.963432,
+  7 + 0.72934,
+  5 + -0.0415711,
+  3 + -0.0615771,
+ -1 + -0.441843,
+  5 + -0.196666,
+ -5 + 0.656983,
+  5 + 0.764159,
+ -7 + -0.0188419,
+ -1 + 0.515285,
+ -5 + 0.77527,
+ -1 + -0.362528,
+  1 + 0.360052,
+  3 + 0.134359,
+ -5 + 0.37625,
+  7 + -0.511201,
+  7 + -0.846493,
+  5 + 0.94168,
+  1 + -0.100134,
+  5 + -0.157002,
+  3 + -0.374631,
+ -7 + -0.364117,
+ -1 + -0.142558,
+ -7 + 0.0265685,
+ -3 + 0.138828,
+ -5 + -0.289868,
+  1 + 0.664193,
+ -7 + 0.887828,
+  1 + -0.652588,
+  3 + -0.527631,
+ -1 + 0.284251,
+ -5 + 0.278712,
+  1 + -0.105013,
+ -1 + 0.853542,
+  1 + -0.436623,
+ -5 + -0.867476,
+  3 + 0.96232,
+  7 + 0.427617,
+  3 + -0.501165,
+ -5 + 0.411637,
+  7 + 0.891616,
+ -7 + 0.664072,
+ -1 + -0.888475,
+  5 + 0.548079,
+  3 + 0.503912,
+ -5 + -0.612317,
+ -1 + -0.180983,
+  1 + -0.239876,
+  1 + 0.596635,
+ -3 + -0.0827705,
+ -7 + 0.277359,
+  5 + -0.941413,
+ -5 + 0.697875,
+  3 + 0.714356,
+  1 + -0.558584,
+  1 + -0.0174082,
+  5 + -0.587225,
+ -5 + -0.512741,
+  7 + -0.434388,
+  7 + -0.473811,
+ -1 + 0.285865,
+  5 + 0.988991,
+ -5 + -0.991867,
+ -3 + 0.864291,
+ -5 + 0.661288,
+  5 + -0.460111,
+  7 + 0.366331,
+ -7 + 0.784093,
+  5 + 0.918848,
+  7 + 0.965396,
+ -3 + -0.161624,
+  7 + -0.476323,
+ -5 + 0.501047,
+  7 + 0.964268,
+  1 + -0.388995,
+ -1 + 0.308069,
+  7 + 0.449621,
+ -3 + 0.517261,
+ -1 + -0.931887,
+ -3 + -0.314139,
+ -1 + -0.88269,
+  1 + -0.641202,
+ -7 + 0.426506,
+ -7 + 0.765908,
+  3 + -0.839435,
+ -1 + 0.85062,
+ -5 + -0.068266,
+  7 + -0.336073,
+  5 + -0.552052,
+  7 + 0.968225,
+  5 + -0.489061,
+ -1 + 0.549817,
+  7 + 0.155363,
+  7 + 0.287813,
+  5 + -0.0712527,
+  7 + -0.539294,
+  3 + 0.515963,
+ -7 + 0.309448,
+  5 + -0.400565,
+ -3 + 0.772515,
+ -3 + 0.47223,
+ -5 + -0.377265,
+ -3 + -0.277457,
+  3 + -0.0481647,
+  1 + 0.253072,
+  7 + -0.701416,
+  3 + -0.983524,
+ -1 + 0.859256,
+  3 + 0.684439,
+  7 + -0.715583,
+  1 + -0.927083,
+  5 + -0.820364,
+  3 + -0.818987,
+ -1 + 0.0484889,
+ -5 + 0.88172,
+ -1 + 0.642372,
+  7 + -0.486761,
+  1 + -0.154892,
+ -3 + 0.620922,
+ -7 + -0.307461,
+ -5 + 0.958143,
+ -5 + -0.945751,
+ -7 + 0.420205,
+  3 + 0.212257,
+ -7 + 0.343969,
+ -7 + -0.56883,
+ -7 + 0.542757,
+  1 + 0.338133,
+ -1 + 0.205287,
+  3 + -0.678275,
+ -3 + 0.162556,
+  7 + 0.7356,
+ -1 + -0.366469,
+ -5 + 0.818684,
+  1 + -0.375059,
+ -7 + -0.326917,
+ -1 + 0.21386,
+ -1 + 0.933421,
+ -5 + -0.0965871,
+ -1 + -0.327707,
+ -3 + -0.293112,
+  5 + -0.399372,
+ -1 + -0.243464,
+ -1 + -0.477791,
+  5 + 0.160018,
+  3 + 0.0379489,
+ -7 + -0.468135,
+ -5 + -0.924231,
+  7 + -0.559268,
+ -1 + -0.869929,
+  1 + 0.644987,
+  7 + -0.416144,
+ -3 + -0.64862,
+  1 + 0.0932449,
+ -1 + -0.941752,
+ -7 + -0.448205,
+  5 + 0.816932,
+ -1 + -0.010022,
+ -3 + -0.611324,
+  5 + -0.688206,
+  1 + 0.868089,
+ -3 + -0.454031,
+  3 + -0.633225,
+  5 + -0.11036,
+  7 + 0.119173,
+ -7 + -0.663239,
+ -7 + 0.86954,
+  7 + 0.335132,
+ -1 + 0.512855,
+  1 + -0.130088,
+  3 + -0.225548,
+  5 + -0.745615,
+  7 + 0.963223,
+ -3 + -0.678778,
+ -7 + -0.430329,
+ -3 + 0.964206,
+  7 + 0.808534,
+  5 + -0.632605,
+ -5 + -0.728056,
+ -5 + -0.0283051,
+ -1 + -0.292853,
+  3 + -0.960114,
+  1 + 0.266249,
+  7 + -0.94076,
+  7 + -0.680042,
+ -1 + 0.678469,
+  3 + 0.553279,
+  7 + 0.392802,
+  1 + -0.308376,
+  7 + -0.588163,
+  5 + -0.235282,
+  7 + -0.490381,
+  5 + 0.412499,
+ -7 + -0.148118,
+  7 + -0.20069,
+ -1 + -0.256974,
+  1 + -0.946528,
+ -5 + -0.190544,
+  1 + -0.774484,
+ -1 + 0.939011,
+  3 + 0.401197,
+  7 + 0.763682,
+ -7 + 0.970152,
+  5 + -0.471915,
+ -3 + -0.0230657,
+ -1 + 0.666549,
+  3 + -0.312851,
+  5 + 0.909774,
+ -5 + 0.608703,
+ -1 + -0.398985,
+ -1 + -0.579955,
+ -3 + 0.427466,
+ -3 + -0.406024,
+  5 + -0.923879,
+  5 + -0.124516,
+ -7 + 0.389177,
+ -1 + 0.978163,
+  7 + 0.321733,
+ -5 + -0.401276,
+ -3 + -0.669763,
+  5 + 0.837051,
+ -3 + -0.507979,
+ -5 + 0.650163,
+  5 + -0.533125,
+ -7 + -0.352708,
+ -3 + 0.975917,
+ -1 + 0.333199,
+  1 + 0.786429,
+  7 + 0.588826,
+ -3 + -0.254794,
+ -5 + 0.577074,
+  3 + -0.445216,
+ -3 + -0.913091,
+  1 + 0.833436,
+  3 + 0.879009,
+  7 + -0.420452,
+ -7 + -0.841488,
+  3 + 0.941771,
+ -5 + -0.516194,
+  1 + -0.111796,
+  1 + 0.913016,
+ -3 + 0.831405,
+  7 + -0.456459,
+  5 + 0.52518,
+  7 + 0.407003,
+  5 + 0.477567,
+ -1 + 0.420401,
+ -1 + 0.437449,
+ -7 + -0.0206778,
+ -3 + 0.132506,
+  3 + -0.0369548,
+ -3 + -0.66723,
+  3 + 0.639026,
+ -5 + 0.818826,
+ -3 + 0.521142,
+ -7 + 0.239988,
+  7 + 0.798847,
+  3 + 0.568449,
+ -7 + -0.322325,
+  1 + 0.74602,
+  5 + -0.820488,
+  5 + 0.422569,
+ -5 + 0.154974,
+  3 + -0.598438,
+ -3 + -0.0493216,
+  5 + -0.437171,
+ -7 + 0.91565,
+  1 + -0.76322,
+ -7 + 0.655683,
+  1 + -0.221855,
+  3 + 0.499042,
+  7 + -0.551781,
+ -1 + 0.776521,
+  3 + 0.364049,
+  7 + 0.76778,
+  1 + 0.98362,
+  1 + 0.901754,
+ -7 + -0.301171,
+ -7 + -0.154012,
+ -3 + -0.967804,
+ -1 + 0.205987,
+  7 + -0.231608,
+  1 + 0.577335,
+ -5 + 0.133768,
+ -5 + 0.959646,
+ -3 + -0.0372217,
+ -3 + 0.404834,
+ -1 + 0.457923,
+  1 + 0.0552233,
+ -3 + 0.2,
+  5 + -0.787169,
+ -1 + 0.572437,
+  7 + -0.18741,
+ -1 + 0.0523727,
+ -1 + -0.804208,
+  7 + -0.303471,
+  7 + 0.73635,
+ -3 + -0.804122,
+  1 + 0.962955,
+  7 + 0.065147,
+ -7 + -0.464851,
+  7 + 0.410402,
+ -1 + -0.213138,
+  7 + 0.323269,
+  5 + -0.812589,
+  1 + -0.924136,
+  3 + -0.0515391,
+  5 + -0.942719,
+ -7 + 0.0813437,
+ -5 + -0.919358,
+ -3 + 0.09817,
+ -3 + 0.204768,
+ -3 + 0.895305,
+ -5 + 0.426145,
+ -1 + -0.654514,
+  1 + -0.527968,
+  1 + -0.93447,
+  7 + -0.259295,
+ -5 + -0.357566,
+ -3 + 0.820761,
+  3 + 0.061946,
+  1 + -0.365104,
+ -1 + -0.484186,
+  5 + -0.0747202,
+  7 + 0.373292,
+  3 + -0.225615,
+  1 + 0.387072,
+ -1 + 0.0964885,
+  5 + 0.318965,
+ -5 + -0.574407,
+ -1 + -0.5876,
+  3 + -0.0651205,
+ -7 + -0.131517,
+ -5 + -0.700999,
+ -1 + 0.431009,
+ -5 + -0.378572,
+ -5 + -0.438665,
+  3 + -0.0663064,
+ -1 + 0.303877,
+  7 + 0.252822,
+ -5 + 0.127981,
+ -5 + -0.979741,
+ -7 + -0.977809,
+  1 + -0.939208,
+ -5 + -0.619289,
+ -3 + -0.817288,
+ -7 + -0.682975,
+  5 + 0.945473,
+  3 + 0.696275,
+ -1 + 0.466816,
+  3 + -0.632966,
+ -3 + 0.078222,
+  5 + 0.546507,
+ -1 + 0.977089,
+  7 + -0.133295,
+ -5 + -0.604371,
+ -3 + 0.365631,
+ -3 + 0.673212,
+ -1 + 0.180141,
+  5 + 0.223484,
+ -1 + 0.146777,
+  1 + -0.319683,
+ -1 + 0.857262,
+  5 + -0.356152,
+  5 + -0.598653,
+  1 + 0.975409,
+ -5 + -0.881246,
+ -7 + -0.472377,
+ -3 + 0.0214979,
+  7 + -0.788032,
+  7 + -0.333508,
+  7 + -0.750094,
+ -3 + -0.814424,
+  7 + -0.965833,
+  5 + -0.36787,
+  3 + -0.612635,
+ -5 + 0.236003,
+ -5 + -0.785485,
+ -5 + 0.745934,
+  3 + 0.841095,
+  3 + 0.331357,
+  3 + -0.341722,
+  1 + 0.0449292,
+  7 + -0.256584,
+ -3 + -0.666529,
+  7 + -0.203782,
+  1 + -0.442113,
+  5 + 0.281735,
+ -7 + -0.600958,
+  5 + -0.297631,
+  7 + 0.834514,
+  1 + -0.965433,
+ -7 + 0.980322,
+ -5 + -0.275104,
+ -5 + 0.501189,
+  1 + 0.861033,
+  3 + -0.186388,
+ -7 + -0.783021,
+ -3 + -0.331772,
+ -7 + -0.923864,
+  7 + 0.981171,
+ -7 + 0.677146,
+  5 + -0.764622,
+  7 + 0.544671,
+  3 + -0.149741,
+ -1 + -0.115158,
+  5 + 0.315554,
+  3 + -0.0435786,
+ -7 + -0.198421,
+  3 + 0.728623,
+  3 + 0.917598,
+ -7 + -0.222429,
+ -1 + -0.839337,
+  1 + -0.837996,
+  5 + 0.7184,
+  3 + 0.279682,
+  5 + 0.89931,
+  1 + -0.0903269,
+ -3 + 0.311248,
+ -3 + -0.0615842,
+ -5 + 0.978228,
+  5 + -0.0288547,
+ -7 + -0.319235,
+  1 + 0.459872,
+ -7 + -0.762583,
+  1 + 0.430673,
+  7 + -0.202576,
+  7 + -0.508028,
+  5 + -0.563939,
+  7 + 0.431253,
+  3 + 0.924691,
+ -7 + -0.929823,
+ -7 + -0.745149,
+ -3 + -0.54763,
+  7 + -0.233056,
+ -3 + 0.0728049,
+  3 + 0.173541,
+  5 + -0.99085,
+ -5 + -0.509606,
+ -7 + -0.0573629,
+ -5 + 0.146235,
+  7 + -0.530049,
+  5 + -0.92378,
+  5 + -0.150627,
+  7 + -0.632136,
+  3 + -0.544558,
+ -1 + -0.559563,
+ -5 + -0.183858,
+ -3 + -0.0823922,
+  3 + -0.845123,
+ -5 + 0.740183,
+ -1 + -0.864943,
+ -7 + -0.517753,
+ -7 + 0.273158,
+ -7 + 0.597718,
+  7 + -0.960088,
+ -1 + 0.628689,
+  5 + -0.100486,
+  5 + -0.28978,
+ -3 + 0.591832,
+  5 + -0.225949,
+  1 + 0.434438,
+  3 + 0.701275,
+ -5 + -0.110868,
+  3 + -0.993528,
+ -1 + -0.279674,
+ -7 + -0.695508,
+  3 + 0.208776,
+  5 + 0.280286,
+ -7 + 0.098819,
+  1 + -0.270841,
+ -3 + 0.163315,
+  7 + -0.339504,
+ -1 + 0.503129,
+ -5 + -0.42331,
+ -5 + 0.289597,
+  5 + -0.48842,
+ -1 + -0.301035,
+ -7 + 0.307344,
+  3 + 0.149469,
+ -7 + -0.91815,
+ -7 + 0.735915,
+ -7 + 0.651662,
+ -5 + -0.367747,
+  3 + 0.571618,
+  3 + -0.0886024,
+  7 + -0.287501,
+  3 + -0.332199,
+ -3 + 0.103811,
+  1 + 0.281067,
+  1 + -0.380718,
+ -1 + 0.343006,
+ -7 + -0.940098,
+ -3 + 0.722196,
+  5 + 0.874495,
+  1 + 0.990522,
+  3 + -0.915597,
+ -5 + -0.278943,
+ -7 + 0.203699,
+ -5 + 0.170043,
+  7 + 0.536621,
+ -5 + 0.824829,
+  5 + -0.832656,
+ -7 + 0.333,
+ -3 + -0.667407,
+  7 + 0.105231,
+  7 + -0.905234,
+ -1 + -0.810245,
+  3 + 0.294136,
+ -1 + -0.514902,
+  3 + -0.2467,
+  3 + -0.587121,
+  3 + 0.60538,
+ -3 + 0.0694657,
+ -5 + 0.0962229,
+  7 + -0.291999,
+ -5 + 0.450209,
+  3 + -0.147034,
+ -1 + -0.0838816,
+  3 + 0.112086,
+ -5 + 0.194085,
+  5 + -0.0903105,
+ -7 + -0.919954,
+ -5 + -0.967825,
+ -1 + -0.441373,
+  5 + 0.768526,
+  5 + 0.38484,
+  3 + -0.947454,
+  5 + -0.262922,
+  7 + -0.593716,
+ -3 + 0.219333,
+  3 + 0.076773,
+  7 + 0.192425,
+  1 + 0.970687,
+  7 + -0.00340885,
+  3 + -0.199764,
+ -3 + 0.255666,
+ -5 + 0.439951,
+  1 + 0.505418,
+  3 + -0.356007,
+  5 + -0.318271,
+ -3 + 0.788047,
+  5 + -0.924415,
+ -1 + 0.394691,
+  1 + 0.972997,
+  1 + 0.357046,
+  3 + 0.419342,
+ -5 + -0.774465,
+ -7 + 0.0996104,
+  5 + -0.458399,
+ -3 + -0.133173,
+ -1 + -0.671463,
+  7 + -0.916153,
+ -7 + 0.110461,
+  3 + 0.409689,
+ -3 + -0.355372,
+ -5 + -0.896134,
+ -7 + -0.950039,
+  7 + 0.386037,
+  3 + -0.798405,
+ -3 + -0.744455,
+  1 + -0.572819,
+ -1 + 0.839239,
+ -3 + 0.570676,
+  3 + -0.835377,
+ -7 + 0.034378,
+  5 + 0.724415,
+  5 + -0.252927,
+ -3 + 0.287315,
+ -3 + 0.334237,
+  5 + -0.118203,
+ -1 + 0.502825,
+ -5 + -0.154511,
+  5 + -0.127665,
+  7 + 0.0817964,
+  1 + 0.132329,
+ -5 + -0.546248,
+ -3 + 0.874254,
+ -3 + 0.421468,
+  3 + -0.928829,
+  5 + 0.620968,
+  7 + 0.0580643,
+ -7 + -0.687253,
+ -7 + -0.628005,
+  5 + -0.883083,
+ -5 + -0.270135,
+  1 + -0.623219,
+ -7 + 0.277921,
+  3 + 0.116588,
+ -5 + 0.264649,
+ -1 + -0.593871,
+ -7 + 0.329278,
+ -1 + -0.0926952,
+ -1 + 0.64349,
+  1 + -0.10689,
+  3 + -0.541441,
+  1 + 0.499186,
+ -3 + 0.920398,
+ -1 + 0.381933,
+  5 + -0.518618,
+ -5 + 0.618314,
+  1 + 0.110954,
+ -1 + 0.576074,
+  3 + 0.45385,
+ -5 + -0.917242,
+  5 + -0.451152,
+  5 + -0.705703,
+ -5 + -0.97524,
+ -5 + -0.732996,
+  5 + 0.702813,
+  3 + -0.229341,
+  7 + -0.13257,
+  7 + 0.994484,
+  7 + -0.0231948,
+  5 + 0.538224,
+  1 + -0.838791,
+  7 + 0.848763,
+ -7 + -0.539283,
+ -3 + 0.321736,
+  5 + 0.22943,
+  1 + -0.626804,
+  5 + 0.209983,
+ -5 + 0.977037,
+  3 + 0.448198,
+  5 + -0.419565,
+  7 + 0.666147,
+ -7 + 0.412532,
+  7 + -0.0260039,
+  1 + 0.545681,
+  1 + 0.657399,
+ -5 + 0.275525,
+  5 + 0.563082,
+  1 + 0.88785,
+ -5 + 0.855898,
+ -1 + -0.758617,
+ -1 + 0.0505126,
+  5 + 0.0387102,
+  5 + 0.574784,
+  1 + 0.1487,
+  7 + -0.234118,
+ -1 + 0.458783,
+  5 + -0.798949,
+ -7 + -0.300432,
+  3 + -0.455072,
+  1 + 0.24667,
+ -3 + 0.034758,
+  1 + -0.491485,
+  1 + 0.27987,
+ -5 + -0.92334,
+  1 + 0.486993,
+  5 + -0.624284,
+ -3 + 0.259474,
+  3 + 0.384827,
+  7 + -0.744943,
+  3 + 0.669036,
+ -7 + -0.171024,
+  1 + -0.963747,
+ -3 + -0.457945,
+ -1 + -0.271542,
+  3 + -0.642662,
+  5 + 0.867933,
+ -7 + 0.872486,
+ -5 + -0.0610653,
+ -3 + 0.0567537,
+ -5 + -0.384634,
+ -1 + -0.810843,
+  1 + -0.210336,
+  7 + -0.782186,
+ -3 + 0.206301,
+  3 + -0.532726,
+ -1 + 0.792476,
+  1 + -0.0254994,
+  1 + -0.38317,
+  5 + -0.444631,
+ -3 + 0.202259,
+  7 + 0.906256,
+ -5 + -0.283238,
+  1 + 0.761982,
+ -1 + 0.456456,
+  7 + -0.213898,
+  7 + -0.98443,
+ -7 + -0.984132,
+ -3 + -0.549083,
+  7 + 0.946917,
+  1 + -0.817794,
+  3 + -0.902041,
+ -7 + 0.667457,
+  7 + 0.476978,
+ -1 + 0.864841,
+ -1 + -0.100561,
+ -1 + 0.589944,
+  1 + -0.417731,
+ -5 + -0.291668,
+  3 + -0.341364,
+  1 + -0.116372,
+ -5 + -0.678389,
+  5 + -0.621016,
+ -7 + -0.557662,
+  5 + -0.916104,
+  1 + 0.416737,
+ -3 + -0.397013,
+  3 + -0.767577,
+  1 + 0.340769,
+  7 + -0.54333,
+ -5 + 0.825698,
+ -7 + -0.0227328,
+  1 + 0.688705,
+ -5 + 0.783876,
+ -5 + 0.36354,
+  3 + -0.405894,
+ -1 + -0.505203,
+  3 + -0.280375,
+ -7 + -0.0717587,
+ -5 + 0.254936,
+ -5 + -0.792482,
+  7 + -0.425804,
+  3 + 0.295604,
+ -5 + 0.294844,
+ -3 + 0.730185,
+  3 + 0.0271969,
+  5 + -0.303161,
+ -3 + 0.883759,
+  3 + 0.827756,
+ -7 + 0.450664,
+  5 + 0.435759,
+  3 + 0.360285,
+ -7 + 0.409698,
+  1 + 0.230758,
+  7 + -0.352144,
+  1 + -0.389721,
+  7 + -0.718911,
+  3 + 0.41957,
+ -3 + 0.620353,
+ -7 + 0.254944,
+ -1 + 0.81995,
+  3 + -0.280774,
+  3 + 0.906947,
+  7 + -0.349169,
+ -1 + -0.00793728,
+ -5 + -0.64104,
+ -7 + 0.445183,
+  3 + 0.914473,
+  3 + -0.570084,
+ -1 + 0.594879,
+ -5 + -0.521969,
+  1 + 0.0416743,
+ -3 + -0.799298,
+  5 + -0.041766,
+ -7 + -0.218755,
+  1 + 0.173665,
+  7 + -0.880771,
+ -7 + 0.339146,
+ -1 + 0.961946,
+  1 + 0.859441,
+ -5 + 0.0599979,
+ -3 + -0.243646,
+  1 + 0.642304,
+  5 + 0.427633,
+ -3 + 0.337803,
+  5 + -0.876868,
+ -5 + 0.124084,
+  7 + -0.390476,
+  5 + -0.889517,
+  7 + -0.0881519,
+ -5 + -0.985327,
+ -1 + 0.364205,
+ -1 + 0.481156,
+  1 + 0.878136,
+  3 + 0.270873,
+ -1 + -0.133771,
+  7 + -0.599314,
+  7 + 0.784159,
+  1 + 0.555296,
+  7 + -0.974226,
+  5 + 0.520163,
+ -5 + 0.046348,
+ -5 + -0.487602,
+  3 + 0.0383354,
+ -7 + -0.969134,
+  5 + -0.00830264,
+  5 + 0.582434,
+ -5 + 0.498667,
+ -5 + 0.0475678,
+  7 + -0.011481,
+ -5 + 0.0134767,
+  1 + 0.897857,
+ -1 + 0.859261,
+  3 + -0.741447,
+ -5 + 0.61813,
+  3 + 0.976057,
+ -5 + 0.671342,
+ -1 + -0.480269,
+ -7 + -0.183415,
+  3 + -0.955847,
+  3 + 0.770801,
+ -3 + 0.470981,
+ -7 + -0.778816,
+  3 + -0.906343,
+ -1 + -0.727997,
+  7 + -0.39431,
+  7 + 0.80919,
+  7 + -0.973433,
+ -3 + -0.627311,
+  3 + 0.373299,
+  5 + 0.907636,
+ -5 + 0.658848,
+  7 + 0.681815,
+  5 + 0.589045,
+ -5 + 0.0950571,
+ -7 + 0.112081,
+  5 + 0.34511,
+ -3 + 0.315859,
+  5 + -0.181386,
+ -3 + -0.714938,
+  1 + 0.308135,
+  7 + 0.535557,
+  7 + -0.0709868,
+ -1 + 0.552407,
+ -7 + -0.847801,
+  7 + 0.160415,
+  5 + -0.51117,
+  3 + -0.951139,
+ -3 + 0.0406191,
+  5 + -0.895575,
+  5 + 0.0746354,
+ -3 + 0.915248,
+ -3 + 0.842174,
+ -7 + 0.595946,
+  3 + 0.700337,
+ -3 + -0.23779,
+  3 + -0.655733,
+ -5 + -0.894634,
+ -3 + -0.695807,
+  5 + -0.476673,
+  7 + -0.279169,
+ -5 + 0.507948,
+ -5 + 0.499507,
+  3 + 0.0916842,
+  3 + -0.837399,
+ -5 + 0.143527,
+  3 + 0.58052,
+ -7 + 0.378768,
+  5 + 0.811361,
+ -1 + 0.0748057,
+  3 + 0.453959,
+ -7 + 0.990606,
+  3 + -0.450379,
+  5 + 0.395584,
+ -7 + -0.114441,
+  5 + 0.426232,
+  1 + -0.711673,
+  1 + 0.077825,
+ -5 + -0.584918,
+  1 + -0.457057,
+ -3 + -0.366392,
+ -7 + 0.00484131,
+ -3 + 0.215838,
+ -3 + -0.19239,
+ -5 + 0.300349,
+  5 + 0.925702,
+  7 + 0.693147,
+ -3 + -0.771327,
+  7 + 0.850479,
+  7 + 0.55379,
+ -5 + -0.622361,
+ -7 + -0.797468,
+ -1 + 0.865325,
+ -1 + 0.594149,
+ -3 + 0.402537,
+  3 + 0.5647,
+ -5 + 0.408661,
+  7 + 0.434393,
+ -5 + 0.369053,
+  7 + 0.193313,
+  7 + 0.0768285,
+ -5 + -0.966767,
+  7 + 0.316068,
+  5 + 0.393416,
+ -1 + 0.678055,
+ -1 + -0.426397,
+  7 + -0.0972791,
+  5 + 0.863534,
+  7 + 0.857534,
+  3 + -0.591288,
+ -1 + -0.978807,
+ -5 + 0.47735,
+  1 + -0.387742,
+  7 + 0.418231,
+ -7 + -0.918646,
+  3 + -0.487032,
+ -7 + 0.169229,
+  5 + 0.963037,
+  3 + -0.651308,
+  1 + -0.963926,
+ -7 + -0.870113,
+ -1 + -0.598625,
+  1 + 0.578904,
+ -1 + -0.0948276,
+ -5 + 0.227649,
+  1 + 0.555606,
+ -1 + -0.668322,
+  1 + 0.0749024,
+ -5 + -0.607571,
+  5 + -0.349931,
+ -1 + -0.898107,
+  5 + 0.312465,
+  7 + 0.772347,
+  5 + 0.0899041,
+ -1 + -0.741034,
+ -3 + 0.26158,
+  1 + -0.539694,
+  7 + -0.115106,
+ -1 + -0.411724,
+  3 + 0.0316011,
+ -7 + -0.810337,
+ -5 + 0.181813,
+  5 + 0.318575,
+ -5 + -0.176396,
+ -1 + -0.639559,
+  1 + 0.966577,
+  7 + -0.685124,
+ -3 + -0.036449,
+ -5 + -0.456288,
+ -1 + 0.80942,
+  1 + -0.842449,
+ -7 + 0.390273,
+  3 + -0.931459,
+  5 + 0.693488,
+ -7 + 0.247743,
+ -3 + -0.848713,
+ -3 + 0.137249,
+ -7 + -0.213185,
+ -7 + -0.755191,
+  7 + -0.639001,
+  5 + 0.91416,
+  5 + -0.193425,
+ -5 + 0.80731,
+ -1 + -0.716912,
+  5 + -0.503475,
+  5 + -0.0585372,
+  5 + -0.0209306,
+  5 + -0.150028,
+ -3 + 0.634776,
+  5 + 0.538764,
+  7 + 0.704398,
+ -1 + -0.61061,
+ -7 + -0.624288,
+  1 + -0.926651,
+ -7 + 0.580724,
+  3 + 0.24162,
+  1 + 0.447202,
+  7 + -0.76537,
+  7 + -0.753749,
+  7 + -0.93289,
+  7 + 0.570568,
+ -1 + 0.901893,
+ -1 + -0.297356,
+  5 + -0.189813,
+ -3 + 0.21001,
+ -3 + 0.541859,
+ -5 + -0.73421,
+  7 + 0.928552,
+ -7 + -0.355678,
+ -5 + -0.221657,
+ -5 + -0.0512875,
+  3 + -0.298442,
+ -1 + -0.820576,
+  7 + -0.771328,
+  1 + -0.961217,
+  5 + -0.161851,
+ -1 + -0.405209,
+  3 + -0.662432,
+ -3 + 0.528404,
+  1 + -0.226934,
+ -3 + 0.0363932,
+  7 + 0.886687,
+  3 + 0.393918,
+ -5 + -0.507128,
+  1 + -0.189558,
+ -7 + -0.823271,
+  7 + -0.180617,
+ -1 + 0.321553,
+ -1 + 0.989206,
+ -7 + -0.874277,
+  1 + -0.113906,
+  7 + 0.161257,
+  3 + 0.670416,
+ -3 + -0.763578,
+ -1 + 0.424893,
+  3 + -0.0447045,
+ -5 + -0.957789,
+ -1 + 0.196626,
+ -5 + 0.00535004,
+  3 + 0.254757,
+ -7 + -0.927024,
+  3 + -0.959979,
+  1 + -0.949363,
+ -5 + 0.674222,
+  1 + -0.848884,
+ -7 + 0.0919615,
+  1 + -0.58394,
+ -1 + -0.515551,
+ -7 + -0.961024,
+  7 + -0.978422,
+  7 + 0.86705,
+  7 + -0.323448,
+ -5 + -0.916549,
+ -3 + -0.512443,
+ -3 + -0.892435,
+ -1 + 0.0811992,
+  7 + -0.1951,
+  1 + -0.31832,
+  7 + 0.389861,
+ -7 + -0.429737,
+  7 + 0.14079,
+ -7 + -0.306634,
+  1 + -0.0533624,
+  1 + -0.438584,
+ -7 + -0.63111,
+ -7 + -0.559344,
+ -5 + 0.783094,
+ -7 + -0.735777,
+  7 + -0.58636,
+ -7 + -0.116192,
+ -5 + -0.801831,
+ -5 + 0.969511,
+ -5 + 0.144718,
+ -5 + 0.363059,
+ -1 + -0.667404,
+  3 + -0.134134,
+ -1 + 0.734085,
+  5 + -0.165216,
+  1 + 0.149468,
+ -5 + -0.15301,
+ -3 + 0.83035,
+ -3 + -0.27281,
+ -1 + 0.688733,
+  5 + -0.406828,
+ -5 + -0.018298,
+  5 + 0.219722,
+ -5 + 0.840822,
+ -7 + 0.256695,
+ -1 + -0.300632,
+ -5 + 0.403999,
+ -5 + 0.574885,
+ -3 + -0.92988,
+  1 + -0.837794,
+  3 + 0.510347,
+  1 + 0.946242,
+  1 + -0.558269,
+  7 + -0.945935,
+ -7 + -0.106771,
+  3 + -0.383966,
+ -5 + 0.370004,
+ -7 + 0.428693,
+  5 + 0.936122,
+  1 + -0.782085,
+ -7 + 0.528864,
+  1 + 0.697761,
+ -7 + -0.681381,
+ -5 + 0.152231,
+  5 + -0.900638,
+  5 + -0.334353,
+  1 + 0.862458,
+ -5 + -0.694343,
+ -7 + -0.938721,
+ -5 + 0.119729,
+ -7 + -0.874769,
+ -5 + -0.120494,
+ -3 + 0.506938,
+  5 + 0.965172,
+ -1 + -0.888394,
+ -3 + -0.595798,
+ -5 + 0.802503,
+ -3 + -0.789257,
+ -3 + 0.351862,
+  3 + -0.750966,
+ -1 + 0.584273,
+ -3 + -0.0831131,
+ -7 + -0.28384,
+ -3 + 0.806411,
+  7 + -0.200101,
+  3 + 0.640918,
+ -1 + 0.977479,
+  1 + 0.865009,
+ -3 + -0.368203,
+  7 + 0.556652,
+ -1 + -0.991885,
+ -5 + 0.332904,
+  3 + 0.470344,
+ -7 + 0.205081,
+ -7 + -0.314842,
+ -3 + -0.62,
+  3 + 0.34363,
+  1 + -0.425907,
+ -7 + -0.702084,
+ -3 + -0.288143,
+ -7 + 0.243932,
+ -1 + 0.0855131,
+ -5 + -0.139345,
+  3 + -0.959163,
+  3 + 0.431497,
+ -7 + 0.261823,
+ -3 + 0.914225,
+ -1 + 0.325961,
+  3 + -0.359881,
+  7 + -0.468639,
+  7 + -0.803865,
+ -1 + 0.343444,
+  1 + 0.736499,
+  5 + 0.382909,
+ -1 + -0.721058,
+ -1 + -0.823382,
+  3 + -0.176144,
+  5 + 0.251272,
+ -1 + -0.786581,
+ -5 + 0.273133,
+  7 + -0.41622,
+  3 + 0.121719,
+  7 + 0.620911,
+ -1 + 0.237504,
+  1 + -0.335624,
+ -7 + 0.42324,
+ -3 + 0.729575,
+ -7 + -0.723781,
+  3 + 0.273075,
+  3 + -0.229695,
+  3 + 0.507748,
+ -5 + 0.294614,
+ -7 + -0.490011,
+  3 + 0.297713,
+ -3 + -0.330685,
+ -7 + 0.441233,
+  5 + -0.622061,
+  5 + -0.208099,
+  5 + -0.710362,
+ -1 + 0.154774,
+ -5 + 0.486696,
+  5 + -0.168477,
+  7 + -0.653855,
+  7 + -0.0172002,
+ -1 + -0.1059,
+  3 + 0.654305,
+  1 + -0.459053,
+  7 + 0.751362,
+  7 + 0.407269,
+  7 + 0.871658,
+  7 + 0.654213,
+  7 + 0.0624889,
+  7 + -0.583527,
+  1 + -0.252231,
+  1 + -0.320237,
+  5 + -0.0136125,
+  7 + -0.729181,
+ -5 + -0.0353086,
+  5 + -0.0951113,
+  3 + -0.0836304,
+ -1 + -0.11923,
+  7 + 0.962136,
+ -5 + -0.830669,
+  1 + 0.29644,
+  5 + 0.045498,
+  1 + 0.76292,
+ -5 + -0.929796,
+  5 + -0.083544,
+ -7 + 0.472663,
+  7 + -0.746787,
+  3 + 0.662228,
+ -5 + -0.41748,
+ -7 + 0.850784,
+ -7 + -0.130054,
+ -1 + 0.432904,
+  7 + -0.787268,
+ -3 + -0.248262,
+  5 + 0.406222,
+  5 + -0.775207,
+  7 + -0.0549824,
+ -1 + 0.930082,
+ -3 + 0.651628,
+ -7 + -0.373963,
+  7 + -0.38767,
+ -5 + -0.199335,
+  3 + -0.0845591,
+ -3 + -0.400573,
+ -1 + -0.423932,
+  3 + 0.496079,
+  3 + -0.0049753,
+  5 + -0.937373,
+ -1 + 0.00805519,
+  7 + -0.387026,
+ -7 + 0.379173,
+  3 + -0.509631,
+ -3 + 0.0652572,
+ -7 + 0.292195,
+ -3 + -0.0630124,
+ -3 + 0.210706,
+ -7 + 0.0474516,
+ -3 + 0.088253,
+  5 + -0.729131,
+ -1 + -0.118407,
+  5 + 0.587638,
+ -7 + 0.963741,
+ -3 + 0.912494,
+ -7 + 0.723939,
+  5 + 0.977461,
+  3 + 0.230908,
+ -7 + 0.0875093,
+ -5 + 0.827526,
+  7 + -0.821136,
+ -3 + 0.402932,
+ -7 + 0.441547,
+  7 + 0.416953,
+  5 + 0.70044,
+  3 + 0.973559,
+  3 + 0.407091,
+ -5 + -0.826277,
+  3 + -0.389221,
+  5 + -0.583906,
+  1 + -0.0841909,
+ -7 + 0.530444,
+ -1 + -0.918261,
+  3 + -0.638232,
+  1 + -0.776938,
+ -7 + 0.706762,
+ -1 + 0.16429,
+ -7 + -0.306863,
+ -3 + -0.670615,
+  1 + -0.819745,
+  1 + -0.014878,
+ -3 + 0.178679,
+  1 + 0.441678,
+ -1 + -0.193108,
+ -3 + -0.33399,
+  5 + 0.275276,
+ -7 + 0.167054,
+ -5 + 0.134306,
+  7 + -0.394252,
+  3 + 0.941986,
+ -7 + -0.878877,
+ -5 + 0.770656,
+ -5 + 0.730814,
+ -1 + 0.143592,
+ -3 + 0.442492,
+ -1 + -0.712593,
+  5 + 0.599122,
+  1 + 0.263907,
+ -7 + 0.47737,
+ -7 + 0.0559669,
+ -3 + 0.208639,
+  1 + 0.827161,
+  1 + 0.886639,
+  1 + 0.598246,
+ -7 + -0.191541,
+  3 + 0.511962,
+  3 + -0.645528,
+  1 + -0.593154,
+ -5 + 0.52999,
+  5 + -0.653963,
+  1 + 0.574099,
+ -5 + -0.0896155,
+  1 + -0.636268,
+  7 + 0.343794,
+ -7 + 0.155548,
+ -1 + -0.121609,
+ -1 + -0.297629,
+ -5 + -0.468962,
+  5 + -0.555227,
+ -1 + -0.296793,
+ -3 + -0.855934,
+  7 + -0.739775,
+  1 + -0.756048,
+  1 + -0.46236,
+ -7 + -0.179736,
+  3 + 0.125628,
+  1 + 0.10038,
+ -5 + -0.380856,
+  7 + 0.450066,
+  7 + 0.959734,
+ -3 + 0.796831,
+ -1 + 0.23315,
+ -3 + 0.298099,
+ -5 + -0.383893,
+ -3 + -0.296636,
+ -5 + 0.138614,
+  1 + -0.114746,
+  7 + 0.555051,
+  1 + -0.950471,
+ -1 + 0.124465,
+  1 + 0.037862,
+  1 + 0.719934,
+  7 + -0.0167727,
+ -7 + -0.983453,
+ -5 + -0.418557,
+  7 + -0.192828,
+  7 + -0.0814223,
+  1 + 0.224621,
+  5 + -0.597524,
+  5 + 0.415634,
+  1 + -0.954608,
+ -3 + 0.227498,
+ -5 + -0.108549,
+  7 + 0.0881721,
+  3 + 0.845206,
+  3 + -0.913562,
+ -7 + 0.24586,
+ -7 + 0.289418,
+ -1 + 0.194941,
+  3 + 0.793157,
+  7 + -0.434518,
+ -7 + 0.820917,
+  5 + 0.2382,
+  5 + -0.946464,
+  1 + 0.686291,
+  3 + -0.265611,
+ -1 + -0.215793,
+  1 + 0.247293,
+  3 + 0.370775,
+ -1 + -0.1934,
+  5 + 0.306202,
+  5 + -0.454743,
+ -1 + -0.529622,
+  1 + 0.856026,
+ -5 + -0.672594,
+ -5 + -0.429688,
+  7 + -0.898493,
+  3 + -0.296784,
+ -7 + -0.839249,
+  7 + -0.238149,
+ -3 + 0.87197,
+  7 + -0.985437,
+ -3 + 0.243879,
+  1 + -0.0590569,
+ -7 + 0.3087,
+ -7 + -0.415904,
+ -3 + 0.238146,
+ -3 + -0.00380364,
+  7 + -0.524692,
+ -1 + 0.715206,
+ -1 + -0.382632,
+  7 + -0.433315,
+ -3 + 0.671116,
+  5 + 0.319951,
+ -5 + -0.467809,
+  1 + -0.914862,
+ -1 + -0.848039,
+ -7 + 0.916399,
+ -3 + 0.158824,
+ -7 + 0.432194,
+  5 + 0.939947,
+ -3 + -0.938313,
+ -1 + 0.111712,
+  1 + -0.830159,
+ -1 + 0.269145,
+ -3 + -0.282773,
+ -7 + 0.397815,
+ -7 + 0.312644,
+  7 + 0.101858,
+  5 + 0.398991,
+  7 + 0.931748,
+  5 + -0.216404,
+  5 + -0.739909,
+ -3 + 0.837449,
+  5 + -0.292918,
+  3 + -0.811216,
+  3 + -0.54535,
+  3 + -0.206546,
+  7 + 0.287012,
+  5 + 0.416343,
+ -7 + 0.226965,
+  3 + 0.650639,
+  7 + -0.513567,
+  3 + 0.35494,
+  7 + 0.251297,
+  3 + 0.222854,
+ -3 + 0.631017,
+  1 + -0.834925,
+ -5 + 0.302606,
+  5 + -0.161238,
+ -1 + -0.717755,
+ -1 + 0.163733,
+  7 + 0.683634,
+ -3 + -0.0890416,
+  5 + -0.0241376,
+ -7 + -0.331885,
+ -1 + -0.566607,
+  5 + -0.0680727,
+ -1 + 0.69374,
+ -5 + -0.441671,
+  3 + -0.917287,
+  5 + -0.447226,
+  5 + 0.530121,
+  3 + -0.393156,
+  7 + -0.625747,
+  1 + 0.660945,
+  1 + 0.0093144,
+  7 + -0.198812,
+  5 + 0.442133,
+  1 + -0.569587,
+ -1 + 0.969233,
+ -3 + 0.831887,
+  7 + -0.129281,
+ -5 + 0.790104,
+ -3 + -0.329582,
+  3 + -0.846209,
+  5 + 0.921283,
+  5 + 0.0625507,
+ -3 + 0.292014,
+ -5 + 0.833173,
+ -7 + -0.674783,
+ -3 + -0.846611,
+  1 + 0.893338,
+ -7 + 0.983207,
+ -7 + -0.776993,
+ -7 + 0.250987,
+ -5 + 0.0683537,
+  7 + -0.183423,
+  1 + -0.0923144,
+  3 + 0.316882,
+  3 + 0.436083,
+ -1 + 0.561959,
+  5 + 0.199397,
+  3 + 0.998894,
+ -5 + -0.762317,
+  1 + -0.264652,
+ -1 + 0.000935957,
+ -5 + -0.737429,
+  5 + -0.449802,
+ -3 + -0.153005,
+ -7 + -0.825486,
+ -3 + 0.381528,
+ -3 + -0.834704,
+  1 + -0.869081,
+ -5 + 0.658949,
+ -7 + 0.538412,
+  1 + -0.274676,
+ -3 + -0.131948,
+ -5 + -0.89239,
+  5 + -0.216419,
+  5 + 0.0464617,
+ -5 + -0.202859,
+ -5 + 0.937449,
+  5 + 0.424624,
+  1 + 0.22882,
+  7 + 0.683182,
+  1 + -0.649762,
+  3 + -0.764787,
+  7 + -0.573145,
+ -5 + 0.304541,
+  3 + 0.3929,
+ -7 + -0.210616,
+ -3 + 0.373165,
+ -7 + -0.21229,
+ -7 + 0.897832,
+ -7 + 0.909656,
+  1 + 0.948898,
+  3 + -0.42523,
+  3 + 0.567772,
+ -3 + -0.527982,
+  3 + -0.189502,
+  5 + 0.970517,
+  7 + 0.282051,
+ -3 + 0.430664,
+  3 + -0.793949,
+ -7 + 0.545716,
+ -3 + 0.35154,
+ -3 + -0.821351,
+  5 + -0.395689,
+ -5 + -0.620034,
+  5 + -0.608408,
+ -3 + 0.94029,
+ -1 + 0.0666049,
+  5 + -0.51607,
+  1 + 0.991041,
+  7 + 0.172753,
+  5 + -0.0221328,
+  5 + -0.193889,
+ -5 + -0.13076,
+  3 + 0.138734,
+  3 + 0.59089,
+  3 + -0.887206,
+ -3 + 0.845891,
+ -1 + -0.347074,
+  5 + -0.0834612,
+  3 + -0.876824,
+ -1 + -0.810422,
+ -1 + -0.231434,
+  1 + -0.239487,
+ -5 + 0.0323537,
+  1 + -0.581238,
+  5 + 0.00602403,
+  5 + 0.0905542,
+  3 + 0.498012,
+ -5 + 0.254225,
+  3 + 0.314102,
+  5 + 0.0299345,
+  5 + -0.45939,
+ -1 + 0.448653,
+ -3 + 0.647585,
+  1 + 0.318478,
+  5 + 0.455767,
+ -1 + 0.133022,
+  1 + 0.614847,
+  1 + 0.120892,
+ -5 + 0.224634,
+  5 + 0.132055,
+ -1 + 0.743952,
+ -5 + 0.425553,
+  5 + -0.111105,
+  1 + 0.174118,
+  1 + 0.221772,
+ -7 + -0.845315,
+ -3 + 0.19196,
+  7 + -0.840461,
+  5 + -0.129635,
+  1 + -0.596764,
+  3 + -0.955832,
+  1 + 0.585824,
+  5 + 0.0742671,
+  5 + -0.517633,
+ -1 + 0.48289,
+  7 + 0.0644312,
+  1 + -0.795109,
+ -7 + -0.782286,
+ -1 + 0.0230929,
+  1 + -0.718512,
+ -1 + 0.764088,
+  5 + 0.510258,
+ -5 + 0.657883,
+ -7 + -0.345766,
+ -3 + 0.430414,
+  5 + 0.0833478,
+ -5 + -0.264892,
+  3 + 0.710985,
+  1 + 0.150336,
+  5 + -0.861506,
+  3 + -0.0429562,
+ -1 + 0.434927,
+  7 + 0.815823,
+ -5 + -0.824405,
+  7 + -0.262346,
+ -7 + -0.164051,
+ -5 + -0.646918,
+  3 + -0.147091,
+  3 + 0.13859,
+ -1 + -0.575533,
+ -3 + 0.103353,
+ -5 + 0.992246,
+ -1 + -0.611302,
+  7 + -0.0318776,
+  1 + 0.460203,
+ -3 + 0.548152,
+ -7 + 0.0172631,
+ -3 + -0.485489,
+ -7 + -0.980713,
+ -7 + -0.827265,
+ -1 + -0.864176,
+ -7 + 0.851271,
+  7 + -0.466744,
+ -7 + 0.436088,
+ -3 + 0.576107,
+ -7 + -0.637538,
+  7 + 0.655137,
+  5 + -0.826798,
+ -5 + 0.848056,
+  3 + 0.666798,
+ -1 + -0.180115,
+  7 + 0.419637,
+  5 + -0.0167801,
+  3 + -0.68837,
+  3 + 0.946745,
+  3 + -0.0950071,
+ -7 + -0.827281,
+ -1 + 0.78343,
+ -5 + -0.582113,
+  7 + 0.299523,
+  1 + -0.488113,
+  5 + -0.341736,
+  7 + 0.530617,
+  7 + -0.326339,
+ -7 + -0.817531,
+ -3 + -0.221869,
+ -5 + 0.416757,
+  1 + 0.506333,
+  1 + -0.2654,
+  7 + 0.763487,
+ -5 + -0.943085,
+  7 + 0.791527,
+ -5 + 0.0668543,
+ -7 + 0.938847,
+ -3 + 0.143887,
+ -3 + 0.381707,
+ -3 + 0.19505,
+ -3 + -0.920517,
+ -5 + 0.145063,
+ -5 + 0.237513,
+ -7 + -0.120207,
+ -7 + -0.0991134,
+ -5 + 0.0680013,
+  1 + -0.0638738,
+  5 + 0.970159,
+  5 + 0.213576,
+  1 + -0.263613,
+ -7 + -0.544301,
+ -5 + -0.828692,
+ -5 + 0.166918,
+ -5 + -0.761728,
+  5 + 0.120694,
+  5 + 0.903705,
+ -5 + 0.211521,
+  3 + 0.290967,
+  7 + -0.464751,
+ -7 + 0.186847,
+  7 + 0.32524,
+ -7 + 0.111797,
+  1 + -0.788556,
+  1 + -0.14745,
+ -3 + -0.968889,
+  3 + -0.37981,
+  5 + 0.00729347,
+  7 + 0.504821,
+  1 + -0.961113,
+  3 + 0.710415,
+ -5 + -0.613475,
+  5 + -0.895771,
+ -1 + -0.895503,
+  5 + -0.461719,
+  5 + 0.0161815,
+ -5 + -0.24625,
+ -7 + -0.572922,
+ -1 + -0.459816,
+  7 + -0.419624,
+ -5 + 0.696952,
+ -5 + 0.927165,
+ -5 + 0.243638,
+  7 + 0.360799,
+  3 + 0.347879,
+ -3 + -0.0232377,
+  3 + 0.712201,
+ -1 + 0.759489,
+ -7 + 0.438561,
+ -7 + -0.572822,
+  1 + -0.737766,
+  3 + 0.0680258,
+ -1 + 0.686509,
+  5 + -0.262713,
+ -5 + -0.79966,
+  5 + -0.236232,
+ -7 + -0.0260004,
+ -7 + 0.218216,
+ -3 + 0.370607,
+  3 + 0.816354,
+  7 + 0.452291,
+ -3 + -0.822625,
+  3 + 0.848817,
+  7 + 0.365835,
+  1 + -0.676283,
+  1 + -0.0594598,
+ -5 + 0.521534,
+  1 + -0.486592,
+  7 + -0.986362,
+ -7 + 0.0779941,
+ -3 + -0.08751,
+  7 + -0.491647,
+  7 + -0.270531,
+ -1 + -0.204778,
+  1 + -0.231377,
+ -7 + -0.469895,
+ -1 + -0.844354,
+ -7 + -0.264911,
+ -1 + -0.1599,
+ -7 + -0.44972,
+ -1 + 0.194789,
+  1 + -0.104809,
+  3 + -0.228419,
+ -7 + -0.803297,
+ -7 + 0.625464,
+ -1 + -0.352292,
+ -1 + -0.755153,
+ -1 + -0.67635,
+  7 + 0.297913,
+  5 + 0.57017,
+  5 + -0.173484,
+  5 + 0.668881,
+  1 + 0.277459,
+ -3 + -0.784868,
+  5 + -0.499577,
+  3 + -0.10745,
+  7 + 0.92074,
+ -3 + -0.987991,
+  7 + 0.915782,
+  3 + -0.98239,
+  1 + -0.781632,
+ -5 + 0.853114,
+  5 + -0.13405,
+ -5 + 0.870097,
+  7 + -0.696323,
+  7 + -0.94934,
+ -3 + -0.398685,
+ -7 + 0.869119,
+ -5 + -0.903581,
+ -7 + 0.131423,
+ -3 + 0.834563,
+  7 + 0.143985,
+  3 + 0.145958,
+ -3 + 0.536994,
+ -5 + -0.691582,
+  5 + 0.556042,
+  7 + -0.58014,
+ -5 + -0.103551,
+ -1 + 0.15221,
+  3 + -0.757364,
+ -5 + 0.580815,
+  5 + 0.852026,
+ -7 + -0.470408,
+ -3 + 0.0561844,
+  5 + -0.515549,
+  1 + 0.173103,
+ -3 + -0.168945,
+  5 + -0.762956,
+ -3 + 0.793081,
+ -1 + -0.676991,
+  3 + 0.665824,
+  5 + 0.121066,
+ -5 + 0.731384,
+ -5 + 0.671191,
+ -7 + -0.175862,
+ -7 + 0.486734,
+  5 + 0.163906,
+ -3 + -0.529629,
+ -3 + -0.741516,
+ -5 + 0.780671,
+ -7 + -0.230291,
+ -3 + 0.302234,
+  7 + -0.987584,
+ -7 + 0.429419,
+  7 + -0.123349,
+ -3 + -0.693596,
+  1 + 0.156304,
+ -7 + -0.070418,
+ -5 + 0.939389,
+  3 + -0.282077,
+  7 + -0.461724,
+ -7 + -0.266467,
+ -3 + 0.973726,
+  5 + 0.324534,
+  1 + 0.798357,
+ -3 + -0.225007,
+ -3 + 0.326469,
+  1 + 0.217389,
+ -7 + 0.771884,
+  1 + -0.448262,
+  1 + 0.834186,
+  5 + -0.8447,
+  7 + 0.265382,
+  7 + 0.882236,
+  7 + 0.951853,
+  3 + -0.212489,
+  7 + -0.900493,
+ -1 + 0.827988,
+  5 + -0.96957,
+  5 + -0.794382,
+  1 + -0.360357,
+ -7 + 0.686111,
+ -5 + -0.770717,
+ -3 + 0.777591,
+  1 + -0.164214,
+ -1 + 0.85202,
+ -1 + -0.838606,
+  5 + 0.727194,
+  3 + 0.628267,
+  3 + 0.94657,
+  3 + 0.664833,
+ -1 + -0.545169,
+  1 + -0.791937,
+  5 + -0.863989,
+  1 + -0.433051,
+  7 + 0.604505,
+ -5 + 0.469176,
+  5 + 0.521661,
+  5 + -0.652277,
+  5 + -0.956757,
+ -1 + 0.179364,
+  3 + 0.0835185,
+  5 + 0.379708,
+ -5 + -0.00418501,
+ -3 + 0.802623,
+ -1 + 0.127959,
+  3 + 0.740128,
+  7 + 0.0877058,
+ -3 + -0.644691,
+ -7 + 0.803557,
+ -3 + 0.35763,
+  7 + -0.896354,
+  5 + -0.985988,
+ -5 + -0.475576,
+ -7 + -0.837911,
+ -5 + 0.399102,
+ -1 + 0.180557,
+  7 + -0.257409,
+ -3 + 0.748304,
+  1 + 0.488153,
+  1 + -0.528074,
+ -7 + -0.568786,
+ -1 + -0.209861,
+  7 + 0.758874,
+ -7 + 0.690599,
+ -5 + 0.29666,
+ -7 + 0.14263,
+ -5 + -0.580595,
+ -5 + 0.436222,
+ -7 + -0.230854,
+  1 + -0.0199466,
+  7 + 0.0582533,
+  1 + -0.241347,
+ -7 + 0.120772,
+ -5 + 0.158568,
+ -7 + 0.590528,
+  1 + 0.26066,
+  7 + 0.696681,
+ -3 + 0.343628,
+ -1 + -0.341235,
+ -1 + 0.426748,
+ -5 + -0.39029,
+ -3 + 0.0793041,
+ -1 + 0.240872,
+ -7 + -0.986816,
+  5 + -0.546091,
+  7 + -0.435825,
+ -5 + 0.631116,
+  5 + 0.793044,
+ -3 + -0.219459,
+  7 + 0.140597,
+  5 + 0.447243,
+  1 + -0.968491,
+  5 + 0.843524,
+ -5 + -0.860415,
+  5 + -0.620946,
+  1 + -0.41902,
+  7 + -0.81125,
+  5 + 0.753432,
+ -3 + -0.727435,
+ -1 + -0.141588,
+ -3 + -0.551413,
+ -5 + 0.381663,
+  5 + -0.0711982,
+ -5 + 0.390526,
+  1 + 0.783724,
+ -7 + 0.573399,
+ -3 + -0.939007,
+ -7 + 0.238314,
+ -1 + -0.521158,
+  5 + 0.779281,
+ -7 + -0.53298,
+  3 + 0.21555,
+  3 + 0.482487,
+  7 + -0.514751,
+ -1 + -0.800237,
+  1 + -0.764197,
+ -3 + 0.647617,
+  7 + 0.0499004,
+ -5 + 0.979748,
+ -3 + 0.67735,
+ -7 + 0.183253,
+ -5 + 0.362151,
+  5 + -0.545888,
+  3 + 0.771438,
+ -3 + 0.255733,
+ -7 + 0.115492,
+  3 + 0.469995,
+ -1 + 0.129762,
+  3 + -0.767167,
+ -1 + 0.59735,
+ -7 + 0.999858,
+ -5 + -0.412252,
+ -5 + -0.240744,
+ -7 + -0.94988,
+  7 + -0.533656,
+  3 + 0.842152,
+  5 + -0.0103345,
+  7 + 0.0454008,
+  3 + 0.333439,
+  3 + -0.456548,
+ -3 + -0.295064,
+  1 + -0.0291067,
+  3 + -0.980701,
+  5 + 0.0998633,
+ -7 + -0.236756,
+ -1 + -0.209321,
+  3 + -0.238139,
+ -1 + 0.873939,
+  3 + -0.723713,
+ -5 + 0.814455,
+  3 + 0.679885,
+ -5 + -0.309287,
+  1 + 0.911921,
+ -5 + -0.330781,
+  5 + 0.780826,
+  1 + 0.715838,
+  3 + -0.334343,
+ -1 + 0.986761,
+ -1 + -0.439617,
+ -3 + -0.590452,
+  1 + -0.263775,
+  7 + 0.667562,
+ -5 + -0.76034,
+ -5 + 0.362745,
+  1 + -0.472352,
+ -7 + 0.206034,
+ -3 + 0.376895,
+  5 + 0.551758,
+ -3 + 0.0431443,
+  5 + -0.310862,
+ -3 + -0.430074,
+  5 + 0.275111,
+  7 + -0.912242,
+  5 + -0.535872,
+  3 + 0.320622,
+  3 + 0.381784,
+  5 + 0.39575,
+ -5 + 0.419947,
+ -1 + 0.632249,
+  7 + 0.699329,
+  5 + -0.53677,
+ -7 + 0.160241,
+  5 + -0.293807,
+ -5 + 0.291076,
+ -5 + 0.691705,
+  1 + 0.759055,
+  3 + -0.907042,
+ -5 + -0.23742,
+ -1 + -0.718808,
+ -3 + 0.324324,
+ -5 + 0.768603,
+ -1 + -0.765854,
+  3 + -0.270759,
+ -3 + -0.780064,
+  7 + 0.530695,
+  5 + -0.923683,
+ -1 + -0.209208,
+  5 + -0.3521,
+  7 + -0.81082,
+  7 + -0.472168,
+  7 + 0.56371,
+  5 + -0.87698,
+  3 + -0.0658053,
+ -3 + 0.646983,
+  1 + -0.603423,
+  7 + 0.458566,
+  7 + 0.32752,
+ -7 + 0.852152,
+  1 + 0.996179,
+ -1 + 0.686456,
+ -3 + -0.484814,
+  5 + -0.675017,
+  5 + -0.458211,
+  3 + -0.984357,
+ -1 + 0.266912,
+ -7 + -0.589247,
+ -5 + 0.082882,
+ -5 + -0.885084,
+ -3 + -0.560765,
+  5 + -0.942018,
+  7 + 0.572901,
+  7 + -0.171902,
+ -3 + 0.895929,
+ -7 + -0.655681,
+  5 + -0.029179,
+  1 + -0.978318,
+  1 + -0.0494022,
+ -3 + 0.315903,
+ -7 + -0.249841,
+  7 + -0.960858,
+ -3 + 0.444645,
+  3 + -0.725221,
+ -1 + -0.250617,
+  5 + 0.072717,
+  3 + -0.348692,
+ -7 + 0.465731,
+  7 + 0.770554,
+ -1 + 0.161133,
+  3 + 0.0440529,
+ -1 + -0.245592,
+ -1 + -0.286838,
+  1 + 0.710223,
+  7 + -0.744359,
+ -7 + 0.754745,
+ -3 + 0.268595,
+ -7 + -0.952184,
+  5 + -0.12754,
+  1 + -0.113531,
+  3 + -0.965244,
+  3 + -0.295564,
+  5 + -0.589246,
+ -5 + 0.901493,
+  7 + 0.499927,
+ -1 + 0.205479,
+ -1 + 0.799496,
+  7 + 0.159986,
+  1 + 0.0494691,
+  5 + 0.414586,
+  1 + 0.160234,
+  5 + -0.754135,
+  7 + 0.533292,
+  3 + 0.20959,
+ -3 + 0.265984,
+ -1 + -0.596171,
+ -3 + 0.59227,
+ -5 + 0.809165,
+ -3 + 0.731077,
+ -5 + 0.77249,
+ -3 + 0.114624,
+  7 + -0.612689,
+ -3 + -0.226237,
+ -1 + -0.491637,
+  5 + -0.902752,
+  7 + -0.340862,
+  7 + -0.764615,
+  1 + 0.361337,
+  5 + 0.907293,
+ -1 + -0.207671,
+ -7 + 0.749045,
+  7 + -0.736116,
+  7 + 0.331618,
+ -5 + -0.0821605,
+  3 + -0.784978,
+  3 + -0.962937,
+  5 + 0.0240877,
+ -7 + -0.357058,
+  7 + 0.582812,
+ -1 + 0.300038,
+  3 + 0.442207,
+  1 + 0.311886,
+  1 + -0.0907658,
+ -3 + -0.190202,
+  3 + 0.752307,
+ -5 + 0.110897,
+ -3 + -0.130689,
+  3 + 0.604778,
+ -5 + 0.832513,
+ -5 + 0.20769,
+  1 + 0.918947,
+  7 + 0.635097,
+ -3 + -0.250696,
+ -5 + -0.673562,
+ -7 + 0.188827,
+ -7 + 0.859836,
+ -5 + -0.553663,
+ -1 + -0.693482,
+ -3 + -0.0370091,
+ -5 + -0.945403,
+ -3 + -0.0942642,
+  5 + -0.788987,
+  7 + 0.130865,
+ -3 + -0.0568169,
+  1 + 0.469934,
+ -3 + 0.236228,
+ -3 + 0.969961,
+ -7 + 0.777844,
+ -1 + -0.863909,
+  1 + -0.0100366,
+  3 + -0.901984,
+  7 + -0.188674,
+ -3 + -0.0859814,
+ -7 + 0.289988,
+ -5 + 0.216434,
+  5 + 0.373371,
+ -3 + 0.756403,
+ -3 + -0.327696,
+ -1 + 0.500791,
+  5 + 0.577182,
+  1 + 0.846249,
+  7 + -0.851769,
+ -7 + 0.957447,
+ -3 + -0.351796,
+ -1 + -0.985339,
+ -7 + -0.840053,
+  7 + -0.911335,
+  3 + 0.856743,
+  3 + -0.901107,
+  3 + -0.966849,
+  7 + -0.885129,
+ -5 + -0.284155,
+  7 + -0.344691,
+ -5 + 0.355503,
+  7 + 0.752017,
+  5 + -0.243656,
+  3 + -0.928544,
+  5 + 0.782105,
+ -7 + -0.759649,
+  1 + -0.0744518,
+ -3 + 0.609258,
+  5 + -0.125631,
+  5 + 0.25112,
+ -7 + -0.339128,
+  7 + 0.412046,
+ -5 + 0.555857,
+  7 + -0.635087,
+  7 + 0.516426,
+ -1 + 0.74659,
+  3 + 0.969918,
+ -1 + 0.436694,
+ -5 + 0.0135384,
+ -3 + 0.340553,
+  1 + -0.333334,
+  5 + -0.401135,
+  3 + 0.217065,
+  5 + -0.585701,
+  7 + 0.283774,
+  1 + 0.436392,
+  7 + 0.636664,
+  5 + -0.0233952,
+  5 + 0.966634,
+ -5 + 0.792896,
+  5 + 0.946402,
+ -1 + -0.831078,
+ -7 + -0.944117,
+  7 + 0.832928,
+ -3 + -0.37542,
+ -7 + -0.951767,
+ -7 + -0.414159,
+  3 + -0.440777,
+  5 + -0.591346,
+ -3 + -0.942129,
+  1 + -0.475855,
+ -1 + -0.452418,
+ -7 + 0.0502203,
+ -1 + -0.715986,
+  5 + -0.39207,
+ -1 + 0.00692897,
+  1 + -0.305166,
+ -3 + -0.469096,
+ -1 + 0.214434,
+ -7 + 0.0882326,
+ -7 + -0.311931,
+  7 + 0.289892,
+  5 + 0.529032,
+ -3 + 0.543897,
+ -7 + 0.734108,
+  5 + 0.760244,
+  7 + -0.921361,
+ -7 + -0.499923,
+  5 + 0.932586,
+  3 + -0.492252,
+ -5 + 0.29961,
+  3 + 0.40997,
+  1 + 0.607012,
+ -1 + 0.0977883,
+  7 + -0.666918,
+  1 + 0.092606,
+ -3 + 0.48582,
+ -7 + -0.413194,
+ -1 + 0.657655,
+  7 + -0.790176,
+  3 + -0.79396,
+  5 + -0.401432,
+  3 + 0.241941,
+ -7 + -0.0372352,
+  1 + -0.422785,
+ -7 + 0.412112,
+  3 + -0.649941,
+  5 + -0.885332,
+ -1 + 0.918587,
+  5 + 0.580861,
+  5 + -0.56943,
+  7 + -0.313623,
+  1 + 0.508329,
+ -7 + -0.311971,
+ -1 + 0.384163,
+  7 + -0.407872,
+  5 + 0.252608,
+ -5 + -0.748733,
+  7 + -0.766854,
+  7 + 0.963027,
+  7 + 0.370056,
+  7 + 0.91614,
+  5 + -0.10655,
+  5 + 0.114024,
+  3 + 0.6354,
+ -3 + 0.526766,
+ -3 + 0.0656808,
+ -1 + 0.273656,
+  3 + -0.518891,
+  5 + 0.602608,
+ -3 + 0.14799,
+ -5 + -0.304276,
+  5 + 0.282315,
+ -5 + 0.525241,
+  3 + 0.917138,
+  1 + -0.407829,
+  1 + 0.148744,
+  7 + 0.374387,
+  1 + 0.719541,
+  5 + -0.845279,
+ -7 + -0.271885,
+ -3 + 0.498453,
+ -3 + -0.108517,
+  7 + -0.916167,
+  1 + -0.00524844,
+  3 + 0.230628,
+  1 + 0.928817,
+  5 + 0.961846,
+  3 + -0.970376,
+ -5 + -0.991187,
+  1 + -0.988078,
+ -3 + -0.321644,
+  7 + 0.299365,
+ -1 + 0.260651,
+ -5 + 0.901838,
+ -7 + 0.905185,
+ -7 + -0.998068,
+ -1 + -0.717301,
+  3 + -0.448447,
+ -5 + 0.853505,
+  1 + 0.691012,
+ -5 + 0.858187,
+ -7 + 0.744305,
+ -1 + -0.546463,
+ -5 + 0.0513083,
+ -5 + 0.113148,
+  1 + 0.753596,
+ -1 + 0.453985,
+  1 + -0.558975,
+ -3 + -0.931769,
+ -7 + -0.421414,
+ -7 + -0.61578,
+  3 + -0.601418,
+ -1 + 0.384031,
+  1 + 0.180447,
+ -1 + 0.160505,
+  7 + -0.14269,
+  3 + 0.553436,
+  3 + 0.842422,
+ -1 + -0.298941,
+ -3 + -0.704512,
+  1 + -0.817883,
+ -5 + 0.689056,
+  3 + 0.54275,
+ -7 + -0.244876,
+ -7 + 0.497505,
+ -3 + -0.385801,
+ -7 + -0.228079,
+  1 + 0.607185,
+  7 + -0.625709,
+  5 + -0.851795,
+ -3 + 0.657661,
+  7 + 0.568546,
+  1 + -0.0359739,
+  1 + 0.836243,
+  1 + -0.747603,
+ -5 + 0.463366,
+  7 + -0.62775,
+ -5 + -0.129517,
+  7 + -0.0784853,
+ -5 + -0.338617,
+  1 + -0.0951821,
+ -3 + -0.0586496,
+  1 + 0.548171,
+ -5 + -0.142791,
+  1 + -0.137619,
+ -5 + 0.86615,
+  3 + 0.337578,
+ -7 + -0.0597365,
+ -5 + -0.843939,
+ -3 + -0.607342,
+ -1 + -0.630138,
+ -3 + -0.393534,
+  7 + 0.354908,
+ -5 + 0.184251,
+  5 + -0.154522,
+ -5 + 0.828516,
+  5 + 0.817169,
+ -5 + 0.833938,
+ -5 + 0.689288,
+  5 + -0.995259,
+ -1 + -0.932191,
+ -7 + 0.964076,
+  1 + -0.85304,
+ -3 + -0.0782913,
+  7 + -0.696813,
+  5 + 0.231297,
+  7 + 0.688421,
+  7 + 0.0322752,
+  1 + 0.839409,
+  1 + -0.362455,
+ -3 + 0.561378,
+  3 + -0.496498,
+  1 + 0.841212,
+ -7 + -0.299443,
+  7 + 0.527505,
+ -1 + 0.51827,
+  5 + -0.348049,
+ -3 + -0.983604,
+ -1 + 0.694304,
+  1 + -0.31786,
+ -3 + 0.643969,
+ -1 + -0.650723,
+ -7 + -0.14479,
+ -3 + 0.455813,
+  7 + -0.627596,
+ -3 + -0.245695,
+ -5 + 0.0893783,
+  3 + -0.236629,
+  5 + -0.277597,
+  7 + 0.481512,
+ -7 + 0.143052,
+  3 + 0.615401,
+  7 + -0.975698,
+ -1 + 0.50143,
+ -3 + 0.0737497,
+  1 + 0.345961,
+ -1 + 0.944933,
+ -1 + 0.00710848,
+  3 + -0.908855,
+  3 + -0.104037,
+ -1 + -0.0996714,
+ -1 + 0.480154,
+ -5 + -0.684452,
+ -3 + -0.104955,
+ -1 + -0.972497,
+  5 + 0.619405,
+ -5 + -0.361996,
+  1 + -0.780079,
+ -7 + 0.443635,
+  7 + 0.527956,
+ -1 + 0.927314,
+  3 + 0.606136,
+  3 + -0.22611,
+  1 + -0.288871,
+ -3 + 0.683856,
+  5 + 0.486252,
+ -7 + -0.781706,
+  5 + 0.348522,
+ -7 + -0.743252,
+  5 + 0.790582,
+ -1 + -0.417564,
+  1 + 0.971814,
+  1 + -0.394633,
+  3 + -0.538042,
+  7 + -0.82342,
+ -5 + 0.46215,
+ -3 + -0.725289,
+ -1 + -0.248699,
+  3 + 0.194388,
+ -1 + 0.572686,
+ -1 + 0.57203,
+ -1 + -0.73258,
+  3 + -0.841193,
+  3 + 0.846292,
+  7 + -0.106951,
+ -1 + -0.82125,
+  5 + -0.565781,
+ -7 + -0.178221,
+  3 + -0.396988,
+ -1 + -0.194377,
+ -7 + -0.184276,
+  3 + 0.530178,
+ -1 + 0.0792818,
+  3 + 0.698151,
+  7 + 0.540132,
+  5 + -0.0324876,
+ -5 + -0.539282,
+  1 + -0.0612176,
+  1 + -0.00825787,
+ -5 + -0.594088,
+  5 + -0.720534,
+ -3 + -0.726017,
+  3 + -0.247803,
+ -5 + -0.0351876,
+ -3 + -0.485217,
+  7 + -0.711281,
+  1 + -0.143779,
+  5 + 0.830104,
+ -1 + -0.680937,
+ -5 + -0.406956,
+ -7 + -0.572693,
+  1 + -0.916711,
+ -7 + -0.361021,
+  5 + -0.669143,
+ -7 + 0.0977001,
+ -1 + -0.351618,
+ -3 + -0.292778,
+ -3 + 0.94385,
+ -5 + 0.64688,
+ -5 + 0.462901,
+ -7 + 0.139473,
+  5 + -0.923586,
+ -7 + 0.100025,
+  7 + 0.762592,
+  5 + -0.669251,
+ -5 + 0.552417,
+  3 + 0.578362,
+ -3 + 0.286511,
+ -5 + -0.819517,
+  5 + -0.174663,
+  1 + 0.898405,
+ -3 + 0.276757,
+ -5 + -0.860502,
+ -3 + -0.508774,
+ -7 + -0.619703,
+ -1 + -0.576515,
+  7 + 0.442863,
+  1 + -0.792524,
+  1 + -0.967062,
+ -7 + 0.495375,
+ -7 + -0.497338,
+ -5 + -0.649645,
+ -1 + -0.692724,
+ -7 + -0.681675,
+  5 + 0.80008,
+ -1 + -0.476369,
+ -3 + 0.102149,
+ -3 + -0.595665,
+ -5 + -0.961165,
+  7 + -0.990363,
+ -5 + 0.716457,
+ -7 + -0.404208,
+ -1 + -0.483432,
+  1 + 0.236347,
+ -1 + 0.376305,
+  1 + -0.0533286,
+ -7 + -0.610223,
+  3 + 0.843043,
+ -1 + -0.609047,
+  1 + 0.725496,
+ -1 + -0.31617,
+ -5 + -0.0189003,
+ -3 + -0.425178,
+ -7 + -0.321938,
+  3 + 0.0120751,
+ -1 + 0.315381,
+ -3 + -0.324733,
+ -3 + -0.571329,
+  5 + -0.30955,
+  3 + -0.997293,
+  3 + 0.105692,
+  1 + 0.0166829,
+ -7 + 0.295209,
+ -5 + 0.0396503,
+ -7 + -0.698527,
+  1 + -0.983116,
+  7 + 0.659054,
+ -1 + 0.33142,
+ -7 + -0.0377453,
+ -5 + -0.0574753,
+ -1 + 0.852526,
+ -1 + 0.983994,
+ -5 + 0.938022,
+  1 + 0.513438,
+  3 + 0.0546758,
+ -5 + 0.0823434,
+ -7 + 0.166195,
+ -3 + -0.852176,
+  1 + 0.366113,
+  1 + -0.397224,
+ -7 + 0.665549,
+  1 + -0.0446258,
+  3 + 0.702024,
+  5 + -0.733169,
+ -1 + -0.0454769,
+ -7 + -0.668073,
+  1 + 0.27592,
+  7 + -0.323333,
+  5 + -0.674522,
+  7 + 0.0814798,
+  7 + -0.782666,
+  3 + -0.0710991,
+  5 + 0.773968,
+ -1 + 0.803732,
+ -1 + 0.142462,
+ -3 + -0.243322,
+ -3 + -0.958958,
+  5 + 0.308394,
+  7 + -0.500096,
+ -7 + 0.914925,
+  7 + 0.150591,
+ -5 + 0.58597,
+  7 + 0.251341,
+ -3 + -0.636188,
+  7 + 0.909046,
+  3 + -0.577617,
+ -7 + -0.903661,
+  7 + -0.275888,
+  1 + -0.21705,
+ -5 + 0.736324,
+ -1 + -0.820161,
+ -1 + -0.545268,
+  3 + -0.0618935,
+  7 + -0.126791,
+  1 + -0.792842,
+ -7 + -0.398747,
+  3 + -0.583208,
+ -5 + -0.325178,
+  7 + -0.0370357,
+ -5 + -0.083306,
+  5 + 0.819585,
+ -7 + 0.0991425,
+ -3 + -0.130402,
+ -5 + -0.157376,
+  7 + 0.691842,
+  5 + -0.748137,
+ -1 + 0.758925,
+  1 + -0.312916,
+  3 + -0.820843,
+  7 + -0.261816,
+  7 + -0.172358,
+  7 + 0.536986,
+  7 + 0.759576,
+  7 + -0.754446,
+ -7 + 0.567095,
+ -1 + -0.524981,
+ -3 + -0.802519,
+ -3 + 0.3109,
+  3 + -0.248219,
+  5 + 0.0748601,
+  7 + 0.960564,
+  1 + 0.667926,
+ -7 + -0.706296,
+ -3 + 0.635725,
+  7 + 0.978146,
+ -1 + -0.574543,
+  5 + -0.430696,
+  1 + 0.0996064,
+  1 + -0.00163434,
+  3 + 0.14937,
+  3 + -0.0844981,
+  3 + -0.136261,
+  5 + 0.973049,
+  3 + 0.282247,
+  7 + 0.579739,
+  5 + -0.0823847,
+  5 + -0.0467881,
+  5 + 0.596636,
+ -1 + -0.297972,
+ -5 + 0.706257,
+ -7 + 0.604586,
+ -3 + 0.0669439,
+ -1 + -0.453354,
+  5 + -0.477196,
+  5 + 0.311931,
+  5 + 0.166079,
+  3 + 0.412152,
+  7 + 0.474994,
+  5 + -0.771076,
+  5 + 0.536177,
+ -5 + -0.0305953,
+ -3 + 0.580228,
+ -3 + 0.284461,
+ -7 + -0.726361,
+ -3 + -0.726564,
+  1 + -0.345421,
+  3 + 0.80056,
+  1 + 0.878273,
+ -5 + 0.654627,
+ -1 + 0.295187,
+  7 + 0.591756,
+  3 + 0.260911,
+  3 + 0.481528,
+ -3 + -0.77778,
+  3 + -0.683316,
+ -7 + -0.658198,
+ -3 + -0.74585,
+  1 + 0.938157,
+  1 + 0.192402,
+  5 + 0.361699,
+  3 + -0.163265,
+ -3 + 0.783476,
+ -5 + 0.737259,
+  1 + -0.569672,
+  7 + 0.10586,
+ -1 + -0.173976,
+  1 + 0.935026,
+ -7 + 0.356488,
+ -1 + 0.0017309,
+  5 + -0.675919,
+ -1 + 0.0665381,
+ -1 + -0.307875,
+  7 + 0.0983045,
+  5 + 0.963101,
+  3 + -0.519587,
+ -5 + 0.899631,
+  1 + 0.31666,
+  7 + -0.756871,
+  7 + 0.333545,
+ -3 + -0.168074,
+  7 + 0.87813,
+ -1 + 0.779471,
+ -5 + 0.754198,
+  7 + -0.868269,
+  1 + 0.333521,
+  7 + -0.731973,
+ -1 + 0.33527,
+ -3 + -0.467703,
+ -1 + 0.234056,
+ -3 + -0.237028,
+  3 + 0.74204,
+  7 + -0.257894,
+ -7 + 0.690854,
+ -1 + 0.652636,
+  3 + 0.0301753,
+ -7 + 0.814373,
+ -1 + -0.951698,
+ -5 + 0.976247,
+ -3 + 0.431324,
+ -3 + 0.192437,
+  3 + 0.31289,
+ -3 + 0.422132,
+  3 + -0.00384281,
+  3 + 0.72445,
+ -5 + 0.920278,
+ -3 + -0.324996,
+  3 + 0.181187,
+  7 + 0.658717,
+ -5 + -0.977313,
+ -1 + 0.378038,
+  1 + 0.615551,
+ -1 + 0.475454,
+  3 + 0.735309,
+  7 + -0.398705,
+  7 + 0.0674037,
+ -1 + 0.273941,
+  5 + -0.376697,
+  1 + -0.934663,
+  3 + 0.764279,
+ -5 + -0.67983,
+ -5 + -0.951744,
+ -7 + 0.559239,
+ -7 + 0.123601,
+ -1 + 0.279154,
+  7 + -0.349745,
+ -1 + 0.881504,
+  5 + 0.743417,
+ -7 + -0.126299,
+ -3 + 0.129631,
+ -7 + -0.248369,
+  3 + -0.582388,
+  7 + 0.606937,
+ -1 + -0.766819,
+ -1 + -0.887898,
+ -3 + 0.628891,
+ -3 + 0.797051,
+  1 + 0.258235,
+  1 + -0.289372,
+ -7 + -0.689227,
+ -5 + -0.223412,
+ -5 + -0.0717334,
+  5 + 0.444987,
+  3 + -0.47443,
+  5 + -0.622907,
+  1 + 0.231064,
+  7 + 0.0643792,
+ -5 + -0.545879,
+ -3 + 0.881704,
+  7 + 0.421487,
+  7 + -0.163227,
+  1 + -0.19334,
+  5 + 0.754454,
+ -7 + -0.173896,
+ -1 + -0.148776,
+ -5 + 0.342022,
+ -3 + 0.00779013,
+  7 + -0.959293,
+  5 + 0.888742,
+  1 + -0.0373372,
+  3 + 0.154647,
+  7 + 0.522902,
+ -1 + -0.91692,
+  1 + -0.762814,
+  1 + -0.308587,
+ -5 + 0.252501,
+  3 + 0.186752,
+  7 + -0.897854,
+  3 + -0.314141,
+  7 + -0.123752,
+  5 + -0.986531,
+  7 + 0.89791,
+  1 + -0.133572,
+ -7 + -0.828677,
+ -7 + -0.362269,
+  1 + -0.231981,
+  1 + 0.6903,
+  5 + 0.212784,
+ -1 + 0.790468,
+ -7 + -0.822496,
+  1 + -0.215268,
+  5 + -0.232525,
+ -1 + -0.479589,
+  3 + -0.79679,
+ -5 + -0.604188,
+  7 + -0.201313,
+ -1 + -0.525663,
+ -7 + -0.155085,
+  1 + -0.820419,
+ -3 + -0.37499,
+ -3 + -0.983146,
+ -5 + -0.793733,
+ -1 + -0.0931721,
+  5 + -0.601751,
+  3 + 0.0783009,
+ -1 + 0.768638,
+  1 + 0.492399,
+ -5 + -0.0098969,
+ -1 + 0.19191,
+ -7 + -0.979377,
+ -7 + -0.0178371,
+ -5 + -0.329518,
+  1 + 0.373382,
+ -7 + -0.845312,
+  3 + -0.922893,
+  3 + 0.315986,
+  3 + 0.486665,
+  1 + -0.263414,
+ -5 + 0.375741,
+  3 + 0.909047,
+  1 + -0.905982,
+  1 + -0.887325,
+  1 + -0.20989,
+  5 + -0.476245,
+  1 + -0.937806,
+  3 + -0.749343,
+  3 + -0.786876,
+ -3 + -0.67605,
+ -1 + 0.0446474,
+ -5 + 0.652167,
+  1 + 0.543258,
+ -5 + 0.15279,
+ -5 + 0.148326,
+  5 + 0.254656,
+ -3 + 0.856795,
+ -7 + 0.751831,
+ -3 + 0.630068,
+  5 + 0.0417778,
+ -5 + -0.789099,
+ -7 + 0.741281,
+ -3 + 0.391712,
+ -3 + -0.134653,
+ -1 + 0.326939,
+  7 + -0.0234458,
+ -3 + -0.23408,
+ -5 + -0.239154,
+ -5 + -0.832932,
+  5 + -0.305414,
+  7 + 0.447744,
+ -3 + -0.729455,
+  7 + 0.48413,
+  5 + 0.236162,
+  5 + -0.534741,
+  5 + 0.00340226,
+ -5 + -0.92795,
+  5 + -0.802271,
+  5 + -0.486955,
+ -3 + -0.958796,
+  5 + -0.576444,
+ -1 + 0.107654,
+ -5 + -0.759059,
+ -5 + 0.292163,
+  1 + -0.785662,
+  3 + -0.374019,
+  7 + -0.0159586,
+ -1 + 0.70116,
+ -5 + 0.0846993,
+  1 + 0.401001,
+  7 + 0.0279956,
+ -7 + -0.394888,
+  5 + 0.505212,
+  7 + 0.786975,
+  3 + 0.532436,
+ -7 + 0.204459,
+  3 + -0.615921,
+ -3 + 0.0758607,
+ -5 + 0.130031,
+ -5 + -0.772899,
+  3 + -0.274121,
+  5 + 0.056024,
+ -1 + -0.218418,
+ -7 + -0.183809,
+ -5 + 0.109609,
+  5 + -0.821093,
+  7 + -0.353014,
+  3 + 0.228901,
+  1 + -0.594237,
+ -3 + 0.39832,
+ -5 + 0.575415,
+ -1 + 0.398899,
+ -5 + -0.239754,
+  3 + -0.535948,
+  5 + -0.487767,
+  5 + 0.282845,
+  1 + -0.720766,
+ -7 + 0.678491,
+ -3 + 0.389419,
+  5 + -0.862186,
+  7 + -0.942864,
+  7 + -0.341864,
+  7 + -0.332763,
+ -7 + 0.290539,
+ -5 + -0.076314,
+ -3 + 0.14099,
+  1 + -0.0547188,
+  3 + 0.735025,
+  3 + -0.197414,
+  5 + 0.690544,
+  5 + 0.630046,
+ -3 + -0.117688,
+  7 + 0.656909,
+  7 + 0.417193,
+ -3 + -0.489404,
+ -1 + 0.66448,
+  3 + 0.109689,
+  1 + -0.601325,
+  5 + 0.930691,
+  1 + 0.122041,
+ -3 + 0.991223,
+ -5 + -0.700354,
+ -1 + 0.0347951,
+  7 + 0.122125,
+  1 + 0.218395,
+ -7 + -0.177617,
+  5 + 0.209456,
+ -5 + -0.976741,
+ -5 + -0.41843,
+ -3 + -0.580374,
+ -1 + -0.424389,
+ -5 + -0.183439,
+  1 + 0.159905,
+  1 + -0.825052,
+ -1 + -0.783269,
+  3 + 0.150836,
+ -5 + 0.385557,
+ -1 + -0.657701,
+ -5 + 0.739214,
+  7 + -0.990613,
+ -5 + 0.787245,
+ -5 + 0.604144,
+ -5 + -0.871588,
+  5 + 0.721765,
+  5 + 0.118939,
+ -5 + -0.859039,
+ -3 + 0.111408,
+ -1 + -0.479201,
+  1 + -0.470303,
+ -1 + -0.136117,
+  5 + 0.956995,
+  1 + -0.39388,
+ -1 + 0.614385,
+  1 + 0.556813,
+  7 + 0.844387,
+  1 + -0.436025,
+ -5 + -0.108634,
+  5 + -0.100592,
+ -7 + -0.723946,
+  1 + 0.0688398,
+  7 + 0.180889,
+ -3 + 0.628736,
+  1 + 0.112598,
+  3 + 0.318029,
+ -3 + 0.634139,
+  7 + -0.691032,
+  1 + 0.356673,
+  5 + 0.0566803,
+  1 + -0.351812,
+  5 + 0.531286,
+ -7 + -0.157417,
+  7 + -0.99541,
+  7 + -0.681986,
+  5 + -0.997084,
+ -7 + 0.741155,
+  1 + -0.622678,
+  1 + 0.705248,
+ -5 + 0.711669,
+  7 + 0.377357,
+ -5 + -0.62871,
+ -5 + 0.0214289,
+ -1 + -0.997903,
+  5 + 0.0933239,
+  3 + -0.526274,
+ -7 + -0.951203,
+ -1 + -0.755676,
+  5 + 0.339232,
+ -1 + 0.773219,
+ -3 + 0.426269,
+  3 + -0.396471,
+  7 + 0.567064,
+  5 + 0.633394,
+ -7 + 0.791714,
+  3 + 0.787449,
+  3 + -0.472383,
+ -5 + -0.155762,
+ -5 + -0.0783671,
+ -5 + -0.338965,
+  3 + -0.793645,
+ -5 + 0.876857,
+ -5 + -0.02886,
+ -1 + 0.566931,
+  5 + 0.623439,
+  5 + 0.50836,
+  7 + -0.3025,
+  7 + -0.714796,
+ -7 + 0.179475,
+  7 + -0.662018,
+  1 + -0.348355,
+  3 + -0.794334,
+ -3 + -0.157082,
+  7 + 0.149085,
+  1 + 0.640906,
+ -3 + 0.349559,
+ -3 + 0.857413,
+ -1 + -0.0283983,
+ -1 + 0.693171,
+ -3 + -0.214092,
+ -5 + -0.98936,
+  1 + 0.639767,
+  3 + -0.194655,
+ -5 + 0.940209,
+ -3 + 0.20604,
+ -3 + -0.564045,
+  3 + -0.590761,
+  5 + 0.685986,
+  3 + -0.764822,
+ -1 + 0.42185,
+ -3 + -0.295677,
+  1 + 0.216797,
+  1 + -0.814246,
+ -1 + 0.206404,
+ -3 + 0.328757,
+  7 + -0.566083,
+  3 + 0.597134,
+ -3 + 0.642763,
+ -7 + -0.395769,
+  7 + -0.935252,
+ -7 + 0.626113,
+ -3 + -0.849858,
+  5 + 0.917923,
+  5 + -0.376758,
+  3 + 0.849631,
+ -5 + -0.327594,
+ -7 + -0.0529906,
+ -3 + -0.923709,
+  1 + 0.0692206,
+ -5 + 0.056296,
+  3 + 0.467438,
+ -1 + -0.814233,
+ -5 + -0.302013,
+ -3 + 0.695497,
+  7 + 0.651437,
+  3 + 0.168943,
+  5 + 0.605341,
+ -1 + -0.372329,
+  1 + 0.765342,
+  1 + 0.947534,
+ -5 + 0.116956,
+ -3 + 0.577997,
+  5 + 0.810715,
+  1 + -0.779946,
+ -7 + -0.370998,
+  3 + 0.558406,
+ -1 + -0.233575,
+  1 + 0.77588,
+ -7 + -0.311882,
+  5 + -0.910265,
+  5 + -0.992932,
+  5 + -0.760745,
+  1 + 0.318678,
+  5 + -0.210387,
+  1 + 0.872963,
+  3 + 0.220112,
+ -5 + -0.811578,
+  5 + -0.711665,
+  5 + -0.150111,
+ -1 + 0.641725,
+  1 + 0.898414,
+ -3 + -0.650104,
+  7 + -0.14629,
+  7 + 0.865109,
+ -1 + -0.347701,
+ -1 + 0.921759,
+  1 + 0.697452,
+  1 + 0.0354798,
+  5 + -0.176528,
+ -7 + 0.664795,
+ -3 + 0.896781,
+  3 + -0.958731,
+  5 + -0.141991,
+  7 + 0.120368,
+ -5 + 0.485083,
+  7 + -0.376901,
+ -5 + -0.43829,
+ -5 + -0.586847,
+  1 + -0.959211,
+  7 + 0.0708796,
+ -3 + 0.0492324,
+ -3 + -0.993246,
+ -1 + 0.650188,
+ -1 + -0.865149,
+ -5 + 0.37034,
+  7 + -0.338674,
+  3 + 0.623087,
+ -7 + -0.321175,
+  7 + -0.764244,
+ -1 + 0.378604,
+  1 + -0.812146,
+  3 + 0.444655,
+ -5 + 0.253273,
+  7 + 0.481744,
+  3 + 0.455208,
+  5 + 0.908443,
+  1 + 0.0686094,
+ -7 + 0.844868,
+ -5 + -0.976591,
+  7 + -0.72575,
+  5 + 0.675135,
+ -7 + 0.274097,
+ -3 + 0.409609,
+  3 + -0.175133,
+ -3 + 0.796693,
+  3 + -0.247288,
+ -1 + -0.549564,
+ -7 + 0.967288,
+ -1 + -0.839667,
+  3 + -0.681989,
+ -1 + -0.523145,
+ -5 + 0.396439,
+  5 + -0.120618,
+  3 + 0.693885,
+ -1 + -0.816144,
+ -5 + -0.968818,
+ -3 + -0.390704,
+  3 + -0.448062,
+  1 + 0.569756,
+  5 + -0.336729,
+ -1 + 0.136729,
+  5 + 0.941006,
+  5 + -0.465103,
+  7 + 0.468966,
+ -1 + 0.355103,
+ -7 + 0.615847,
+ -1 + -0.692941,
+ -1 + -0.173114,
+  3 + 0.594599,
+  7 + 0.557483,
+  3 + 0.997697,
+ -5 + 0.24401,
+  1 + -0.00963287,
+  5 + 0.0275448,
+  5 + 0.659747,
+ -7 + -0.567272,
+ -5 + -0.405348,
+ -1 + -0.614457,
+  1 + 0.19472,
+ -7 + 0.553533,
+ -3 + -0.612328,
+  1 + -0.348393,
+ -3 + 0.771169,
+ -3 + 0.354427,
+ -5 + 0.785281,
+  3 + -0.318974,
+ -5 + -0.170041,
+ -1 + -0.667593,
+ -1 + -0.514524,
+ -5 + -0.76729,
+  3 + 0.924267,
+  7 + -0.893804,
+ -7 + -0.250356,
+  7 + -0.732358,
+ -7 + 0.490774,
+  1 + -0.437992,
+ -3 + 0.469562,
+  1 + 0.436426,
+ -3 + -0.400156,
+  7 + -0.860264,
+  1 + 0.0900252,
+ -1 + -0.754367,
+  1 + -0.838147,
+ -5 + 0.404529,
+ -7 + -0.437069,
+ -5 + -0.496662,
+  5 + 0.952867,
+ -3 + 0.894237,
+ -3 + -0.555447,
+ -1 + -0.354976,
+  1 + -0.60926,
+ -7 + 0.759444,
+  3 + 0.662752,
+ -7 + -0.815089,
+ -5 + 0.98253,
+  3 + -0.817391,
+  5 + -0.61243,
+ -5 + -0.456923,
+ -1 + -0.824931,
+  7 + 0.514605,
+ -1 + 0.828664,
+ -5 + -0.195044,
+ -3 + -0.333318,
+  3 + 0.164695,
+ -7 + 0.0349422,
+  7 + 0.118845,
+  5 + -0.174882,
+  7 + -0.872202,
+  7 + 0.710986,
+  3 + 0.699916,
+ -5 + 0.066256,
+  3 + -0.148756,
+  7 + 0.508584,
+  5 + 0.825367,
+ -5 + -0.729841,
+ -5 + -0.887612,
+  5 + -0.758424,
+ -5 + 0.998181,
+ -7 + 0.65577,
+  5 + -0.474471,
+  7 + -0.269234,
+  3 + 0.104569,
+ -5 + -0.102212,
+ -5 + 0.738547,
+  5 + -0.94242,
+ -1 + 0.15571,
+  7 + -0.421775,
+ -7 + 0.804305,
+  3 + 0.770802,
+  7 + 0.642568,
+ -7 + 0.971034,
+  1 + -0.144741,
+ -7 + 0.902049,
+  7 + 0.157032,
+  7 + -0.710021,
+  7 + 0.719006,
+  1 + -0.119823,
+ -7 + 0.156298,
+  3 + 0.970851,
+ -1 + -0.163907,
+ -7 + -0.353286,
+ -7 + 0.497258,
+ -7 + 0.283671,
+  1 + 0.0405689,
+ -5 + -0.962454,
+ -3 + -0.219818,
+  1 + -0.436599,
+ -3 + -0.651331,
+  5 + 0.192501,
+ -5 + 0.627465,
+  3 + -0.0387857,
+ -5 + 0.235464,
+  3 + -0.0781319,
+ -1 + 0.372664,
+ -7 + 0.144817,
+ -3 + -0.981248,
+ -7 + -0.438408,
+  5 + 0.851478,
+ -1 + -0.473764,
+  1 + 0.00188464,
+  3 + 0.433134,
+ -7 + -0.132385,
+  7 + -0.0645663,
+ -1 + -0.202906,
+ -7 + -0.19273,
+ -5 + 0.490564,
+  5 + -0.986688,
+  3 + -0.259055,
+ -5 + -0.0975989,
+ -1 + -0.599443,
+ -1 + 0.313751,
+ -3 + 0.839625,
+ -3 + 0.0875769,
+  7 + 0.531778,
+  5 + 0.78374,
+ -7 + -0.568377,
+ -5 + -0.772801,
+ -5 + -0.0559519,
+ -5 + 0.945151,
+ -7 + 0.260123,
+ -7 + -0.909106,
+ -5 + 0.0617756,
+ -3 + -0.0675705,
+  3 + 0.425518,
+ -3 + 0.0981296,
+ -1 + -0.137702,
+  5 + 0.353555,
+  7 + 0.895279,
+ -7 + 0.247132,
+ -1 + 0.346749,
+ -3 + 0.748198,
+ -5 + 0.584672,
+  3 + -0.731422,
+  3 + 0.0579248,
+  5 + 0.212579,
+  5 + 0.1419,
+ -1 + -0.51401,
+  1 + -0.844899,
+ -1 + -0.478985,
+ -5 + 0.918879,
+  3 + -0.0802303,
+  5 + 0.995209,
+  1 + 0.228169,
+ -3 + 0.580333,
+ -3 + -0.866062,
+  7 + -0.978268,
+ -5 + 0.501526,
+ -7 + 0.334392,
+ -1 + 0.442487,
+ -5 + 0.0704108,
+ -5 + -0.711541,
+ -5 + 0.982968,
+ -7 + 0.722414,
+  5 + -0.799889,
+  1 + -0.853645,
+ -7 + 0.997917,
+  5 + -0.513696,
+  5 + 0.0364606,
+  5 + -0.248071,
+ -7 + -0.387232,
+  1 + -0.811699,
+  1 + 0.732048,
+  3 + -0.679307,
+ -1 + -0.978209,
+ -1 + -0.964028,
+ -5 + -0.611812,
+ -7 + -0.902063,
+ -3 + 0.398009,
+  3 + 0.00542146,
+  5 + 0.601782,
+  5 + -0.104203,
+  1 + 0.506752,
+ -5 + 0.436524,
+  7 + 0.982469,
+ -1 + -0.0633421,
+ -7 + 0.446072,
+ -1 + 0.927761,
+  1 + 0.658156,
+ -7 + 0.785148,
+ -1 + -0.591183,
+ -3 + 0.0137029,
+ -1 + -0.388246,
+  7 + -0.675978,
+  1 + 0.0143937,
+ -7 + 0.690042,
+ -5 + -0.693171,
+ -7 + -0.352858,
+  3 + -0.970363,
+ -7 + -0.723423,
+  3 + 0.724452,
+ -3 + 0.158585,
+  7 + -0.175004,
+  1 + -0.19285,
+ -1 + 0.992788,
+  3 + -0.851952,
+  5 + 0.81,
+  3 + -0.0435364,
+ -1 + -0.0813053,
+ -1 + -0.765415,
+ -7 + -0.0372974,
+ -1 + 0.694064,
+  1 + -0.136753,
+  3 + 0.826244,
+ -7 + 0.140024,
+  5 + -0.0882701,
+  1 + 0.295136,
+  7 + -0.5227,
+ -5 + -0.237363,
+ -3 + 0.709084,
+ -3 + 0.629578,
+ -5 + 0.643857,
+  7 + -0.668263,
+ -5 + 0.249376,
+ -1 + -0.760648,
+  1 + -0.927984,
+  7 + -0.659877,
+  7 + -0.567002,
+ -1 + 0.0565217,
+ -3 + 0.805679,
+ -3 + -0.528236,
+ -7 + -0.13752,
+ -3 + 0.887507,
+  7 + 0.63262,
+  3 + -0.119278,
+  3 + 0.890306,
+ -1 + -0.274285,
+ -1 + 0.369489,
+  7 + 0.0317755,
+  3 + -0.856605,
+  7 + 0.912634,
+ -7 + 0.0492215,
+  1 + -0.276292,
+ -7 + -0.177337,
+  3 + -0.787517,
+ -3 + -0.53,
+ -1 + -0.186417,
+  3 + -0.949098,
+ -7 + -0.517213,
+ -1 + -0.986841,
+  5 + 0.600896,
+  7 + 0.48168,
+ -3 + -0.458465,
+  5 + 0.321443,
+ -3 + -0.234238,
+  1 + -0.954936,
+  5 + -0.0275234,
+ -7 + 0.924262,
+  1 + 0.977532,
+ -5 + -0.669258,
+  3 + 0.364021,
+  1 + 0.135028,
+ -3 + -0.473695,
+ -7 + -0.185051,
+ -7 + -0.232574,
+  3 + -0.944187,
+  3 + -0.0543526,
+  5 + 0.673031,
+  5 + 0.195805,
+  1 + -0.45507,
+  7 + 0.404971,
+  3 + -0.610784,
+  5 + 0.0659073,
+ -1 + -0.207704,
+  7 + 0.644995,
+ -1 + 0.121214,
+ -3 + -0.483027,
+ -7 + 0.711033,
+  5 + -0.673219,
+ -1 + -0.895776,
+  3 + 0.951024,
+ -3 + 0.56215,
+  3 + -0.329154,
+ -5 + -0.577541,
+ -7 + -0.309147,
+ -1 + -0.511309,
+  7 + 0.499812,
+ -5 + -0.681876,
+ -1 + -0.801156,
+  7 + 0.151605,
+ -3 + 0.241685,
+  7 + 0.992835,
+ -3 + 0.982038,
+ -5 + 0.0631867,
+ -5 + 0.950436,
+  7 + 0.31088,
+  5 + -0.708879,
+ -7 + 0.460315,
+  1 + 0.397522,
+  3 + -0.830289,
+ -1 + -0.146992,
+  3 + 0.667571,
+ -5 + 0.870575,
+  5 + -0.692335,
+  1 + -0.399896,
+ -7 + -0.421033,
+  7 + -0.740574,
+ -3 + 0.0441913,
+ -5 + 0.000759854,
+ -1 + -0.526559,
+  7 + -0.50311,
+  3 + -0.00944866,
+ -7 + 0.250031,
+ -5 + 0.579793,
+ -3 + 0.554107,
+  5 + 0.737397,
+  1 + 0.434328,
+ -5 + -0.698991,
+ -7 + 0.0322755,
+  5 + -0.995791,
+ -7 + 0.233862,
+  3 + -0.201264,
+  7 + -0.297969,
+ -5 + 0.377501,
+  3 + -0.571389,
+ -1 + 0.530284,
+  5 + -0.179379,
+  7 + -0.356844,
+ -7 + 0.941165,
+  1 + 0.339271,
+  3 + -0.66842,
+ -5 + -0.423012,
+  3 + 0.316588,
+ -1 + -0.984114,
+  1 + -0.5428,
+ -1 + 0.766658,
+  1 + -0.960606,
+  5 + -0.620487,
+  7 + 0.266202,
+  7 + 0.901102,
+  1 + -0.268669,
+ -5 + -0.607472,
+ -7 + -0.52709,
+ -3 + 0.0705389,
+  1 + -0.608374,
+ -3 + -0.288577,
+ -5 + 0.843351,
+ -3 + 0.612135,
+ -5 + 0.230486,
+  5 + -0.244291,
+ -1 + 0.576229,
+ -3 + 0.446377,
+ -3 + -0.106511,
+ -3 + 0.889909,
+ -5 + -0.918941,
+  1 + 0.848997,
+ -5 + 0.10993,
+ -3 + 0.256356,
+  1 + 0.504098,
+  5 + -0.170462,
+  1 + 0.835316,
+  7 + 0.644516,
+ -7 + 0.90372,
+ -7 + 0.463742,
+ -5 + 0.349377,
+ -7 + -0.553437,
+  1 + 0.330349,
+  5 + 0.710921,
+ -3 + 0.654504,
+ -5 + -0.447801,
+ -5 + 0.0517276,
+ -1 + 0.975718,
+  3 + 0.874352,
+ -1 + 0.678769,
+ -1 + -0.264881,
+ -3 + -0.0680661,
+  1 + -0.824504,
+ -7 + -0.0992408,
+ -5 + -0.862084,
+  3 + -0.805812,
+  5 + 0.237566,
+ -3 + 0.888929,
+  1 + -0.476846,
+ -1 + 0.621217,
+  1 + 0.65046,
+  1 + -0.177248,
+ -1 + 0.0533044,
+  3 + -0.176522,
+ -1 + 0.676266,
+  5 + 0.0818662,
+  5 + -0.0801649,
+  5 + -0.430938,
+  3 + -0.763183,
+ -7 + -0.453813,
+  3 + 0.555379,
+ -3 + 0.858594,
+  3 + 0.227172,
+ -1 + -0.632746,
+ -7 + 0.627382,
+  1 + -0.0489046,
+  7 + -0.828429,
+  3 + 0.555978,
+ -7 + -0.130752,
+  1 + 0.978551,
+  1 + 0.985192,
+ -3 + -0.601231,
+ -3 + 0.3876,
+  1 + 0.907771,
+ -3 + -0.183183,
+ -5 + -0.297217,
+ -5 + 0.579173,
+ -5 + 0.751301,
+  5 + 0.675477,
+ -7 + -0.700691,
+  1 + 0.947316,
+ -7 + -0.635739,
+ -1 + -0.1091,
+ -5 + -0.655627,
+ -7 + -0.74121,
+  1 + 0.334598,
+  5 + -0.133385,
+ -5 + 0.364959,
+  5 + -0.692856,
+ -7 + -0.432334,
+ -3 + 0.0911902,
+ -5 + 0.670209,
+ -7 + -0.0777559,
+ -3 + 0.769741,
+  7 + 0.0235715,
+  1 + 0.181115,
+ -7 + -0.688748,
+ -7 + -0.641734,
+ -1 + 0.972104,
+  7 + -0.474228,
+ -7 + -0.984007,
+  3 + 0.25339,
+  3 + 0.87889,
+  5 + 0.624509,
+  5 + -0.896409,
+  7 + -0.146804,
+  5 + 0.79753,
+ -1 + 0.0419583,
+ -3 + -0.978575,
+  5 + -0.799147,
+  7 + -0.100029,
+  5 + 0.34877,
+  5 + 0.726533,
+ -3 + 0.902539,
+ -7 + -0.0300989,
+  5 + 0.843366,
+  7 + 0.98872,
+  7 + -0.428589,
+  1 + 0.644193,
+ -5 + 0.0228081,
+  7 + -0.754224,
+  7 + 0.805301,
+  5 + 0.695254,
+ -7 + -0.188701,
+  3 + -0.581044,
+  5 + 0.799149,
+  7 + 0.353339,
+ -1 + -0.9622,
+ -1 + -0.230887,
+  5 + -0.787056,
+ -7 + -0.706222,
+  3 + 0.0197935,
+ -1 + 0.805143,
+  7 + 0.951379,
+  5 + -0.333186,
+ -3 + -0.0693998,
+ -3 + 0.993613,
+ -5 + -0.548791,
+ -5 + -0.964111,
+  3 + -0.584394,
+  1 + 0.867385,
+ -7 + -0.480054,
+  1 + -0.994699,
+  7 + 0.090273,
+ -3 + 0.901709,
+  1 + 0.715806,
+  3 + 0.304813,
+  7 + 0.403796,
+  1 + -0.473723,
+  5 + 0.475125,
+ -1 + 0.0271961,
+  7 + -0.487227,
+  7 + 0.229468,
+ -3 + -0.189796,
+ -3 + -0.625003,
+  1 + -0.401116,
+ -7 + 0.67123,
+ -5 + -0.927091,
+ -7 + 0.270972,
+  7 + -0.617139,
+  1 + -0.91671,
+ -7 + -0.712691,
+ -3 + -0.840406,
+  5 + -0.406998,
+ -1 + -0.849947,
+  3 + -0.158653,
+ -1 + 0.0696663,
+ -1 + 0.758415,
+  1 + 0.0694559,
+  1 + 0.462296,
+ -5 + 0.217909,
+  1 + 0.473663,
+ -3 + 0.473242,
+ -3 + -0.890317,
+ -3 + -0.397198,
+ -7 + -0.508332,
+  5 + 0.990104,
+  5 + -0.32464,
+ -1 + -0.869012,
+  7 + 0.567209,
+  1 + -0.495974,
+  3 + -0.101183,
+ -7 + -0.74694,
+ -5 + -0.675854,
+ -1 + 0.110992,
+ -5 + 0.247456,
+  7 + 0.840274,
+ -3 + 0.395728,
+  5 + -0.362192,
+ -3 + -0.680363,
+  5 + -0.602484,
+ -3 + 0.738772,
+  1 + -0.644167,
+ -3 + 0.634913,
+  3 + -0.384876,
+  5 + -0.916855,
+ -5 + -0.227988,
+ -3 + -0.625356,
+ -5 + -0.740278,
+ -1 + -0.41118,
+  3 + 0.443345,
+  3 + 0.736942,
+  1 + -0.354426,
+ -7 + -0.870946,
+ -3 + -0.546137,
+ -7 + 0.272889,
+  1 + 0.0801028,
+  5 + -0.274639,
+ -5 + -0.154875,
+ -3 + -0.580005,
+ -5 + -0.398665,
+  3 + -0.385197,
+  5 + -0.285359,
+  1 + 0.362706,
+ -7 + -0.855772,
+ -7 + 0.0454971,
+ -5 + -0.424857,
+ -7 + -0.504577,
+ -5 + -0.00591926,
+ -5 + 0.149346,
+  3 + -0.328489,
+  7 + 0.015029,
+  7 + 0.747577,
+ -5 + -0.714686,
+  1 + -0.101717,
+  3 + 0.656319,
+  1 + 0.5271,
+ -7 + -0.64961,
+ -7 + -0.359428,
+ -3 + -0.298523,
+ -3 + -0.0788614,
+  1 + 0.621573,
+ -1 + 0.0175043,
+  3 + -0.579268,
+  5 + 0.710546,
+  7 + -0.511833,
+  5 + 0.162637,
+ -7 + -0.226472,
+  1 + 0.0095225,
+  5 + 0.21144,
+ -5 + -0.582375,
+  7 + 0.231257,
+  1 + 0.248058,
+ -1 + 0.922646,
+  5 + 0.00967738,
+  7 + -0.00782117,
+  1 + 0.930862,
+  1 + 0.920455,
+  7 + -0.994076,
+ -5 + -0.462763,
+  1 + 0.627409,
+  3 + 0.936991,
+ -7 + 0.800793,
+ -1 + 0.193107,
+ -7 + 0.703299,
+ -1 + 0.132479,
+  1 + -0.152733,
+  5 + -0.953622,
+ -7 + -0.997253,
+  7 + 0.556477,
+  3 + 0.272056,
+ -3 + -0.51489,
+  5 + 0.398802,
+  5 + 0.602265,
+ -5 + 0.274229,
+ -7 + -0.700344,
+ -7 + 0.0901991,
+  5 + 0.0552389,
+ -7 + -0.536972,
+ -7 + -0.0797897,
+  5 + 0.291342,
+  3 + -0.846983,
+  3 + 0.700542,
+ -7 + 0.192372,
+  7 + -0.362972,
+  5 + 0.180049,
+ -3 + 0.792655,
+  7 + -0.662956,
+  5 + -0.142891,
+ -3 + 0.244501,
+ -3 + -0.510171,
+ -3 + 0.321085,
+ -1 + 0.664982,
+  7 + -0.905902,
+ -5 + 0.966882,
+ -7 + 0.735439,
+  3 + 0.261407,
+  3 + 0.963571,
+ -7 + -0.475502,
+  7 + 0.78978,
+  7 + 0.365208,
+  3 + 0.820723,
+  3 + -0.594815,
+ -1 + -0.942558,
+ -1 + -0.304459,
+ -3 + 0.391556,
+ -1 + -0.795303,
+ -7 + 0.136453,
+ -5 + -0.955505,
+  1 + -0.534127,
+  5 + -0.981382,
+ -3 + 0.557188,
+ -5 + -0.118641,
+ -3 + -0.621408,
+ -7 + -0.74375,
+  7 + 0.0227463,
+  5 + 0.112073,
+ -3 + 0.950711,
+  5 + 0.643199,
+  5 + -0.351889,
+ -1 + -0.221595,
+ -1 + 0.00700172,
+  7 + 0.928086,
+  5 + 0.0356548,
+  3 + -0.370036,
+ -7 + -0.830755,
+ -5 + -0.222917,
+  1 + -0.782772,
+  1 + 0.237148,
+ -1 + 0.86974,
+  5 + -0.537617,
+ -1 + -0.434889,
+ -7 + -0.0111739,
+  7 + -0.715952,
+  3 + -0.40804,
+  3 + -0.360795,
+  3 + 0.653046,
+ -3 + 0.706949,
+  5 + -0.554727,
+ -1 + 0.183029,
+ -7 + -0.239732,
+ -5 + -0.658072,
+  7 + -0.752212,
+ -5 + 0.293207,
+  7 + -0.34722,
+ -7 + -0.326367,
+ -5 + -0.0589863,
+  5 + -0.927616,
+ -1 + -0.866135,
+  3 + 0.00235856,
+ -3 + -0.0437649,
+ -5 + -0.585851,
+  1 + -0.481841,
+ -5 + 0.632601,
+  3 + -0.874934,
+ -1 + -0.230124,
+ -5 + 0.403241,
+ -5 + -0.986698,
+ -1 + 0.968435,
+ -3 + -0.530127,
+  1 + 0.919559,
+ -7 + 0.425743,
+  7 + 0.123378,
+  7 + -0.142707,
+ -7 + -0.494815,
+  7 + 0.440976,
+ -5 + 0.890096,
+ -3 + -0.708126,
+  7 + 0.943091,
+ -7 + -0.0667361,
+  1 + 0.417654,
+  7 + 0.25984,
+ -1 + 0.846645,
+  3 + -0.416033,
+ -1 + -0.149707,
+  1 + 0.889424,
+  5 + 0.866725,
+ -3 + 0.625568,
+ -1 + -0.376365,
+ -7 + 0.362419,
+ -7 + 0.212156,
+ -1 + 0.898672,
+  3 + -0.684527,
+  3 + 0.350536,
+ -5 + -0.10858,
+ -7 + 0.363887,
+  1 + 0.431342,
+  7 + -0.426099,
+ -1 + -0.0357183,
+  5 + 0.969688,
+ -7 + 0.436647,
+  1 + 0.144824,
+  7 + -0.689202,
+ -5 + -0.369132,
+ -7 + 0.447801,
+  3 + 0.991838,
+ -5 + -0.95315,
+ -5 + -0.486236,
+  7 + 0.635678,
+  7 + -0.672488,
+ -5 + -0.134572,
+ -5 + -0.698523,
+  3 + 0.0914014,
+  5 + 0.826151,
+  7 + 0.179363,
+  3 + 0.905552,
+  3 + 0.460779,
+  3 + -0.195297,
+ -5 + 0.965511,
+  1 + -0.98716,
+  7 + 0.142015,
+ -7 + -0.156042,
+  7 + 0.338355,
+ -3 + 0.630815,
+ -7 + -0.716086,
+ -5 + 0.30445,
+ -3 + -0.0663283,
+ -1 + 0.954605,
+ -7 + -0.516684,
+ -1 + 0.739518,
+ -5 + 0.0926331,
+ -1 + -0.964479,
+ -3 + 0.738004,
+ -1 + -0.0623072,
+ -3 + 0.994729,
+ -7 + -0.483703,
+ -5 + -0.116232,
+ -3 + 0.608111,
+  5 + -0.169533,
+  1 + 0.700974,
+  7 + 0.344404,
+  1 + -0.234486,
+ -5 + 0.753821,
+  3 + 0.264031,
+  1 + 0.365123,
+ -1 + 0.735946,
+ -3 + 0.075701,
+  5 + 0.0457206,
+ -3 + 0.594172,
+  1 + 0.144428,
+  3 + -0.945545,
+  7 + -0.49231,
+ -1 + 0.196516,
+  7 + 0.397096,
+ -1 + 0.68979,
+  3 + -0.283773,
+ -7 + -0.891651,
+ -7 + 0.0992016,
+  3 + 0.364927,
+  3 + 0.692215,
+  1 + 0.902593,
+ -7 + 0.511356,
+  1 + -0.329667,
+  3 + 0.151807,
+ -3 + -0.469367,
+ -1 + 0.839886,
+ -3 + 0.990307,
+  3 + 0.318869,
+  5 + -0.74034,
+ -5 + -0.339204,
+  1 + -0.452787,
+  1 + -0.736788,
+  1 + -0.248248,
+  5 + 0.785201,
+  7 + -0.243082,
+  7 + -0.107551,
+  1 + -0.729608,
+ -3 + -0.358678,
+  1 + -0.786071,
+ -1 + 0.370913,
+  3 + -0.398804,
+  1 + 0.0692376,
+ -1 + -0.103113,
+ -1 + 0.153375,
+  5 + 0.548651,
+ -1 + -0.306503,
+  3 + -0.96292,
+  5 + -0.221047,
+  5 + 0.567843,
+  5 + 0.41284,
+  5 + 0.88284,
+  1 + -0.629206,
+ -3 + -0.494796,
+  3 + 0.424972,
+  7 + 0.365256,
+ -5 + -0.739219,
+  3 + 0.640667,
+ -5 + 0.633005,
+ -1 + 0.759701,
+  5 + -0.0691017,
+ -5 + -0.0647394,
+ -5 + -0.348828,
+ -5 + 0.665346,
+ -1 + -0.135857,
+  5 + 0.437672,
+  5 + 0.381016,
+ -3 + -0.842788,
+ -1 + -0.85829,
+ -7 + 0.19863,
+ -5 + -0.877027,
+  5 + -0.776832,
+  3 + -0.591161,
+  1 + 0.272311,
+  1 + 0.729332,
+ -7 + -0.085479,
+ -1 + 0.867551,
+ -1 + 0.850484,
+ -7 + 0.688455,
+ -7 + 0.657501,
+  1 + -0.781022,
+  7 + -0.853813,
+ -5 + 0.963325,
+  5 + -0.61377,
+  1 + -0.946282,
+ -1 + -0.398061,
+  7 + -0.618336,
+ -5 + 0.210241,
+ -7 + 0.245468,
+  3 + -0.503244,
+ -7 + -0.991443,
+ -7 + -0.832428,
+  3 + 0.633537,
+  3 + -0.0513143,
+ -5 + -0.740331,
+ -5 + -0.571087,
+ -5 + 0.932409,
+ -1 + 0.310949,
+  7 + 0.803959,
+  1 + -0.37293,
+  3 + 0.625741,
+  3 + 0.335055,
+ -3 + -0.0665732,
+ -7 + -0.546747,
+ -3 + -0.824097,
+  3 + 0.185571,
+ -5 + -0.963157,
+  1 + -0.575186,
+  5 + -0.380057,
+ -3 + -0.0146486,
+ -7 + 0.548562,
+  7 + -0.294831,
+  1 + 0.190966,
+  3 + -0.200531,
+  3 + 0.769514,
+  1 + -0.758442,
+  5 + -0.563297,
+  3 + -0.268245,
+  7 + 0.115331,
+  7 + 0.635215,
+  1 + -0.393521,
+  1 + -0.618453,
+ -5 + 0.766947,
+ -5 + -0.89702,
+  3 + -0.290726,
+ -1 + -0.146228,
+ -7 + -0.671038,
+  1 + -0.598244,
+  3 + -0.56863,
+  7 + -0.501319,
+ -7 + 0.627518,
+  3 + -0.389303,
+ -3 + 0.0746856,
+  5 + -0.0666037,
+  5 + -0.275337,
+ -5 + 0.132165,
+  5 + -0.379456,
+ -3 + -0.232648,
+ -1 + -0.722393,
+ -3 + -0.848371,
+ -3 + -0.894514,
+ -3 + -0.52825,
+ -1 + 0.868408,
+  5 + 0.305525,
+ -5 + -0.274425,
+ -5 + 0.22874,
+  5 + 0.71816,
+ -1 + -0.744417,
+ -3 + 0.874223,
+  1 + -0.0454682,
+  3 + 0.998097,
+ -5 + 0.393407,
+  5 + 0.187479,
+  1 + 0.85875,
+  3 + -0.930842,
+  7 + -0.683711,
+  3 + -0.625096,
+  7 + -0.363623,
+ -3 + -0.478099,
+  5 + 0.0397175,
+ -1 + 0.772844,
+  1 + 0.0351828,
+ -5 + -0.450596,
+  5 + -0.747949,
+ -1 + -0.901913,
+  1 + -0.396489,
+  7 + 0.266602,
+ -3 + -0.144345,
+ -7 + 0.357022,
+ -1 + 0.17734,
+  3 + -0.490206,
+  5 + -0.0589478,
+ -1 + 0.0215372,
+ -7 + 0.626992,
+  3 + 0.805443,
+  5 + -0.774861,
+  7 + 0.548483,
+ -7 + -0.659366,
+  5 + -0.399126,
+  5 + 0.280639,
+ -1 + 0.382537,
+  5 + 0.253533,
+ -3 + 0.484453,
+ -1 + -0.182041,
+ -7 + 0.403929,
+  5 + 0.799799,
+ -1 + 0.872509,
+ -1 + 0.446505,
+  1 + 0.072863,
+  1 + 0.511757,
+  5 + -0.0447141,
+  7 + 0.418114,
+  3 + -0.412815,
+ -7 + 0.270519,
+  1 + -0.691355,
+  3 + -0.197421,
+  3 + -0.86134,
+ -5 + -0.0102158,
+  1 + 0.35777,
+  3 + 0.447566,
+ -1 + 0.0185418,
+ -7 + 0.78905,
+  7 + 0.691196,
+ -5 + -0.980607,
+  3 + 0.307422,
+  1 + 0.612522,
+  5 + -0.199466,
+ -1 + -0.459671,
+  1 + 0.170203,
+  5 + 0.345741,
+ -1 + 0.442178,
+ -5 + 0.431563,
+  3 + -0.534043,
+  5 + -0.76423,
+  3 + 0.121284,
+  3 + 0.645713,
+  7 + 0.96808,
+ -7 + 0.488072,
+  3 + -0.00669708,
+  1 + -0.971889,
+ -1 + -0.315525,
+  5 + 0.541525,
+  3 + -0.787017,
+ -1 + 0.544075,
+  3 + -0.0730717,
+ -5 + 0.522401,
+ -5 + -0.323174,
+  7 + 0.526918,
+  5 + -0.385761,
+  5 + -0.895487,
+ -3 + 0.0897052,
+ -5 + -0.670281,
+ -5 + -0.182219,
+ -5 + 0.303178,
+ -5 + -0.947146,
+ -3 + -0.721791,
+ -5 + -0.626817,
+  1 + -0.583032,
+  3 + 0.641241,
+ -7 + -0.520007,
+  1 + -0.425207,
+ -5 + 0.0712658,
+  1 + 0.812682,
+  1 + -0.143148,
+  3 + 0.0762144,
+  1 + 0.0785892,
+  7 + -0.568785,
+  1 + -0.59096,
+  3 + 0.756584,
+ -1 + 0.128497,
+  3 + -0.975302,
+ -1 + -0.757146,
+  5 + 0.448678,
+ -7 + 0.00292395,
+ -3 + -0.0190117,
+  7 + -0.211027,
+ -1 + -0.668733,
+ -5 + -0.447823,
+  1 + -0.502645,
+ -7 + 0.47152,
+ -5 + -0.364533,
+  7 + 0.745433,
+ -5 + 0.753726,
+ -1 + -0.307681,
+ -1 + 0.791775,
+ -5 + -0.151863,
+ -5 + 0.815651,
+  7 + -0.0787568,
+  1 + 0.901984,
+  1 + 0.446558,
+ -5 + 0.035328,
+  5 + -0.461488,
+ -5 + 0.702664,
+  1 + 0.477797,
+ -1 + -0.0921929,
+ -3 + -0.231008,
+  7 + 0.369765,
+ -7 + 0.0220315,
+  5 + -0.0497525,
+ -7 + -0.0740606,
+ -1 + 0.885344,
+  3 + 0.332343,
+ -3 + 0.220104,
+ -1 + 0.384649,
+ -5 + -0.196536,
+ -1 + 0.442901,
+  5 + 0.226845,
+ -7 + 0.378706,
+ -7 + 0.165296,
+  3 + 0.201761,
+  1 + -0.666372,
+ -1 + -0.0523257,
+  3 + 0.636851,
+  5 + -0.717434,
+  1 + -0.354993,
+  3 + -0.720888,
+ -5 + -0.133448,
+ -5 + -0.12999,
+  5 + -0.64646,
+  1 + 0.66513,
+  7 + 0.38796,
+ -3 + 0.983196,
+  1 + 0.156689,
+ -1 + -0.598867,
+  7 + 0.0891009,
+ -3 + 0.564803,
+  5 + 0.647083,
+  3 + 0.28552,
+ -5 + -0.550295,
+  7 + -0.535946,
+  3 + -0.323109,
+  1 + 0.968116,
+ -5 + 0.670887,
+  5 + 0.723851,
+ -7 + 0.14941,
+  1 + 0.751713,
+ -3 + 0.379236,
+ -5 + 0.339108,
+ -5 + -0.301987,
+  3 + -0.683341,
+ -5 + -0.359829,
+  5 + -0.84713,
+ -3 + 0.304565,
+ -3 + 0.861481,
+  7 + -0.877059,
+ -5 + 0.289428,
+ -7 + -0.434084,
+ -1 + -0.481805,
+ -3 + 0.932735,
+ -3 + -0.309733,
+ -3 + -0.656653,
+ -1 + 0.858222,
+ -5 + -0.945002,
+ -3 + -0.379574,
+  1 + -0.329053,
+ -5 + -0.965912,
+ -7 + -0.0862743,
+ -3 + 0.564742,
+  1 + 0.430712,
+  7 + -0.134825,
+  3 + -0.0142276,
+ -3 + 0.461407,
+ -3 + 0.237931,
+  5 + 0.189721,
+ -5 + -0.164975,
+  3 + 0.158177,
+  5 + 0.761349,
+  5 + -0.603701,
+ -1 + 0.343416,
+ -7 + 0.479708,
+  5 + -0.54804,
+  5 + 0.0522417,
+ -7 + -0.975275,
+  3 + 0.908053,
+  7 + -0.324028,
+  1 + 0.20481,
+ -1 + 0.501097,
+ -3 + -0.562607,
+ -5 + 0.555231,
+  1 + -0.158267,
+  3 + -0.0687857,
+  1 + 0.511831,
+ -5 + -0.607408,
+  1 + 0.360143,
+ -1 + 0.437194,
+ -3 + -0.092719,
+  7 + 0.66663,
+ -7 + 0.610324,
+  1 + 0.477642,
+ -3 + -0.690053,
+  5 + -0.239834,
+  5 + 0.430824,
+ -1 + -0.74709,
+ -7 + 0.666542,
+ -3 + 0.787307,
+  5 + 0.12119,
+ -5 + 0.468506,
+ -7 + -0.655536,
+ -3 + -0.362963,
+ -7 + -0.444575,
+ -5 + -0.813438,
+  3 + -0.658917,
+ -7 + -0.846612,
+ -5 + 0.47478,
+  1 + -0.486082,
+ -7 + 0.325601,
+ -3 + 0.10135,
+  3 + 0.616988,
+ -5 + 0.030061,
+  1 + 0.546106,
+ -3 + -0.107568,
+  1 + -0.526698,
+  1 + -0.402568,
+  1 + 0.476488,
+  5 + -0.876816,
+ -7 + -0.814004,
+ -5 + -0.742022,
+  1 + 0.396799,
+  3 + 0.302924,
+  5 + -0.330856,
+  3 + -0.20346,
+  1 + -0.0134361,
+  3 + 0.603609,
+  5 + -0.531407,
+  7 + 0.711484,
+ -1 + 0.520469,
+ -1 + 0.148813,
+  3 + 0.0432309,
+  1 + 0.669779,
+  1 + -0.428549,
+ -3 + 0.260938,
+ -3 + 0.941317,
+ -5 + -0.780941,
+ -3 + -0.747831,
+  1 + -0.998692,
+ -5 + 0.892504,
+ -1 + 0.62686,
+  7 + 0.940684,
+ -1 + -0.157277,
+ -3 + -0.215904,
+  3 + -0.149222,
+ -3 + -0.876603,
+ -7 + -0.20916,
+  3 + -0.984649,
+  7 + -0.60173,
+ -1 + -0.806134,
+ -1 + 0.209397,
+  1 + 0.310198,
+  5 + -0.348507,
+ -3 + 0.966827,
+  1 + -0.781644,
+ -3 + -0.417686,
+  1 + -0.618801,
+  7 + 0.862017,
+ -3 + -0.405402,
+ -7 + 0.125069,
+ -7 + 0.815787,
+ -5 + 0.135567,
+ -5 + 0.652664,
+ -5 + 0.509215,
+ -3 + -0.247757,
+ -3 + -0.697007,
+  7 + -0.760593,
+  3 + -0.772638,
+ -5 + 0.870941,
+ -1 + 0.864873,
+ -1 + -0.695855,
+  3 + -0.952328,
+  7 + -0.984213,
+ -5 + -0.825547,
+  7 + -0.937066,
+  1 + -0.030252,
+  7 + -0.370309,
+ -1 + 0.976445,
+ -1 + 0.105839,
+ -7 + -0.151788,
+  5 + 0.329837,
+  5 + 0.484323,
+  3 + -0.185114,
+  1 + -0.450171,
+  7 + -0.174316,
+  7 + -0.840168,
+ -3 + -0.188744,
+  7 + 0.4487,
+ -5 + 0.0857224,
+  7 + 0.836002,
+ -3 + -0.180574,
+  7 + 0.933189,
+ -3 + 0.850465,
+ -3 + 0.217683,
+  7 + -0.504985,
+  3 + -0.244207,
+ -3 + 0.827852,
+ -3 + 0.231895,
+ -3 + -0.210397,
+ -5 + 0.225256,
+ -5 + -0.424323,
+ -3 + 0.584223,
+  5 + -0.21417,
+  7 + 0.0492111,
+ -5 + 0.717212,
+  3 + 0.127463,
+  5 + -0.412335,
+ -3 + -0.235105,
+  1 + -0.142685,
+  5 + -0.499895,
+  3 + -0.081105,
+ -5 + -0.145618,
+  7 + -0.823428,
+  5 + -0.860577,
+  3 + -0.433851,
+  1 + -0.917788,
+  1 + 0.0316082,
+ -7 + 0.825787,
+ -7 + -0.453454,
+ -7 + 0.00504467,
+ -3 + 0.495271,
+  3 + 0.0318126,
+  5 + -0.344928,
+ -1 + -0.550629,
+ -7 + -0.352606,
+ -1 + -0.122732,
+ -3 + 0.159171,
+  3 + 0.261004,
+  3 + -0.691171,
+  3 + -0.746879,
+  1 + 0.626657,
+ -3 + 0.0388675,
+ -1 + 0.51117,
+  5 + -0.673213,
+ -3 + 0.864677,
+ -7 + -0.726019,
+  7 + -0.729394,
+ -5 + 0.330155,
+ -7 + -0.0177368,
+ -7 + -0.300845,
+  1 + 0.615713,
+  5 + 0.00178831,
+  1 + 0.0232089,
+  7 + 0.0501066,
+ -5 + -0.620755,
+  1 + -0.446627,
+ -1 + -0.417687,
+  7 + 0.871591,
+  7 + -0.750383,
+  7 + 0.402812,
+  1 + -0.147176,
+ -5 + 0.443187,
+  3 + 0.286959,
+  5 + 0.608735,
+ -3 + 0.380043,
+  3 + -0.175819,
+  7 + -0.829562,
+ -7 + -0.79598,
+ -1 + -0.192267,
+ -5 + -0.110678,
+  1 + 0.6394,
+  1 + -0.0846046,
+  1 + 0.714054,
+  5 + 0.811509,
+  1 + -0.398193,
+  7 + 0.760568,
+ -1 + -0.452345,
+ -5 + 0.687367,
+  5 + -0.318674,
+ -3 + 0.324117,
+ -7 + 0.236211,
+ -5 + 0.649759,
+  7 + -0.548562,
+  3 + 0.0579074,
+ -3 + 0.967526,
+  5 + 0.205966,
+  3 + -0.575908,
+ -5 + -0.137605,
+  7 + 0.927195,
+ -5 + 0.454236,
+  5 + -0.445633,
+  3 + 0.770301,
+  7 + -0.281772,
+ -1 + -0.810031,
+ -5 + 0.104421,
+ -3 + 0.920684,
+ -1 + 0.868938,
+  3 + -0.0053164,
+ -3 + -0.718631,
+ -5 + 0.455326,
+  5 + -0.820026,
+ -5 + -0.768273,
+  3 + 0.0752762,
+  5 + 0.714693,
+  7 + -0.17771,
+ -3 + 0.42292,
+ -1 + -0.0175617,
+  5 + 0.528179,
+  3 + 0.568353,
+  5 + -0.587159,
+  1 + 0.801071,
+  7 + 0.0826319,
+ -3 + 0.0275306,
+ -5 + 0.676104,
+ -7 + 0.583124,
+ -3 + 0.218791,
+ -7 + 0.227567,
+ -3 + -0.430536,
+  5 + 0.654163,
+  3 + -0.467692,
+  7 + -0.155845,
+ -7 + 0.089255,
+ -3 + 0.938383,
+ -3 + 0.906627,
+  7 + 0.950595,
+ -5 + -0.489709,
+  7 + 0.671718,
+  7 + 0.164742,
+  3 + -0.852821,
+  7 + 0.582895,
+ -3 + -0.742699,
+  1 + -0.0381558,
+  1 + 0.752823,
+  1 + 0.749102,
+ -1 + 0.403834,
+ -3 + -0.442988,
+  3 + 0.769955,
+ -1 + 0.729227,
+  3 + -0.464394,
+ -1 + 0.982971,
+  5 + 0.32225,
+  3 + 0.707018,
+  7 + 0.284523,
+ -5 + -0.390641,
+  7 + 0.838552,
+  1 + -0.261646,
+  7 + 0.763129,
+ -1 + 0.26582,
+  7 + 0.47961,
+  5 + 0.195016,
+ -1 + 0.442942,
+  1 + -0.566928,
+  1 + -0.885894,
+  3 + 0.809517,
+  7 + -0.794782,
+  1 + 0.396051,
+ -1 + -0.717371,
+ -7 + -0.372855,
+ -3 + -0.435502,
+ -5 + 0.486243,
+ -7 + 0.226385,
+ -3 + -0.674962,
+  5 + -0.818546,
+ -1 + 0.662066,
+ -3 + 0.371445,
+  7 + -0.181262,
+ -7 + -0.96998,
+  7 + -0.243668,
+  1 + -0.622788,
+ -3 + -0.934349,
+ -7 + -0.531977,
+  7 + 0.913129,
+ -5 + 0.0873188,
+ -5 + -0.802866,
+  5 + 0.176445,
+  7 + 0.931233,
+ -1 + -0.345816,
+ -7 + -0.698489,
+  3 + -0.0641756,
+ -1 + 0.20042,
+  3 + -0.225253,
+  7 + 0.611709,
+ -3 + -0.526143,
+  5 + -0.494852,
+ -7 + -0.543889,
+  5 + -0.865676,
+  7 + -0.361067,
+ -7 + 0.157247,
+ -1 + -0.148807,
+ -1 + 0.754306,
+ -3 + -0.232635,
+  1 + 0.285416,
+  5 + 0.977439,
+  3 + -0.545843,
+ -5 + -0.684446,
+  5 + 0.00538877,
+ -1 + -0.416723,
+  1 + 0.455052,
+ -1 + -0.694408,
+ -5 + 0.5697,
+ -3 + 0.239728,
+  7 + -0.157425,
+ -3 + 0.307093,
+  3 + 0.598074,
+ -3 + -0.192316,
+ -5 + 0.683009,
+  1 + -0.276813,
+  7 + -0.0605859,
+  7 + -0.160651,
+  1 + 0.745574,
+  5 + -0.595225,
+ -3 + 0.679057,
+ -7 + 0.681067,
+ -3 + 0.254237,
+  3 + -0.309311,
+ -7 + 0.537294,
+  7 + -0.527087,
+ -1 + -0.914636,
+ -5 + 0.3696,
+ -5 + 0.758544,
+ -3 + 0.615554,
+ -3 + -0.800559,
+  5 + 0.857245,
+ -7 + 0.911095,
+ -7 + -0.476043,
+  1 + 0.286482,
+ -7 + -0.106087,
+ -5 + 0.396264,
+ -5 + -0.897017,
+  1 + -0.963821,
+ -7 + -0.566173,
+ -5 + 0.578676,
+  1 + 0.813064,
+  7 + 0.491473,
+  7 + -0.270985,
+  5 + 0.132949,
+  5 + 0.0161494,
+  1 + 0.474008,
+ -5 + 0.796655,
+ -3 + -0.63918,
+  3 + -0.967985,
+  7 + 0.879643,
+ -1 + 0.214509,
+ -5 + 0.00227151,
+  5 + 0.0762274,
+  3 + 0.59941,
+  3 + 0.340686,
+ -5 + -0.518312,
+ -5 + -0.6534,
+ -3 + -0.133582,
+  1 + 0.772737,
+ -3 + -0.796512,
+ -1 + -0.232784,
+  7 + -0.567475,
+ -5 + -0.612535,
+ -5 + -0.743451,
+ -5 + 0.922795,
+  7 + -0.360325,
+ -5 + 0.664416,
+ -7 + 0.537588,
+ -7 + 0.090611,
+ -1 + -0.411909,
+  3 + -0.926915,
+  7 + 0.395344,
+ -7 + -0.661518,
+ -3 + -0.170838,
+  7 + -0.357837,
+ -5 + 0.471491,
+ -3 + -0.382249,
+ -3 + -0.52305,
+ -1 + -0.97666,
+  3 + 0.0582765,
+ -1 + -0.0656394,
+  7 + -0.406727,
+  1 + 0.00918714,
+ -5 + -0.137935,
+  7 + -0.614004,
+  1 + -0.979364,
+ -7 + 0.416733,
+ -1 + -0.759126,
+ -7 + -0.370293,
+ -7 + -0.100497,
+  1 + 0.869131,
+ -3 + 0.164885,
+ -1 + -0.0975662,
+ -7 + 0.186475,
+  3 + -0.918565,
+  3 + -0.0801415,
+  7 + -0.100654,
+ -7 + -0.0564053,
+ -5 + -0.266266,
+  1 + -0.250558,
+ -7 + 0.00064827,
+  1 + 0.0900851,
+ -5 + -0.598895,
+ -3 + -0.300177,
+ -3 + -0.733429,
+ -1 + 0.644141,
+ -7 + 0.473614,
+ -1 + -0.641922,
+  5 + -0.771156,
+  1 + -0.408759,
+  5 + 0.12316,
+ -5 + 0.293248,
+  1 + -0.878825,
+ -7 + -0.414203,
+  1 + -0.158712,
+  7 + 0.739709,
+ -7 + -0.86936,
+  3 + 0.642115,
+  3 + -0.385535,
+ -7 + 0.143439,
+ -3 + 0.698413,
+  5 + -0.678345,
+  5 + 0.565038,
+  5 + 0.815733,
+  5 + -0.707831,
+ -7 + -0.849665,
+  3 + -0.293231,
+  3 + 0.511878,
+ -7 + 0.0476101,
+ -5 + -0.612903,
+  5 + 0.912856,
+ -1 + -0.229084,
+ -1 + -0.228542,
+ -1 + 0.543728,
+  7 + -0.254476,
+  5 + -0.538093,
+  7 + 0.873386,
+ -7 + -0.797387,
+  1 + 0.472407,
+ -5 + 0.952256,
+ -7 + 0.795923,
+ -1 + -0.0898826,
+ -3 + 0.851045,
+  3 + 0.649821,
+ -5 + -0.623912,
+ -1 + -0.232825,
+ -5 + -0.293336,
+  3 + -0.175406,
+  7 + -0.126623,
+ -3 + -0.458458,
+ -1 + -0.716308,
+  3 + -0.442831,
+  5 + -0.240306,
+ -3 + 0.62798,
+  7 + -0.901771,
+ -1 + 0.980463,
+  3 + -0.502372,
+ -7 + -0.861722,
+ -1 + 0.827093,
+  1 + 0.12554,
+ -3 + 0.270311,
+ -5 + 0.348095,
+ -1 + 0.913085,
+  7 + 0.957399,
+  7 + 0.340458,
+  5 + 0.0422461,
+ -1 + -0.369125,
+ -3 + 0.43044,
+  7 + -0.632377,
+ -1 + -0.90659,
+  1 + -0.89239,
+  7 + 0.828316,
+  5 + 0.824523,
+ -7 + -0.0536567,
+  1 + -0.0399239,
+  1 + 0.197041,
+ -1 + -0.554157,
+ -5 + 0.0431199,
+ -3 + -0.304071,
+ -3 + -0.331796,
+  5 + 0.822257,
+  3 + -0.638709,
+  3 + 0.639501,
+ -1 + -0.549931,
+ -5 + 0.893208,
+  3 + 0.791099,
+  7 + 0.153618,
+  3 + -0.838246,
+ -7 + 0.475597,
+  1 + -0.354901,
+ -7 + -0.761264,
+ -1 + 0.106035,
+ -3 + -0.481434,
+ -1 + 0.234136,
+  5 + 0.375285,
+ -7 + -0.539323,
+ -3 + -0.671027,
+ -3 + 0.212608,
+ -5 + 0.992672,
+ -3 + -0.655146,
+ -1 + -0.675066,
+ -1 + 0.944776,
+  5 + 0.653261,
+  7 + 0.703227,
+ -1 + -0.329846,
+ -3 + -0.29662,
+  5 + 0.0306179,
+  3 + 0.308382,
+  5 + -0.37852,
+  1 + 0.569875,
+ -1 + 0.262195,
+ -7 + 0.65172,
+ -1 + -0.324076,
+ -1 + -0.592955,
+  3 + 0.330534,
+ -7 + 0.236835,
+  7 + -0.16363,
+  5 + -0.350766,
+  7 + 0.33076,
+ -3 + 0.713702,
+  7 + 0.986953,
+  1 + -0.484957,
+  1 + 0.232317,
+  1 + -0.241183,
+  1 + -0.652168,
+ -7 + -0.969083,
+ -3 + -0.00466762,
+  7 + -0.643621,
+  5 + -0.512406,
+  3 + 0.559345,
+ -1 + 0.876841,
+  1 + 0.0247327,
+ -5 + 0.579806,
+ -7 + -0.45585,
+ -1 + -0.978404,
+ -3 + -0.211921,
+  3 + 0.0595151,
+ -5 + -0.772737,
+  1 + 0.701463,
+  7 + -0.055659,
+  1 + -0.434081,
+ -7 + -0.748698,
+  5 + -0.742137,
+  5 + -0.0588123,
+ -5 + 0.446934,
+ -7 + -0.9576,
+ -1 + -0.910423,
+ -1 + -0.798973,
+ -7 + 0.643822,
+ -3 + -0.240149,
+  1 + -0.366265,
+  1 + -0.168219,
+ -7 + -0.030838,
+  7 + -0.591915,
+ -3 + -0.92018,
+  7 + 0.57597,
+ -1 + 0.351344,
+ -7 + 0.647625,
+  5 + -0.537432,
+ -5 + -0.69753,
+  3 + 0.489766,
+ -3 + -0.263308,
+  1 + 0.40383,
+ -1 + 0.0716793,
+ -3 + 0.0739884,
+  7 + -0.543397,
+ -5 + 0.313842,
+ -1 + -0.290457,
+ -3 + -0.84267,
+ -3 + -0.568324,
+ -3 + -0.18694,
+  7 + 0.544842,
+  5 + 0.340199,
+ -5 + -0.465435,
+  5 + 0.386054,
+  3 + -0.248471,
+ -1 + -0.536871,
+ -3 + -0.00456425,
+  5 + 0.30784,
+ -7 + 0.567282,
+ -3 + -0.689596,
+  7 + -0.973479,
+ -5 + -0.292588,
+  1 + -0.0853992,
+  1 + 0.54008,
+  1 + 0.933126,
+  7 + 0.308498,
+ -5 + 0.933511,
+ -1 + -0.616556,
+  1 + 0.5256,
+ -3 + 0.11786,
+ -1 + 0.742156,
+ -1 + 0.169955,
+ -1 + -0.96657,
+ -3 + 0.556796,
+ -1 + -0.865691,
+ -3 + -0.238262,
+ -5 + 0.647911,
+  3 + 0.359834,
+  7 + 0.613736,
+  1 + 0.507745,
+ -7 + -0.892512,
+  3 + 0.444704,
+  7 + -0.939748,
+ -1 + 0.672554,
+ -7 + 0.136662,
+ -7 + 0.565658,
+  3 + 0.942443,
+ -1 + 0.0449975,
+  1 + 0.92684,
+  3 + -0.297685,
+  5 + 0.568496,
+  3 + -0.144333,
+  1 + -0.166059,
+  5 + 0.245617,
+ -7 + 0.0561295,
+  5 + -0.053852,
+  5 + 0.796947,
+ -5 + 0.352517,
+ -5 + 0.967329,
+  5 + -0.892274,
+  7 + -0.335576,
+ -1 + -0.545664,
+  5 + 0.768217,
+ -7 + -0.188918,
+ -7 + 0.285642,
+ -3 + -0.467917,
+ -1 + 0.356141,
+ -7 + -0.382192,
+ -5 + 0.0410403,
+ -3 + 0.593099,
+ -1 + -0.407076,
+  7 + 0.399012,
+  3 + -0.215368,
+  5 + 0.00567285,
+  3 + 0.833758,
+  7 + -0.469107,
+ -3 + 0.84339,
+ -1 + -0.648244,
+ -1 + 0.45709,
+  5 + 0.221697,
+ -3 + 0.2979,
+ -1 + -0.801441,
+  5 + 0.358525,
+  5 + 0.0155232,
+  7 + -0.613239,
+ -3 + 0.770038,
+ -3 + 0.386763,
+ -1 + -0.977012,
+ -5 + 0.0247041,
+  3 + -0.774763,
+  1 + -0.269862,
+  3 + 0.598317,
+ -7 + -0.604919,
+ -5 + -0.295425,
+ -3 + -0.501016,
+  5 + 0.893051,
+ -7 + 0.592268,
+ -1 + -0.135156,
+  5 + -0.766252,
+ -3 + 0.445672,
+  5 + 0.612924,
+ -5 + 0.107889,
+ -1 + 0.306333,
+ -3 + -0.720024,
+  1 + -0.256542,
+ -5 + -0.644907,
+ -1 + -0.198375,
+ -1 + 0.530318,
+  7 + 0.865427,
+ -5 + -0.186188,
+  3 + 0.15118,
+  5 + 0.652307,
+  1 + 0.908472,
+  3 + 0.747761,
+ -1 + -0.654492,
+  1 + -0.454527,
+  5 + 0.682724,
+ -5 + 0.372245,
+  7 + 0.871819,
+  3 + -0.80367,
+ -1 + 0.448117,
+ -1 + 0.948526,
+ -7 + -0.348271,
+  7 + -0.927127,
+  1 + 0.449701,
+ -1 + -0.680563,
+  1 + 0.892784,
+  1 + -0.0924386,
+ -1 + -0.959661,
+  7 + -0.081394,
+  5 + -0.963336,
+ -5 + 0.805157,
+ -7 + -0.285785,
+ -7 + -0.592211,
+ -5 + 0.413432,
+ -1 + -0.723101,
+ -3 + -0.0432179,
+ -3 + 0.357774,
+  3 + -0.969629,
+ -7 + 0.840992,
+  7 + -0.0670359,
+  1 + -0.230027,
+ -7 + 0.00539775,
+ -1 + 0.992222,
+ -5 + 0.508197,
+ -1 + -0.0701932,
+ -7 + -0.916136,
+  1 + 0.121754,
+  3 + 0.979212,
+  5 + 0.710977,
+ -3 + -0.444553,
+  1 + 0.775755,
+  1 + -0.731095,
+ -5 + -0.962054,
+ -7 + -0.137716,
+  1 + 0.0744596,
+ -3 + -0.298853,
+  3 + -0.287877,
+  7 + -0.537653,
+  7 + -0.370057,
+  5 + 0.558642,
+ -1 + -0.306097,
+  5 + 0.298301,
+  5 + 0.890951,
+  7 + 0.461226,
+  5 + -0.273165,
+ -3 + 0.767864,
+ -1 + -0.427128,
+ -7 + 0.0742497,
+  3 + -0.628171,
+ -1 + -0.383706,
+ -5 + 0.926895,
+ -3 + -0.111893,
+ -1 + -0.568481,
+  3 + 0.982367,
+  3 + -0.746265,
+  7 + 0.602531,
+  5 + 0.639663,
+ -5 + 0.640932,
+  3 + -0.339199,
+ -7 + -0.872224,
+  7 + 0.493771,
+  5 + -0.0426846,
+  7 + -0.222289,
+  7 + -0.802753,
+  5 + -0.998975,
+  5 + 0.739618,
+  5 + -0.949418,
+ -7 + -0.348646,
+  7 + -0.122117,
+ -3 + -0.786274,
+ -1 + -0.910026,
+  5 + -0.521515,
+  5 + 0.786492,
+ -3 + -0.956601,
+ -7 + -0.935189,
+ -1 + 0.816024,
+  5 + 0.675236,
+  5 + 0.0495799,
+ -7 + 0.738648,
+  7 + 0.424409,
+  3 + -0.438266,
+ -7 + -0.491474,
+  1 + 0.22495,
+ -5 + -0.0235629,
+ -3 + 0.479672,
+ -1 + 0.84058,
+ -5 + -0.166951,
+  5 + -0.0577841,
+ -1 + -0.642721,
+ -1 + 0.723607,
+  1 + -0.873909,
+  3 + -0.888751,
+ -1 + -0.370589,
+ -3 + -0.0403842,
+  3 + 0.564038,
+  1 + -0.590923,
+ -1 + -0.301823,
+  3 + -0.525907,
+ -7 + -0.700129,
+ -7 + -0.286343,
+ -1 + -0.746766,
+ -1 + 0.510312,
+ -7 + 0.68781,
+ -1 + -0.071507,
+  5 + 0.20512,
+  7 + 0.193939,
+ -3 + 0.0940258,
+ -1 + -0.815724,
+  7 + 0.914182,
+  3 + 0.582396,
+ -5 + 0.182791,
+  5 + -0.169328,
+  5 + -0.539398,
+  1 + -0.544711,
+ -7 + -0.29523,
+ -7 + -0.220718,
+ -7 + -0.424836,
+ -1 + -0.583509,
+  5 + -0.998364,
+  7 + -0.624936,
+ -3 + 0.682019,
+  7 + -0.0926723,
+ -3 + -0.596477,
+ -1 + -0.380871,
+ -3 + -0.215605,
+  7 + -0.0981703,
+ -7 + -0.181927,
+ -1 + 0.668344,
+  1 + 0.550972,
+  1 + -0.362117,
+ -1 + 0.434212,
+ -7 + 0.529025,
+  5 + -0.166071,
+ -3 + 0.473601,
+  5 + 0.555215,
+  7 + 0.878004,
+  3 + 0.90408,
+ -5 + 0.504969,
+ -3 + -0.667642,
+ -5 + -0.538538,
+  5 + 0.188161,
+ -1 + 0.914107,
+  3 + 0.472097,
+  7 + 0.510842,
+ -5 + 0.985461,
+ -7 + -0.394255,
+ -5 + 0.890095,
+  5 + 0.634067,
+ -7 + -0.944812,
+ -1 + -0.199624,
+ -1 + -0.447444,
+  3 + -0.228946,
+  7 + 0.22322,
+ -5 + 0.654362,
+ -5 + -0.200935,
+  3 + -0.833657,
+ -7 + 0.802499,
+  1 + -0.704644,
+  5 + -0.415231,
+  5 + -0.488818,
+ -5 + -0.405574,
+ -3 + -0.551587,
+  3 + -0.143344,
+ -5 + 0.992058,
+  7 + 0.973004,
+ -1 + 0.899068,
+ -1 + -0.201666,
+ -5 + -0.327868,
+  3 + -0.727053,
+ -7 + 0.268601,
+ -7 + 0.109424,
+  7 + -0.950672,
+  1 + 0.76586,
+ -3 + 0.875399,
+  7 + 0.0168127,
+ -5 + -0.751942,
+  1 + 0.455423,
+  5 + -0.133098,
+  5 + 0.576325,
+ -5 + -0.760309,
+ -7 + -0.273288,
+ -7 + -0.766843,
+  1 + -0.862775,
+  7 + -0.885211,
+  7 + 0.696724,
+ -1 + 0.0780369,
+  1 + 0.275855,
+ -5 + 0.21323,
+ -1 + 0.30191,
+  5 + -0.129398,
+ -3 + -0.659394,
+  7 + -0.537345,
+ -5 + 0.726379,
+  1 + -0.351187,
+  1 + 0.413273,
+ -7 + -0.460414,
+ -1 + 0.780082,
+  7 + -0.750839,
+  7 + 0.140123,
+ -1 + 0.431409,
+ -1 + 0.467309,
+  7 + -0.189717,
+ -5 + -0.619566,
+  1 + -0.664491,
+  5 + -0.259023,
+ -3 + 0.956683,
+ -3 + -0.749516,
+ -5 + 0.131912,
+ -7 + 0.20736,
+ -7 + -0.370862,
+  3 + -0.38448,
+ -7 + -0.0683076,
+  5 + -0.0808511,
+  3 + -0.716107,
+ -7 + 0.282494,
+ -5 + 0.690208,
+  5 + -0.0140297,
+  3 + -0.0253589,
+ -1 + -0.286539,
+  1 + 0.632755,
+  3 + 0.678366,
+  7 + -0.298717,
+  7 + 0.931446,
+  3 + -0.000155271,
+  5 + 0.593412,
+ -1 + -0.237465,
+  3 + 0.495449,
+  1 + 0.854041,
+  7 + 0.417438,
+  5 + 0.130533,
+  3 + 0.11828,
+  7 + -0.492641,
+ -3 + 0.31251,
+ -1 + -0.746348,
+ -3 + 0.00667295,
+ -7 + -0.849606,
+ -1 + -0.621633,
+  5 + -0.780689,
+ -7 + 0.325068,
+ -1 + 0.14253,
+ -5 + -0.467373,
+ -7 + -0.215694,
+ -5 + 0.473324,
+ -5 + -0.0749665,
+  1 + 0.0177372,
+  1 + 0.874646,
+ -3 + -0.548775,
+ -5 + -0.644173,
+  7 + 0.890543,
+  1 + -0.258939,
+ -1 + -0.381203,
+  7 + -0.989668,
+  7 + -0.370075,
+ -7 + 0.0443089,
+  7 + -0.655745,
+ -1 + 0.576317,
+  1 + -0.867409,
+ -1 + -0.242211,
+  3 + -0.414673,
+ -3 + -0.668824,
+ -7 + -0.880169,
+ -7 + -0.337623,
+  3 + 0.421604,
+  5 + 0.213655,
+  5 + -0.797275,
+  5 + 0.0784746,
+ -7 + 0.29279,
+  5 + -0.266808,
+  5 + -0.847968,
+  3 + 0.627592,
+  5 + 0.100925,
+ -7 + -0.836569,
+ -5 + -0.484448,
+ -7 + -0.260665,
+  7 + 0.98659,
+  5 + 0.811925,
+  5 + -0.263092,
+  3 + -0.423208,
+  3 + -0.219005,
+ -7 + -0.0725037,
+ -1 + -0.814871,
+  3 + 0.181891,
+ -3 + 0.309198,
+  1 + 0.951535,
+ -7 + 0.694465,
+ -3 + 0.851734,
+ -3 + 0.240617,
+  7 + -0.545582,
+  7 + -0.582447,
+ -3 + -0.895393,
+  1 + -0.607017,
+  5 + 0.575812,
+  7 + 0.0485804,
+ -5 + -0.609581,
+  3 + -0.991071,
+  1 + -0.69817,
+ -1 + 0.612983,
+  7 + 0.124632,
+  1 + -0.934992,
+ -5 + 0.629333,
+ -1 + -0.479678,
+ -7 + -0.690851,
+  3 + 0.0123024,
+  3 + 0.579883,
+ -7 + -0.797862,
+  3 + 0.930494,
+  5 + 0.0959856,
+  5 + 0.799511,
+  3 + -0.702544,
+  3 + 0.863534,
+ -7 + 0.723902,
+  3 + -0.925485,
+ -3 + 0.0838314,
+  5 + -0.539124,
+ -7 + 0.795782,
+ -7 + -0.508871,
+  3 + -0.666186,
+ -5 + -0.437818,
+  1 + 0.430824,
+ -1 + 0.890288,
+  3 + 0.0323077,
+ -5 + -0.451717,
+  1 + -0.994217,
+ -5 + -0.889329,
+  1 + -0.154296,
+  3 + -0.139546,
+  3 + 0.783946,
+ -1 + 0.843542,
+ -7 + 0.742655,
+  3 + 0.0644047,
+ -3 + 0.707173,
+  7 + -0.292937,
+ -1 + 0.978045,
+  3 + -0.495493,
+  1 + 0.576421,
+ -5 + 0.830068,
+ -7 + -0.7389,
+ -3 + 0.545496,
+  5 + 0.525718,
+ -5 + 0.491613,
+ -5 + 0.0724149,
+ -5 + -0.581892,
+ -5 + 0.148299,
+ -3 + -0.0143521,
+ -7 + 0.224096,
+ -1 + -0.58379,
+ -7 + -0.746189,
+  3 + 0.678161,
+  5 + -0.60352,
+  1 + -0.0123151,
+ -3 + 0.935789,
+  7 + 0.146463,
+  5 + 0.0833464,
+ -5 + 0.0973773,
+  1 + -0.634221,
+  5 + -0.199689,
+ -5 + -0.977316,
+  1 + -0.468532,
+ -3 + 0.912407,
+ -1 + 0.618525,
+ -5 + 0.641828,
+ -3 + 0.161639,
+  3 + -0.521444,
+  1 + 0.217545,
+ -3 + 0.776886,
+ -5 + -0.0861521,
+  7 + -0.684462,
+  3 + 0.025459,
+  5 + -0.588791,
+  3 + -0.968869,
+ -5 + 0.936218,
+  5 + -0.962381,
+  1 + 0.102731,
+  7 + 0.487412,
+  5 + -0.586347,
+ -5 + 0.483033,
+  3 + 0.147303,
+  7 + 0.545176,
+ -1 + -0.346122,
+ -3 + -0.550012,
+ -3 + 0.175068,
+  5 + -0.32015,
+  1 + 0.524341,
+ -7 + 0.645118,
+ -5 + -0.940018,
+ -1 + -0.97908,
+ -7 + -0.515108,
+ -3 + 0.367395,
+  1 + 0.545659,
+  1 + -0.286328,
+  5 + -0.58779,
+  1 + 0.337098,
+  7 + -0.330973,
+ -3 + 0.374149,
+  7 + -0.0352384,
+ -3 + 0.100802,
+ -3 + -0.496571,
+  5 + -0.780307,
+  1 + -0.478443,
+  5 + 0.67526,
+  7 + -0.425565,
+  7 + 0.754558,
+ -7 + -0.775828,
+  5 + 0.655701,
+  7 + -0.438407,
+  3 + -0.775985,
+  7 + -0.666725,
+ -1 + 0.797674,
+  1 + -0.749333,
+ -7 + 0.194764,
+ -7 + 0.625181,
+ -5 + -0.060977,
+ -5 + 0.643178,
+  3 + -0.933005,
+ -3 + -0.998434,
+  3 + 0.713815,
+ -3 + -0.574046,
+ -3 + -0.0416154,
+ -7 + 0.296629,
+  7 + 0.191779,
+ -7 + 0.833033,
+ -3 + 0.487987,
+ -3 + -0.575328,
+  5 + 0.496461,
+  3 + 0.589905,
+  7 + -0.924183,
+ -1 + 0.696718,
+  5 + -0.875373,
+ -3 + 0.0319824,
+  5 + -0.207871,
+  3 + 0.177233,
+ -3 + -0.761711,
+  1 + 0.401589,
+  7 + 0.538526,
+  7 + -0.320289,
+ -3 + -0.281917,
+ -5 + -0.547839,
+ -7 + -0.322797,
+ -5 + -0.605992,
+  5 + 0.785395,
+ -1 + 0.0550308,
+ -5 + 0.511285,
+ -7 + 0.402531,
+ -7 + -0.464181,
+  5 + -0.160938,
+ -5 + -0.735561,
+ -5 + 0.0996571,
+  7 + 0.593118,
+  7 + -0.0328994,
+ -5 + -0.98964,
+  3 + 0.205471,
+ -1 + 0.200857,
+  7 + -0.771514,
+  1 + -0.587245,
+  3 + 0.26805,
+ -3 + 0.784424,
+ -5 + -0.963779,
+  7 + -0.505932,
+ -1 + -0.171588,
+ -1 + 0.670593,
+ -7 + 0.301767,
+  5 + 0.0138393,
+ -1 + -0.984387,
+ -1 + 0.0391519,
+ -3 + -0.222087,
+  7 + 0.0864488,
+  5 + -0.4927,
+  7 + 0.257574,
+ -3 + 0.232144,
+ -7 + 0.327466,
+  1 + -0.464061,
+ -3 + -0.275329,
+ -1 + -0.0648923,
+ -7 + 0.674159,
+ -7 + -0.413218,
+ -7 + -0.692417,
+  1 + -0.762459,
+ -5 + -0.913253,
+ -7 + 0.36255,
+ -5 + 0.917413,
+ -7 + 0.556944,
+  7 + 0.869794,
+ -5 + 0.599393,
+ -7 + -0.957509,
+  3 + -0.0653876,
+ -3 + 0.542317,
+  7 + -0.919778,
+ -1 + 0.389195,
+  1 + -0.694826,
+ -1 + -0.684451,
+  5 + -0.232338,
+  7 + 0.107159,
+  1 + -0.408376,
+  3 + -0.669585,
+  5 + 0.257082,
+  5 + 0.831891,
+ -1 + 0.211606,
+ -5 + -0.384855,
+  7 + 0.020007,
+ -5 + -0.428625,
+ -3 + -0.0360878,
+  5 + -0.848203,
+  3 + 0.0254734,
+ -3 + 0.749542,
+ -7 + -0.804563,
+ -1 + -0.0972806,
+  1 + -0.248763,
+ -5 + -0.480906,
+ -7 + 0.494774,
+ -7 + 0.809284,
+  1 + 0.892301,
+  3 + -0.866702,
+  7 + 0.549121,
+ -7 + -0.807113,
+  5 + 0.817796,
+ -3 + -0.258985,
+ -3 + -0.652257,
+  1 + 0.857754,
+  1 + 0.602559,
+ -3 + 0.459551,
+ -5 + 0.12109,
+  7 + 0.228169,
+  3 + 0.268535,
+ -5 + -0.511365,
+  3 + 0.473797,
+ -3 + 0.789188,
+  5 + -0.233201,
+ -1 + 0.337202,
+  3 + 0.0872898,
+ -5 + -0.577231,
+ -3 + -0.794605,
+ -3 + 0.948282,
+  1 + 0.86739,
+  7 + -0.853303,
+  1 + 0.585277,
+ -5 + -0.0480538,
+  3 + 0.131517,
+ -5 + 0.256086,
+  3 + -0.220017,
+ -1 + 0.968746,
+  1 + -0.866085,
+  1 + -0.75045,
+  3 + 0.103057,
+  3 + -0.280213,
+  7 + -0.915525,
+  1 + 0.910469,
+ -1 + 0.122471,
+  7 + 0.756213,
+ -1 + -0.979998,
+ -3 + -0.526045,
+ -3 + -0.515105,
+ -3 + 0.191857,
+ -5 + 0.861293,
+ -5 + 0.557644,
+ -7 + 0.955665,
+ -7 + -0.218954,
+ -5 + 0.843849,
+  3 + 0.700339,
+ -5 + 0.308848,
+  5 + -0.671504,
+ -7 + -0.977673,
+ -3 + -0.243973,
+ -7 + -0.21181,
+  5 + -0.722984,
+  1 + -0.679969,
+  1 + -0.943541,
+ -5 + 0.705531,
+ -5 + -0.327772,
+  3 + -0.462895,
+ -3 + 0.0536484,
+ -5 + -0.181505,
+  1 + -0.89014,
+  3 + -0.24572,
+  3 + -0.890222,
+ -3 + 0.668824,
+ -1 + -0.785433,
+ -5 + -0.835302,
+  7 + -0.464588,
+ -3 + -0.970526,
+ -7 + -0.881556,
+  3 + -0.690873,
+ -7 + 0.627452,
+  7 + 0.162041,
+  1 + 0.574909,
+ -3 + -0.436167,
+ -7 + -0.415736,
+ -1 + -0.330565,
+  3 + -0.0637465,
+  1 + -0.952135,
+  7 + 0.820211,
+  1 + 0.670167,
+  3 + -0.227245,
+  3 + 0.784935,
+ -7 + -0.114356,
+ -7 + -0.79073,
+ -7 + -0.0845568,
+ -3 + 0.0352457,
+ -1 + 0.23913,
+  3 + -0.319363,
+ -1 + -0.784674,
+  7 + 0.182406,
+ -3 + -0.208943,
+  1 + -0.0539068,
+  5 + -0.793545,
+  7 + -0.926668,
+ -3 + -0.327488,
+ -5 + 0.286006,
+  5 + 0.755716,
+ -1 + 0.396711,
+ -5 + 0.50953,
+ -5 + 0.0396668,
+ -7 + 0.294158,
+  7 + 0.191498,
+  1 + -0.157408,
+  1 + -0.341843,
+  1 + 0.34502,
+  1 + 0.892611,
+  7 + 0.205394,
+ -3 + 0.558871,
+ -5 + 0.209696,
+ -1 + 0.119176,
+  3 + -0.0071817,
+ -5 + -0.177535,
+  3 + 0.909066,
+ -3 + -0.741923,
+  1 + -0.539941,
+ -3 + -0.037078,
+  1 + 0.791042,
+ -5 + 0.482362,
+ -5 + -0.0119576,
+ -3 + 0.52501,
+ -7 + 0.76094,
+ -7 + 0.813217,
+  7 + 0.985842,
+  3 + -0.529906,
+  1 + -0.423377,
+ -3 + 0.0981717,
+ -3 + -0.223135,
+ -5 + -0.61793,
+  5 + -0.559953,
+  5 + -0.469591,
+ -1 + 0.342377,
+  3 + -0.0782716,
+  7 + -0.684588,
+  7 + 0.389739,
+  5 + 0.10658,
+ -5 + 0.922608,
+  7 + 0.602939,
+ -1 + 0.464956,
+  3 + -0.789037,
+  5 + 0.429394,
+  3 + -0.550469,
+  1 + -0.900731,
+ -3 + -0.623247,
+ -7 + -0.650424,
+ -1 + 0.131661,
+ -1 + -0.806985,
+  1 + 0.960326,
+ -1 + -0.193632,
+  7 + 0.582939,
+ -1 + -0.468436,
+  5 + 0.0584084,
+ -3 + 0.989501,
+ -7 + -0.836051,
+ -7 + 0.494241,
+ -3 + 0.338635,
+ -1 + -0.648491,
+ -3 + 0.319444,
+  5 + -0.976509,
+ -7 + -0.560152,
+  1 + 0.968145,
+ -3 + 0.506876,
+  1 + -0.446687,
+ -3 + -0.557403,
+ -5 + 0.386343,
+  7 + -0.26601,
+  5 + 0.768097,
+ -1 + -0.862516,
+  3 + 0.092811,
+  1 + 0.688699,
+ -7 + 0.437148,
+ -7 + 0.819611,
+ -5 + 0.433439,
+ -3 + 0.0525214,
+  7 + -0.875873,
+ -1 + -0.318693,
+ -7 + 0.941041,
+  3 + -0.938497,
+ -5 + -0.700787,
+ -5 + -0.208713,
+ -1 + -0.926069,
+  5 + 0.763435,
+ -3 + -0.753673,
+ -3 + -0.436892,
+  5 + 0.25309,
+  3 + 0.376517,
+  7 + 0.234089,
+ -1 + 0.602584,
+  7 + -0.729457,
+ -5 + 0.528713,
+  5 + -0.0616122,
+ -5 + 0.485624,
+ -3 + 0.341517,
+  3 + -0.364478,
+  7 + 0.124957,
+ -1 + -0.27282,
+  5 + 0.606241,
+ -7 + 0.409408,
+ -7 + 0.326685,
+  1 + -0.778263,
+ -5 + -0.479604,
+ -5 + 0.454517,
+  5 + -0.236371,
+ -5 + -0.208087,
+ -7 + -0.336902,
+ -3 + 0.704184,
+ -1 + -0.607403,
+ -1 + 0.790341,
+ -1 + -0.458402,
+  3 + 0.29028,
+ -5 + 0.608615,
+ -5 + 0.064577,
+  7 + -0.440438,
+  7 + 0.518133,
+  3 + -0.400959,
+ -5 + 0.957821,
+ -3 + 0.832433,
+ -7 + -0.941491,
+ -3 + -0.158894,
+ -3 + 0.735858,
+ -5 + -0.942659,
+ -7 + 0.362461,
+ -3 + 0.175003,
+ -3 + 0.756938,
+  5 + -0.586989,
+ -3 + -0.867437,
+ -7 + 0.204605,
+  7 + -0.447344,
+  7 + 0.37656,
+ -7 + 0.548076,
+  5 + -0.720016,
+ -7 + -0.533887,
+ -1 + 0.0948688,
+ -1 + 0.921622,
+  5 + -0.363181,
+  1 + 0.875163,
+  1 + -0.975703,
+ -7 + -0.991177,
+  3 + 0.142339,
+ -7 + -0.670125,
+  7 + 0.835181,
+ -7 + -0.176508,
+  7 + -0.391808,
+ -3 + 0.659639,
+ -7 + 0.311382,
+ -5 + 0.965804,
+  3 + 0.127325,
+  1 + -0.000208556,
+ -7 + -0.777168,
+ -3 + 0.467445,
+ -7 + -0.274472,
+  7 + -0.125423,
+ -7 + -0.341567,
+ -7 + -0.152778,
+  3 + 0.328462,
+  3 + 0.96799,
+  3 + -0.863599,
diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat
new file mode 100644 (file)
index 0000000..462b664
--- /dev/null
@@ -0,0 +1,2484 @@
+69,
+35,
+24,
+72,
+92,
+92,
+20,
+88,
+31,
+124,
+88,
+87,
+65,
+30,
+169,
+225,
+0,
+98,
+8,
+39,
+35,
+233,
+205,
+67,
+15,
+37,
+249,
+114,
+194,
+215,
+196,
+7,
+251,
+93,
+80,
+215,
+186,
+228,
+48,
+217,
+97,
+137,
+177,
+163,
+168,
+90,
+132,
+168,
+189,
+140,
+208,
+224,
+118,
+158,
+36,
+134,
+196,
+29,
+248,
+134,
+245,
+189,
+141,
+240,
+26,
+221,
+200,
+212,
+194,
+248,
+173,
+35,
+130,
+95,
+198,
+42,
+185,
+74,
+211,
+119,
+215,
+164,
+88,
+78,
+66,
+124,
+212,
+6,
+154,
+204,
+141,
+143,
+137,
+27,
+127,
+164,
+249,
+72,
+120,
+187,
+64,
+38,
+222,
+195,
+133,
+165,
+237,
+63,
+240,
+193,
+183,
+199,
+101,
+15,
+21,
+168,
+140,
+233,
+175,
+38,
+182,
+60,
+182,
+64,
+87,
+53,
+228,
+80,
+126,
+93,
+11,
+191,
+132,
+234,
+130,
+10,
+143,
+112,
+74,
+127,
+49,
+2,
+71,
+150,
+18,
+93,
+63,
+158,
+71,
+238,
+197,
+253,
+43,
+123,
+62,
+130,
+177,
+35,
+211,
+47,
+129,
+223,
+238,
+6,
+202,
+112,
+17,
+89,
+224,
+91,
+217,
+17,
+94,
+33,
+168,
+112,
+126,
+231,
+14,
+197,
+214,
+212,
+195,
+1,
+79,
+1,
+132,
+1,
+36,
+87,
+48,
+165,
+55,
+30,
+172,
+1,
+143,
+189,
+90,
+112,
+24,
+52,
+130,
+119,
+85,
+42,
+231,
+211,
+18,
+246,
+153,
+232,
+202,
+92,
+234,
+26,
+93,
+110,
+27,
+130,
+197,
+75,
+40,
+253,
+106,
+212,
+254,
+250,
+145,
+89,
+106,
+170,
+141,
+236,
+33,
+227,
+23,
+9,
+183,
+41,
+255,
+80,
+18,
+201,
+172,
+252,
+227,
+10,
+107,
+255,
+141,
+49,
+74,
+181,
+46,
+181,
+138,
+44,
+175,
+27,
+133,
+26,
+198,
+19,
+6,
+232,
+246,
+29,
+241,
+174,
+71,
+240,
+254,
+90,
+185,
+171,
+87,
+157,
+182,
+194,
+157,
+67,
+243,
+232,
+248,
+34,
+157,
+130,
+78,
+77,
+158,
+212,
+103,
+100,
+231,
+110,
+76,
+222,
+140,
+61,
+140,
+211,
+46,
+138,
+46,
+232,
+54,
+133,
+133,
+236,
+72,
+35,
+47,
+59,
+11,
+40,
+94,
+168,
+171,
+172,
+246,
+74,
+128,
+93,
+174,
+104,
+204,
+251,
+70,
+88,
+57,
+210,
+44,
+103,
+93,
+90,
+79,
+148,
+223,
+213,
+129,
+39,
+248,
+177,
+99,
+4,
+217,
+193,
+172,
+133,
+110,
+162,
+207,
+239,
+0,
+126,
+87,
+205,
+121,
+158,
+37,
+179,
+113,
+81,
+27,
+207,
+171,
+107,
+99,
+139,
+65,
+228,
+178,
+58,
+149,
+22,
+62,
+111,
+216,
+234,
+244,
+70,
+141,
+195,
+54,
+142,
+66,
+141,
+91,
+187,
+44,
+129,
+111,
+157,
+210,
+138,
+108,
+126,
+245,
+208,
+9,
+55,
+180,
+188,
+113,
+74,
+211,
+175,
+185,
+171,
+154,
+174,
+242,
+40,
+114,
+40,
+183,
+180,
+182,
+19,
+112,
+226,
+148,
+223,
+128,
+103,
+106,
+237,
+229,
+96,
+189,
+239,
+151,
+114,
+172,
+8,
+189,
+127,
+184,
+118,
+43,
+83,
+37,
+29,
+123,
+151,
+70,
+50,
+76,
+252,
+69,
+188,
+223,
+218,
+156,
+96,
+65,
+6,
+77,
+39,
+102,
+11,
+23,
+254,
+125,
+195,
+7,
+59,
+67,
+191,
+178,
+111,
+18,
+215,
+141,
+142,
+111,
+211,
+192,
+187,
+208,
+6,
+119,
+176,
+225,
+19,
+16,
+34,
+26,
+94,
+74,
+128,
+105,
+97,
+127,
+231,
+37,
+134,
+35,
+104,
+69,
+213,
+215,
+88,
+172,
+101,
+230,
+27,
+56,
+167,
+214,
+9,
+174,
+78,
+185,
+143,
+98,
+202,
+178,
+124,
+40,
+253,
+253,
+146,
+94,
+124,
+122,
+131,
+2,
+157,
+236,
+72,
+114,
+196,
+161,
+31,
+41,
+136,
+58,
+98,
+47,
+17,
+107,
+222,
+96,
+37,
+110,
+194,
+239,
+32,
+63,
+24,
+29,
+60,
+170,
+124,
+185,
+37,
+0,
+188,
+195,
+237,
+4,
+53,
+178,
+165,
+84,
+219,
+45,
+143,
+62,
+93,
+161,
+169,
+60,
+1,
+206,
+170,
+196,
+190,
+203,
+4,
+214,
+232,
+65,
+129,
+101,
+250,
+166,
+102,
+182,
+105,
+83,
+186,
+159,
+5,
+96,
+244,
+225,
+142,
+132,
+31,
+236,
+37,
+201,
+40,
+39,
+152,
+210,
+236,
+86,
+157,
+240,
+44,
+134,
+49,
+173,
+235,
+44,
+83,
+81,
+226,
+189,
+165,
+157,
+93,
+170,
+254,
+81,
+140,
+141,
+213,
+171,
+121,
+251,
+117,
+161,
+35,
+13,
+116,
+16,
+99,
+17,
+0,
+144,
+152,
+50,
+61,
+132,
+95,
+145,
+214,
+66,
+79,
+123,
+223,
+172,
+38,
+222,
+254,
+178,
+107,
+211,
+94,
+229,
+207,
+212,
+134,
+242,
+225,
+251,
+2,
+69,
+12,
+3,
+214,
+164,
+54,
+20,
+40,
+149,
+165,
+254,
+215,
+245,
+122,
+183,
+162,
+160,
+150,
+160,
+83,
+1,
+116,
+177,
+230,
+67,
+133,
+109,
+54,
+103,
+104,
+56,
+173,
+117,
+60,
+131,
+26,
+115,
+151,
+67,
+9,
+61,
+65,
+224,
+50,
+188,
+152,
+212,
+92,
+46,
+116,
+175,
+48,
+232,
+97,
+23,
+44,
+231,
+132,
+98,
+78,
+237,
+155,
+251,
+98,
+215,
+126,
+124,
+74,
+22,
+191,
+83,
+83,
+1,
+52,
+133,
+189,
+205,
+90,
+26,
+252,
+207,
+202,
+45,
+183,
+43,
+68,
+228,
+19,
+201,
+70,
+98,
+182,
+225,
+93,
+25,
+185,
+220,
+150,
+4,
+243,
+86,
+88,
+70,
+88,
+141,
+203,
+21,
+90,
+38,
+48,
+87,
+245,
+250,
+132,
+173,
+38,
+200,
+145,
+57,
+145,
+215,
+156,
+72,
+185,
+250,
+98,
+114,
+215,
+248,
+119,
+202,
+78,
+207,
+16,
+166,
+92,
+220,
+188,
+183,
+2,
+237,
+14,
+247,
+231,
+146,
+164,
+14,
+91,
+53,
+72,
+237,
+13,
+228,
+53,
+199,
+222,
+151,
+57,
+181,
+144,
+177,
+127,
+222,
+128,
+143,
+133,
+220,
+107,
+66,
+147,
+109,
+47,
+162,
+101,
+23,
+52,
+9,
+37,
+143,
+63,
+110,
+125,
+77,
+82,
+179,
+20,
+49,
+75,
+78,
+230,
+219,
+255,
+102,
+186,
+127,
+246,
+64,
+92,
+98,
+130,
+240,
+208,
+177,
+146,
+53,
+200,
+198,
+63,
+238,
+86,
+127,
+92,
+212,
+204,
+175,
+135,
+224,
+224,
+210,
+47,
+199,
+173,
+46,
+45,
+104,
+174,
+36,
+168,
+10,
+134,
+42,
+250,
+86,
+220,
+141,
+139,
+165,
+83,
+203,
+148,
+170,
+74,
+241,
+126,
+22,
+160,
+6,
+247,
+128,
+216,
+38,
+72,
+134,
+85,
+117,
+238,
+3,
+153,
+151,
+13,
+32,
+194,
+8,
+118,
+158,
+149,
+2,
+68,
+233,
+205,
+217,
+148,
+23,
+202,
+19,
+46,
+106,
+25,
+38,
+235,
+241,
+76,
+51,
+120,
+162,
+169,
+103,
+165,
+66,
+254,
+179,
+98,
+192,
+188,
+217,
+95,
+82,
+219,
+164,
+59,
+169,
+125,
+208,
+193,
+71,
+227,
+239,
+177,
+252,
+22,
+157,
+238,
+98,
+208,
+102,
+5,
+121,
+206,
+170,
+188,
+204,
+94,
+31,
+141,
+26,
+248,
+237,
+108,
+212,
+146,
+168,
+125,
+15,
+120,
+62,
+87,
+91,
+46,
+9,
+88,
+68,
+166,
+70,
+167,
+118,
+173,
+172,
+240,
+124,
+87,
+172,
+72,
+181,
+203,
+214,
+207,
+196,
+196,
+59,
+152,
+86,
+228,
+21,
+102,
+92,
+84,
+190,
+183,
+131,
+199,
+16,
+199,
+110,
+86,
+110,
+229,
+4,
+27,
+213,
+128,
+114,
+129,
+201,
+39,
+77,
+160,
+247,
+17,
+100,
+51,
+169,
+187,
+23,
+191,
+33,
+115,
+20,
+223,
+43,
+151,
+167,
+59,
+94,
+21,
+146,
+205,
+251,
+150,
+233,
+208,
+23,
+91,
+82,
+224,
+131,
+159,
+129,
+122,
+177,
+229,
+173,
+91,
+160,
+196,
+27,
+194,
+56,
+47,
+162,
+99,
+198,
+74,
+159,
+37,
+95,
+49,
+243,
+91,
+200,
+220,
+43,
+223,
+55,
+126,
+192,
+187,
+29,
+65,
+53,
+207,
+39,
+226,
+42,
+200,
+167,
+69,
+138,
+223,
+116,
+45,
+67,
+59,
+119,
+226,
+97,
+215,
+20,
+84,
+50,
+221,
+48,
+94,
+188,
+104,
+220,
+125,
+35,
+249,
+191,
+89,
+200,
+230,
+60,
+243,
+175,
+227,
+56,
+57,
+195,
+173,
+103,
+7,
+233,
+222,
+234,
+74,
+181,
+254,
+158,
+232,
+219,
+207,
+70,
+152,
+56,
+34,
+22,
+92,
+28,
+213,
+181,
+229,
+188,
+241,
+216,
+107,
+213,
+17,
+165,
+153,
+190,
+12,
+160,
+167,
+235,
+139,
+242,
+161,
+138,
+144,
+137,
+101,
+96,
+208,
+254,
+152,
+242,
+20,
+244,
+14,
+234,
+170,
+243,
+167,
+155,
+204,
+19,
+113,
+221,
+184,
+11,
+156,
+197,
+171,
+68,
+177,
+55,
+54,
+82,
+193,
+199,
+220,
+39,
+39,
+172,
+37,
+192,
+158,
+58,
+180,
+173,
+37,
+94,
+161,
+204,
+250,
+109,
+224,
+108,
+75,
+153,
+119,
+232,
+94,
+35,
+45,
+15,
+90,
+99,
+98,
+27,
+43,
+62,
+66,
+83,
+234,
+104,
+20,
+137,
+162,
+201,
+54,
+200,
+39,
+215,
+149,
+34,
+69,
+117,
+142,
+144,
+14,
+6,
+121,
+109,
+41,
+166,
+125,
+131,
+10,
+223,
+159,
+53,
+29,
+225,
+137,
+8,
+74,
+157,
+145,
+237,
+102,
+200,
+181,
+142,
+159,
+74,
+177,
+229,
+192,
+64,
+118,
+207,
+70,
+239,
+60,
+111,
+149,
+185,
+243,
+160,
+153,
+146,
+214,
+182,
+116,
+95,
+191,
+190,
+253,
+80,
+171,
+99,
+25,
+97,
+242,
+185,
+172,
+163,
+158,
+108,
+228,
+20,
+59,
+42,
+4,
+120,
+154,
+154,
+49,
+141,
+58,
+202,
+32,
+16,
+129,
+149,
+112,
+65,
+83,
+109,
+146,
+255,
+209,
+171,
+96,
+196,
+100,
+13,
+103,
+2,
+121,
+76,
+23,
+181,
+118,
+28,
+45,
+17,
+183,
+95,
+158,
+241,
+42,
+191,
+2,
+172,
+84,
+115,
+237,
+168,
+224,
+127,
+168,
+178,
+42,
+8,
+118,
+142,
+22,
+222,
+145,
+143,
+42,
+169,
+69,
+160,
+197,
+114,
+177,
+124,
+210,
+80,
+110,
+252,
+16,
+113,
+168,
+101,
+228,
+149,
+13,
+197,
+20,
+181,
+119,
+63,
+190,
+237,
+206,
+212,
+203,
+95,
+100,
+245,
+9,
+169,
+150,
+207,
+28,
+72,
+76,
+238,
+153,
+186,
+234,
+169,
+44,
+146,
+14,
+17,
+40,
+28,
+214,
+61,
+209,
+77,
+125,
+144,
+59,
+75,
+100,
+6,
+171,
+200,
+252,
+180,
+114,
+147,
+131,
+142,
+219,
+207,
+124,
+117,
+138,
+102,
+31,
+183,
+249,
+45,
+200,
+34,
+74,
+158,
+96,
+27,
+236,
+221,
+172,
+39,
+40,
+16,
+46,
+212,
+217,
+43,
+136,
+75,
+190,
+11,
+217,
+154,
+219,
+85,
+15,
+102,
+188,
+46,
+29,
+182,
+92,
+229,
+217,
+166,
+131,
+57,
+194,
+112,
+22,
+110,
+151,
+63,
+127,
+197,
+19,
+88,
+241,
+156,
+163,
+175,
+168,
+125,
+73,
+131,
+211,
+88,
+233,
+143,
+135,
+7,
+70,
+227,
+236,
+31,
+138,
+112,
+88,
+77,
+224,
+111,
+187,
+120,
+174,
+59,
+62,
+194,
+147,
+47,
+94,
+55,
+222,
+6,
+180,
+40,
+138,
+135,
+129,
+116,
+23,
+8,
+123,
+93,
+236,
+103,
+125,
+118,
+216,
+213,
+195,
+184,
+69,
+127,
+49,
+244,
+187,
+111,
+182,
+78,
+158,
+21,
+134,
+125,
+27,
+59,
+165,
+165,
+195,
+38,
+25,
+218,
+47,
+149,
+56,
+27,
+252,
+181,
+146,
+213,
+139,
+86,
+142,
+208,
+213,
+191,
+196,
+145,
+46,
+123,
+223,
+205,
+144,
+102,
+75,
+171,
+161,
+240,
+81,
+101,
+23,
+107,
+64,
+70,
+0,
+120,
+98,
+253,
+46,
+244,
+210,
+185,
+74,
+96,
+138,
+32,
+32,
+78,
+177,
+79,
+201,
+145,
+28,
+89,
+248,
+103,
+5,
+154,
+88,
+87,
+255,
+112,
+195,
+63,
+183,
+196,
+184,
+25,
+193,
+230,
+14,
+148,
+160,
+89,
+245,
+42,
+122,
+21,
+121,
+43,
+100,
+67,
+189,
+129,
+157,
+182,
+233,
+162,
+80,
+65,
+250,
+80,
+178,
+190,
+143,
+105,
+130,
+72,
+131,
+67,
+47,
+145,
+216,
+208,
+235,
+205,
+251,
+101,
+227,
+116,
+145,
+71,
+183,
+78,
+201,
+84,
+4,
+178,
+247,
+85,
+244,
+242,
+165,
+166,
+176,
+53,
+16,
+50,
+126,
+147,
+118,
+173,
+37,
+78,
+125,
+16,
+28,
+120,
+117,
+0,
+237,
+6,
+71,
+164,
+85,
+17,
+249,
+90,
+195,
+240,
+175,
+184,
+227,
+85,
+94,
+147,
+138,
+110,
+197,
+8,
+2,
+60,
+182,
+39,
+139,
+51,
+55,
+167,
+172,
+173,
+167,
+153,
+179,
+239,
+62,
+9,
+1,
+55,
+99,
+196,
+40,
+19,
+124,
+12,
+104,
+219,
+159,
+243,
+74,
+101,
+251,
+76,
+161,
+178,
+115,
+44,
+230,
+171,
+212,
+146,
+88,
+124,
+44,
+12,
+108,
+107,
+21,
+109,
+163,
+121,
+50,
+204,
+140,
+175,
+216,
+244,
+138,
+119,
+232,
+213,
+221,
+228,
+33,
+127,
+150,
+149,
+172,
+124,
+64,
+129,
+15,
+153,
+253,
+59,
+166,
+105,
+167,
+187,
+215,
+74,
+53,
+9,
+22,
+193,
+184,
+238,
+182,
+67,
+102,
+158,
+24,
+68,
+130,
+58,
+195,
+24,
+207,
+111,
+149,
+16,
+240,
+164,
+170,
+238,
+224,
+80,
+88,
+135,
+12,
+47,
+209,
+65,
+57,
+232,
+2,
+242,
+215,
+185,
+53,
+62,
+87,
+78,
+130,
+218,
+136,
+69,
+243,
+87,
+181,
+136,
+104,
+166,
+44,
+18,
+148,
+13,
+99,
+237,
+148,
+111,
+28,
+102,
+176,
+86,
+79,
+179,
+72,
+38,
+109,
+125,
+100,
+197,
+203,
+231,
+159,
+83,
+44,
+146,
+171,
+226,
+27,
+20,
+137,
+72,
+39,
+29,
+85,
+138,
+10,
+234,
+249,
+39,
+81,
+170,
+125,
+160,
+94,
+197,
+198,
+203,
+67,
+43,
+145,
+15,
+18,
+48,
+98,
+63,
+195,
+14,
+34,
+222,
+35,
+171,
+39,
+74,
+201,
+125,
+212,
+212,
+103,
+206,
+251,
+185,
+121,
+121,
+89,
+215,
+63,
+32,
+163,
+130,
+75,
+52,
+145,
+94,
+101,
+244,
+158,
+40,
+3,
+192,
+7,
+38,
+107,
+47,
+113,
+52,
+172,
+69,
+8,
+20,
+20,
+4,
+205,
+141,
+126,
+38,
+101,
+189,
+71,
+9,
+64,
+147,
+62,
+210,
+241,
+163,
+198,
+143,
+204,
+202,
+80,
+212,
+241,
+187,
+4,
+98,
+240,
+176,
+168,
+249,
+197,
+188,
+254,
+146,
+73,
+124,
+185,
+175,
+57,
+1,
+184,
+122,
+148,
+246,
+76,
+134,
+154,
+19,
+21,
+102,
+222,
+102,
+59,
+207,
+33,
+63,
+49,
+18,
+240,
+218,
+11,
+181,
+150,
+9,
+72,
+224,
+134,
+2,
+143,
+192,
+3,
+71,
+58,
+151,
+62,
+135,
+29,
+216,
+154,
+51,
+63,
+120,
+153,
+123,
+72,
+187,
+187,
+122,
+206,
+171,
+84,
+218,
+97,
+234,
+228,
+169,
+203,
+106,
+172,
+90,
+42,
+175,
+162,
+101,
+71,
+224,
+236,
+101,
+185,
+135,
+153,
+248,
+0,
+51,
+116,
+72,
+238,
+47,
+194,
+189,
+218,
+22,
+151,
+60,
+1,
+123,
+230,
+204,
+230,
+146,
+38,
+17,
+66,
+200,
+118,
+137,
+169,
+99,
+239,
+98,
+234,
+136,
+91,
+234,
+187,
+208,
+51,
+170,
+255,
+245,
+103,
+218,
+11,
+255,
+22,
+12,
+123,
+252,
+217,
+97,
+142,
+255,
+115,
+208,
+200,
+234,
+90,
+114,
+77,
+73,
+212,
+56,
+209,
+48,
+35,
+141,
+0,
+86,
+55,
+0,
+75,
+159,
+218,
+87,
+159,
+240,
+100,
+26,
+237,
+61,
+124,
+124,
+61,
+239,
+77,
+6,
+218,
+167,
+120,
+39,
+241,
+77,
+96,
+195,
+125,
+132,
+80,
+126,
+218,
+136,
+126,
+38,
+40,
+88,
+126,
+199,
+73,
+226,
+225,
+55,
+32,
+94,
+179,
+94,
+78,
+1,
+100,
+40,
+168,
+220,
+80,
+154,
+41,
+177,
+93,
+167,
+53,
+173,
+37,
+16,
+54,
+164,
+55,
+94,
+253,
+181,
+37,
+70,
+152,
+7,
+126,
+184,
+102,
+50,
+22,
+180,
+51,
+123,
+221,
+220,
+87,
+46,
+118,
+129,
+223,
+211,
+41,
+20,
+129,
+78,
+37,
+183,
+243,
+92,
+21,
+240,
+17,
+59,
+55,
+169,
+67,
+181,
+98,
+170,
+231,
+121,
+94,
+27,
+244,
+60,
+247,
+76,
+106,
+109,
+206,
+73,
+64,
+247,
+94,
+193,
+70,
+131,
+121,
+57,
+223,
+143,
+41,
+241,
+203,
+97,
+155,
+14,
+23,
+253,
+184,
+255,
+119,
+23,
+26,
+108,
+83,
+17,
+184,
+190,
+127,
+135,
+7,
+191,
+126,
+102,
+129,
+196,
+233,
+251,
+254,
+200,
+138,
+40,
+186,
+85,
+137,
+85,
+100,
+160,
+83,
+29,
+159,
+202,
+53,
+185,
+54,
+137,
+203,
+239,
+71,
+74,
+119,
+79,
+10,
+245,
+181,
+140,
+186,
+158,
+135,
+184,
+103,
+18,
+224,
+33,
+103,
+106,
+118,
+204,
+10,
+201,
+234,
+170,
+147,
+31,
+99,
+202,
+168,
+47,
+186,
+239,
+121,
+50,
+62,
+131,
+39,
+243,
+15,
+225,
+146,
+151,
+154,
+249,
+169,
+123,
+26,
+17,
+229,
+145,
+221,
+239,
+90,
+199,
+153,
+238,
+230,
+253,
+185,
+142,
+44,
+116,
+126,
+166,
+166,
+189,
+41,
+206,
+176,
+57,
+176,
+67,
+208,
+74,
+60,
+121,
+197,
+87,
+138,
+170,
+232,
+104,
+154,
+67,
+48,
+52,
+50,
+22,
+49,
+236,
+165,
+94,
+96,
+36,
+4,
+7,
+225,
+46,
+213,
+146,
+104,
+133,
+213,
+57,
+207,
+18,
+178,
+149,
+105,
+61,
+63,
+82,
+166,
+218,
+150,
+214,
+14,
+200,
+237,
+64,
+180,
+147,
+159,
+21,
+183,
+164,
+28,
+152,
+210,
+241,
+42,
+59,
+118,
+0,
+116,
+70,
+18,
diff --git a/gr-atsc/src/lib/qa_convolutional_interleaver.cc b/gr-atsc/src/lib/qa_convolutional_interleaver.cc
new file mode 100644 (file)
index 0000000..fff6e61
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_convolutional_interleaver.h>
+
+void
+qa_convolutional_interleaver::t0 ()
+{
+  static int input[16] = {
+     1,  2,  3,  4,
+     5,  6,  7,  8,
+     9, 10, 11, 12,
+    13, 14, 15, 16
+  };
+
+  static int output[16] = {
+     1,  0, 0, 0,
+     5,  2, 0, 0,
+     9,  6, 3, 0,
+    13, 10, 7, 4
+  };
+
+  // test interleaver
+  intl = new convolutional_interleaver<int>(true, 4, 1);
+
+  for (int i = 0; i < 16; i++)
+    CPPUNIT_ASSERT_EQUAL (output[i], intl->transform (input[i]));
+}
+
+void
+qa_convolutional_interleaver::t1 ()
+{
+  static int input[16] = {
+     1,  0, 0, 0,
+     5,  2, 0, 0,
+     9,  6, 3, 0,
+    13, 10, 7, 4
+  };
+
+  static int output[16] = {
+     0,  0, 0, 0,
+     0,  0, 0, 0,
+     0,  0, 0, 0,
+     1,  2, 3, 4
+  };
+
+  // test deinterleaver
+  intl = new convolutional_interleaver<int>(false, 4, 1);
+
+  for (int i = 0; i < 16; i++)
+    CPPUNIT_ASSERT_EQUAL (output[i], intl->transform (input[i]));
+}
+
+void
+qa_convolutional_interleaver::t2 ()
+{
+  intl = new convolutional_interleaver<int>(true, 4, 1);
+  deintl = new convolutional_interleaver<int>(false, 4, 1);
+
+  int  icount = 6000;
+  int  dcount = 6000;
+  
+  int  end_to_end_delay = intl->end_to_end_delay ();
+  for (int i = 0; i < end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++)));
+  }
+
+  for (int i = 0; i < 3 * end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++)));
+  }
+}
+
+void
+qa_convolutional_interleaver::t3 ()
+{
+  intl = new convolutional_interleaver<int>(true, 4, 2);
+  deintl = new convolutional_interleaver<int>(false, 4, 2);
+
+  int  icount = 6000;
+  int  dcount = 6000;
+  
+  int  end_to_end_delay = intl->end_to_end_delay ();
+  for (int i = 0; i < end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++)));
+  }
+
+  for (int i = 0; i < 3 * end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++)));
+  }
+}
+
+void
+qa_convolutional_interleaver::t4 ()
+{
+  intl = new convolutional_interleaver<int>(true, 52, 4);
+  deintl = new convolutional_interleaver<int>(false, 52, 4);
+
+  int  icount = 6000;
+  int  dcount = 6000;
+  
+  int  end_to_end_delay = intl->end_to_end_delay ();
+  CPPUNIT_ASSERT_EQUAL (10608, end_to_end_delay);
+  
+  for (int i = 0; i < end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++)));
+  }
+
+  for (int i = 0; i < 3 * end_to_end_delay; i++){
+    CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++)));
+  }
+}
diff --git a/gr-atsc/src/lib/qa_convolutional_interleaver.h b/gr-atsc/src/lib/qa_convolutional_interleaver.h
new file mode 100644 (file)
index 0000000..3f96065
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_CONVOLUTIONAL_INTERLEAVER_H_
+#define _QA_CONVOLUTIONAL_INTERLEAVER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <convolutional_interleaver.h>
+
+class qa_convolutional_interleaver : public CppUnit::TestCase {
+ private:
+  convolutional_interleaver<int>       *intl;
+  convolutional_interleaver<int>       *deintl;
+  
+  CPPUNIT_TEST_SUITE (qa_convolutional_interleaver);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST (t4);
+  CPPUNIT_TEST_SUITE_END ();
+
+ public:
+
+  void setUp (){
+    intl = 0;
+    deintl = 0;
+  }
+
+  void tearDown (){
+    delete intl;
+    intl = 0;
+    delete deintl;
+    deintl = 0;
+  }
+
+ private:
+
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+  void t4 ();
+
+};
+
+
+#endif /* _QA_CONVOLUTIONAL_INTERLEAVER_H_ */
diff --git a/gr-atsc/src/lib/qa_interleaver_fifo.cc b/gr-atsc/src/lib/qa_interleaver_fifo.cc
new file mode 100644 (file)
index 0000000..3c3aad4
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_interleaver_fifo.h>
+
+void
+qa_interleaver_fifo::t0 ()
+{
+  fifo = new interleaver_fifo<int>(0);
+
+  for (int i = 10; i < 20; i++)
+    CPPUNIT_ASSERT_EQUAL (i, fifo->stuff (i));
+}
+
+void
+qa_interleaver_fifo::t1 ()
+{
+  fifo = new interleaver_fifo<int>(1);
+
+  CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (2));
+  
+  for (int i = 1; i < 10; i++)
+    CPPUNIT_ASSERT_EQUAL (i * 2, fifo->stuff ((i + 1) * 2));
+}
+
+void
+qa_interleaver_fifo::t2 ()
+{
+  fifo = new interleaver_fifo<int>(4);
+
+  CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (1));
+  CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (2));
+  CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (3));
+  CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (4));
+
+  for (int i = 5; i < 20; i++)
+    CPPUNIT_ASSERT_EQUAL (i - 4, fifo->stuff (i));
+}
diff --git a/gr-atsc/src/lib/qa_interleaver_fifo.h b/gr-atsc/src/lib/qa_interleaver_fifo.h
new file mode 100644 (file)
index 0000000..bd29baa
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 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.
+ */
+
+#ifndef _QA_INTERLEAVER_FIFO_H_
+#define _QA_INTERLEAVER_FIFO_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+#include <interleaver_fifo.h>
+
+class qa_interleaver_fifo : public CppUnit::TestCase {
+ private:
+  interleaver_fifo<int>        *fifo;
+  
+ public:
+
+  void tearDown (){
+    delete fifo;
+    fifo = 0;
+  }
+
+  CPPUNIT_TEST_SUITE (qa_interleaver_fifo);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t0 ();
+  void t1 ();
+  void t2 ();
+
+};
+
+
+#endif /* _QA_INTERLEAVER_FIFO_H_ */
diff --git a/gr-atsc/src/lib/test_atsci.cc b/gr-atsc/src/lib/test_atsci.cc
new file mode 100644 (file)
index 0000000..5267e0d
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_atsci.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_atsc::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gr-atsc/src/python/.gitignore b/gr-atsc/src/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-atsc/src/python/Makefile.am b/gr-atsc/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..37b60e6
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright 2004,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =           \
+       run_tests.in
+
+ourdatadir = $(exampledir)/atsc
+
+dist_ourdata_DATA =    \
+       README
+
+dist_ourdata_SCRIPTS =  \
+       btl-fsd.py      \
+       fpll.py         \
+       interp.py       \
+       xlate.py        \
+       viterbi-out.py
+
+TESTS =                                \
+       run_tests
+
+noinst_PYTHON =                        \
+       atsc_utils.py                   \
+       qa_atsc.py                      
diff --git a/gr-atsc/src/python/README b/gr-atsc/src/python/README
new file mode 100644 (file)
index 0000000..abe0937
--- /dev/null
@@ -0,0 +1,34 @@
+Decoding ATSC using 19.2MSps rate over 5 processes
+--------------------------------------------------
+
+1) Verify signal, adjust antenna and find best gain setting using usrp_fft.py,
+station frequency from the fcc video database, and decimation of 10.
+
+2) Capture data - adjust gain (-g) frequency (-f) and which side
+the tvrx is on to fit your local setup:
+
+usrp_rx_cfile.py -s -R B -d 10 -g 65 -f 503e6 atsc_data_6-4m_complex 
+
+You probably still need fast disks to take the data, like a raid-0 set of
+striped sata drives. Make sure there are no or very few Ou overruns. Saving
+the raw usrp data in 'short' form halves the disk space/bus bandwidth that
+the usual complex form uses.
+
+3) Make pipes:
+
+mkfifo /tmp/atsc_pipe_1
+mkfifo /tmp/atsc_pipe_2
+mkfifo /tmp/atsc_pipe_3
+mkfifo /tmp/atsc_pipe_4
+mkfifo /tmp/atsc_pipe_5
+
+4) In seperate windows run processes:
+
+./interp_short.py <input rf data at 6.4Msps>
+./xlate.py
+./fpll.py
+./btl-fsd.py
+./viterbi-out.py <output mpeg transport stream>
+
+
+
diff --git a/gr-atsc/src/python/atsc_utils.py b/gr-atsc/src/python/atsc_utils.py
new file mode 100644 (file)
index 0000000..1e74d22
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# 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.
+# 
+
+import random
+import sys
+
+MPEG_SYNC_BYTE = 0x47
+
+def make_fake_transport_stream_packet(npkts):
+    """
+    Return a sequence of 8-bit ints that represents an MPEG Transport Stream packet.
+
+    @param npkts: how many 188-byte packets to return
+
+    FYI, each ATSC Data Frame contains two Data Fields, each of which contains
+    312 data segments.  Each transport stream packet maps to a data segment.
+    """
+    r = [0] * (npkts * 188)
+    i = 0
+    for j in range(npkts):
+        r[i+0] = MPEG_SYNC_BYTE
+        r[i+1] = random.randint(0, 127) # top bit (transport error bit) clear
+        i = i + 2
+        for n in range(186):
+            r[i + n] = random.randint(0, 255)
+        i = i + 186
+        
+    return r
+
+
+def pad_stream(src, sizeof_total, sizeof_pad):
+    sizeof_valid = sizeof_total - sizeof_pad
+    assert sizeof_valid > 0
+    assert (len(src) % sizeof_valid) == 0
+    npkts = len(src) // sizeof_valid
+    dst = [0] * (npkts * sizeof_total)
+    for i in range(npkts):
+        src_s = i * sizeof_valid
+        dst_s = i * sizeof_total
+        dst[dst_s:dst_s + sizeof_valid] = src[src_s:src_s + sizeof_valid]
+    return dst
+
+
+def depad_stream(src, sizeof_total, sizeof_pad):
+    sizeof_valid = sizeof_total - sizeof_pad
+    assert sizeof_valid > 0
+    assert (len(src) % sizeof_total) == 0
+    npkts = len(src) // sizeof_total
+    dst = [0] * (npkts * sizeof_valid)
+    for i in range(npkts):
+        src_s = i * sizeof_total
+        dst_s = i * sizeof_valid
+        dst[dst_s:dst_s + sizeof_valid] = src[src_s:src_s + sizeof_valid]
+    return dst
+
+
diff --git a/gr-atsc/src/python/btl-fsd.py b/gr-atsc/src/python/btl-fsd.py
new file mode 100755 (executable)
index 0000000..37f3f98
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr
+from gnuradio import atsc
+import os
+
+print os.getpid()
+
+tb = gr.top_block()
+
+btl = atsc.bit_timing_loop()
+fsc = atsc.fs_checker()
+eq = atsc.equalizer()
+fsd = atsc.field_sync_demux()
+
+out_data = gr.file_sink(atsc.sizeof_atsc_soft_data_segment,"/tmp/atsc_pipe_5")
+
+inp = gr.file_source(gr.sizeof_float,"/tmp/atsc_pipe_3")
+
+tb.connect(inp,btl)
+tb.connect((btl,0),(fsc,0),(eq,0),(fsd,0))
+tb.connect((btl,1),(fsc,1),(eq,1),(fsd,1))
+tb.connect(fsd,out_data)
+
+tb.run()
+
+
diff --git a/gr-atsc/src/python/fpll.py b/gr-atsc/src/python/fpll.py
new file mode 100755 (executable)
index 0000000..24bc727
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, atsc
+import math, os
+
+def main():
+
+       print os.getpid()
+
+       tb = gr.top_block()
+
+        u = gr.file_source(gr.sizeof_float,"/tmp/atsc_pipe_2")
+
+        input_rate = 19.2e6
+       IF_freq = 5.75e6
+
+
+       # 1/2 as wide because we're designing lp filter
+       symbol_rate = atsc.ATSC_SYMBOL_RATE/2. 
+       NTAPS = 279
+       tt = gr.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS)
+  # heterodyne the low pass coefficients up to the specified bandpass
+  # center frequency.  Note that when we do this, the filter bandwidth
+  # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
+  # matches the diagram in the ATSC spec.
+       arg = 2. * math.pi * IF_freq / input_rate
+       t=[]
+       for i in range(len(tt)):
+         t += [tt[i] * 2. * math.cos(arg * i)]
+       rrc = gr.fir_filter_fff(1, t)
+
+       fpll = atsc.fpll()
+
+       pilot_freq = IF_freq - 3e6 + 0.31e6
+       lower_edge = 6e6 - 0.31e6
+       upper_edge = IF_freq - 3e6 + pilot_freq
+       transition_width = upper_edge - lower_edge
+       lp_coeffs = gr.firdes.low_pass (1.0,
+                          input_rate,
+                          (lower_edge + upper_edge) * 0.5,
+                           transition_width,
+                           gr.firdes.WIN_HAMMING);
+
+       lp_filter = gr.fir_filter_fff (1,lp_coeffs)
+
+       alpha = 1e-5
+       iir = gr.single_pole_iir_filter_ff(alpha)
+       remove_dc = gr.sub_ff()
+
+       out = gr.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_3")
+       # out = gr.file_sink(gr.sizeof_float,"/mnt/sata/atsc_data_float")
+
+        tb.connect(u, fpll, lp_filter)
+       tb.connect(lp_filter, iir)
+       tb.connect(lp_filter, (remove_dc,0))
+       tb.connect(iir, (remove_dc,1))
+       tb.connect(remove_dc, out)
+
+       tb.run()
+
+
+if __name__ == '__main__':
+    main ()
+
+
+
diff --git a/gr-atsc/src/python/interp.py b/gr-atsc/src/python/interp.py
new file mode 100755 (executable)
index 0000000..ad69c6b
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env /usr/bin/python
+#
+# Copyright 2004,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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+# This module starts the atsc processing chain taking the captured
+# off-air signal created with:
+#
+#  usrp_rx_cfile.py -R <side with tuner, a or b>
+#                   -d 10     set decimation to get signal at 6.4e6 rate
+#                   -f <center of tv signal channel freq>
+#                   -g <appropriate gain for best signal / noise>
+# 
+# All this module does is multiply the sample rate by 3, from 6.4e6 to
+# 19.2e6 complex samples / sec, then lowpass filter with a cutoff of 3.2MHz
+# and a transition band width of .5MHz.  Center of the tv channels is
+# then at 0 with edges at -3.2MHz and 3.2MHz.
+
+from gnuradio import gr
+import sys
+
+def graph (args):
+
+    nargs = len (args)
+    if nargs == 1:
+       infile = args[0]
+    else:
+       sys.stderr.write('usage: interp.py input_file\n')
+       sys.exit (1)
+
+    tb = gr.top_block ()
+
+    src0 = gr.file_source (gr.sizeof_gr_complex,infile)
+
+    lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING )
+    lp = gr.interp_fir_filter_ccf ( 1, lp_coeffs )
+
+    file = gr.file_sink(gr.sizeof_gr_complex,"/tmp/atsc_pipe_1")
+
+    tb.connect( src0, lp, file )
+
+    tb.start()
+    raw_input ('Head End: Press Enter to stop')
+    tb.stop()
+
+if __name__ == '__main__':
+    graph (sys.argv[1:])
+
+
diff --git a/gr-atsc/src/python/interp_short.py b/gr-atsc/src/python/interp_short.py
new file mode 100755 (executable)
index 0000000..11b169b
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/env /usr/bin/python
+#
+# 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+# This module starts the atsc processing chain taking the captured
+# off-air signal created with:
+#
+#  usrp_rx_cfile.py -R <side with tuner, a or b>
+#                   -d 10     set decimation to get signal at 6.4e6 rate
+#                   -f <center of tv signal channel freq>
+#                   -g <appropriate gain for best signal / noise>
+#                   -s output shorts
+#
+# All this module does is multiply the sample rate by 3, from 6.4e6 to
+# 19.2e6 complex samples / sec, then lowpass filter with a cutoff of 3.2MHz
+# and a transition band width of .5MHz.  Center of the tv channels is
+# then at 0 with edges at -3.2MHz and 3.2MHz.
+
+from gnuradio import gr
+import sys, os
+
+def graph (args):
+
+    print os.getpid()
+
+    nargs = len (args)
+    if nargs == 1:
+       infile = args[0]
+    else:
+       sys.stderr.write('usage: interp.py input_file\n')
+       sys.exit (1)
+
+    tb = gr.top_block ()
+
+    srcf = gr.file_source (gr.sizeof_short,infile)
+    s2ss = gr.stream_to_streams(gr.sizeof_short,2)
+    s2f1 = gr.short_to_float()
+    s2f2 = gr.short_to_float()
+    src0 = gr.float_to_complex()
+
+
+    lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING )
+    lp = gr.interp_fir_filter_ccf ( 3, lp_coeffs )
+
+    file = gr.file_sink(gr.sizeof_gr_complex,"/tmp/atsc_pipe_1")
+
+    tb.connect( srcf, s2ss )
+    tb.connect( (s2ss, 0), s2f1, (src0,0) )
+    tb.connect( (s2ss, 1), s2f2, (src0,1) )
+    tb.connect( src0, lp, file)
+
+    tb.start()
+    raw_input ('Head End: Press Enter to stop')
+    tb.stop()
+
+if __name__ == '__main__':
+    graph (sys.argv[1:])
+
+
diff --git a/gr-atsc/src/python/qa_atsc.py b/gr-atsc/src/python/qa_atsc.py
new file mode 100755 (executable)
index 0000000..63621bd
--- /dev/null
@@ -0,0 +1,222 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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, gr_unittest
+import atsc                    # qa code needs to run without being installed
+#from gnuradio import atsc
+from atsc_utils import *
+import sys
+
+
+class memoize(object):
+    def __init__(self, thunk):
+        self.thunk = thunk
+        self.cached = False
+        self.value = None
+
+    def __call__(self):
+        if self.cached:
+            return self.value
+        self.value = self.thunk()
+        self.cached = True
+        return self.value
+
+
+"""
+Make a fake transport stream that's big enough for our purposes.
+We generate 8 full fields.  This is relatively expensive.  It
+takes about 2 seconds to execute.  
+"""
+make_transport_stream = \
+    memoize(lambda : tuple(make_fake_transport_stream_packet(8 * atsc.ATSC_DSEGS_PER_FIELD)))
+
+
+def pad_transport_stream(src):
+    """
+    An MPEG transport stream packet is 188 bytes long.  Internally we use a packet
+    that is 256 bytes long to help with buffer alignment.  This function adds the
+    appropriate trailing padding to convert each packet from 188 to 256 bytes.
+    """
+    return pad_stream(src, atsc.sizeof_atsc_mpeg_packet, atsc.sizeof_atsc_mpeg_packet_pad)
+
+
+def depad_transport_stream(src):
+    """
+    An MPEG transport stream packet is 188 bytes long.  Internally we use a packet
+    that is 256 bytes long to help with buffer alignment.  This function removes the
+    trailing padding to convert each packet from 256 back to 188 bytes.
+    """
+    return depad_stream(src, atsc.sizeof_atsc_mpeg_packet, atsc.sizeof_atsc_mpeg_packet_pad)
+
+
+class vector_source_ts(gr.hier_block2):
+    """
+    MPEG Transport stream source for testing.
+    """
+    def __init__(self, ts):
+        """
+        Pad tranport stream packets to 256 bytes and reformat appropriately.
+        
+        @param ts: MPEG transport stream.
+        @type  ts: sequence of ints in [0,255]; len(ts) % 188 == 0
+        """
+                               
+        src = gr.vector_source_b(pad_transport_stream(ts))
+        s2v = gr.stream_to_vector(gr.sizeof_char, atsc.sizeof_atsc_mpeg_packet)
+
+       gr.hier_block2.__init__(self, "vector_source_ts",
+                               gr.io_signature(0, 0, 0),
+                               s2v.output_signature())
+        self.connect(src, s2v, self)
+
+
+class vector_sink_ts(gr.hier_block2):
+    """
+    MPEG Transport stream sink for testing.
+    """
+    def __init__(self):
+        """
+        """
+
+        v2s = gr.vector_to_stream(gr.sizeof_char, atsc.sizeof_atsc_mpeg_packet)
+        self.sink = gr.vector_sink_b()
+       gr.hier_block2.__init__(self, "vector_sink_ts",
+                               v2s.input_signature(),
+                               gr.io_signature(0, 0, 0))
+        self.connect(self, v2s, self.sink)
+
+    def data(self):
+        """
+        Extracts tranport stream from sink and returns it to python.
+
+        Depads tranport stream packets from 256 back to 188 bytes.
+        @rtype: tuple of ints in [0,255]; len(result) % 188 == 0
+        """
+        return tuple(depad_transport_stream(self.sink.data()))
+
+
+
+class qa_atsc(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+
+    # The tests are run in alphabetical order
+
+    def test_loopback_000(self):
+        """
+        Loopback randomizer to derandomizer
+        """
+        src_data = make_transport_stream()
+        expected_result = src_data
+
+        src = vector_source_ts(src_data)
+        rand = atsc.randomizer()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts()
+        self.tb.connect(src, rand, derand, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+
+    def test_loopback_001(self):
+        """
+        Loopback randomizer/rs_encoder to rs_decoder/derandomizer
+        """
+        src_data = make_transport_stream()
+        expected_result = src_data
+
+        src = vector_source_ts(src_data)
+        rand = atsc.randomizer()
+        rs_enc = atsc.rs_encoder()
+        rs_dec = atsc.rs_decoder()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts()
+        self.tb.connect(src, rand, rs_enc, rs_dec, derand, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+
+    def test_loopback_002(self):
+        """
+        Loopback randomizer/rs_encoder/interleaver to
+       deinterleaver/rs_decoder/derandomizer 
+        """
+        src_data = make_transport_stream()
+       interleaver_delay = 52
+        expected_result = src_data[0:len(src_data)-(interleaver_delay*atsc.ATSC_MPEG_PKT_LENGTH)]
+
+        src = vector_source_ts(src_data)
+        rand = atsc.randomizer()
+        rs_enc = atsc.rs_encoder()
+       inter = atsc.interleaver()
+       deinter = atsc.deinterleaver()
+        rs_dec = atsc.rs_decoder()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts()
+        self.tb.connect(src, rand, rs_enc, inter, deinter, rs_dec, derand, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+       result_data = result_data[(interleaver_delay*atsc.ATSC_MPEG_PKT_LENGTH):len(result_data)]
+        self.assertEqual (expected_result, result_data)
+
+
+    def test_loopback_003(self):
+        """
+        Loopback randomizer/rs_encoder/interleaver/trellis_encoder
+       via ds_to_softds to
+       viterbi_decoder/deinterleaver/rs_decoder/derandomizer 
+        """
+        src_data = make_transport_stream()
+       interleaver_delay = 52
+       viterbi_delay = 12
+        expected_result = src_data[0:len(src_data)-((interleaver_delay+viterbi_delay)*atsc.ATSC_MPEG_PKT_LENGTH)]
+
+        src = vector_source_ts(src_data)
+        rand = atsc.randomizer()
+        rs_enc = atsc.rs_encoder()
+        inter = atsc.interleaver()
+       trellis = atsc.trellis_encoder()
+       softds = atsc.ds_to_softds()
+       viterbi = atsc.viterbi_decoder()
+        deinter = atsc.deinterleaver()
+        rs_dec = atsc.rs_decoder()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts()
+       self.tb.connect(src, rand, rs_enc, inter, trellis, softds, viterbi, deinter, rs_dec, derand, dst)
+        self.tb.run ()
+        result_data = dst.data ()[((interleaver_delay+viterbi_delay)*atsc.ATSC_MPEG_PKT_LENGTH):len(dst.data())]
+        self.assertEqual (expected_result, result_data)
+
+        
+if __name__ == '__main__':
+    gr_unittest.main()
+
+
+
+
+
+
diff --git a/gr-atsc/src/python/run_tests.in b/gr-atsc/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..561917f
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# 1st parameter is absolute path to component source directory
+# 2nd parameter is absolute path to component build directory
+# 3rd parameter is path to Python QA directory
+
+@top_builddir@/run_tests.sh \
+    @abs_top_srcdir@/gr-atsc \
+    @abs_top_builddir@/gr-atsc \
+    @srcdir@
diff --git a/gr-atsc/src/python/viterbi-out.py b/gr-atsc/src/python/viterbi-out.py
new file mode 100755 (executable)
index 0000000..eedbaa5
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, atsc
+import sys, os
+
+def main(args):
+
+       print os.getpid()
+
+       nargs = len (args)
+       if nargs == 1:
+          outfile = args[0]
+       else:
+          sys.stderr.write ('usage: viterbi_out.py output_file\n')
+          sys.exit (1)
+
+       tb = gr.top_block()
+
+        src = gr.file_source(atsc.sizeof_atsc_soft_data_segment, "/tmp/atsc_pipe_5")
+       viterbi = atsc.viterbi_decoder()
+        deinter = atsc.deinterleaver()
+        rs_dec = atsc.rs_decoder()
+        derand = atsc.derandomizer()
+       depad = atsc.depad()
+        dst = gr.file_sink(gr.sizeof_char,outfile)
+       tb.connect(src, viterbi, deinter, rs_dec, derand, depad, dst)
+        tb.run ()
+
+        
+if __name__ == '__main__':
+    main(sys.argv[1:])
+
+
+
+
+
+
diff --git a/gr-atsc/src/python/xlate.py b/gr-atsc/src/python/xlate.py
new file mode 100755 (executable)
index 0000000..e37af9a
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env /usr/bin/python
+#
+# Copyright 2004,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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+# This module upconverts the 19.2e6 sample rate signal from a center
+# of 0 to 5.75e6 and converts to float, to prepare the signal for
+# the old gnuradio 0.9 block (bit timing loop, field sync checker,
+# equalizer and field sync demux), effectively simulating an
+# mc4020 card, except the sample rate is 19.2e6 instead of 20e6.
+#
+# The signal is then centered on 5.75e6 with edges at 5.75 + 3.2 = 8.95MHz
+# and 5.75 - 3.2 = 2.55Mhz, low pass filtered with cutoff at 9Mhz and a
+# transition band width of 1Mhz.
+#
+# Input complex -3.2 to 3.2Mhz, output float 2.55 to 8.95Mhz.
+
+from gnuradio import gr
+import os
+
+def graph ():
+    print os.getpid()
+    sampling_freq = 19200000
+
+    tb = gr.top_block ()
+
+    src0 = gr.file_source (gr.sizeof_gr_complex,"/tmp/atsc_pipe_1")
+
+    duc_coeffs = gr.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING )
+    duc = gr.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, 5.75e6, 19.2e6 )
+
+    c2f = gr.complex_to_float()
+    file = gr.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_2")
+
+    tb.connect( src0, duc, c2f, file )
+
+    tb.run()
+
+if __name__ == '__main__':
+    graph ()
diff --git a/gr-audio-alsa/.gitignore b/gr-audio-alsa/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
index 6afff4d9c01d87a226923e375e16e1fa66b92b5f..5bd92b0ff7595866b89a7d7c5e3d7891c5077e9c 100644 (file)
 
 include $(top_srcdir)/Makefile.common
 
-EXTRA_DIST = \
-    gr-audio-alsa.pc.in
-
 SUBDIRS = src
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = gr-audio-alsa.pc
+dist_pkgconfig_DATA = gnuradio-audio-alsa.pc
 
-etcdir = $(gr_sysconfdir)
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gr-audio-alsa.conf
diff --git a/gr-audio-alsa/build-stamp b/gr-audio-alsa/build-stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-audio-alsa/gnuradio-audio-alsa.pc.in b/gr-audio-alsa/gnuradio-audio-alsa.pc.in
new file mode 100644 (file)
index 0000000..d5147e6
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-audio-alsa
+Description: The GNU Radio block for the ALSA sound system
+Requires: gnuradio-core alsa
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-audio-alsa
+Cflags: -I${includedir}
diff --git a/gr-audio-alsa/src/.gitignore b/gr-audio-alsa/src/.gitignore
new file mode 100644 (file)
index 0000000..b751c67
--- /dev/null
@@ -0,0 +1,16 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/usrp.py
+/usrp.cc
+/audio_oss.cc
+/audio_oss.py
+/audio_alsa.py
+/audio_alsa.cc
+/run_tests
+/*.pyc
index 8230ab56999dee5c0173765c0e6042b8cdf25e6e..ed92cc197dece844e39c5c9a76f73dc46d51cbef 100644 (file)
@@ -23,10 +23,6 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
-
 # C/C++ headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS =                    \
        audio_alsa_sink.h               \
@@ -54,11 +50,13 @@ libgnuradio_audio_alsa_la_LIBADD =  \
        $(GNURADIO_CORE_LA)             \
        $(ALSA_LIBS)
 
-libgnuradio_audio_alsa_la_LDFLAGS =    \
-       $(NO_UNDEFINED)
+libgnuradio_audio_alsa_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        audio_alsa.i
@@ -81,3 +79,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
\ No newline at end of file
diff --git a/gr-audio-jack/.gitignore b/gr-audio-jack/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
index c39b9d3f6f6e7f023cea23e86bc4411f430c938f..cdc1433db6f29404cc3fbc56cdfdcd743162b891 100644 (file)
@@ -23,5 +23,8 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
 
-etcdir = $(gr_sysconfdir)
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-audio-jack.pc
+
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gr-audio-jack.conf
diff --git a/gr-audio-jack/gnuradio-audio-jack.pc.in b/gr-audio-jack/gnuradio-audio-jack.pc.in
new file mode 100644 (file)
index 0000000..8fb4a2e
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-audio-jack
+Description: GNU Radio blocks for the JACK sound system
+Requires: gnuradio-core jack
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-audio-jack
+Cflags: -I${includedir}
diff --git a/gr-audio-jack/src/.gitignore b/gr-audio-jack/src/.gitignore
new file mode 100644 (file)
index 0000000..46103bc
--- /dev/null
@@ -0,0 +1,12 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/audio_jack.cc
+/audio_jack.py
+/run_tests
index bd8694a26188709232858d04dbecd80e03b8d5bd..8e0dfe1e386dd9b0597dfa8fee824e4abd4f29ce 100644 (file)
@@ -23,10 +23,6 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
-
 # C/C++ headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS =                    \
        audio_jack_sink.h               \
@@ -35,13 +31,29 @@ grinclude_HEADERS =                 \
 noinst_HEADERS =                       \
        gri_jack.h
 
+lib_LTLIBRARIES = libgnuradio-audio-jack.la
+
+libgnuradio_audio_jack_la_SOURCES =    \
+       audio_jack_sink.cc              \
+       audio_jack_source.cc            \
+       gri_jack.cc
+
+libgnuradio_audio_jack_la_LIBADD =     \
+       $(GNURADIO_CORE_LA)             \
+       $(JACK_LIBS)
+
+libgnuradio_audio_jack_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
 noinst_PYTHON =                        \
        qa_jack.py
 
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        audio_jack.i
@@ -53,16 +65,9 @@ TOP_SWIG_IFILES =                    \
 audio_jack_pythondir_category =                \
        gnuradio
 
-# additional sources for the SWIG-generated library
-audio_jack_la_swig_sources =           \
-       audio_jack_sink.cc              \
-       audio_jack_source.cc            \
-       gri_jack.cc
-
 # additional libraries for linking with the SWIG-generated library
 audio_jack_la_swig_libadd =            \
-       $(GNURADIO_CORE_LA)             \
-       $(JACK_LIBS)
+       libgnuradio-audio-jack.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -71,3 +76,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-audio-oss/.gitignore b/gr-audio-oss/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
index 89f7e5ce04ccbd249fb045bc70174730c74ce378..c55d3ecb716643d8edd3b58d8a92be5ceb3ecea7 100644 (file)
@@ -23,5 +23,8 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
 
-etcdir = $(gr_sysconfdir)
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-audio-oss.pc
+
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gr-audio-oss.conf
diff --git a/gr-audio-oss/gnuradio-audio-oss.pc.in b/gr-audio-oss/gnuradio-audio-oss.pc.in
new file mode 100644 (file)
index 0000000..4a215bd
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-audio-oss
+Description: The GNU Radio block for the OSS sound system
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-audio-oss
+Cflags: -I${includedir}
diff --git a/gr-audio-oss/src/.gitignore b/gr-audio-oss/src/.gitignore
new file mode 100644 (file)
index 0000000..ac39b2a
--- /dev/null
@@ -0,0 +1,14 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/usrp.py
+/usrp.cc
+/audio_oss.cc
+/audio_oss.py
+/run_tests
+/*.pyc
index f83ba68ca98927a2714f28c73f9044dd300e8134..628c9fd9304c52096902d397eff3b697386f7883 100644 (file)
 
 include $(top_srcdir)/Makefile.common
 
-EXTRA_DIST = run_tests.in
-
-TESTS = run_tests
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
-DISTCLEANFILES = run_tests
+EXTRA_DIST = run_tests.in
 
 # C/C++ headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS =            \
@@ -34,10 +32,23 @@ grinclude_HEADERS =         \
 
 noinst_PYTHON = qa_oss.py
 
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+lib_LTLIBRARIES = libgnuradio-audio-oss.la
+
+libgnuradio_audio_oss_la_SOURCES =     \
+       audio_oss_sink.cc               \
+       audio_oss_source.cc
 
+libgnuradio_audio_oss_la_LIBADD =      \
+       $(GNURADIO_CORE_LA)             \
+       $(OSS_LIBS)
+
+libgnuradio_audio_oss_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =              \
        audio_oss.i
@@ -49,15 +60,9 @@ TOP_SWIG_IFILES =            \
 audio_oss_pythondir_category = \
        gnuradio
 
-# additional sources for the SWIG-generated library
-audio_oss_la_swig_sources =    \
-       audio_oss_sink.cc       \
-       audio_oss_source.cc
-
 # additional libraries for linking with the SWIG-generated library
 audio_oss_la_swig_libadd =     \
-       $(GNURADIO_CORE_LA)     \
-       $(OSS_LIBS)
+       libgnuradio-audio-oss.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -66,3 +71,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-audio-osx/.gitignore b/gr-audio-osx/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
diff --git a/gr-audio-osx/src/.gitignore b/gr-audio-osx/src/.gitignore
new file mode 100644 (file)
index 0000000..5a5590a
--- /dev/null
@@ -0,0 +1,13 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/usrp.py
+/usrp.cc
+/audio_osx.cc
+/audio_osx.py
+/run_tests
index a4e690963ad63a433d023e18798ca42f64acb90d..ee9df776596607f6809cebafba4b5bfa6e97031f 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2006,2008,2009 Free Software Foundation, Inc.
+# Copyright 2006,2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio.
 # 
@@ -23,10 +23,6 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
-
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
 # C/C++ headers get installed in ${prefix}/include/gnuradio
@@ -36,15 +32,33 @@ grinclude_HEADERS =                 \
 
 noinst_HEADERS =                       \
        audio_osx.h                     \
-       circular_buffer.h               \
-       mld_threads.h
+       circular_buffer.h
 
 noinst_PYTHON =                                \
        qa_osx.py                       \
        test_audio_loop.py
 
+lib_LTLIBRARIES = libgnuradio-audio-osx.la
+
+libgnuradio_audio_osx_la_SOURCES =     \
+       audio_osx_sink.cc               \
+       audio_osx_source.cc
+
+libgnuradio_audio_osx_la_LIBADD =      \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_audio_osx_la_LDFLAGS =     \
+       -framework AudioUnit            \
+       -framework CoreAudio            \
+       -framework AudioToolbox         \
+       $(NO_UNDEFINED)                 \
+       $(LTVERSIONFLAGS)
+
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        audio_osx.i
@@ -56,20 +70,9 @@ TOP_SWIG_IFILES =                    \
 audio_osx_pythondir_category =         \
        gnuradio
 
-# additional sources for the SWIG-generated library
-audio_osx_la_swig_sources =            \
-       audio_osx_sink.cc               \
-       audio_osx_source.cc
-
 # additional libraries for linking with the SWIG-generated library
 audio_osx_la_swig_libadd =             \
-       $(GNURADIO_CORE_LA)
-
-# additional LD flags for linking the SWIG-generated library
-audio_osx_la_swig_ldflags =            \
-       -framework AudioUnit            \
-       -framework CoreAudio            \
-       -framework AudioToolbox
+       libgnuradio-audio-osx.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -78,3 +81,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
index c92fbcb0d9cf641e11582634680a8791171894f6..79e79e36cb0edeed5f7d43183cf76a520b32db53 100644 (file)
 #ifndef INCLUDED_AUDIO_OSX_H
 #define INCLUDED_AUDIO_OSX_H
 
-#define CheckErrorAndThrow(err,what,throw_str) \
-if (err) { \
-  OSStatus error = static_cast<OSStatus>(err); \
-  fprintf (stderr, "%s\n  Error# %ld ('%4s')\n  %s:%d\n", \
-          what, error, (char*)(&err), __FILE__, __LINE__); \
-  fflush (stdout); \
-  throw std::runtime_error (throw_str); \
-}
+#include <iostream>
+#include <string.h>
 
-#define CheckError(err,what) \
-if (err) { \
-  OSStatus error = static_cast<OSStatus>(err); \
-  fprintf (stderr, "%s\n  Error# %ld ('%4s')\n  %s:%d\n", \
-          what, error, (char*)(&err), __FILE__, __LINE__); \
-  fflush (stdout); \
-}
+#define CheckErrorAndThrow(err,what,throw_str)                         \
+  if (err) {                                                           \
+    OSStatus error = static_cast<OSStatus>(err);                       \
+    char err_str[4];                                                   \
+    strncpy (err_str, (char*)(&err), 4);                               \
+    std::cerr << what << std::endl;                                    \
+    std::cerr << "  Error# " << error << " ('" << err_str              \
+             << "')" << std::endl;                                     \
+    std::cerr << "  " << __FILE__ << ":" << __LINE__ << std::endl;     \
+    fflush (stderr);                                                   \
+    throw std::runtime_error (throw_str);                              \
+  }
+
+#define CheckError(err,what)                                           \
+  if (err) {                                                           \
+    OSStatus error = static_cast<OSStatus>(err);                       \
+    char err_str[4];                                                   \
+    strncpy (err_str, (char*)(&err), 4);                               \
+    std::cerr << what << std::endl;                                    \
+    std::cerr << "  Error# " << error << " ('" << err_str              \
+             << "')" << std::endl;                                     \
+    std::cerr << "  " << __FILE__ << ":" << __LINE__ << std::endl;     \
+    fflush (stderr);                                                   \
+  }
 
 #ifdef WORDS_BIGENDIAN
 #define GR_PCM_ENDIANNESS kLinearPCMFormatFlagIsBigEndian
@@ -46,4 +57,15 @@ if (err) { \
 #define GR_PCM_ENDIANNESS 0
 #endif
 
+// Check the version of MacOSX being used
+#ifdef __APPLE_CC__
+#include <AvailabilityMacros.h>
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+#define GR_USE_OLD_AUDIO_UNIT
+#endif
+#endif
+
 #endif /* INCLUDED_AUDIO_OSX_H */
index fef21babd939be34b6196c58ede4716ad5f40866..20fd895b989a4ef691746b32fbd64861f1c85bd4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio.
  *
@@ -24,8 +24,6 @@
 #include "config.h"
 #endif
 
-#define _USE_OMNI_THREADS_
-
 #include <audio_osx_sink.h>
 #include <gr_io_signature.h>
 #include <stdexcept>
@@ -47,19 +45,19 @@ audio_osx_sink::audio_osx_sink (int sample_rate,
     d_OutputAU (0)
 {
   if (sample_rate <= 0) {
-    fprintf (stderr, "Invalid Sample Rate: %d\n", sample_rate);
+    std::cerr << "Invalid Sample Rate: " << sample_rate << std::endl;
     throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
   } else
     d_sample_rate = (Float64) sample_rate;
 
   if (channel_config <= 0 & channel_config != -1) {
-    fprintf (stderr, "Invalid Channel Config: %d\n", channel_config);
+    std::cerr << "Invalid Channel Config: " << channel_config << std::endl;
     throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
   } else if (channel_config == -1) {
 // no user input; try "device name" instead
     int l_n_channels = (int) strtol (device_name.data(), (char **)NULL, 10);
     if (l_n_channels == 0 & errno) {
-      fprintf (stderr, "Error Converting Device Name: %d\n", errno);
+      std::cerr << "Error Converting Device Name: " << errno << std::endl;
       throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
     }
     if (l_n_channels <= 0)
@@ -79,7 +77,7 @@ audio_osx_sink::audio_osx_sink (int sample_rate,
   if (max_sample_count == -1)
     max_sample_count = sample_rate;
   else if (max_sample_count <= 0) {
-    fprintf (stderr, "Invalid Max Sample Count: %d\n", max_sample_count);
+    std::cerr << "Invalid Max Sample Count: " << max_sample_count << std::endl;
     throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
   }
 
@@ -98,21 +96,39 @@ audio_osx_sink::audio_osx_sink (int sample_rate,
   OSStatus err = noErr;
 
 // Open the default output unit
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  AudioComponentDescription desc;
+#else
   ComponentDescription desc;
+#endif
+
   desc.componentType = kAudioUnitType_Output;
   desc.componentSubType = kAudioUnitSubType_DefaultOutput;
   desc.componentManufacturer = kAudioUnitManufacturer_Apple;
   desc.componentFlags = 0;
   desc.componentFlagsMask = 0;
 
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  AudioComponent comp = AudioComponentFindNext(NULL, &desc);
+  if (comp == NULL) {
+    std::cerr << "AudioComponentFindNext Error" << std::endl;
+    throw std::runtime_error ("audio_osx_sink::audio_osx_sink");
+  }
+#else
   Component comp = FindNextComponent (NULL, &desc);
   if (comp == NULL) {
-    fprintf (stderr, "FindNextComponent Error\n");
+    std::cerr << "FindNextComponent Error" << std::endl;
     throw std::runtime_error ("audio_osx_sink::audio_osx_sink");
   }
+#endif
 
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  err = AudioComponentInstanceNew (comp, &d_OutputAU);
+  CheckErrorAndThrow (err, "AudioComponentInstanceNew", "audio_osx_sink::audio_osx_sink");
+#else
   err = OpenAComponent (comp, &d_OutputAU);
   CheckErrorAndThrow (err, "OpenAComponent", "audio_osx_sink::audio_osx_sink");
+#endif
 
 // Set up a callback function to generate output to the output unit
 
@@ -154,11 +170,15 @@ audio_osx_sink::audio_osx_sink (int sample_rate,
 
 // create the stuff to regulate I/O
 
-  d_cond_data = new mld_condition ();
+  d_cond_data = new gruel::condition_variable ();
   if (d_cond_data == NULL)
-    CheckErrorAndThrow (errno, "new mld_condition (data)",
-                       "audio_osx_source::audio_osx_source");
-  d_internal = d_cond_data->mutex ();
+    CheckErrorAndThrow (errno, "new condition (data)",
+                       "audio_osx_sink::audio_osx_sink");
+
+  d_internal = new gruel::mutex ();
+  if (d_internal == NULL)
+    CheckErrorAndThrow (errno, "new mutex (internal)",
+                       "audio_osx_sink::audio_osx_sink");
 
 // initialize the AU for output
 
@@ -167,11 +187,10 @@ audio_osx_sink::audio_osx_sink (int sample_rate,
                      "audio_osx_sink::audio_osx_sink");
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "audio_osx_sink Parameters:\n");
-  fprintf (stderr, "  Sample Rate is %g\n", d_sample_rate);
-  fprintf (stderr, "  Number of Channels is %ld\n", d_n_channels);
-  fprintf (stderr, "  Max # samples to store per channel is %ld",
-          d_max_sample_count);
+  std::cerr << "audio_osx_sink Parameters:" << std::endl;
+  std::cerr << "  Sample Rate is " << d_sample_rate << std::endl;
+  std::cerr << "  Number of Channels is " << d_n_channels << std::endl;
+  std::cerr << "  Max # samples to store per channel is " << d_max_sample_count << std::endl;
 #endif
 }
 
@@ -220,7 +239,11 @@ audio_osx_sink::~audio_osx_sink ()
 // stop and close the AudioUnit
   stop ();
   AudioUnitUninitialize (d_OutputAU);
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  AudioComponentInstanceDispose (d_OutputAU);
+#else
   CloseComponent (d_OutputAU);
+#endif
 
 // empty and delete the queues
   for (UInt32 n = 0; n < d_n_channels; n++) {
@@ -232,6 +255,9 @@ audio_osx_sink::~audio_osx_sink ()
 
 // close and delete control stuff
   delete d_cond_data;
+  d_cond_data = 0;
+  delete d_internal;
+  d_internal = 0;
 }
 
 audio_osx_sink_sptr
@@ -253,7 +279,7 @@ audio_osx_sink::work (int noutput_items,
                      gr_vector_const_void_star &input_items,
                      gr_vector_void_star &output_items)
 {
-  d_internal->lock ();
+  gruel::scoped_lock l (*d_internal);
 
   /* take the input data, copy it, and push it to the bottom of the queue
      mono input are pushed onto queue[0];
@@ -275,8 +301,8 @@ audio_osx_sink::work (int noutput_items,
 #endif
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "work1: qSC = %ld, lMC = %ld, dmSC = %ld, nOI = %d\n",
-          d_queueSampleCount, l_max_count, d_max_sample_count, noutput_items);
+  std::cerr << "work1: qSC = " << d_queueSampleCount << ", lMC = "<< l_max_count
+           << ", dmSC = " << d_max_sample_count << ", nOI = " << noutput_items << std::endl;
 #endif
 
   if (d_queueSampleCount > l_max_count) {
@@ -286,8 +312,8 @@ audio_osx_sink::work (int noutput_items,
       while (d_queueSampleCount > l_max_count) {
 // release control so-as to allow data to be retrieved;
 // block until there is data to return
-       d_cond_data->wait ();
-// the condition's signal() was called; acquire control
+       d_cond_data->wait (l);
+// the condition's 'notify' was called; acquire control
 // to keep thread safe
       }
     }
@@ -318,7 +344,7 @@ audio_osx_sink::work (int noutput_items,
   if (res == -1) {
 // data coming in too fast
 // drop oldest buffer
-    fputs ("oX", stderr);
+    fputs ("aO", stderr);
     fflush (stderr);
 // set the local number of samples available to the max
     d_queueSampleCount = d_buffers[0]->buffer_length_items ();
@@ -328,13 +354,10 @@ audio_osx_sink::work (int noutput_items,
   }
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "work2: #OI = %4d, #Cnt = %4ld, mSC = %ld\n",
-          noutput_items, d_queueSampleCount, d_max_sample_count);
+  std::cerr << "work2: #OI = " << noutput_items << ", #Cnt = "
+           << d_queueSampleCount << ", mSC = " << d_max_sample_count << std::endl;
 #endif
 
-// release control to allow for other processing parts to run
-  d_internal->unlock ();
-
   return (noutput_items);
 }
 
@@ -349,11 +372,11 @@ OSStatus audio_osx_sink::AUOutputCallback
   audio_osx_sink* This = (audio_osx_sink*) inRefCon;
   OSStatus err = noErr;
 
-  This->d_internal->lock ();
+  gruel::scoped_lock l (*This->d_internal);
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb_in: SC = %4ld, in#F = %4ld\n",
-          This->d_queueSampleCount, inNumberFrames);
+  std::cerr << "cb_in: SC = " << This->d_queueSampleCount
+           << ", in#F = " << inNumberFrames << std::endl;
 #endif
 
   if (This->d_queueSampleCount < inNumberFrames) {
@@ -364,7 +387,7 @@ OSStatus audio_osx_sink::AUOutputCallback
     int l_counter = This->d_n_channels;
 
     while (--l_counter >= 0) {
-      UInt32 t_n_output_items = inNumberFrames;
+      size_t t_n_output_items = inNumberFrames;
       float* outBuffer = (float*) ioData->mBuffers[l_counter].mData;
       This->d_buffers[l_counter]->dequeue (outBuffer, &t_n_output_items);
       if (t_n_output_items != inNumberFrames) {
@@ -378,14 +401,11 @@ OSStatus audio_osx_sink::AUOutputCallback
   }
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb_out: SC = %4ld\n", This->d_queueSampleCount);
+  std::cerr << "cb_out: SC = " << This->d_queueSampleCount << std::endl;
 #endif
 
 // signal that data is available
-  This->d_cond_data->signal ();
-
-// release control to allow for other processing parts to run
-  This->d_internal->unlock ();
+  This->d_cond_data->notify_one ();
 
   return (err);
 }
index ceb291d0fb1214a1df45d627d05bd68c09b10a39..a1a56502cb8d19a4805ae4b2076726f0e879579f 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio.
  *
@@ -59,8 +59,8 @@ class audio_osx_sink : public gr_sync_block {
   UInt32              d_n_channels;
   UInt32              d_queueSampleCount, d_max_sample_count;
   bool                d_do_block;
-  mld_mutex_ptr       d_internal;
-  mld_condition_ptr   d_cond_data;
+  gruel::mutex*       d_internal;
+  gruel::condition_variable* d_cond_data;
   circular_buffer<float>** d_buffers;
 
 // AudioUnits and Such
index e82e8ad21515e128a8ea778ff7b0860912ca0036..538cfd8f695d2b1ff34dff444af762d701275237 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio.
  *
@@ -24,8 +24,6 @@
 #include "config.h"
 #endif
 
-#define _USE_OMNI_THREADS_
-
 #include <audio_osx_source.h>
 #include <gr_io_signature.h>
 #include <stdexcept>
 void PrintStreamDesc (AudioStreamBasicDescription *inDesc)
 {
   if (inDesc == NULL) {
-    fprintf (stderr, "PrintStreamDesc: Can't print a NULL desc!\n");
+    std::cerr << "PrintStreamDesc: Can't print a NULL desc!" << std::endl;
     return;
   }
 
-  fprintf (stderr, "  Sample Rate        : %g\n", inDesc->mSampleRate);
-  fprintf (stderr, "  Format ID          : %4s\n", (char*)&inDesc->mFormatID);
-  fprintf (stderr, "  Format Flags       : %lX\n", inDesc->mFormatFlags);
-  fprintf (stderr, "  Bytes per Packet   : %ld\n", inDesc->mBytesPerPacket);
-  fprintf (stderr, "  Frames per Packet  : %ld\n", inDesc->mFramesPerPacket);
-  fprintf (stderr, "  Bytes per Frame    : %ld\n", inDesc->mBytesPerFrame);
-  fprintf (stderr, "  Channels per Frame : %ld\n", inDesc->mChannelsPerFrame);
-  fprintf (stderr, "  Bits per Channel   : %ld\n", inDesc->mBitsPerChannel);
+  std::cerr << "  Sample Rate        : " << inDesc->mSampleRate << std::endl;
+  char format_id[4];
+  strncpy (format_id, (char*)(&inDesc->mFormatID), 4);
+  std::cerr << "  Format ID          : " << format_id << std::endl;
+  std::cerr << "  Format Flags       : " << inDesc->mFormatFlags << std::endl;
+  std::cerr << "  Bytes per Packet   : " << inDesc->mBytesPerPacket << std::endl;
+  std::cerr << "  Frames per Packet  : " << inDesc->mFramesPerPacket << std::endl;
+  std::cerr << "  Bytes per Frame    : " << inDesc->mBytesPerFrame << std::endl;
+  std::cerr << "  Channels per Frame : " << inDesc->mChannelsPerFrame << std::endl;
+  std::cerr << "  Bits per Channel   : " << inDesc->mBitsPerChannel << std::endl;
 }
 
 // FIXME these should query some kind of user preference
@@ -79,19 +79,19 @@ audio_osx_source::audio_osx_source (int sample_rate,
     d_AudioConverter (0)
 {
   if (sample_rate <= 0) {
-    fprintf (stderr, "Invalid Sample Rate: %d\n", sample_rate);
+    std::cerr << "Invalid Sample Rate: " << sample_rate << std::endl;
     throw std::invalid_argument ("audio_osx_source::audio_osx_source");
   } else
     d_outputSampleRate = (Float64) sample_rate;
 
   if (channel_config <= 0 & channel_config != -1) {
-    fprintf (stderr, "Invalid Channel Config: %d\n", channel_config);
+    std::cerr << "Invalid Channel Config: " << channel_config << std::endl;
     throw std::invalid_argument ("audio_osx_source::audio_osx_source");
   } else if (channel_config == -1) {
 // no user input; try "device name" instead
     int l_n_channels = (int) strtol (device_name.data(), (char **)NULL, 10);
     if (l_n_channels == 0 & errno) {
-      fprintf (stderr, "Error Converting Device Name: %d\n", errno);
+      std::cerr << "Error Converting Device Name: " << errno << std::endl;
       throw std::invalid_argument ("audio_osx_source::audio_osx_source");
     }
     if (l_n_channels <= 0)
@@ -107,14 +107,14 @@ audio_osx_source::audio_osx_source (int sample_rate,
   if (max_sample_count == -1)
     max_sample_count = sample_rate;
   else if (max_sample_count <= 0) {
-    fprintf (stderr, "Invalid Max Sample Count: %d\n", max_sample_count);
+    std::cerr << "Invalid Max Sample Count: " << max_sample_count << std::endl;
     throw std::invalid_argument ("audio_osx_source::audio_osx_source");
   }
 
   d_max_sample_count = max_sample_count;
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "source(): max # samples = %ld\n", d_max_sample_count);
+  std::cerr << "source(): max # samples = " << d_max_sample_count << std::endl;
 #endif
 
   OSStatus err = noErr;
@@ -122,7 +122,12 @@ audio_osx_source::audio_osx_source (int sample_rate,
 // create the default AudioUnit for input
 
 // Open the default input unit
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  AudioComponentDescription InputDesc;
+#else
   ComponentDescription InputDesc;
+#endif
+  
 
   InputDesc.componentType = kAudioUnitType_Output;
   InputDesc.componentSubType = kAudioUnitSubType_HALOutput;
@@ -130,15 +135,31 @@ audio_osx_source::audio_osx_source (int sample_rate,
   InputDesc.componentFlags = 0;
   InputDesc.componentFlagsMask = 0;
 
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  AudioComponent comp = AudioComponentFindNext (NULL, &InputDesc);
+#else
   Component comp = FindNextComponent (NULL, &InputDesc);
+#endif
+  
   if (comp == NULL) {
-    fprintf (stderr, "FindNextComponent Error\n");
+#ifndef GR_USE_OLD_AUDIO_UNIT
+    std::cerr << "AudioComponentFindNext Error" << std::endl;
+#else
+    std::cerr << "FindNextComponent Error" << std::endl;
+#endif
     throw std::runtime_error ("audio_osx_source::audio_osx_source");
   }
 
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  err = AudioComponentInstanceNew (comp, &d_InputAU);
+  CheckErrorAndThrow (err, "AudioComponentInstanceNew",
+                     "audio_osx_source::audio_osx_source");
+#else
   err = OpenAComponent (comp, &d_InputAU);
   CheckErrorAndThrow (err, "OpenAComponent",
                      "audio_osx_source::audio_osx_source");
+#endif
+  
 
   UInt32 enableIO;
 
@@ -208,7 +229,7 @@ audio_osx_source::audio_osx_source (int sample_rate,
   CheckErrorAndThrow (err, "AudioUnitGetProperty HasIO",
                      "audio_osx_source::audio_osx_source");
   if (hasInput == 0) {
-    fprintf (stderr, "Selected Audio Device does not support Input.\n");
+    std::cerr << "Selected Audio Device does not support Input." << std::endl;
     throw std::runtime_error ("audio_osx_source::audio_osx_source");
   }
 
@@ -248,7 +269,7 @@ audio_osx_source::audio_osx_source (int sample_rate,
                      "audio_osx_source::audio_osx_source");
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "\n---- Device Stream Format ----\n" );
+  std::cerr << std::endl << "---- Device Stream Format ----" << std::endl;
   PrintStreamDesc (&asbd_device);
 #endif
 
@@ -264,7 +285,7 @@ audio_osx_source::audio_osx_source (int sample_rate,
                      "audio_osx_source::audio_osx_source");
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "\n---- Client Stream Format ----\n");
+  std::cerr << std::endl << "---- Client Stream Format ----" << std::endl;
   PrintStreamDesc (&asbd_client);
 #endif
 
@@ -423,11 +444,15 @@ audio_osx_source::audio_osx_source (int sample_rate,
 
 // create the stuff to regulate I/O
 
-  d_cond_data = new mld_condition ();
+  d_cond_data = new gruel::condition_variable ();
   if (d_cond_data == NULL)
-    CheckErrorAndThrow (errno, "new mld_condition (data)",
+    CheckErrorAndThrow (errno, "new condition (data)",
+                       "audio_osx_source::audio_osx_source");
+
+  d_internal = new gruel::mutex ();
+  if (d_internal == NULL)
+    CheckErrorAndThrow (errno, "new mutex (internal)",
                        "audio_osx_source::audio_osx_source");
-  d_internal = d_cond_data->mutex ();
 
 // initialize the AU for input
 
@@ -436,22 +461,17 @@ audio_osx_source::audio_osx_source (int sample_rate,
                      "audio_osx_source::audio_osx_source");
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "audio_osx_source Parameters:\n");
-  fprintf (stderr, "  Device Sample Rate is %g\n", d_deviceSampleRate);
-  fprintf (stderr, "  User Sample Rate is %g\n", d_outputSampleRate);
-  fprintf (stderr, "  Max Sample Count is %ld\n", d_max_sample_count);
-  fprintf (stderr, "  # Device Channels is %ld\n", d_n_deviceChannels);
-  fprintf (stderr, "  # Max Channels is %ld\n", d_n_max_channels);
-  fprintf (stderr, "  Device Buffer Size is Frames = %ld\n",
-          d_deviceBufferSizeFrames);
-  fprintf (stderr, "  Lead Size is Frames = %ld\n",
-          d_leadSizeFrames);
-  fprintf (stderr, "  Trail Size is Frames = %ld\n",
-          d_trailSizeFrames);
-  fprintf (stderr, "  Input Buffer Size is Frames = %ld\n",
-          d_inputBufferSizeFrames);
-  fprintf (stderr, "  Output Buffer Size is Frames = %ld\n",
-          d_outputBufferSizeFrames);
+  std::cerr << "audio_osx_source Parameters:" << std::endl;
+  std::cerr << "  Device Sample Rate is " << d_deviceSampleRate << std::endl;
+  std::cerr << "  User Sample Rate is " << d_outputSampleRate << std::endl;
+  std::cerr << "  Max Sample Count is " << d_max_sample_count << std::endl;
+  std::cerr << "  # Device Channels is " << d_n_deviceChannels << std::endl;
+  std::cerr << "  # Max Channels is " << d_n_max_channels << std::endl;
+  std::cerr << "  Device Buffer Size is Frames = " << d_deviceBufferSizeFrames << std::endl;
+  std::cerr << "  Lead Size is Frames = " << d_leadSizeFrames << std::endl;
+  std::cerr << "  Trail Size is Frames = " << d_trailSizeFrames << std::endl;
+  std::cerr << "  Input Buffer Size is Frames = " << d_inputBufferSizeFrames << std::endl;
+  std::cerr << "  Output Buffer Size is Frames = " << d_outputBufferSizeFrames << std::endl;
 #endif
 }
 
@@ -564,8 +584,13 @@ audio_osx_source::~audio_osx_source ()
   err = AudioUnitUninitialize (d_InputAU);
   CheckError (err, "~audio_osx_source: AudioUnitUninitialize");
 
+#ifndef GR_USE_OLD_AUDIO_UNIT
+  err = AudioComponentInstanceDispose (d_InputAU);
+  CheckError (err, "~audio_osx_source: AudioComponentInstanceDispose");
+#else
   err = CloseComponent (d_InputAU);
   CheckError (err, "~audio_osx_source: CloseComponent");
+#endif
 
 // empty and delete the queues
   for (UInt32 n = 0; n < d_n_max_channels; n++) {
@@ -577,6 +602,9 @@ audio_osx_source::~audio_osx_source ()
 
 // close and delete the control stuff
   delete d_cond_data;
+  d_cond_data = 0;
+  delete d_internal;
+  d_internal = 0;
 }
 
 audio_osx_source_sptr
@@ -598,18 +626,18 @@ audio_osx_source::check_topology (int ninputs, int noutputs)
 {
 // check # inputs to make sure it's valid
   if (ninputs != 0) {
-    fprintf (stderr, "audio_osx_source::check_topology(): "
-            "number of input streams provided (%d) should be 0.\n",
-            ninputs);
+    std::cerr << "audio_osx_source::check_topology(): number of input "
+             << "streams provided (" << ninputs
+             << ") should be 0." << std::endl;
     throw std::runtime_error ("audio_osx_source::check_topology()");
   }
 
 // check # outputs to make sure it's valid
   if ((noutputs < 1) | (noutputs > (int) d_n_max_channels)) {
-    fprintf (stderr, "audio_osx_source::check_topology(): "
-            "number of output streams provided (%d) should be in "
-            "[1,%ld] for the selected audio device.\n",
-            noutputs, d_n_max_channels);
+    std::cerr << "audio_osx_source::check_topology(): number of output "
+             << "streams provided (" << noutputs << ") should be in [1,"
+             << d_n_max_channels << "] for the selected audio device."
+             << std::endl;
     throw std::runtime_error ("audio_osx_source::check_topology()");
   }
 
@@ -617,8 +645,8 @@ audio_osx_source::check_topology (int ninputs, int noutputs)
   d_n_user_channels = noutputs;
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "chk_topo: Actual # user output channels = %d\n",
-          noutputs);
+  std::cerr << "chk_topo: Actual # user output channels = "
+           << noutputs << std::endl;
 #endif
 
   return (true);
@@ -631,11 +659,12 @@ audio_osx_source::work
  gr_vector_void_star &output_items)
 {
   // acquire control to do processing here only
-  d_internal->lock ();
+  gruel::scoped_lock l (*d_internal);
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "work1: SC = %4ld, #OI = %4d, #Chan = %ld\n",
-          d_queueSampleCount, noutput_items, output_items.size());
+  std::cerr << "work1: SC = " << d_queueSampleCount
+           << ", #OI = " << noutput_items
+           << ", #Chan = " << output_items.size() << std::endl;
 #endif
 
   // set the actual # of output items to the 'desired' amount then
@@ -653,14 +682,12 @@ audio_osx_source::work
        while (d_queueSampleCount == 0) {
          // release control so-as to allow data to be retrieved;
          // block until there is data to return
-         d_cond_data->wait ();
-         // the condition's signal() was called; acquire control to
+         d_cond_data->wait (l);
+         // the condition's 'notify' was called; acquire control to
          // keep thread safe
        }
       } else {
        // no data & not blocking; return nothing
-       // release control so-as to allow data to be retrieved
-       d_internal->unlock ();
        return (0);
       }
     }
@@ -675,14 +702,14 @@ audio_osx_source::work
   // verify that the number copied out is as expected.
 
   while (--l_counter >= 0) {
-    UInt32 t_n_output_items = actual_noutput_items;
+    size_t t_n_output_items = actual_noutput_items;
     d_buffers[l_counter]->dequeue ((float*) output_items[l_counter],
                                   &t_n_output_items);
     if (t_n_output_items != actual_noutput_items) {
-      fprintf (stderr, "audio_osx_source::work(): "
-              "number of available items changing "
-              "unexpectedly; expecting %ld, got %ld.\n",
-              actual_noutput_items, t_n_output_items);
+      std::cerr << "audio_osx_source::work(): ERROR: number of "
+               << "available items changing unexpectedly; expecting "
+               << actual_noutput_items << ", got "
+               << t_n_output_items << "." << std::endl;
       throw std::runtime_error ("audio_osx_source::work()");
     }
   }
@@ -693,16 +720,9 @@ audio_osx_source::work
   d_queueSampleCount -= actual_noutput_items;
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "work2: SC = %4ld, act#OI = %4ld\n",
-          d_queueSampleCount, actual_noutput_items);
-#endif
-
-  // release control to allow for other processing parts to run
-
-  d_internal->unlock ();
-
-#if _OSX_AU_DEBUG_
-  fprintf (stderr, "work3: Returning.\n");
+  std::cerr << "work2: SC = " << d_queueSampleCount
+           << ", act#OI = " << actual_noutput_items << std::endl
+           << "Returning." << std::endl;
 #endif
 
   return (actual_noutput_items);
@@ -728,8 +748,9 @@ audio_osx_source::ConverterCallback
   This->d_n_ActualInputFrames = (*ioNumberDataPackets);
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cc1: io#DP = %ld, TIBSB = %ld, #C = %d\n",
-          *ioNumberDataPackets, totalInputBufferSizeBytes, counter);
+  std::cerr << "cc1: io#DP = " << (*ioNumberDataPackets)
+           << ", TIBSB = " << totalInputBufferSizeBytes
+           << ", #C = " << counter << std::endl;
 #endif
 
   while (--counter >= 0)  {
@@ -740,7 +761,7 @@ audio_osx_source::ConverterCallback
   }
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cc2: Returning.\n");
+  std::cerr << "cc2: Returning." << std::endl;
 #endif
 
   return (noErr);
@@ -757,11 +778,12 @@ audio_osx_source::AUInputCallback (void* inRefCon,
   OSStatus err = noErr;
   audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon);
 
-  This->d_internal->lock ();
+  gruel::scoped_lock l (*This->d_internal);
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb0: in#F = %4ld, inBN = %ld, SC = %4ld\n",
-          inNumberFrames, inBusNumber, This->d_queueSampleCount);
+  std::cerr << "cb0: in#F = " << inNumberFrames
+           << ", inBN = " << inBusNumber
+           << ", SC = " << This->d_queueSampleCount << std::endl;
 #endif
 
 // Get the new audio data from the input device
@@ -821,8 +843,8 @@ audio_osx_source::AUInputCallback (void* inRefCon,
 #endif
 
 #if _OSX_AU_DEBUG_
-    fprintf (stderr, "cb1:  avail: #IF = %ld, #OF = %ld\n",
-            AvailableInputFrames, AvailableOutputFrames);
+    std::cerr << "cb1:  avail: #IF = " << AvailableInputFrames
+             << ", #OF = " << AvailableOutputFrames << std::endl;
 #endif
     ActualOutputFrames = AvailableOutputFrames;
 
@@ -841,11 +863,11 @@ audio_osx_source::AUInputCallback (void* inRefCon,
 // on output, ActualOutputFrames is the actual number of output frames
 
 #if _OSX_AU_DEBUG_
-    fprintf (stderr, "cb2: actual: #IF = %ld, #OF = %ld\n",
-            This->d_n_ActualInputFrames, AvailableOutputFrames);
+    std::cerr << "cb2: actual: #IF = " << This->d_n_ActualInputFrames
+             << ", #OF = " << AvailableOutputFrames << std::endl;
     if (This->d_n_ActualInputFrames != AvailableInputFrames)
-      fprintf (stderr, "cb2.1: avail#IF = %ld, actual#IF = %ld\n",
-              AvailableInputFrames, This->d_n_ActualInputFrames);
+      std::cerr << "cb2.1: avail#IF = " << AvailableInputFrames
+               << ", actual#IF = " << This->d_n_ActualInputFrames << std::endl;
 #endif
   }
 
@@ -858,7 +880,7 @@ audio_osx_source::AUInputCallback (void* inRefCon,
     float* inBuffer = (float*) This->d_OutputBuffer->mBuffers[l_counter].mData;
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb3: enqueuing audio data.\n");
+    std::cerr << "cb3: enqueuing audio data." << std::endl;
 #endif
 
     int l_res = This->d_buffers[l_counter]->enqueue (inBuffer, ActualOutputFrames);
@@ -879,23 +901,16 @@ audio_osx_source::AUInputCallback (void* inRefCon,
   }
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb4: #OI = %4ld, #Cnt = %4ld, mSC = %ld, \n",
-          ActualOutputFrames, This->d_queueSampleCount,
-          This->d_max_sample_count);
+  std::cerr << "cb4: #OI = " << ActualOutputFrames
+           << ", #Cnt = " << This->d_queueSampleCount
+           << ", mSC = " << This->d_max_sample_count << std::endl;
 #endif
 
 // signal that data is available, if appropraite
-  This->d_cond_data->signal ();
-
-#if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb5: releasing internal mutex.\n");
-#endif
-
-// release control to allow for other processing parts to run
-  This->d_internal->unlock ();
+  This->d_cond_data->notify_one ();
 
 #if _OSX_AU_DEBUG_
-  fprintf (stderr, "cb6: returning.\n");
+  std::cerr << "cb5: returning." << std::endl;
 #endif
 
   return (err);
@@ -930,7 +945,7 @@ audio_osx_source::HardwareListener
   OSStatus err = noErr;
   audio_osx_source* This = static_cast<audio_osx_source*>(inClientData);
 
-  fprintf (stderr, "a_o_s::HardwareListener\n");
+  std::cerr << "a_o_s::HardwareListener" << std::endl;
 
 // set the new default hardware input device for use by our AU
 
@@ -957,7 +972,7 @@ audio_osx_source::UnitListener
   audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon);
   AudioStreamBasicDescription asbd;                    
 
-  fprintf (stderr, "a_o_s::UnitListener\n");
+  std::cerr << "a_o_s::UnitListener" << std::endl;
 
 // get the converter's input ASBD (for printing)
 
@@ -970,8 +985,8 @@ audio_osx_source::UnitListener
                      "CurrentInputStreamDescription",
                      "audio_osx_source::UnitListener");
 
-  fprintf (stderr, "UnitListener: Input Source changed.\n"
-          "Old Source Output Info:\n");
+  std::cerr << "UnitListener: Input Source changed." << std::endl
+           << "Old Source Output Info:" << std::endl;
   PrintStreamDesc (&asbd);
 
 // get the new input unit's output ASBD
@@ -984,7 +999,7 @@ audio_osx_source::UnitListener
   CheckErrorAndThrow (err, "AudioUnitGetProperty StreamFormat",
                      "audio_osx_source::UnitListener");
 
-  fprintf (stderr, "New Source Output Info:\n");
+  std::cerr << "New Source Output Info:" << std::endl;
   PrintStreamDesc (&asbd);
 
 // set the converter's input ASBD to this
index 780f7ec6b809bbcc02f761957133cdc2d3b4591d..e8df47b16fb15ad2c5fbd3d7a49542f80fd6c1f0 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio.
  *
@@ -66,8 +66,8 @@ class audio_osx_source : public gr_sync_block {
   UInt32              d_n_AvailableInputFrames, d_n_ActualInputFrames;
   UInt32              d_n_user_channels, d_n_max_channels, d_n_deviceChannels;
   bool                d_do_block, d_passThrough, d_waiting_for_data;
-  mld_mutex_ptr       d_internal;
-  mld_condition_ptr   d_cond_data;
+  gruel::mutex*       d_internal;
+  gruel::condition_variable* d_cond_data;
   circular_buffer<float>** d_buffers;
 
 // AudioUnits and Such
index fa451d607b728e2c64a92ef067720b1551351d39..48758bf878ecdbffc7aabc090ed98208f8571b01 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio.
  *
 #ifndef _CIRCULAR_BUFFER_H_
 #define _CIRCULAR_BUFFER_H_
 
-#include "mld_threads.h"
+#include <gruel/thread.h>
+#include <iostream>
 #include <stdexcept>
 
+#ifndef DO_DEBUG
 #define DO_DEBUG 0
+#endif
 
 #if DO_DEBUG
 #define DEBUG(X) do{X} while(0);
 #define DEBUG(X) do{} while(0);
 #endif
 
-template <class T> class circular_buffer
+template <class T>
+class circular_buffer
 {
 private:
 // the buffer to use
   T* d_buffer;
 
 // the following are in Items (type T)
-  UInt32 d_bufLen_I, d_readNdx_I, d_writeNdx_I;
-  UInt32 d_n_avail_write_I, d_n_avail_read_I;
+  size_t d_bufLen_I, d_readNdx_I, d_writeNdx_I;
+  size_t d_n_avail_write_I, d_n_avail_read_I;
 
 // stuff to control access to class internals
-  mld_mutex_ptr d_internal;
-  mld_condition_ptr d_readBlock, d_writeBlock;
+  gruel::mutex* d_internal;
+  gruel::condition_variable* d_readBlock;
+  gruel::condition_variable* d_writeBlock;
 
 // booleans to decide how to control reading, writing, and aborting
   bool d_doWriteBlock, d_doFullRead, d_doAbort;
@@ -67,7 +72,7 @@ private:
   };
 
 public:
-  circular_buffer (UInt32 bufLen_I,
+  circular_buffer (size_t bufLen_I,
                   bool doWriteBlock = true, bool doFullRead = false) {
     if (bufLen_I == 0)
       throw std::runtime_error ("circular_buffer(): "
@@ -79,10 +84,10 @@ public:
     d_internal = NULL;
     d_readBlock = d_writeBlock = NULL;
     reset ();
-    DEBUG (fprintf (stderr, "c_b(): buf len (items) = %ld, "
-                   "doWriteBlock = %s, doFullRead = %s\n", d_bufLen_I,
-                   (d_doWriteBlock ? "true" : "false"),
-                   (d_doFullRead ? "true" : "false")));
+    DEBUG (std::cerr << "c_b(): buf len (items) = " << d_bufLen_
+          << ", doWriteBlock = " << (d_doWriteBlock ? "true" : "false")
+          << ", doFullRead = " << (d_doFullRead ? "true" : "false")
+          << std::endl);
   };
 
   ~circular_buffer () {
@@ -90,21 +95,19 @@ public:
     delete [] d_buffer;
   };
 
-  inline UInt32 n_avail_write_items () {
-    d_internal->lock ();
-    UInt32 retVal = d_n_avail_write_I;
-    d_internal->unlock ();
+  inline size_t n_avail_write_items () {
+    gruel::scoped_lock l (*d_internal);
+    size_t retVal = d_n_avail_write_I;
     return (retVal);
   };
 
-  inline UInt32 n_avail_read_items () {
-    d_internal->lock ();
-    UInt32 retVal = d_n_avail_read_I;
-    d_internal->unlock ();
+  inline size_t n_avail_read_items () {
+    gruel::scoped_lock l (*d_internal);
+    size_t retVal = d_n_avail_read_I;
     return (retVal);
   };
 
-  inline UInt32 buffer_length_items () {return (d_bufLen_I);};
+  inline size_t buffer_length_items () {return (d_bufLen_I);};
   inline bool do_write_block () {return (d_doWriteBlock);};
   inline bool do_full_read () {return (d_doFullRead);};
 
@@ -117,13 +120,13 @@ public:
     // create a mutex to handle contention of shared resources;
     // any routine needed access to shared resources uses lock()
     // before doing anything, then unlock() when finished.
-    d_internal = new mld_mutex ();
+    d_internal = new gruel::mutex ();
     // link the internal mutex to the read and write conditions;
     // when wait() is called, the internal mutex will automatically
-    // be unlock()'ed.  Upon return (from a signal() to the condition),
+    // be unlock()'ed.  Upon return (from a notify_one() to the condition),
     // the internal mutex will be lock()'ed.
-    d_readBlock = new mld_condition (d_internal);
-    d_writeBlock = new mld_condition (d_internal);
+    d_readBlock = new gruel::condition_variable ();
+    d_writeBlock = new gruel::condition_variable ();
   };
 
 /*
@@ -147,14 +150,15 @@ public:
  *     buffer length is larger than the instantiated buffer length
  */
 
-  int enqueue (T* buf, UInt32 bufLen_I) {
-    DEBUG (fprintf (stderr, "enqueue: buf = %X, bufLen = %ld, #av_wr = %ld, "
-                   "#av_rd = %ld.\n", (unsigned int)buf, bufLen_I,
-                   d_n_avail_write_I, d_n_avail_read_I));
+  int enqueue (T* buf, size_t bufLen_I) {
+    DEBUG (std::cerr << "enqueue: buf = " << (void*) buf
+          << ", bufLen = " << bufLen_I
+          << ", #av_wr = " << d_n_avail_write_I
+          << ", #av_rd = " << d_n_avail_read_I << std::endl);
     if (bufLen_I > d_bufLen_I) {
-      fprintf (stderr, "cannot add buffer longer (%ld"
-              ") than instantiated length (%ld"
-              ").\n", bufLen_I, d_bufLen_I);
+      std::cerr << "ERROR: cannot add buffer longer ("
+               << bufLen_I << ") than instantiated length ("
+               << d_bufLen_I << ")." << std::endl;
       throw std::runtime_error ("circular_buffer::enqueue()");
     }
 
@@ -163,9 +167,8 @@ public:
     if (!buf)
       throw std::runtime_error ("circular_buffer::enqueue(): "
                                "input buffer is NULL.\n");
-    d_internal->lock ();
+    gruel::scoped_lock l (*d_internal);
     if (d_doAbort) {
-      d_internal->unlock ();
       return (2);
     }
     // set the return value to 1: success; change if needed
@@ -173,25 +176,25 @@ public:
     if (bufLen_I > d_n_avail_write_I) {
       if (d_doWriteBlock) {
        while (bufLen_I > d_n_avail_write_I) {
-         DEBUG (fprintf (stderr, "enqueue: #len > #a, waiting.\n"));
-         // wait will automatically unlock() the internal mutex
-         d_writeBlock->wait ();
-         // and lock() it here.
+         DEBUG (std::cerr << "enqueue: #len > #a, waiting." << std::endl);
+         // wait; will automatically unlock() the internal mutex via
+         // the scoped lock
+         d_writeBlock->wait (l);
+         // and auto re-lock() it here.
          if (d_doAbort) {
-           d_internal->unlock ();
-           DEBUG (fprintf (stderr, "enqueue: #len > #a, aborting.\n"));
+           DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl);
            return (2);
          }
-         DEBUG (fprintf (stderr, "enqueue: #len > #a, done waiting.\n"));
+         DEBUG (std::cerr << "enqueue: #len > #a, done waiting." << std::endl);
        }
       } else {
        d_n_avail_read_I = d_bufLen_I - bufLen_I;
        d_n_avail_write_I = bufLen_I;
-       DEBUG (fprintf (stderr, "circular_buffer::enqueue: overflow\n"));
+       DEBUG (std::cerr << "circular_buffer::enqueue: overflow" << std::endl);
        retval = -1;
       }
     }
-    UInt32 n_now_I = d_bufLen_I - d_writeNdx_I, n_start_I = 0;
+    size_t n_now_I = d_bufLen_I - d_writeNdx_I, n_start_I = 0;
     if (n_now_I > bufLen_I)
       n_now_I = bufLen_I;
     else if (n_now_I < bufLen_I)
@@ -204,8 +207,7 @@ public:
       d_writeNdx_I += n_now_I;
     d_n_avail_read_I += bufLen_I;
     d_n_avail_write_I -= bufLen_I;
-    d_readBlock->signal ();
-    d_internal->unlock ();
+    d_readBlock->notify_one ();
     return (retval);
   };
 
@@ -230,61 +232,61 @@ public:
  *     buffer length is larger than the instantiated buffer length
  */
 
-  int dequeue (T* buf, UInt32* bufLen_I) {
-    DEBUG (fprintf (stderr, "dequeue: buf = %X, *bufLen = %ld, #av_wr = %ld, "
-                   "#av_rd = %ld.\n", (unsigned int)buf, *bufLen_I,
-                   d_n_avail_write_I, d_n_avail_read_I));
+  int dequeue (T* buf, size_t* bufLen_I) {
+    DEBUG (std::cerr << "dequeue: buf = " << ((void*) buf)
+          << ", *bufLen = " << (*bufLen_I)
+          << ", #av_wr = " <<  d_n_avail_write_I
+          << ", #av_rd = " << d_n_avail_read_I << std::endl);
     if (!bufLen_I)
       throw std::runtime_error ("circular_buffer::dequeue(): "
                                "input bufLen pointer is NULL.\n");
     if (!buf)
       throw std::runtime_error ("circular_buffer::dequeue(): "
                                "input buffer pointer is NULL.\n");
-    UInt32 l_bufLen_I = *bufLen_I;
+    size_t l_bufLen_I = *bufLen_I;
     if (l_bufLen_I == 0)
       return (0);
     if (l_bufLen_I > d_bufLen_I) {
-      fprintf (stderr, "cannot remove buffer longer (%ld"
-              ") than instantiated length (%ld"
-              ").\n", l_bufLen_I, d_bufLen_I);
+      std::cerr << "ERROR: cannot remove buffer longer ("
+               << l_bufLen_I << ") than instantiated length ("
+               << d_bufLen_I << ")." << std::endl;
       throw std::runtime_error ("circular_buffer::dequeue()");
     }
 
-    d_internal->lock ();
+    gruel::scoped_lock l (*d_internal);
     if (d_doAbort) {
-      d_internal->unlock ();
       return (2);
     }
     if (d_doFullRead) {
       while (d_n_avail_read_I < l_bufLen_I) {
-       DEBUG (fprintf (stderr, "dequeue: #a < #len, waiting.\n"));
-       // wait will automatically unlock() the internal mutex
-       d_readBlock->wait ();
-       // and lock() it here.
+       DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl);
+       // wait; will automatically unlock() the internal mutex via
+       // the scoped lock
+       d_readBlock->wait (l);
+       // and re-lock() it here.
        if (d_doAbort) {
-         d_internal->unlock ();
-         DEBUG (fprintf (stderr, "dequeue: #a < #len, aborting.\n"));
+         DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl);
          return (2);
        }
-       DEBUG (fprintf (stderr, "dequeue: #a < #len, done waiting.\n"));
+       DEBUG (std::cerr << "dequeue: #a < #len, done waiting." << std::endl);
      }
     } else {
       while (d_n_avail_read_I == 0) {
-       DEBUG (fprintf (stderr, "dequeue: #a == 0, waiting.\n"));
-       // wait will automatically unlock() the internal mutex
-       d_readBlock->wait ();
-       // and lock() it here.
+       DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl);
+       // wait; will automatically unlock() the internal mutex via
+       // the scoped lock
+       d_readBlock->wait (l);
+       // and re-lock() it here.
        if (d_doAbort) {
-         d_internal->unlock ();
-         DEBUG (fprintf (stderr, "dequeue: #a == 0, aborting.\n"));
+         DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl);
          return (2);
        }
-       DEBUG (fprintf (stderr, "dequeue: #a == 0, done waiting.\n"));
+       DEBUG (std::cerr << "dequeue: #a == 0, done waiting." << std::endl);
       }
     }
     if (l_bufLen_I > d_n_avail_read_I)
       l_bufLen_I = d_n_avail_read_I;
-    UInt32 n_now_I = d_bufLen_I - d_readNdx_I, n_start_I = 0;
+    size_t n_now_I = d_bufLen_I - d_readNdx_I, n_start_I = 0;
     if (n_now_I > l_bufLen_I)
       n_now_I = l_bufLen_I;
     else if (n_now_I < l_bufLen_I)
@@ -298,17 +300,15 @@ public:
     *bufLen_I = l_bufLen_I;
     d_n_avail_read_I -= l_bufLen_I;
     d_n_avail_write_I += l_bufLen_I;
-    d_writeBlock->signal ();
-    d_internal->unlock ();
+    d_writeBlock->notify_one ();
     return (1);
   };
 
   void abort () {
-    d_internal->lock ();
+    gruel::scoped_lock l (*d_internal);
     d_doAbort = true;
-    d_writeBlock->signal ();
-    d_readBlock->signal ();
-    d_internal->unlock ();
+    d_writeBlock->notify_one ();
+    d_readBlock->notify_one ();
   };
 };
 
diff --git a/gr-audio-portaudio/.gitignore b/gr-audio-portaudio/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
index 47aa808bffa28cb5d9a5f0179115d67ed444f215..198d89f87932352e68dcaeeb084fc5302dc65ea8 100644 (file)
@@ -23,5 +23,8 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
 
-etcdir = $(gr_sysconfdir)
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-audio-portaudio.pc
+
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gr-audio-portaudio.conf
diff --git a/gr-audio-portaudio/autoconfiscate.patch b/gr-audio-portaudio/autoconfiscate.patch
new file mode 100755 (executable)
index 0000000..fd7b9c3
--- /dev/null
@@ -0,0 +1,1299 @@
+Index: portaudio-2.0.pc.in
+===================================================================
+RCS file: /home/cvs/portaudio/Attic/portaudio-2.0.pc.in,v
+retrieving revision 1.1.2.1
+diff -u -b -B -w -p -r1.1.2.1 portaudio-2.0.pc.in
+--- portaudio-2.0.pc.in        19 Mar 2006 13:02:36 -0000      1.1.2.1
++++ portaudio-2.0.pc.in        19 Mar 2006 22:26:01 -0000
+@@ -9,4 +9,4 @@ Requires:
+ Version: 19
+ Libs: -L${libdir} -lportaudio @LIBS@
+-Cflags: -I${includedir} @THREAD_CFLAGS@
++Cflags: -I${includedir} @PTHREAD_CFLAGS@
+Index: pa_asio/iasiothiscallresolver.cpp
+===================================================================
+RCS file: /home/cvs/portaudio/pa_asio/Attic/iasiothiscallresolver.cpp,v
+retrieving revision 1.1.2.4
+diff -u -b -B -w -p -r1.1.2.4 iasiothiscallresolver.cpp
+--- pa_asio/iasiothiscallresolver.cpp  10 Jul 2004 03:27:41 -0000      1.1.2.4
++++ pa_asio/iasiothiscallresolver.cpp  19 Mar 2006 22:26:03 -0000
+@@ -152,6 +152,7 @@
+     recent versions of the gcc assembler.
+ */
++#include <config.h>
+ // We only need IASIOThiscallResolver at all if we are on Win32. For other
+ // platforms we simply bypass the IASIOThiscallResolver definition to allow us
+Index: pa_asio/pa_asio.cpp
+===================================================================
+RCS file: /home/cvs/portaudio/pa_asio/pa_asio.cpp,v
+retrieving revision 1.7.2.68
+diff -u -b -B -w -p -r1.7.2.68 pa_asio.cpp
+--- pa_asio/pa_asio.cpp        5 Dec 2005 04:55:28 -0000       1.7.2.68
++++ pa_asio/pa_asio.cpp        19 Mar 2006 22:26:14 -0000
+@@ -106,7 +106,7 @@
+         must be closed).
+ */
+-
++#include <config.h>
+ #include <stdio.h>
+ #include <assert.h>
+Index: pa_common/pa_allocation.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_allocation.c,v
+retrieving revision 1.1.2.6
+diff -u -b -B -w -p -r1.1.2.6 pa_allocation.c
+--- pa_common/pa_allocation.c  20 Dec 2004 12:07:51 -0000      1.1.2.6
++++ pa_common/pa_allocation.c  19 Mar 2006 22:26:15 -0000
+@@ -35,6 +35,8 @@
+ */
++#include <config.h>
++
+ #include "pa_allocation.h"
+ #include "pa_util.h"
+Index: pa_common/pa_converters.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_converters.c,v
+retrieving revision 1.1.2.27
+diff -u -b -B -w -p -r1.1.2.27 pa_converters.c
+--- pa_common/pa_converters.c  2 Nov 2005 12:14:07 -0000       1.1.2.27
++++ pa_common/pa_converters.c  19 Mar 2006 22:26:23 -0000
+@@ -49,6 +49,8 @@
+ */
++#include <config.h>
++
+ #include "pa_converters.h"
+ #include "pa_dither.h"
+ #include "pa_endianness.h"
+Index: pa_common/pa_cpuload.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_cpuload.c,v
+retrieving revision 1.1.2.14
+diff -u -b -B -w -p -r1.1.2.14 pa_cpuload.c
+--- pa_common/pa_cpuload.c     8 Jan 2004 22:01:12 -0000       1.1.2.14
++++ pa_common/pa_cpuload.c     19 Mar 2006 22:26:24 -0000
+@@ -41,6 +41,8 @@
+ */
++#include <config.h>
++
+ #include "pa_cpuload.h"
+ #include <assert.h>
+Index: pa_common/pa_dither.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_dither.c,v
+retrieving revision 1.1.2.6
+diff -u -b -B -w -p -r1.1.2.6 pa_dither.c
+--- pa_common/pa_dither.c      28 May 2005 22:49:02 -0000      1.1.2.6
++++ pa_common/pa_dither.c      19 Mar 2006 22:26:24 -0000
+@@ -34,6 +34,8 @@
+ */
++#include <config.h>
++
+ #include "pa_dither.h"
+ #include "pa_types.h"
+Index: pa_common/pa_front.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_front.c,v
+retrieving revision 1.1.2.52
+diff -u -b -B -w -p -r1.1.2.52 pa_front.c
+--- pa_common/pa_front.c       7 Dec 2005 20:10:34 -0000       1.1.2.52
++++ pa_common/pa_front.c       19 Mar 2006 22:26:30 -0000
+@@ -89,6 +89,8 @@ enquire about status on the PortAudio ma
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <memory.h>
+Index: pa_common/pa_process.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_process.c,v
+retrieving revision 1.1.2.51
+diff -u -b -B -w -p -r1.1.2.51 pa_process.c
+--- pa_common/pa_process.c     27 Oct 2005 23:28:48 -0000      1.1.2.51
++++ pa_common/pa_process.c     19 Mar 2006 22:26:35 -0000
+@@ -72,6 +72,8 @@
+ */
++#include <config.h>
++
+ #include <assert.h>
+ #include <string.h> /* memset() */
+Index: pa_common/pa_skeleton.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_skeleton.c,v
+retrieving revision 1.1.2.39
+diff -u -b -B -w -p -r1.1.2.39 pa_skeleton.c
+--- pa_common/pa_skeleton.c    26 Nov 2003 14:56:09 -0000      1.1.2.39
++++ pa_common/pa_skeleton.c    19 Mar 2006 22:26:38 -0000
+@@ -40,6 +40,8 @@
+ */
++#include <config.h>
++
+ #include <string.h> /* strlen() */
+ #include "pa_util.h"
+Index: pa_common/pa_stream.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/Attic/pa_stream.c,v
+retrieving revision 1.1.2.12
+diff -u -b -B -w -p -r1.1.2.12 pa_stream.c
+--- pa_common/pa_stream.c      20 Sep 2003 21:31:00 -0000      1.1.2.12
++++ pa_common/pa_stream.c      19 Mar 2006 22:26:39 -0000
+@@ -36,6 +36,8 @@
+ */
++#include <config.h>
++
+ #include "pa_stream.h"
+Index: pa_common/pa_trace.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_common/pa_trace.c,v
+retrieving revision 1.1.1.1.2.4
+diff -u -b -B -w -p -r1.1.1.1.2.4 pa_trace.c
+--- pa_common/pa_trace.c       2 Nov 2005 12:06:44 -0000       1.1.1.1.2.4
++++ pa_common/pa_trace.c       19 Mar 2006 22:26:39 -0000
+@@ -35,6 +35,8 @@
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+Index: pa_jack/pa_jack.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_jack/Attic/pa_jack.c,v
+retrieving revision 1.1.2.20
+diff -u -b -B -w -p -r1.1.2.20 pa_jack.c
+--- pa_jack/pa_jack.c  2 Oct 2005 22:02:26 -0000       1.1.2.20
++++ pa_jack/pa_jack.c  19 Mar 2006 22:26:46 -0000
+@@ -35,6 +35,8 @@
+  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  */
++#include <config.h>
++
+ #include <string.h>
+ #include <regex.h>
+ #include <stdlib.h>
+@@ -56,7 +58,7 @@
+ #include "pa_process.h"
+ #include "pa_allocation.h"
+ #include "pa_cpuload.h"
+-#include "../pablio/ringbuffer.c"
++#include "pablio/ringbuffer.c"
+ static int aErr_;
+ static PaError paErr_;     /* For use with ENSURE_PA */
+Index: pa_linux_alsa/pa_linux_alsa.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_linux_alsa/Attic/pa_linux_alsa.c,v
+retrieving revision 1.1.2.90
+diff -u -b -B -w -p -r1.1.2.90 pa_linux_alsa.c
+--- pa_linux_alsa/pa_linux_alsa.c      19 Mar 2006 12:28:44 -0000      1.1.2.90
++++ pa_linux_alsa/pa_linux_alsa.c      19 Mar 2006 22:27:00 -0000
+@@ -34,6 +34,8 @@
+  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  */
++#include <config.h>
++
+ #define ALSA_PCM_NEW_HW_PARAMS_API
+ #define ALSA_PCM_NEW_SW_PARAMS_API
+ #include <alsa/asoundlib.h>
+Index: pa_mac/pa_mac_hostapis.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_mac/Attic/pa_mac_hostapis.c,v
+retrieving revision 1.1.2.1
+diff -u -b -B -w -p -r1.1.2.1 pa_mac_hostapis.c
+--- pa_mac/pa_mac_hostapis.c   27 May 2004 22:39:58 -0000      1.1.2.1
++++ pa_mac/pa_mac_hostapis.c   19 Mar 2006 22:27:00 -0000
+@@ -33,6 +33,7 @@
+ Mac OS host API initialization function table.
+ */
++#include <config.h>
+ #include "pa_hostapi.h"
+Index: pa_mac_core/pa_mac_core.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_mac_core/pa_mac_core.c,v
+retrieving revision 1.8.2.11
+diff -u -b -B -w -p -r1.8.2.11 pa_mac_core.c
+--- pa_mac_core/pa_mac_core.c  27 Feb 2006 14:25:50 -0000      1.8.2.11
++++ pa_mac_core/pa_mac_core.c  19 Mar 2006 22:27:08 -0000
+@@ -45,6 +45,8 @@
+  @brief AUHAL implementation of PortAudio
+ */
++#include <config.h>
++
+ #include <string.h> /* strlen(), memcmp() etc. */
+ #include <AudioUnit/AudioUnit.h>
+Index: pa_mac_core/pa_mac_core_old.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_mac_core/Attic/pa_mac_core_old.c,v
+retrieving revision 1.1.2.1
+diff -u -b -B -w -p -r1.1.2.1 pa_mac_core_old.c
+--- pa_mac_core/pa_mac_core_old.c      24 Dec 2005 01:22:52 -0000      1.1.2.1
++++ pa_mac_core/pa_mac_core_old.c      19 Mar 2006 22:27:14 -0000
+@@ -34,6 +34,8 @@
+  *
+  */
++#include <config.h>
++
+ #include <CoreAudio/CoreAudio.h>
+ #include <AudioToolbox/AudioToolbox.h>
+ #include <stdio.h>
+Index: pa_mac_core/pa_mac_core_utilities.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_mac_core/Attic/pa_mac_core_utilities.c,v
+retrieving revision 1.1.2.2
+diff -u -b -B -w -p -r1.1.2.2 pa_mac_core_utilities.c
+--- pa_mac_core/pa_mac_core_utilities.c        9 Dec 2005 19:43:14 -0000       1.1.2.2
++++ pa_mac_core/pa_mac_core_utilities.c        19 Mar 2006 22:27:14 -0000
+@@ -10,6 +10,8 @@
+  * by Bjorn Roche.
+  */
++#include <config.h>
++
+ /*
+  * Translates MacOS generated errors into PaErrors
+  */
+Index: pa_mac_sm/pa_mac_sm.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_mac_sm/Attic/pa_mac_sm.c,v
+retrieving revision 1.1.2.1
+diff -u -b -B -w -p -r1.1.2.1 pa_mac_sm.c
+--- pa_mac_sm/pa_mac_sm.c      7 Jun 2002 21:20:48 -0000       1.1.2.1
++++ pa_mac_sm/pa_mac_sm.c      19 Mar 2006 22:27:21 -0000
+@@ -76,6 +76,8 @@ O- Add support for native sample data fo
+ O- Review buffer sizing. Should it be based on result of siDeviceBufferInfo query?
+ O- Determine default devices somehow.
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+Index: pa_sgi/pa_sgi.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_sgi/pa_sgi.c,v
+retrieving revision 1.2.2.20
+diff -u -b -B -w -p -r1.2.2.20 pa_sgi.c
+--- pa_sgi/pa_sgi.c    3 Jan 2004 19:20:09 -0000       1.2.2.20
++++ pa_sgi/pa_sgi.c    19 Mar 2006 22:27:27 -0000
+@@ -123,6 +123,8 @@
+        a outputs stereo. One can observe this in SGI's 'Audio Queue Monitor'.
+ */
++#include <config.h>
++
+ #include <string.h>         /* For strlen() but also for strerror()! */
+ #include <stdio.h>          /* printf() */
+ #include <math.h>           /* fabs()   */
+Index: pa_unix/pa_unix_hostapis.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_unix/Attic/pa_unix_hostapis.c,v
+retrieving revision 1.1.2.5
+diff -u -b -B -w -p -r1.1.2.5 pa_unix_hostapis.c
+--- pa_unix/pa_unix_hostapis.c 2 Oct 2003 12:35:46 -0000       1.1.2.5
++++ pa_unix/pa_unix_hostapis.c 19 Mar 2006 22:27:28 -0000
+@@ -30,6 +30,8 @@
+  */
++#include <config.h>
++
+ #include "pa_hostapi.h"
+ PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+Index: pa_unix/pa_unix_util.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_unix/Attic/pa_unix_util.c,v
+retrieving revision 1.1.2.8
+diff -u -b -B -w -p -r1.1.2.8 pa_unix_util.c
+--- pa_unix/pa_unix_util.c     20 Nov 2005 13:46:13 -0000      1.1.2.8
++++ pa_unix/pa_unix_util.c     19 Mar 2006 22:27:28 -0000
+@@ -31,6 +31,8 @@
+  */
+  
++#include <config.h>
++
+ #include <pthread.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+Index: pa_unix_oss/pa_unix_oss.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_unix_oss/pa_unix_oss.c,v
+retrieving revision 1.6.2.27
+diff -u -b -B -w -p -r1.6.2.27 pa_unix_oss.c
+--- pa_unix_oss/pa_unix_oss.c  21 Feb 2006 19:13:56 -0000      1.6.2.27
++++ pa_unix_oss/pa_unix_oss.c  19 Mar 2006 22:27:35 -0000
+@@ -35,6 +35,8 @@
+  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <string.h>
+ #include <math.h>
+@@ -42,7 +44,6 @@
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+ #include <pthread.h>
+-#include <alloca.h>
+ #include <malloc.h>
+ #include <assert.h>
+ #include <errno.h>
+@@ -52,14 +53,21 @@
+ #include <limits.h>
+ #include <semaphore.h>
+-#ifdef __FreeBSD__
++#ifdef HAVE_SYS_SOUNDCARD_H
+ # include <sys/soundcard.h>
++#elif HAVE_LINUX_SOUNDCARD_H
++# include <linux/soundcard.h>
++#elif HAVE_SOUNDCARD_H
++# include <soundcard.h>
++#else
++# include <machine/soundcard.h> /* JH20010905 */
++#endif
++
++#ifdef __FreeBSD__
+ # define DEVICE_NAME_BASE            "/dev/dsp"
+ #elif defined __linux__
+-# include <linux/soundcard.h>
+ # define DEVICE_NAME_BASE            "/dev/dsp"
+ #else
+-# include <machine/soundcard.h> /* JH20010905 */
+ # define DEVICE_NAME_BASE            "/dev/audio"
+ #endif
+@@ -1913,7 +1921,12 @@ static signed long GetStreamWriteAvailab
+     PaOssStream *stream = (PaOssStream*)s;
+     int delay = 0;
++/*
++ * FIXME: SNDCTL_DSP_GETODELAY does not exist on NetBSD
++ */
++#ifdef SNDCTL_DSP_GETODELAY
+     if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
++#endif
+         return paUnanticipatedHostError;
+     
+     return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
+Index: pa_unix_oss/recplay.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_unix_oss/recplay.c,v
+retrieving revision 1.1.1.1
+diff -u -b -B -w -p -r1.1.1.1 recplay.c
+--- pa_unix_oss/recplay.c      22 Jan 2002 00:52:44 -0000      1.1.1.1
++++ pa_unix_oss/recplay.c      19 Mar 2006 22:27:35 -0000
+@@ -4,6 +4,8 @@
+  * Minimal record and playback test.
+  * 
+  */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+Index: pa_win/pa_win_hostapis.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win/Attic/pa_win_hostapis.c,v
+retrieving revision 1.1.2.10
+diff -u -b -B -w -p -r1.1.2.10 pa_win_hostapis.c
+--- pa_win/pa_win_hostapis.c   8 Sep 2004 17:31:37 -0000       1.1.2.10
++++ pa_win/pa_win_hostapis.c   19 Mar 2006 22:27:36 -0000
+@@ -36,6 +36,7 @@
+     the Unix version does, we should consider being consistent.
+ */
++#include <config.h>
+ #include "pa_hostapi.h"
+Index: pa_win/pa_win_util.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win/Attic/pa_win_util.c,v
+retrieving revision 1.1.2.7
+diff -u -b -B -w -p -r1.1.2.7 pa_win_util.c
+--- pa_win/pa_win_util.c       15 Sep 2003 18:30:26 -0000      1.1.2.7
++++ pa_win/pa_win_util.c       19 Mar 2006 22:27:36 -0000
+@@ -37,6 +37,9 @@
+     bug. (see msdn kb Q274323).
+ */
+  
++#include <config.h>
++
++
+ #include <windows.h>
+ #include <mmsystem.h> /* for timeGetTime() */
+Index: pa_win/pa_x86_plain_converters.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win/Attic/pa_x86_plain_converters.c,v
+retrieving revision 1.1.2.2
+diff -u -b -B -w -p -r1.1.2.2 pa_x86_plain_converters.c
+--- pa_win/pa_x86_plain_converters.c   28 Feb 2003 01:49:59 -0000      1.1.2.2
++++ pa_win/pa_x86_plain_converters.c   19 Mar 2006 22:27:40 -0000
+@@ -1,3 +1,5 @@
++#include <config.h>
++
+ #include "pa_x86_plain_converters.h"
+ #include "pa_converters.h"
+Index: pa_win_ds/dsound_wrapper.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win_ds/dsound_wrapper.c,v
+retrieving revision 1.1.1.1.2.11
+diff -u -b -B -w -p -r1.1.1.1.2.11 dsound_wrapper.c
+--- pa_win_ds/dsound_wrapper.c 7 Sep 2003 13:04:53 -0000       1.1.1.1.2.11
++++ pa_win_ds/dsound_wrapper.c 19 Mar 2006 22:27:43 -0000
+@@ -33,6 +33,8 @@
+  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  *
+  */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
+Index: pa_win_ds/pa_win_ds.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win_ds/Attic/pa_win_ds.c,v
+retrieving revision 1.1.2.51
+diff -u -b -B -w -p -r1.1.2.51 pa_win_ds.c
+--- pa_win_ds/pa_win_ds.c      26 Jan 2006 01:13:18 -0000      1.1.2.51
++++ pa_win_ds/pa_win_ds.c      19 Mar 2006 22:27:49 -0000
+@@ -58,6 +58,8 @@
+         O- fix "patest_stop.c"
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <string.h> /* strlen() */
+Index: pa_win_wdmks/pa_win_wdmks.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win_wdmks/Attic/pa_win_wdmks.c,v
+retrieving revision 1.1.2.4
+diff -u -b -B -w -p -r1.1.2.4 pa_win_wdmks.c
+--- pa_win_wdmks/pa_win_wdmks.c        19 Nov 2005 10:14:01 -0000      1.1.2.4
++++ pa_win_wdmks/pa_win_wdmks.c        19 Mar 2006 22:28:00 -0000
+@@ -42,6 +42,8 @@
+  of a device for the duration of active stream using those devices
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ /* Debugging/tracing support */
+Index: pa_win_wmme/pa_win_wmme.c
+===================================================================
+RCS file: /home/cvs/portaudio/pa_win_wmme/pa_win_wmme.c,v
+retrieving revision 1.6.2.88
+diff -u -b -B -w -p -r1.6.2.88 pa_win_wmme.c
+--- pa_win_wmme/pa_win_wmme.c  16 Feb 2006 01:56:45 -0000      1.6.2.88
++++ pa_win_wmme/pa_win_wmme.c  19 Mar 2006 22:28:14 -0000
+@@ -100,6 +100,8 @@ Non-critical stuff for the future:
+     Events (when necessary) inside the ReadStream() and WriteStream() functions.
+ */
++#include <config.h>
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
+--- /dev/null  2006-03-10 00:02:48.821312048 +0100
++++ Makefile.am        2006-03-19 22:49:42.000000000 +0100
+@@ -0,0 +1,215 @@
++#
++# PortAudio V19 Makefile.am
++#
++# Stéphane Fillod
++#
++
++INCLUDES = -I$(top_srcdir)/pa_common
++
++COMMON_SRC = \
++      pa_common/pa_allocation.c \
++      pa_common/pa_converters.c \
++      pa_common/pa_cpuload.c \
++      pa_common/pa_dither.c \
++      pa_common/pa_front.c \
++      pa_common/pa_process.c \
++      pa_common/pa_skeleton.c \
++      pa_common/pa_stream.c \
++      pa_common/pa_trace.c
++
++libportaudio_coreaudio_la_SOURCES = \
++      pa_mac/pa_mac_hostapis.c \
++      pa_mac_core/pa_mac_core.c
++      
++libportaudio_mac_asio_la_SOURCES = \
++      pa_asio/iasiothiscallresolver.cpp
++libportaudio_mac_asio_la_LIBADD = @ASIO_OBJS@
++
++libportaudio_dsound_la_SOURCES = \
++      pa_win_ds/pa_win_ds.c \
++      pa_win_ds/dsound_wrapper.c \
++      pa_win/pa_win_hostapis.c \
++      pa_win/pa_win_util.c
++
++libportaudio_win_asio_la_SOURCES = \
++      pa_asio/pa_asio.cpp \
++      pa_win/pa_win_hostapis.c \
++      pa_win/pa_win_util.c \
++      pa_asio/iasiothiscallresolver.cpp 
++libportaudio_win_asio_la_LIBADD = @ASIO_OBJS@
++
++libportaudio_wdmks_la_SOURCES = \
++      pa_win_wdmks/pa_win_wdmks.c \
++      pa_win/pa_win_hostapis.c \
++      pa_win/pa_win_util.c
++
++libportaudio_wmme_la_SOURCES = \
++      pa_win_wmme/pa_win_wmme.c \
++      pa_win/pa_win_hostapis.c \
++              pa_win/pa_win_util.c
++
++libportaudio_sgi_la_SOURCES = \
++      pa_sgi/pa_sgi.c
++
++libportaudio_alsa_la_SOURCES = \
++      pa_linux_alsa/pa_linux_alsa.c
++
++libportaudio_jack_la_SOURCES = \
++      pa_jack/pa_jack.c
++
++libportaudio_oss_la_SOURCES = \
++      pa_unix_oss/pa_unix_oss.c
++
++libportaudio_unix_la_SOURCES = \
++      pa_unix/pa_unix_hostapis.c \
++      pa_unix/pa_unix_util.c
++
++EXTRA_LTLIBRARIES = \
++      libportaudio-coreaudio.la \
++      libportaudio-mac-asio.la \
++      libportaudio-dsound.la \
++      libportaudio-win-asio.la \
++      libportaudio-wdmks.la \
++      libportaudio-wmme.la \
++      libportaudio-sgi.la \
++      libportaudio-alsa.la \
++      libportaudio-jack.la \
++      libportaudio-oss.la \
++      libportaudio-unix.la
++
++noinst_LTLIBRARIES = @PA_LIBADD@
++lib_LTLIBRARIES = libportaudio.la
++
++
++libportaudio_la_SOURCES = \
++      $(COMMON_SRC)
++
++# -no-undefined is required by Win32 and MacOSX, should be harmless otherwise
++libportaudio_la_LDFLAGS = $(WINLDFLAGS) -no-undefined -version-info @PA_ABI@:@PA_REV@:@PA_AGE@
++libportaudio_la_CFLAGS = $(AM_CFLAGS)
++libportaudio_la_LIBADD = @PA_LIBADD@ -lm
++libportaudio_la_DEPENDENCIES = @PA_LIBADD@
++
++
++noinst_HEADERS =  \
++      pa_asio/iasiothiscallresolver.h \
++      pa_asio/pa_asio.h \
++      pa_beos/PlaybackNode.h \
++      pablio/pablio.h \
++      pablio/ringbuffer.h \
++      pa_common/pa_allocation.h \
++      pa_common/pa_converters.h \
++      pa_common/pa_cpuload.h \
++      pa_common/pa_dither.h \
++      pa_common/pa_endianness.h \
++      pa_common/pa_hostapi.h \
++      pa_common/pa_process.h \
++      pa_common/pa_stream.h \
++      pa_common/pa_trace.h \
++      pa_common/pa_types.h \
++      pa_common/pa_util.h \
++      pa_dll_switch/PaDllEntry.h \
++      pa_dll_switch/portaudio.h \
++      pa_linux_alsa/pa_linux_alsa.h \
++      pa_mac_core/pa_mac_core.h \
++      pa_unix/pa_unix_util.h \
++      pa_win_ds/dsound_wrapper.h \
++      pa_win/pa_x86_plain_converters.h \
++      pa_win_wmme/pa_win_wmme.h
++
++include_HEADERS = \
++      pa_common/portaudio.h
++
++
++TESTS = \
++      pa_tests/paqa_errs \
++      pa_tests/patest1 \
++      pa_tests/patest_buffer \
++      pa_tests/patest_callbackstop \
++      pa_tests/patest_clip \
++      pa_tests/patest_dither \
++      pa_tests/patest_hang \
++      pa_tests/patest_in_overflow \
++      pa_tests/patest_latency \
++      pa_tests/patest_leftright \
++      pa_tests/patest_longsine \
++      pa_tests/patest_many \
++      pa_tests/patest_maxsines \
++      pa_tests/patest_multi_sine \
++      pa_tests/patest_out_underflow \
++      pa_tests/patest_pink \
++      pa_tests/patest_prime \
++      pa_tests/patest_read_record \
++      pa_tests/patest_record \
++      pa_tests/patest_ringmix \
++      pa_tests/patest_saw \
++      pa_tests/patest_sine8 \
++      pa_tests/patest_sine \
++      pa_tests/patest_sine_formats \
++      pa_tests/patest_sine_time \
++      pa_tests/patest_start_stop \
++      pa_tests/patest_stop \
++      pa_tests/patest_sync \
++      pa_tests/patest_toomanysines \
++      pa_tests/patest_underflow \
++      pa_tests/patest_wire \
++      pa_tests/patest_write_sine \
++      pa_tests/pa_devs \
++      pa_tests/pa_fuzz \
++      pa_tests/pa_minlat \
++      pa_tests/paqa_devs
++
++check_PROGRAMS = $(TESTS)
++
++LDADD = libportaudio.la
++
++# Most of these don't compile yet.  Put them in TESTS, above, if
++# you want to try to compile them...
++ALL_TESTS = \
++      pa_tests/debug_convert \
++      pa_tests/debug_dither_calc \
++      pa_tests/debug_dual \
++      pa_tests/debug_multi_in \
++      pa_tests/debug_multi_out \
++      pa_tests/debug_record \
++      pa_tests/debug_record_reuse \
++      pa_tests/debug_sine_amp \
++      pa_tests/debug_sine \
++      pa_tests/debug_sine_formats \
++      pa_tests/debug_srate \
++      pa_tests/debug_test1 \
++      $(TESTS) 
++
++pkgconfigdir = $(libdir)/pkgconfig
++pkgconfig_DATA = portaudio-2.0.pc
++
++
++SUBDIRS=
++DIST_SUBDIRS=
++
++ACLOCAL_AMFLAGS = -I config
++
++doc: config.doxy
++      doxygen config.doxy
++
++# pa_asio pa_beos pablio pa_common pa_dll_switch pa_jack pa_linux_alsa pa_mac pa_mac_core pa_mac_sm pa_sgi pa_tests pa_unix pa_unix_oss pa_win pa_win_ds pa_win_wdmks pa_win_wmme
++
++PABLIO = \
++      pablio/pablio.def \
++      pablio/README.txt \
++      pablio/ringbuffer.h \
++      pablio/test_rw_echo.c \
++      pablio/test_w_saw.c \
++      pablio/pablio.c \
++      pablio/pablio.h \
++      pablio/ringbuffer.c \
++      pablio/test_rw.c \
++      pablio/test_w_saw8.c
++
++EXTRA_DIST =  \
++      $(PABLIO) \
++      config.doxy \
++      LICENSE.txt \
++      README.txt \
++      portaudio-2.0.pc.in \
++      V19-devel-readme.txt
+--- /dev/null  2006-03-10 00:02:48.821312048 +0100
++++ configure.ac       2006-03-19 22:49:13.000000000 +0100
+@@ -0,0 +1,278 @@
++dnl
++dnl portaudio V19 configure.ac script
++dnl
++dnl Stephane Fillod, Dominic Mazzoni, Arve Knudsen
++dnl
++
++dnl Require autoconf >= 2.57
++AC_PREREQ(2.57)
++
++dnl Init autoconf and make sure configure is being called
++dnl from the right directory
++AC_INIT([portaudio], [2.0cvs], [portaudio@techweb.rfa.org])
++AC_CONFIG_SRCDIR([pa_common/portaudio.h])
++AC_CONFIG_HEADERS(config.h)
++AC_CANONICAL_TARGET([])
++
++dnl Automake Initialisation.
++AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -)
++AM_MAINTAINER_MODE
++
++dnl Portaudio library interface version, see libtool(info), esp.
++dnl node 6.3 "Updating version info"
++PA_ABI=19
++PA_REV=0
++PA_AGE=0
++AC_SUBST(PA_ABI)
++AC_SUBST(PA_REV)
++AC_SUBST(PA_AGE)
++
++
++dnl Checks for programs.
++
++AC_PROG_CC
++AC_PROG_CXX
++AC_PROG_RANLIB
++AC_PROG_INSTALL
++AC_PROG_MAKE_SET
++
++AC_AIX
++AC_ISC_POSIX
++AC_MINIX
++AM_PROG_CC_STDC
++AC_PROG_GCC_TRADITIONAL
++AC_C_CONST
++AC_C_INLINE
++
++dnl Check for Mingw support
++#GR_PWIN32
++
++dnl libtool Initialisation
++AC_LIBTOOL_WIN32_DLL
++AC_PROG_LIBTOOL
++
++ACX_PTHREAD
++
++dnl This must be one of the first tests we do or it will fail...
++AC_C_BIGENDIAN
++
++dnl checks for various host APIs and arguments to configure that
++dnl turn them on or off
++
++AC_CHECK_LIB(asound, snd_pcm_open, [have_alsa=yes], [have_alsa=no])
++
++
++PKG_CHECK_MODULES(JACK, jack, [have_jack=yes], [have_jack=no])
++PKG_CHECK_LIB(jack_client_new, [$JACK_LIBS], [$JACK_CFLAGS], [have_jack=yes], [have_jack=no])
++
++AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h soundcard.h machine/soundcard.h])
++AC_CHECK_HEADERS(sys/ioctl.h, [have_oss=yes], [have_oss=no])
++
++dnl sizeof checks: we will need a 16-bit and a 32-bit type
++
++AC_CHECK_SIZEOF(short)
++AC_CHECK_SIZEOF(int)
++AC_CHECK_SIZEOF(long)
++
++dnl Specify options
++
++AC_ARG_WITH(alsa, 
++            [  --with-alsa (default=yes)],
++            [with_alsa=$withval], [with_alsa=$have_alsa])
++
++AC_ARG_WITH(jack, 
++            [  --with-jack (default=yes)],
++            [with_jack=$withval], [with_jack=$have_jack])
++
++AC_ARG_WITH(oss, 
++            [  --with-oss (default=yes)],
++            [with_oss=$withval], [with_oss=$have_oss])
++
++AC_ARG_WITH(winapi,
++            [  --with-winapi ((wmme/directx/asio) default=wmme)],
++            [with_winapi=$withval], [with_winapi="wmme"])
++
++dnl Mac API added for ASIO, can have other api's listed
++AC_ARG_WITH(macapi,
++            [  --with-macapi ((asio/core/sm) default=core)],
++            [with_macapi=$withval], [with_macapi="core"])
++
++AC_ARG_WITH(asiodir,
++            [  --with-asiodir (default=/usr/local/asiosdk2)],
++            [with_asiodir=$withval], [with_asiodir="/usr/local/asiosdk2"])
++
++AC_ARG_WITH(dxdir,
++            [  --with-dxdir (default=/usr/local/dx7sdk)],
++            [with_dxdir=$withval], [with_dxdir="/usr/local/dx7sdk"])
++
++AC_ARG_ENABLE(debug-output,
++      [  --enable-debug-output],
++        [if test x$enableval != xno ; then
++           AC_DEFINE(PA_ENABLE_DEBUG_OUTPUT,,[Enable debugging messages])
++          fi
++        ])
++
++dnl BSD configuration
++AC_HAVE_LIBRARY(ossaudio)
++
++dnl Mac OS X configuration
++
++AC_CHECK_LIB(CoreAudio, OpenAComponent,
++          [ 
++           have_coreaudio=yes
++           PA_LIBADD="$PA_LIBADD libportaudio-coreaudio.la"
++           AC_DEFINE([PA_USE_COREAUDIO], [], [Define to use Mac OS X CoreAudio])
++           #LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon"
++           LIBS="-lCoreAudio -lAudioToolbox -lAudioUnit -lCarbon"
++          ], have_coreaudio=no)
++
++ASIO_CFLAGS=""
++ASIO_OBJS=""
++
++if [[ $with_asiodir ]] ; then
++  ASIODIR="$with_asiodir"
++fi
++
++if [[ $with_macapi = "asio" ]] ; then
++  echo "ASIODIR: $ASIODIR"
++  ASIO_CFLAGS="-Ipa_asio -I$ASIDIR/host/mac -I$ASIODIR/common"
++  ASIO_OBJS=$ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/mac/asioshlib.o
++  PA_LIBADD="$PA_LIBADD libportaudio-mac-asio.la"
++fi
++
++if [[ $with_winapi = "asio" ]] ; then
++  echo "ASIODIR: $ASIODIR"
++  ASIO_CFLAGS="-ffast-math -fomit-frame-pointer -Ipa_asio -I$ASIDIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -DPA_NO_WMME -DPA_NO_DS -DPA_NO_WDMKS -DWINDOWS"
++  ASIO_OBJS=$ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o
++  LIBS="$LIBS -lwinmm -lole32 -luuid"
++  PA_LIBADD="$PA_LIBADD libportaudio-win-asio.la"
++fi
++
++
++dnl MingW/Win configuration
++
++AC_TRY_LINK_LIB(dsound, [DSW_InitOutputBuffer(0,0,0,0);], [
++              #include <windows.h>
++              #include <DSound.h>
++              ], [-I$DXDIR/include],
++          [ 
++           have_directx=yes
++           DXDIR="$with_dxdir"
++             echo "DXDIR: $DXDIR"
++           # LDFLAGS -L./dx7sdk/lib  ?
++             LIBS="-lwinmm -ldsound -lole32"
++             CFLAGS="$CFLAGS -I$DXDIR/include -DPA_NO_WMME -DPA_NO_ASIO -DPA_NO_WDMKS"
++           PA_LIBADD="$PA_LIBADD libportaudio-dsound.la"
++          ], have_directx=no)
++
++AC_TRY_LINK_LIB(kernel32, [DeviceIoControl(0,0,0,0,0,0,0,0);],[
++              #include <windows.h>
++              #include <winbase.h>
++              #include <ks.h>
++              ], [-I$DXDIR/include],
++          [ 
++           have_wdmks=yes
++           DXDIR="$with_dxdir"
++             echo "DXDIR: $DXDIR"
++           # LDFLAGS -L./dx7sdk/lib  ?
++             LIBS="-lwinmm -luuid -lsetupapi -lole32"
++             CFLAGS="$CFLAGS -I$DXDIR/include -DPA_NO_WMME -DPA_NO_DS -DPA_NO_ASIO"
++           PA_LIBADD="$PA_LIBADD libportaudio-wdmks.la"
++          ], have_wdmks=no)
++
++# WMME default ?
++AC_TRY_LINK_LIB(winmm, [waveOutOpen(0,0,0,0,0,0);],[
++              #include <windows.h>
++              #include <mmsystem.h>
++              ], [],
++          [ 
++           have_wmme=yes
++             LIBS="-lwinmm -lole32 -luuid"
++             CFLAGS="$CFLAGS -DPA_NO_DS -DPA_NO_ASIO -DPA_NO_WDMKS"
++             PA_LIBADD="$PA_LIBADD libportaudio-wmme.la"
++          ], have_wmme=no)
++
++
++dnl Unix configuration
++
++dnl SGI IRIX audio library (AL) configuration (Pieter, oct 2-13, 2003).
++dnl The 'dmedia' library is needed to read the Unadjusted System Time (UST).
++dnl
++
++AC_CHECK_LIB(audio,   alOpenPort, [have_AL=1], [have_AL=0])
++AC_CHECK_LIB(dmedia,  dmGetUST, [have_dmedia=1], [have_dmedia=0])
++
++
++if [[ $have_AL = "yes" ] && [ $have_dmedia = "yes" ]] ; then
++  dnl See the '#ifdef PA_USE_SGI' in file pa_unix/pa_unix_hostapis.c
++  dnl which selects the appropriate PaXXX_Initialize() function.
++  dnl
++
++  LIBS="-ldmedia -laudio"
++  AC_DEFINE([PA_USE_SGI], [], [Define to use special SGI system support])
++  PA_LIBADD="$PA_LIBADD libportaudio-sgi.la"
++
++ # TODO: 
++ #AC_MSG_ERROR([IRIX audio library not found!])
++ #AC_MSG_ERROR([IRIX digital media library not found!])
++fi
++
++
++if [[ $have_alsa = "yes" ] && [ $with_alsa != "no" ]] ; then
++  LIBS="$LIBS -lasound"
++  AC_DEFINE([PA_USE_ALSA], [], [Define to use ALSA])
++  PA_LIBADD="$PA_LIBADD libportaudio-alsa.la"
++fi
++
++if [[ $have_jack = "yes" ] && [ $with_jack != "no" ]] ; then
++  LIBS="$LIBS $JACK_LIBS"
++  CFLAGS="$CFLAGS $JACK_CFLAGS"
++  AC_DEFINE([PA_USE_JACK], [], [Define to use JACK])
++  PA_LIBADD="$PA_LIBADD libportaudio-jack.la"
++fi
++
++if [[ $with_oss != "no" ]] ; then
++  AC_DEFINE([PA_USE_OSS], [], [Define to use Open Sound System])
++  PA_LIBADD="$PA_LIBADD libportaudio-oss.la"
++fi
++
++dnl SGI books say -lpthread should be the last of the libs mentioned.
++if [[ $acx_pthread_ok = "yes" ]] ; then
++  LIBS="$LIBS $PTHREAD_LIBS"
++  PA_LIBADD="$PA_LIBADD libportaudio-unix.la"
++else
++  if [[ $with_winapi != "wmme" -a $with_winapi != "directx" -a $with_winapi != "asio" ]] ; then
++    AC_MSG_ERROR([libpthread not found!])
++  fi
++fi
++
++
++if [[ $with_macapi = "asio" ] || [ $with_winapi = "asio" ]] ; then
++  echo "ASIODIR: $ASIODIR"
++
++  CFLAGS="$CFLAGS $ASIO_CFLAGS"
++fi
++
++if [[ $ac_cv_c_bigendian = "yes" ]] ; then
++  CFLAGS="$CFLAGS -DPA_BIG_ENDIAN"
++else
++  CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN"
++fi
++
++
++CXXFLAGS="$CXXFLAGS"
++
++#CFLAGS="-g -O2 -Wall -pedantic -pipe"
++
++CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++
++
++dnl extra variables
++AC_SUBST(PA_LIBADD)
++AC_SUBST(ASIO_OBJS)
++AC_SUBST(PTHREAD_CFLAGS)
++AC_SUBST(CXXFLAGS)
++AC_SUBST(NASM)
++AC_SUBST(NASMOPT)
++
++AC_OUTPUT([Makefile portaudio-2.0.pc])
+--- /dev/null  2006-03-10 00:02:48.821312048 +0100
++++ config/acx_pthread.m4      2006-03-17 15:41:05.000000000 +0100
+@@ -0,0 +1,190 @@
++dnl Available from the GNU Autoconf Macro Archive at:
++dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
++dnl
++AC_DEFUN([ACX_PTHREAD], [
++AC_REQUIRE([AC_CANONICAL_HOST])
++AC_LANG_SAVE
++AC_LANG_C
++acx_pthread_ok=no
++
++# We used to check for pthread.h first, but this fails if pthread.h
++# requires special compiler flags (e.g. on True64 or Sequent).
++# It gets checked for in the link test anyway.
++
++# First of all, check if the user has set any of the PTHREAD_LIBS,
++# etcetera environment variables, and if threads linking works using
++# them:
++if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
++        save_CFLAGS="$CFLAGS"
++        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++        save_LIBS="$LIBS"
++        LIBS="$PTHREAD_LIBS $LIBS"
++        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
++        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
++        AC_MSG_RESULT($acx_pthread_ok)
++        if test x"$acx_pthread_ok" = xno; then
++                PTHREAD_LIBS=""
++                PTHREAD_CFLAGS=""
++        fi
++        LIBS="$save_LIBS"
++        CFLAGS="$save_CFLAGS"
++fi
++
++# We must check for the threads library under a number of different
++# names; the ordering is very important because some systems
++# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
++# libraries is broken (non-POSIX).
++
++# Create a list of thread flags to try.  Items starting with a "-" are
++# C compiler flags, and other items are library names, except for "none"
++# which indicates that we try without any flags at all.
++
++acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
++
++# The ordering *is* (sometimes) important.  Some notes on the
++# individual items follow:
++
++# pthreads: AIX (must check this before -lpthread)
++# none: in case threads are in libc; should be tried before -Kthread and
++#       other compiler flags to prevent continual compiler warnings
++# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
++# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
++# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
++# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
++# -pthreads: Solaris/gcc
++# -mthreads: Mingw32/gcc, Lynx/gcc
++# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
++#      doesn't hurt to check since this sometimes defines pthreads too;
++#      also defines -D_REENTRANT)
++# pthread: Linux, etcetera
++# --thread-safe: KAI C++
++
++case "${host_cpu}-${host_os}" in
++        *solaris*)
++
++        # On Solaris (at least, for some versions), libc contains stubbed
++        # (non-functional) versions of the pthreads routines, so link-based
++        # tests will erroneously succeed.  (We need to link with -pthread or
++        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
++        # a function called by this macro, so we could check for that, but
++        # who knows whether they'll stub that too in a future libc.)  So,
++        # we'll just look for -pthreads and -lpthread first:
++
++        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
++        ;;
++esac
++
++if test x"$acx_pthread_ok" = xno; then
++for flag in $acx_pthread_flags; do
++
++        case $flag in
++                none)
++                AC_MSG_CHECKING([whether pthreads work without any flags])
++                ;;
++
++                -*)
++                AC_MSG_CHECKING([whether pthreads work with $flag])
++                PTHREAD_CFLAGS="$flag"
++                ;;
++
++                *)
++                AC_MSG_CHECKING([for the pthreads library -l$flag])
++                PTHREAD_LIBS="-l$flag"
++                ;;
++        esac
++
++        save_LIBS="$LIBS"
++        save_CFLAGS="$CFLAGS"
++        LIBS="$PTHREAD_LIBS $LIBS"
++        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++
++        # Check for various functions.  We must include pthread.h,
++        # since some functions may be macros.  (On the Sequent, we
++        # need a special flag -Kthread to make this header compile.)
++        # We check for pthread_join because it is in -lpthread on IRIX
++        # while pthread_create is in libc.  We check for pthread_attr_init
++        # due to DEC craziness with -lpthreads.  We check for
++        # pthread_cleanup_push because it is one of the few pthread
++        # functions on Solaris that doesn't have a non-functional libc stub.
++        # We try pthread_create on general principles.
++        AC_TRY_LINK([#include <pthread.h>],
++                    [pthread_t th; pthread_join(th, 0);
++                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
++                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
++                    [acx_pthread_ok=yes])
++
++        LIBS="$save_LIBS"
++        CFLAGS="$save_CFLAGS"
++
++        AC_MSG_RESULT($acx_pthread_ok)
++        if test "x$acx_pthread_ok" = xyes; then
++                break;
++        fi
++
++        PTHREAD_LIBS=""
++        PTHREAD_CFLAGS=""
++done
++fi
++
++# Various other checks:
++if test "x$acx_pthread_ok" = xyes; then
++        save_LIBS="$LIBS"
++        LIBS="$PTHREAD_LIBS $LIBS"
++        save_CFLAGS="$CFLAGS"
++        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++
++        # Detect AIX lossage: threads are created detached by default
++        # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
++        AC_MSG_CHECKING([for joinable pthread attribute])
++        AC_TRY_LINK([#include <pthread.h>],
++                    [int attr=PTHREAD_CREATE_JOINABLE;],
++                    ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
++        if test x"$ok" = xunknown; then
++                AC_TRY_LINK([#include <pthread.h>],
++                            [int attr=PTHREAD_CREATE_UNDETACHED;],
++                            ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
++        fi
++        if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
++                AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
++                          [Define to the necessary symbol if this constant
++                           uses a non-standard name on your system.])
++        fi
++        AC_MSG_RESULT(${ok})
++        if test x"$ok" = xunknown; then
++                AC_MSG_WARN([we do not know how to create joinable pthreads])
++        fi
++
++        AC_MSG_CHECKING([if more special flags are required for pthreads])
++        flag=no
++        case "${host_cpu}-${host_os}" in
++                *-aix* | *-freebsd*)     flag="-D_THREAD_SAFE";;
++                *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
++        esac
++        AC_MSG_RESULT(${flag})
++        if test "x$flag" != xno; then
++                PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
++        fi
++
++        LIBS="$save_LIBS"
++        CFLAGS="$save_CFLAGS"
++
++        # More AIX lossage: must compile with cc_r
++        AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
++else
++        PTHREAD_CC="$CC"
++fi
++
++AC_SUBST(PTHREAD_LIBS)
++AC_SUBST(PTHREAD_CFLAGS)
++AC_SUBST(PTHREAD_CC)
++
++# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
++if test x"$acx_pthread_ok" = xyes; then
++        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
++        :
++else
++        acx_pthread_ok=no
++        $2
++fi
++AC_LANG_RESTORE
++])dnl ACX_PTHREAD
+--- /dev/null  2006-03-10 00:02:48.821312048 +0100
++++ config/pkg_check.m4        2006-03-17 22:12:37.000000000 +0100
+@@ -0,0 +1,49 @@
++
++AC_DEFUN([PKG_CHECK_LIB], [
++AC_REQUIRE([AC_CANONICAL_HOST])
++AC_LANG_SAVE
++AC_LANG_C
++
++        save_CFLAGS="$CFLAGS"
++        CFLAGS="$CFLAGS $3"
++        save_LIBS="$LIBS"
++        LIBS="$2 $LIBS"
++        AC_MSG_CHECKING([for $1 in LIBS=$2 with CFLAGS=$3])
++        AC_TRY_LINK_FUNC([$1], pkg_check_try_link=yes, pkg_check_try_link=no)
++        AC_MSG_RESULT($pkg_check_try_link)
++        LIBS="$save_LIBS"
++        CFLAGS="$save_CFLAGS"
++
++# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
++if test x"$pkg_check_try_link" = xyes; then
++      $4
++else
++      $5
++fi
++AC_LANG_RESTORE
++])dnl PKG_CHECK_LIB
++
++
++AC_DEFUN([AC_TRY_LINK_LIB], [
++AC_REQUIRE([AC_CANONICAL_HOST])
++AC_LANG_SAVE
++AC_LANG_C
++
++        save_CFLAGS="$CFLAGS"
++        CFLAGS="$CFLAGS $4"
++        save_LIBS="$LIBS"
++        LIBS="-l$1 $LIBS"
++        AC_MSG_CHECKING([for $2 in $1])
++        AC_TRY_LINK([$3], [$2], ac_try_link_lib=yes, ac_try_link_lib=no)
++        AC_MSG_RESULT($ac_try_link_lib)
++        LIBS="$save_LIBS"
++        CFLAGS="$save_CFLAGS"
++
++# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
++if test x"$ac_try_link_lib" = xyes; then
++      $5
++else
++      $6
++fi
++AC_LANG_RESTORE
++])dnl AC_TRY_LINK_LIB
+--- /dev/null  2006-03-10 00:02:48.821312048 +0100
++++ bootstrap  2006-03-19 23:33:58.000000000 +0100
+@@ -0,0 +1,9 @@
++#!/bin/sh
++
++rm -rf config.cache autom4te*.cache
++
++aclocal-1.9 -I config
++autoconf2.50
++autoheader2.50
++libtoolize --automake
++automake-1.9 --add-missing --foreign
diff --git a/gr-audio-portaudio/gnuradio-audio-portaudio.pc.in b/gr-audio-portaudio/gnuradio-audio-portaudio.pc.in
new file mode 100644 (file)
index 0000000..0861959
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-audio-portaudio
+Description: The GNU Radio block for the PORTAUDIO sound system
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-audio-portaudio
+Cflags: -I${includedir}
diff --git a/gr-audio-portaudio/src/.gitignore b/gr-audio-portaudio/src/.gitignore
new file mode 100644 (file)
index 0000000..8c29d35
--- /dev/null
@@ -0,0 +1,17 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/usrp.py
+/usrp.cc
+/audio_oss.cc
+/audio_oss.py
+/audio_portaudio.py
+/audio_portaudio.cc
+/run_tests
index 4b44807d8363c420bbd69236591cff36433723d6..4fa098dcc48f189d24ec6e415bdd0b355e7b8f47 100644 (file)
@@ -23,10 +23,6 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
-
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \
        $(PORTAUDIO_CFLAGS) $(WITH_INCLUDES)
 
@@ -41,8 +37,25 @@ noinst_HEADERS =                     \
 noinst_PYTHON =                        \
        qa_portaudio.py
 
+lib_LTLIBRARIES = libgnuradio-audio-portaudio.la
+
+libgnuradio_audio_portaudio_la_SOURCES = \
+       audio_portaudio_sink.cc         \
+       audio_portaudio_source.cc       \
+       gri_portaudio.cc
+
+libgnuradio_audio_portaudio_la_LIBADD =        \
+       $(GNURADIO_CORE_LA)             \
+       $(PORTAUDIO_LIBS)
+
+libgnuradio_audio_portaudio_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        audio_portaudio.i
@@ -54,16 +67,9 @@ TOP_SWIG_IFILES =                    \
 audio_portaudio_pythondir_category =   \
        gnuradio
 
-# additional sources for the SWIG-generated library
-audio_portaudio_la_swig_sources =      \
-       audio_portaudio_sink.cc         \
-       audio_portaudio_source.cc       \
-       gri_portaudio.cc
-
 # additional libraries for linking with the SWIG-generated library
 audio_portaudio_la_swig_libadd =       \
-       $(GNURADIO_CORE_LA)             \
-       $(PORTAUDIO_LIBS)
+       libgnuradio-audio-portaudio.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -72,3 +78,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
index cfdc6302af4fdbd6e6e8eba8e06d18787894d21f..65a38f9119011f4dc96bd66bc1a6a71e7bb08023 100644 (file)
 #include <unistd.h>
 #include <stdexcept>
 #include <gri_portaudio.h>
-#include <gnuradio/omnithread.h>
 #include <string.h>
 
-#define        LOGGING   0             // define to 0 or 1
+//#define      LOGGING   0             // define to 0 or 1
 
 #define SAMPLE_FORMAT          paFloat32
 typedef float sample_t;
@@ -84,31 +83,33 @@ portaudio_sink_callback (const void *inputBuffer,
 
   int navail_samples = self->d_reader->items_available();
   
-  if (nreqd_samples <= navail_samples){  // We've got enough data...
-    if (LOGGING)
-      self->d_log->printf("PAsink cb: f/b = %4ld\n", framesPerBuffer);
-    // copy from ringbuffer into output buffer
-    memcpy(outputBuffer,
-          self->d_reader->read_pointer(),
-          nreqd_samples * sizeof(sample_t));
-    self->d_reader->update_read_pointer(nreqd_samples);
-        
+  if (nreqd_samples <= navail_samples) {  // We've got enough data...
+    {
+      gruel::scoped_lock guard(self->d_ringbuffer_mutex);
+
+      memcpy(outputBuffer,
+            self->d_reader->read_pointer(),
+            nreqd_samples * sizeof(sample_t));
+      self->d_reader->update_read_pointer(nreqd_samples);
+
+      self->d_ringbuffer_ready = true;
+    }
+
     // Tell the sink thread there is new room in the ringbuffer.
-    self->d_ringbuffer_ready.post();
+    self->d_ringbuffer_cond.notify_one();
     return paContinue;
   }
 
   else {                       // underrun
-    if (LOGGING)
-      self->d_log->printf("PAsink cb: f/b = %4ld UNDERRUN\n", framesPerBuffer);
-
     self->d_nunderuns++;
     ::write(2, "aU", 2);       // FIXME change to non-blocking call
 
     // FIXME we should transfer what we've got and pad the rest
     memset(outputBuffer, 0, nreqd_samples * sizeof(sample_t));
 
-    self->d_ringbuffer_ready.post();  // Tell the sink to get going!
+    self->d_ringbuffer_ready = true;
+    self->d_ringbuffer_cond.notify_one();  // Tell the sink to get going!
+
     return paContinue;
   }
 }
@@ -135,12 +136,14 @@ audio_portaudio_sink::audio_portaudio_sink(int sampling_rate,
     d_verbose(gr_prefs::singleton()->get_bool("audio_portaudio", "verbose", false)),
     d_portaudio_buffer_size_frames(0),
     d_stream(0),
-    d_ringbuffer_ready(1, 1),          // binary semaphore
+    d_ringbuffer_mutex(),
+    d_ringbuffer_cond(),
+    d_ringbuffer_ready(false),
     d_nunderuns(0)
 {
   memset(&d_output_parameters, 0, sizeof(d_output_parameters));
-  if (LOGGING)
-    d_log = gri_logger::singleton();
+  //if (LOGGING)
+  //  d_log = gri_logger::singleton();
 
   PaError            err;
   int                i, numDevices;
@@ -297,12 +300,17 @@ audio_portaudio_sink::work (int noutput_items,
   const unsigned nchan = d_output_parameters.channelCount; // # of channels == samples/frame
 
   int k;
-  for (k = 0; k < noutput_items; ){
 
+  for (k = 0; k < noutput_items; ){
     int nframes = d_writer->space_available() / nchan; // How much space in ringbuffer
     if (nframes == 0){                 // no room...
       if (d_ok_to_block){
-       d_ringbuffer_ready.wait();      // block here, then try again
+       {
+         gruel::scoped_lock guard(d_ringbuffer_mutex);
+         while (!d_ringbuffer_ready)
+           d_ringbuffer_cond.wait(guard);
+       }
+
        continue;
       }
       else {
@@ -316,16 +324,21 @@ audio_portaudio_sink::work (int noutput_items,
     }
 
     // We can write the smaller of the request and the room we've got
-    int nf = std::min(noutput_items - k, nframes);
-
-    float *p = (float *) d_writer->write_pointer();
-    for (int i = 0; i < nf; i++){
-      for (unsigned int c = 0; c < nchan; c++){
-       *p++ = in[c][k + i];
-      }
+    {
+      gruel::scoped_lock guard(d_ringbuffer_mutex);
+
+      int nf = std::min(noutput_items - k, nframes);
+      float *p = (float *) d_writer->write_pointer();
+      
+      for (int i = 0; i < nf; i++)
+       for (unsigned int c = 0; c < nchan; c++)
+         *p++ = in[c][k + i];
+      
+      d_writer->update_write_pointer(nf * nchan);
+      k += nf;
+
+      d_ringbuffer_ready = false;
     }
-    d_writer->update_write_pointer(nf * nchan);
-    k += nf;
   }
 
   return k;  // tell how many we actually did
index 0e082c5e29932930e4413bd13b765d2f10cc757a..71cbfcf9f011d0c72dbcb67ddf13b0abaad4ca78 100644 (file)
 
 #include <gr_sync_block.h>
 #include <gr_buffer.h>
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
 #include <string>
 #include <portaudio.h>
 #include <stdexcept>
-#include <gri_logger.h>
+//#include <gri_logger.h>
 
 class audio_portaudio_sink;
 typedef boost::shared_ptr<audio_portaudio_sink> audio_portaudio_sink_sptr;
@@ -74,12 +74,14 @@ class audio_portaudio_sink : public gr_sync_block {
 
   gr_buffer_sptr       d_writer;               // buffer used between work and callback
   gr_buffer_reader_sptr        d_reader;
-  omni_semaphore       d_ringbuffer_ready;     // binary semaphore
 
+  gruel::mutex          d_ringbuffer_mutex;
+  gruel::condition_variable d_ringbuffer_cond;
+  bool                  d_ringbuffer_ready;
 
   // random stats
   int                  d_nunderuns;            // count of underruns
-  gri_logger_sptr      d_log;                  // handle to non-blocking logging instance
+  //gri_logger_sptr    d_log;                  // handle to non-blocking logging instance
 
   void output_error_msg (const char *msg, int err);
   void bail (const char *msg, int err) throw (std::runtime_error);
index 29d63a8edf58225504931d3fece6dccc6095c4af..484b7f1e541bb42c86d84937c801ec61319b8c2f 100644 (file)
 #include <unistd.h>
 #include <stdexcept>
 #include <gri_portaudio.h>
-#include <gnuradio/omnithread.h>
 #include <string.h>
 
-#define        LOGGING 0               // define to 0 or 1
+//#define      LOGGING 0               // define to 0 or 1
 
 #define SAMPLE_FORMAT          paFloat32
 typedef float sample_t;
@@ -84,36 +83,32 @@ portaudio_source_callback (const void *inputBuffer,
   int nframes_room = self->d_writer->space_available() / nchan;
 
   if (nframes_to_copy <= nframes_room){  // We've got room for the data ..
-    if (LOGGING)
-      self->d_log->printf("PAsrc  cb: f/b = %4ld\n", framesPerBuffer);
+    //if (LOGGING)
+    //  self->d_log->printf("PAsrc  cb: f/b = %4ld\n", framesPerBuffer);
 
     // copy from input buffer to ringbuffer
-    memcpy(self->d_writer->write_pointer(),
-          inputBuffer,
-          nframes_to_copy * nchan * sizeof(sample_t));
-    self->d_writer->update_write_pointer(nframes_to_copy * nchan);
+    {
+      gruel::scoped_lock(d_ringbuffer_mutex);
+
+      memcpy(self->d_writer->write_pointer(),
+            inputBuffer,
+            nframes_to_copy * nchan * sizeof(sample_t));
+      self->d_writer->update_write_pointer(nframes_to_copy * nchan);
         
-    // Tell the source thread there is new data in the ringbuffer.
-    self->d_ringbuffer_ready.post();
+      // Tell the source thread there is new data in the ringbuffer.
+      self->d_ringbuffer_ready = true;
+    }
+
+    self->d_ringbuffer_cond.notify_one();
     return paContinue;
   }
 
   else {                       // overrun
-    if (LOGGING)
-      self->d_log->printf("PAsrc  cb: f/b = %4ld OVERRUN\n", framesPerBuffer);
-
     self->d_noverruns++;
     ::write(2, "aO", 2);       // FIXME change to non-blocking call
 
-#if 0
-    // copy any frames that will fit
-    memcpy(self->d_writer->write_pointer(),
-          inputBuffer,
-          nframes_room * nchan * sizeof(sample_t));
-    self->d_writer->update_write_pointer(nframes_room * nchan);
-#endif  
-
-    self->d_ringbuffer_ready.post();  // Tell the sink to get going!
+    self->d_ringbuffer_ready = false;
+    self->d_ringbuffer_cond.notify_one();  // Tell the sink to get going!
     return paContinue;
   }
 }
@@ -140,12 +135,14 @@ audio_portaudio_source::audio_portaudio_source(int sampling_rate,
     d_verbose(gr_prefs::singleton()->get_bool("audio_portaudio", "verbose", false)),
     d_portaudio_buffer_size_frames(0),
     d_stream(0),
-    d_ringbuffer_ready(1, 1),          // binary semaphore
+    d_ringbuffer_mutex(),
+    d_ringbuffer_cond(),
+    d_ringbuffer_ready(false),
     d_noverruns(0)
 {
   memset(&d_input_parameters, 0, sizeof(d_input_parameters));
-  if (LOGGING)
-    d_log = gri_logger::singleton();
+  //if (LOGGING)
+  //  d_log = gri_logger::singleton();
 
   PaError            err;
   int                i, numDevices;
@@ -303,11 +300,13 @@ audio_portaudio_source::work (int noutput_items,
       if (k > 0)               // If we've produced anything so far, return that
        return k;
 
-      if (d_ok_to_block){
-       d_ringbuffer_ready.wait();      // block here, then try again
+      if (d_ok_to_block) {
+       gruel:: scoped_lock guard(d_ringbuffer_mutex);
+       while (d_ringbuffer_ready == false)
+         d_ringbuffer_cond.wait(guard);        // block here, then try again
        continue;
       }
-
+      
       assert(k == 0);
 
       // There's no data and we're not allowed to block.
@@ -320,27 +319,38 @@ audio_portaudio_source::work (int noutput_items,
       // FIXME We'll fill with zeros for now.  Yes, it will "click"...
 
       // Fill with some frames of zeros
-      int nf = std::min(noutput_items - k, (int) d_portaudio_buffer_size_frames);
-      for (int i = 0; i < nf; i++){
-       for (unsigned int c = 0; c < nchan; c++){
-         out[c][k + i] = 0;
+      {
+       gruel::scoped_lock guard(d_ringbuffer_mutex);
+
+       int nf = std::min(noutput_items - k, (int) d_portaudio_buffer_size_frames);
+       for (int i = 0; i < nf; i++){
+         for (unsigned int c = 0; c < nchan; c++){
+           out[c][k + i] = 0;
+         }
        }
+       k += nf;
+
+       d_ringbuffer_ready = false;
+       return k;
       }
-      k += nf;
-      return k;
     }
 
     // We can read the smaller of the request and what's in the buffer.
-    int nf = std::min(noutput_items - k, nframes);
+    {
+      gruel::scoped_lock guard(d_ringbuffer_mutex);
 
-    const float *p = (const float *) d_reader->read_pointer();
-    for (int i = 0; i < nf; i++){
-      for (unsigned int c = 0; c < nchan; c++){
-       out[c][k + i] = *p++;
+      int nf = std::min(noutput_items - k, nframes);
+      
+      const float *p = (const float *) d_reader->read_pointer();
+      for (int i = 0; i < nf; i++){
+       for (unsigned int c = 0; c < nchan; c++){
+         out[c][k + i] = *p++;
+       }
       }
+      d_reader->update_read_pointer(nf * nchan);
+      k += nf;
+      d_ringbuffer_ready = false;
     }
-    d_reader->update_read_pointer(nf * nchan);
-    k += nf;
   }
 
   return k;  // tell how many we actually did
index d14fe80587f17c68f0627b772084f421efe036fa..31e70a12779b257f2c72078c6d881cef9cbc119e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006.2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 
 #include <gr_sync_block.h>
 #include <gr_buffer.h>
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
 #include <string>
 #include <portaudio.h>
 #include <stdexcept>
-#include <gri_logger.h>
 
 class audio_portaudio_source;
 typedef boost::shared_ptr<audio_portaudio_source> audio_portaudio_source_sptr;
@@ -74,11 +73,13 @@ class audio_portaudio_source : public gr_sync_block {
 
   gr_buffer_sptr       d_writer;               // buffer used between work and callback
   gr_buffer_reader_sptr        d_reader;
-  omni_semaphore       d_ringbuffer_ready;     // binary semaphore
+
+  gruel::mutex          d_ringbuffer_mutex;
+  gruel::condition_variable d_ringbuffer_cond;
+  bool                  d_ringbuffer_ready;
 
   // random stats
   int                  d_noverruns;            // count of overruns
-  gri_logger_sptr      d_log;                  // handle to non-blocking logging instance
 
   void output_error_msg (const char *msg, int err);
   void bail (const char *msg, int err) throw (std::runtime_error);
@@ -87,7 +88,7 @@ class audio_portaudio_source : public gr_sync_block {
 
  protected:
   audio_portaudio_source (int sampling_rate, const std::string device_name,
-                       bool ok_to_block);
+                         bool ok_to_block);
 
  public:
   ~audio_portaudio_source ();
diff --git a/gr-audio-windows/.gitignore b/gr-audio-windows/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
diff --git a/gr-audio-windows/src/.gitignore b/gr-audio-windows/src/.gitignore
new file mode 100644 (file)
index 0000000..0874465
--- /dev/null
@@ -0,0 +1,35 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
+/run_tests
+/audio_windows.cc
+/audio_windows.py
index 1a8ededa609dc3dfff6e0b00b13f28a5c77347ed..d3e3f5a85b0f0ade0f29d8e53211b93433935ce5 100644 (file)
@@ -23,21 +23,35 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
 noinst_PYTHON = qa_audio_windows.py
 
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-
 # C/C++ headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS =                    \
        audio_windows_sink.h            \
        audio_windows_source.h
 
+lib_LTLIBRARIES = libgnuradio-audio-windows.la
+
+libgnuradio_audio_windows_la_SOURCES =         \
+       audio_windows_sink.cc           \
+       audio_windows_source.cc         
+
+libgnuradio_audio_windows_la_LIBADD =  \
+       $(GNURADIO_CORE_LA)             \
+       $(WINAUDIO_LIBS)
+
+libgnuradio_audio_windows_la_LDFLAGS = \
+       $(LIBGNURADIO_CORE_EXTRA_LDFLAGS) \
+       $(NO_UNDEFINED) \
+       $(LTVERSIONFLAGS)
+
+if PYTHON
 ###################################
 # SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        audio_windows.i
@@ -49,19 +63,9 @@ TOP_SWIG_IFILES =                    \
 audio_windows_pythondir_category =     \
        gnuradio
 
-# additional sources for the SWIG-generated library
-audio_windows_la_swig_sources =        \
-       audio_windows_sink.cc           \
-       audio_windows_source.cc         
-
 # additional libraries for linking with the SWIG-generated library
 audio_windows_la_swig_libadd =         \
-       $(GNURADIO_CORE_LA)             \
-       $(WINAUDIO_LIBS)
-
-# additional LD flags for linking the SWIG-generated library
-audio_windows_la_swig_ldflags =                \
-       $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+       libgnuradio-audio-windows.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -70,3 +74,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-comedi/.gitignore b/gr-comedi/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
diff --git a/gr-comedi/Makefile.am b/gr-comedi/Makefile.am
new file mode 100644 (file)
index 0000000..4fc1e1e
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-comedi.pc
diff --git a/gr-comedi/README b/gr-comedi/README
new file mode 100644 (file)
index 0000000..db6fde7
--- /dev/null
@@ -0,0 +1,3 @@
+This module appears to wrap COMEDI devices for GNU Radio.
+
+See http://www.comedi.org/.
diff --git a/gr-comedi/gnuradio-comedi.pc.in b/gr-comedi/gnuradio-comedi.pc.in
new file mode 100644 (file)
index 0000000..205b40e
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-comedi
+Description: GNU Radio blocks for the comedi library
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-comedi
+Cflags: -I${includedir}
diff --git a/gr-comedi/src/.gitignore b/gr-comedi/src/.gitignore
new file mode 100644 (file)
index 0000000..d95b6dc
--- /dev/null
@@ -0,0 +1,12 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/comedi.cc
+/*.pyc
+/comedi.py
+/run_tests
diff --git a/gr-comedi/src/Makefile.am b/gr-comedi/src/Makefile.am
new file mode 100644 (file)
index 0000000..a55bd17
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# Copyright 2005,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+# C/C++ headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =            \
+       comedi_sink_s.h         \
+       comedi_source_s.h
+
+noinst_HEADERS =               \
+       gri_comedi.h
+
+noinst_PYTHON =                        \
+       qa_comedi.py
+
+lib_LTLIBRARIES = libgnuradio-comedi.la
+
+libgnuradio_comedi_la_SOURCES = \
+       comedi_sink_s.cc        \
+       comedi_source_s.cc      \
+       gri_comedi.cc
+
+libgnuradio_comedi_la_LIBADD = \
+       $(GNURADIO_CORE_LA)     \
+       $(COMEDI_LIBS)
+
+libgnuradio_comedi_la_LDFLAGS =        $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+if PYTHON
+###################################
+# SWIG Python interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
+
+TOP_SWIG_IFILES =              \
+       comedi.i
+
+# Install so that they end up available as:
+#   import gnuradio.comedi
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+comedi_pythondir_category =    \
+       gnuradio
+
+# additional libraries for linking with the SWIG-generated library
+comedi_la_swig_libadd =                \
+       libgnuradio-comedi.la
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-comedi/src/Makefile.swig.gen b/gr-comedi/src/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..dd2c235
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for comedi.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/comedi
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/comedi
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+comedi_pythondir_category ?= gnuradio/comedi
+comedi_pylibdir_category ?= $(comedi_pythondir_category)
+comedi_pythondir = $(pythondir)/$(comedi_pythondir_category)
+comedi_pylibdir = $(pyexecdir)/$(comedi_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+comedi_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/comedi-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += comedi.py comedi.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+comedi_swiginclude_HEADERS =           \
+       comedi.i                        \
+       $(comedi_swiginclude_headers)
+
+comedi_pylib_LTLIBRARIES =             \
+       _comedi.la
+
+_comedi_la_SOURCES =                   \
+       comedi.cc                       \
+       $(comedi_la_swig_sources)
+
+_comedi_la_LIBADD =                    \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(comedi_la_swig_libadd)
+
+_comedi_la_LDFLAGS =                   \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(comedi_la_swig_ldflags)
+
+_comedi_la_CXXFLAGS =                  \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(comedi_la_swig_cxxflags)
+
+comedi_python_PYTHON =                 \
+       comedi.py                       \
+       $(comedi_python)
+
+## Entry rule for running SWIG
+
+comedi.h comedi.py comedi.cc: comedi.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/comedi-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/comedi-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/comedi-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/comedi-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/comedi-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/comedi-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/comedi-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/comedi-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/comedi-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(comedi_swig_args) \
+               -MD -MF $(DEPDIR)/comedi.Std \
+               -module comedi -o comedi.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/comedi.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/comedi.Std \
+                       > $(DEPDIR)/comedi.Sd; \
+               $(RM) $(DEPDIR)/comedi.Std; \
+               $(MV) $(DEPDIR)/comedi.Sd $(DEPDIR)/comedi.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/comedi.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/comedi.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/comedi.Std $(DEPDIR)/comedi.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/comedi.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/comedi.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/comedi.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/comedi.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/comedi-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/comedi.d@am__quote@
+
diff --git a/gr-comedi/src/comedi.i b/gr-comedi/src/comedi.i
new file mode 100644 (file)
index 0000000..cdb77ae
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"                          // the common stuff
+
+%{
+#include "comedi_sink_s.h"
+#include "comedi_source_s.h"
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(comedi,source_s)
+
+comedi_source_s_sptr
+comedi_make_source_s (int sampling_freq,
+                       const std::string dev = ""
+                       ) throw (std::runtime_error);
+
+class comedi_source_s : public gr_sync_block {
+
+ protected:
+  comedi_source_s (int sampling_freq,
+                    const std::string device_name
+                    ) throw (std::runtime_error);
+
+ public:
+  ~comedi_source_s ();
+
+  bool start();
+  bool stop();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(comedi,sink_s)
+
+comedi_sink_s_sptr
+comedi_make_sink_s (int sampling_freq,
+                     const std::string dev = ""
+                     ) throw (std::runtime_error);
+
+class comedi_sink_s : public gr_sync_block {
+
+ protected:
+  comedi_sink_s (int sampling_freq,
+                  const std::string device_name
+                  ) throw (std::runtime_error);
+
+ public:
+  ~comedi_sink_s ();
+};
diff --git a/gr-comedi/src/comedi_sink_s.cc b/gr-comedi/src/comedi_sink_s.cc
new file mode 100644 (file)
index 0000000..7f4c6d6
--- /dev/null
@@ -0,0 +1,233 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/mman.h>
+
+#include <comedi_sink_s.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+#include <errno.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_comedi.h>
+
+
+/*
+ * comedi_sink_s is untested because I don't own appropriate hardware.
+ * Feedback is welcome!  --SF
+ */
+
+static std::string 
+default_device_name ()
+{
+  return "/dev/comedi0";
+}
+
+
+// ----------------------------------------------------------------
+
+comedi_sink_s_sptr
+comedi_make_sink_s (int sampling_freq, const std::string dev)
+{
+  return comedi_sink_s_sptr (new comedi_sink_s (sampling_freq, dev));
+}
+
+comedi_sink_s::comedi_sink_s (int sampling_freq,
+                                 const std::string device_name)
+  : gr_sync_block ("comedi_sink_s",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_freq (sampling_freq),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_dev (0),
+    d_subdevice (COMEDI_SUBD_AO),
+    d_n_chan (1),      // number of input channels
+    d_map (0),
+    d_buffer_size (0),
+    d_buf_front (0),
+    d_buf_back (0)
+{
+  int  aref=AREF_GROUND;
+  int  range=0;
+
+  d_dev = comedi_open(d_device_name.c_str());
+  if (d_dev == 0){
+    comedi_perror(d_device_name.c_str());
+    throw std::runtime_error ("comedi_sink_s");
+  }
+
+  unsigned int chanlist[256];
+
+  for(int i=0; i<d_n_chan; i++){
+    chanlist[i]=CR_PACK(i,range,aref);
+  }
+
+  comedi_cmd cmd;
+  int ret;
+
+  ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,(unsigned int)(1e9/sampling_freq));
+  if(ret<0)
+    bail ("comedi_get_cmd_generic_timed", comedi_errno());
+
+  // TODO: check period_ns is not to far off sampling_freq
+
+  d_buffer_size = comedi_get_buffer_size(d_dev, d_subdevice);
+  if (d_buffer_size <= 0)
+    bail ("comedi_get_buffer_size", comedi_errno());
+
+  d_map = mmap(NULL,d_buffer_size,PROT_WRITE,MAP_SHARED,comedi_fileno(d_dev),0);
+  if (d_map == MAP_FAILED)
+    bail ("mmap", errno);
+
+  cmd.chanlist = chanlist;
+  cmd.chanlist_len = d_n_chan;
+  cmd.scan_end_arg = d_n_chan;
+
+  cmd.stop_src=TRIG_NONE;
+  cmd.stop_arg=0;
+
+  /* comedi_command_test() tests a command to see if the
+   * trigger sources and arguments are valid for the subdevice.
+   * If a trigger source is invalid, it will be logically ANDed
+   * with valid values (trigger sources are actually bitmasks),
+   * which may or may not result in a valid trigger source.
+   * If an argument is invalid, it will be adjusted to the
+   * nearest valid value.  In this way, for many commands, you
+   * can test it multiple times until it passes.  Typically,
+   * if you can't get a valid command in two tests, the original
+   * command wasn't specified very well. */
+  ret = comedi_command_test(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command_test", comedi_errno());
+
+  ret = comedi_command_test(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command_test", comedi_errno());
+
+  /* start the command */
+  ret = comedi_command(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command", comedi_errno());
+
+  set_output_multiple (d_n_chan*sizeof(sampl_t));
+
+  assert(sizeof(sampl_t) == sizeof(short));
+  set_output_signature (gr_make_io_signature (1, 1, sizeof (sampl_t)));
+}
+
+bool
+comedi_sink_s::check_topology (int ninputs, int noutputs)
+{
+  if (ninputs > d_n_chan)
+    throw std::runtime_error ("comedi_sink_s");
+
+  return true;
+}
+
+comedi_sink_s::~comedi_sink_s ()
+{
+  if (d_map) {
+    munmap(d_map, d_buffer_size);
+    d_map = 0;
+  }
+
+  comedi_close(d_dev);
+}
+
+int
+comedi_sink_s::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  int ret;
+
+  int work_left = noutput_items * sizeof(sampl_t) * d_n_chan;
+  sampl_t *pbuf = (sampl_t*)d_map;
+
+  do {
+
+    do {
+      ret = comedi_get_buffer_contents(d_dev,d_subdevice);
+      if (ret < 0)
+        bail ("comedi_get_buffer_contents", comedi_errno());
+
+      assert(ret % sizeof(sampl_t) == 0);
+      assert(work_left % sizeof(sampl_t) == 0);
+
+      ret = std::min(ret, work_left);
+      d_buf_front += ret;
+
+      assert(d_buffer_size%d_n_chan == 0);
+      if (d_buf_front-d_buf_back > (unsigned)d_buffer_size) {
+             d_buf_front+=d_buffer_size;
+             d_buf_back +=d_buffer_size;
+      }
+
+      if(d_buf_front==d_buf_back){
+        usleep(1000000*std::min(work_left,d_buffer_size/2)/(d_sampling_freq*sizeof(sampl_t)*d_n_chan));
+        continue;
+      }
+    } while (d_buf_front==d_buf_back);
+
+    for(unsigned i=d_buf_back/sizeof(sampl_t);i<d_buf_front/sizeof(sampl_t);i++){
+      int chan = i%d_n_chan;
+      int i_idx = noutput_items-work_left/d_n_chan/sizeof(sampl_t)+(i-d_buf_back/sizeof(sampl_t))/d_n_chan;
+
+      pbuf[i%(d_buffer_size/sizeof(sampl_t))] = input_items[chan]==0 ? 0 :
+                       (int)((short*)(input_items[chan]))[i_idx] + 32767;
+    }
+
+    // FIXME: how to tell comedi the buffer is *written* ?
+    ret = comedi_mark_buffer_read(d_dev,d_subdevice,d_buf_front-d_buf_back);
+    if(ret<0)
+      bail ("comedi_mark_buffer_read", comedi_errno());
+
+    work_left -= d_buf_front-d_buf_back;
+
+    d_buf_back = d_buf_front;
+
+  } while(work_left>0);
+
+  return noutput_items;
+}
+
+
+void
+comedi_sink_s::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "comedi_sink_s[%s]: %s: %s\n",
+          d_device_name.c_str(), msg,  comedi_strerror(err));
+}
+
+void
+comedi_sink_s::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("comedi_sink_s");
+}
diff --git a/gr-comedi/src/comedi_sink_s.h b/gr-comedi/src/comedi_sink_s.h
new file mode 100644 (file)
index 0000000..22f0428
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_COMEDI_SINK_H
+#define INCLUDED_COMEDI_SINK_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <comedilib.h>
+#include <stdexcept>
+
+class comedi_sink_s;
+typedef boost::shared_ptr<comedi_sink_s> comedi_sink_s_sptr;
+
+/*!
+ * \brief make an COMEDI sink.
+ *
+ * \param sampling_freq        sampling rate in Hz
+ * \param dev COMEDI device name, e.g., "/dev/comedi0"
+ */
+comedi_sink_s_sptr
+comedi_make_sink_s (int sampling_freq,
+                     const std::string dev = "/dev/comedi0");
+
+/*!
+ * \brief sink using COMEDI
+ *
+ * The sink has one input stream of signed short integers.
+ *
+ * Input samples must be in the range [-32768,32767].
+ */
+class comedi_sink_s : public gr_sync_block {
+  friend comedi_sink_s_sptr
+  comedi_make_sink_s (int sampling_freq, const std::string dev);
+
+  // typedef for pointer to class work method
+  typedef int (comedi_sink_s::*work_t)(int noutput_items,
+                                        gr_vector_const_void_star &input_items,
+                                        gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_freq;
+  std::string          d_device_name;
+
+  comedi_t             *d_dev;
+  int                  d_subdevice;
+  int                  d_n_chan;
+  void                 *d_map;
+  int                  d_buffer_size;
+  unsigned             d_buf_front;
+  unsigned             d_buf_back;
+
+  // random stats
+  int                  d_nunderuns;            // count of underruns
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+ protected:
+  comedi_sink_s (int sampling_freq, const std::string device_name);
+
+ public:
+  ~comedi_sink_s ();
+  
+  bool check_topology (int ninputs, int noutputs);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_COMEDI_SINK_H */
diff --git a/gr-comedi/src/comedi_source_s.cc b/gr-comedi/src/comedi_source_s.cc
new file mode 100644 (file)
index 0000000..4e3980e
--- /dev/null
@@ -0,0 +1,229 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/mman.h>
+
+#include <comedi_source_s.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+#include <errno.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_comedi.h>
+
+
+// FIXME these should query some kind of user preference
+
+
+static std::string 
+default_device_name ()
+{
+  return "/dev/comedi0";
+}
+
+// ----------------------------------------------------------------
+
+comedi_source_s_sptr
+comedi_make_source_s (int sampling_freq, const std::string dev)
+{
+  return comedi_source_s_sptr (new comedi_source_s (sampling_freq, dev));
+}
+
+comedi_source_s::comedi_source_s (int sampling_freq,
+                                 const std::string device_name)
+  : gr_sync_block ("comedi_source_s",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_freq (sampling_freq),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_dev (0),
+    d_subdevice (0/*COMEDI_SUBD_AI*/),
+    d_n_chan (1),      // number of input channels
+    d_map (0),
+    d_buffer_size (0),
+    d_buf_front (0),
+    d_buf_back (0)
+{
+  int  aref=AREF_GROUND;
+  int  range=0;
+
+  d_dev = comedi_open(d_device_name.c_str());
+  if (d_dev == 0){
+    comedi_perror(d_device_name.c_str());
+    throw std::runtime_error ("comedi_source_s");
+  }
+
+  unsigned int chanlist[256];
+
+  for(int i=0; i<d_n_chan; i++){
+    chanlist[i]=CR_PACK(i,range,aref);
+  }
+
+  comedi_cmd cmd;
+  int ret;
+
+  ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,(unsigned int)(1e9/sampling_freq));
+  if(ret<0)
+    bail ("comedi_get_cmd_generic_timed", comedi_errno());
+
+  // TODO: check period_ns is not to far off sampling_freq
+
+  d_buffer_size = comedi_get_buffer_size(d_dev, d_subdevice);
+  if (d_buffer_size <= 0)
+    bail ("comedi_get_buffer_size", comedi_errno());
+
+  d_map = mmap(NULL,d_buffer_size,PROT_READ,MAP_SHARED,comedi_fileno(d_dev),0);
+  if (d_map == MAP_FAILED)
+    bail ("mmap", errno);
+
+  cmd.chanlist = chanlist;
+  cmd.chanlist_len = d_n_chan;
+  cmd.scan_end_arg = d_n_chan;
+
+  cmd.stop_src=TRIG_NONE;
+  cmd.stop_arg=0;
+
+  /* comedi_command_test() tests a command to see if the
+   * trigger sources and arguments are valid for the subdevice.
+   * If a trigger source is invalid, it will be logically ANDed
+   * with valid values (trigger sources are actually bitmasks),
+   * which may or may not result in a valid trigger source.
+   * If an argument is invalid, it will be adjusted to the
+   * nearest valid value.  In this way, for many commands, you
+   * can test it multiple times until it passes.  Typically,
+   * if you can't get a valid command in two tests, the original
+   * command wasn't specified very well. */
+  ret = comedi_command_test(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command_test", comedi_errno());
+
+  ret = comedi_command_test(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command_test", comedi_errno());
+
+  /* start the command */
+  ret = comedi_command(d_dev,&cmd);
+
+  if(ret<0)
+    bail ("comedi_command", comedi_errno());
+
+  set_output_multiple (d_n_chan*sizeof(sampl_t));
+
+  assert(sizeof(sampl_t) == sizeof(short));
+  set_output_signature (gr_make_io_signature (1, 1, sizeof (sampl_t)));
+}
+
+bool
+comedi_source_s::check_topology (int ninputs, int noutputs)
+{
+  if (noutputs > d_n_chan)
+    throw std::runtime_error ("comedi_source_s");
+
+  return true;
+}
+
+comedi_source_s::~comedi_source_s ()
+{
+  if (d_map) {
+    munmap(d_map, d_buffer_size);
+    d_map = 0;
+  }
+
+  comedi_close(d_dev);
+}
+
+int
+comedi_source_s::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  int ret;
+
+  int work_left = noutput_items * sizeof(sampl_t) * d_n_chan;
+  sampl_t *pbuf = (sampl_t*)d_map;
+
+  do {
+
+    do {
+      ret = comedi_get_buffer_contents(d_dev,d_subdevice);
+      if (ret < 0)
+        bail ("comedi_get_buffer_contents", comedi_errno());
+
+      assert(ret % sizeof(sampl_t) == 0);
+      assert(work_left % sizeof(sampl_t) == 0);
+
+      ret = std::min(ret, work_left);
+      d_buf_front += ret;
+
+      assert(d_buffer_size%d_n_chan == 0);
+      if (d_buf_front-d_buf_back > (unsigned)d_buffer_size) {
+             d_buf_front+=d_buffer_size;
+             d_buf_back +=d_buffer_size;
+      }
+
+      if(d_buf_front==d_buf_back){
+        usleep(1000000*std::min(work_left,d_buffer_size/2)/(d_sampling_freq*sizeof(sampl_t)*d_n_chan));
+        continue;
+      }
+    } while (d_buf_front==d_buf_back);
+
+    for(unsigned i=d_buf_back/sizeof(sampl_t);i<d_buf_front/sizeof(sampl_t);i++){
+      int chan = i%d_n_chan;
+      int o_idx = noutput_items-work_left/d_n_chan/sizeof(sampl_t)+(i-d_buf_back/sizeof(sampl_t))/d_n_chan;
+
+      if (output_items[chan])
+        ((short*)(output_items[chan]))[o_idx] = 
+               (int)pbuf[i%(d_buffer_size/sizeof(sampl_t))] - 32767;
+    }
+
+    ret = comedi_mark_buffer_read(d_dev,d_subdevice,d_buf_front-d_buf_back);
+    if(ret<0)
+      bail ("comedi_mark_buffer_read", comedi_errno());
+
+    work_left -= d_buf_front-d_buf_back;
+
+    d_buf_back = d_buf_front;
+
+  } while(work_left>0);
+
+  return noutput_items;
+}
+
+void
+comedi_source_s::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "comedi_source_s[%s]: %s: %s\n",
+          d_device_name.c_str(), msg,  comedi_strerror(err));
+}
+
+void
+comedi_source_s::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("comedi_source_s");
+}
diff --git a/gr-comedi/src/comedi_source_s.h b/gr-comedi/src/comedi_source_s.h
new file mode 100644 (file)
index 0000000..c406f27
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_COMEDI_SOURCE_S_H
+#define INCLUDED_COMEDI_SOURCE_S_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <comedilib.h>
+#include <stdexcept>
+
+class comedi_source_s;
+typedef boost::shared_ptr<comedi_source_s> comedi_source_s_sptr;
+
+/*!
+ * \brief make a COMEDI source.
+ *
+ * \param sampling_freq        sampling rate in Hz
+ * \param dev COMEDI device name, e.g., "/dev/comedi0"
+ */
+comedi_source_s_sptr
+comedi_make_source_s (int sampling_freq,
+                     const std::string dev = "/dev/comedi0");
+
+/*!
+ * \brief source using COMEDI
+ *
+ * The source has one to many input stream of signed short integers.
+ *
+ * Output samples will be in the range [-32768,32767].
+ */
+class comedi_source_s : public gr_sync_block {
+  friend comedi_source_s_sptr
+  comedi_make_source_s (int sampling_freq, const std::string dev);
+
+  // typedef for pointer to class work method
+  typedef int (comedi_source_s::*work_t)(int noutput_items,
+                                        gr_vector_const_void_star &input_items,
+                                        gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_freq;
+  std::string          d_device_name;
+
+  comedi_t             *d_dev;
+  int                  d_subdevice;
+  int                  d_n_chan;
+  void                 *d_map;
+  int                  d_buffer_size;
+  unsigned             d_buf_front;
+  unsigned             d_buf_back;
+
+  // random stats
+  int                  d_noverruns;            // count of overruns
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+
+ protected:
+  comedi_source_s (int sampling_freq, const std::string device_name);
+
+ public:
+  ~comedi_source_s ();
+  
+  bool check_topology (int ninputs, int noutputs);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_COMEDI_SOURCE_S_H */
diff --git a/gr-comedi/src/gri_comedi.cc b/gr-comedi/src/gri_comedi.cc
new file mode 100644 (file)
index 0000000..15caac4
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_comedi.h>
+#include <algorithm>
+
+
diff --git a/gr-comedi/src/gri_comedi.h b/gr-comedi/src/gri_comedi.h
new file mode 100644 (file)
index 0000000..410db84
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_GRI_COMEDI_H
+#define INCLUDED_GRI_COMEDI_H
+
+#include <stdio.h>
+
+#endif /* INCLUDED_GRI_COMEDI_H */
diff --git a/gr-comedi/src/qa_comedi.py b/gr-comedi/src/qa_comedi.py
new file mode 100755 (executable)
index 0000000..e690dfa
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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, gr_unittest
+import comedi
+
+class qa_comedi (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have COMEDI library, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-comedi/src/run_tests.in b/gr-comedi/src/run_tests.in
new file mode 100644 (file)
index 0000000..84fefba
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# 1st parameter is absolute path to component source directory
+# 2nd parameter is absolute path to component build directory
+# 3rd parameter is path to Python QA directory
+
+@top_builddir@/run_tests.sh \
+    @abs_top_srcdir@/gr-comedi \
+    @abs_top_builddir@/gr-comedi \
+    @srcdir@
diff --git a/gr-cvsd-vocoder/.gitignore b/gr-cvsd-vocoder/.gitignore
new file mode 100644 (file)
index 0000000..a37fc0c
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pc
index f2e929644b09dbdc0eba34ad82b7bb2695f0e7c1..48807a34b6d43a71370dab1af8c4dabcd94c1368 100644 (file)
@@ -22,4 +22,6 @@
 include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
-DIST_SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-cvsd-vocoder.pc
diff --git a/gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc.in b/gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc.in
new file mode 100644 (file)
index 0000000..f5f0c2e
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-cvsd-vocoder
+Description: GNU Radio blocks implementing a CVSD vocoder
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-cvsd-vocoder
+Cflags: -I${includedir}
diff --git a/gr-cvsd-vocoder/src/.gitignore b/gr-cvsd-vocoder/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index e3f0399eb093e516a323ed1c5d4a6f7eb12c6cc9..be38b7c1ab43449ae85bcec13768c8afc0452f0b 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-cvsd-vocoder/src/lib/.gitignore b/gr-cvsd-vocoder/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..306156d
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/cvsd_vocoder.cc
+/cvsd_vocoder.py*
index 78a7c6400ecbacf95e8b003e47607eb92ae1602c..c5957f4acc7cbabd21e7d8e0f33562de877d44f4 100644 (file)
@@ -28,6 +28,18 @@ grinclude_HEADERS =                  \
        cvsd_decode_bs.h                \
        cvsd_encode_sb.h
 
+lib_LTLIBRARIES = libgnuradio-cvsd-vocoder.la
+
+libgnuradio_cvsd_vocoder_la_SOURCES =  \
+       cvsd_decode_bs.cc               \
+       cvsd_encode_sb.cc
+
+libgnuradio_cvsd_vocoder_la_LIBADD =   \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_cvsd_vocoder_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+if PYTHON
 ###################################
 # SWIG Python interface and library
 
@@ -41,14 +53,9 @@ TOP_SWIG_IFILES =                    \
 cvsd_vocoder_pythondir_category =      \
        gnuradio/vocoder
 
-# additional sources for the SWIG-generated library
-cvsd_vocoder_la_swig_sources =         \
-       cvsd_decode_bs.cc               \
-       cvsd_encode_sb.cc
-
 # additional libraries for linking with the SWIG-generated library
 cvsd_vocoder_la_swig_libadd =          \
-       $(GNURADIO_CORE_LA)
+       libgnuradio-cvsd-vocoder.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -57,3 +64,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-cvsd-vocoder/src/python/.gitignore b/gr-cvsd-vocoder/src/python/.gitignore
new file mode 100644 (file)
index 0000000..604b402
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/run_tests
diff --git a/gr-gcell/.gitignore b/gr-gcell/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
diff --git a/gr-gcell/src/.gitignore b/gr-gcell/src/.gitignore
new file mode 100644 (file)
index 0000000..8f9e3f0
--- /dev/null
@@ -0,0 +1,36 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
+/run_tests
+/gcell.d
+/gcell.cc
+/gcell.py
index 83dc30f45789a9710515da88affbe4fd80b055b1..63dc156b1162722ce611b382a30617281072ed33 100644 (file)
@@ -22,10 +22,6 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = . examples
 
-EXTRA_DIST = run_tests.in
-
-TESTS = run_tests
-
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(GCELL_INCLUDES) \
        $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
@@ -43,24 +39,27 @@ DISTCLEANFILES = \
 # ----------------------------------------------------------------
 
 # the library for the C++ blocks
-lib_LTLIBRARIES = libgr_gcell.la
+lib_LTLIBRARIES = libgnuradio_gcell.la
 
-libgr_gcell_la_SOURCES = \
+libgnuradio_gcell_la_SOURCES = \
        gcell_fft_vcc.cc
 
 # C/C++ headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS = \
        gcell_fft_vcc.h
 
-libgr_gcell_la_LIBADD = \
+libgnuradio_gcell_la_LIBADD = \
        $(GNURADIO_CORE_LA) \
        $(GCELL_LA)
 
-libgr_gcell_la_LDFLAGS = $(NO_UNDEFINED)
+libgnuradio_gcell_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
+if PYTHON
 # ----------------------------------------------------------------
 #                         SWIG stuff
 # ----------------------------------------------------------------
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
 
 TOP_SWIG_IFILES =              \
        gcell.i
@@ -78,7 +77,7 @@ gcell_swig_args =             \
 
 # additional libraries for linking with the SWIG-generated library
 gcell_la_swig_libadd =         \
-       libgr_gcell.la
+       libgnuradio_gcell.la
 
 # additional SWIG files to be installed
 gcell_swiginclude_headers =    \
@@ -92,3 +91,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-gcell/src/examples/.gitignore b/gr-gcell/src/examples/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
diff --git a/gr-gpio/.gitignore b/gr-gpio/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-gpio/src/.gitignore b/gr-gpio/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 8c9a64b8bfaa485437089e1ddd8e943f101de794..5071c22732a5ec7ada80264241738f7db17f50b5 100644 (file)
@@ -19,4 +19,8 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = python fpga
+SUBDIRS = fpga
+if PYTHON
+SUBDIRS += python
+endif
+
diff --git a/gr-gpio/src/fpga/.gitignore b/gr-gpio/src/fpga/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-gpio/src/fpga/include/.gitignore b/gr-gpio/src/fpga/include/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-gpio/src/fpga/lib/.gitignore b/gr-gpio/src/fpga/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-gpio/src/fpga/rbf/.gitignore b/gr-gpio/src/fpga/rbf/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-gpio/src/fpga/top/.gitignore b/gr-gpio/src/fpga/top/.gitignore
new file mode 100644 (file)
index 0000000..28be78c
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/db
+/prev*.*
+/*.summary
+/*.qws
+/*.rpt
+/*.done
+/*.pin
+/*.sof
+/*.rbf
diff --git a/gr-gpio/src/python/.gitignore b/gr-gpio/src/python/.gitignore
new file mode 100644 (file)
index 0000000..b9e19a9
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/*.pyc
+/run_tests
index 2ef49558905d5b1f9b0609fae5f87c54ab27716b..a315e166bb9a28b312b28a153f2870336ebff84d 100644 (file)
@@ -1,3 +1 @@
-from gpio_swig import *
-
 fpga_filename = 'std_2rxint_2tx_dig.rbf'
index 40b1c54d4a76fbd190ff671dfbf40657ce76bf41..c9ecb032ddeebfd324bbdd4f8fa8ef8e75821802 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+# Copyright 2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -279,7 +279,7 @@ class app_top_block(stdgui2.std_top_block):
                 self.myform['baseband'].set_value(r.baseband_freq)
                 self.myform['ddc'].set_value(r.dxc_freq)
            if not self.options.waterfall and not self.options.oscilloscope:
-               self.scope.win.set_baseband_freq(target_freq)
+               self.scope.set_baseband_freq(target_freq)
            return True
 
         return False
diff --git a/gr-gsm-fr-vocoder/.gitignore b/gr-gsm-fr-vocoder/.gitignore
new file mode 100644 (file)
index 0000000..f3462d0
--- /dev/null
@@ -0,0 +1,23 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/*.pc
index f2e929644b09dbdc0eba34ad82b7bb2695f0e7c1..968ce327c08691ad4c7a273dcb492f7a187d804c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004 Free Software Foundation, Inc.
+# Copyright 2004,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -22,4 +22,6 @@
 include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
-DIST_SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-gsm-fr-vocoder.pc
diff --git a/gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in b/gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in
new file mode 100644 (file)
index 0000000..a799fcd
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-comedi
+Description: GNU Radio blocks implementing a GSM full rate vocoder
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-gsm-fr-vocoder-$@LIBVER@
+Cflags: -I${includedir}
diff --git a/gr-gsm-fr-vocoder/src/.gitignore b/gr-gsm-fr-vocoder/src/.gitignore
new file mode 100644 (file)
index 0000000..bb3f277
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
index e3f0399eb093e516a323ed1c5d4a6f7eb12c6cc9..be38b7c1ab43449ae85bcec13768c8afc0452f0b 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-gsm-fr-vocoder/src/lib/.gitignore b/gr-gsm-fr-vocoder/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..81a82de
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/gsm_full_rate.py
+/gsm_full_rate.cc
+/*.pyc
index 0cf0fb0788fe67653f15cf72e89ea1fae324d6ad..97d6fc30690a36bef975020d85575fae2bc1974e 100644 (file)
@@ -30,8 +30,20 @@ grinclude_HEADERS =                  \
        gsm_fr_decode_ps.h              \
        gsm_fr_encode_sp.h
 
-# SWIG interface and library
+lib_LTLIBRARIES = libgnuradio-gsm-fr-vocoder.la
+
+libgnuradio_gsm_fr_vocoder_la_SOURCES = \
+       gsm_fr_decode_ps.cc             \
+       gsm_fr_encode_sp.cc
+
+libgnuradio_gsm_fr_vocoder_la_LIBADD = \
+       $(GNURADIO_CORE_LA)             \
+       gsm/libgsm.la
 
+libgnuradio_gsm_fr_vocoder_la_LDFLAGS =        $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+if PYTHON
+# SWIG interface and library
 TOP_SWIG_IFILES =                      \
        gsm_full_rate.i
 
@@ -42,15 +54,9 @@ TOP_SWIG_IFILES =                    \
 gsm_full_rate_pythondir_category =     \
        gnuradio/vocoder
 
-# additional sources for the SWIG-generated library
-gsm_full_rate_la_swig_sources =        \
-       gsm_fr_decode_ps.cc             \
-       gsm_fr_encode_sp.cc
-
 # additional libraries for linking with the SWIG-generated library
 gsm_full_rate_la_swig_libadd =         \
-       $(GNURADIO_CORE_LA)             \
-       gsm/libgsm.la
+       libgnuradio-gsm-fr-vocoder.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -59,3 +65,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/.gitignore b/gr-gsm-fr-vocoder/src/lib/gsm/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/README.gsm b/gr-gsm-fr-vocoder/src/lib/gsm/README.gsm
new file mode 100644 (file)
index 0000000..cb6af85
--- /dev/null
@@ -0,0 +1,37 @@
+
+GSM 06.10 13 kbit/s RPE/LTP speech compression available
+--------------------------------------------------------
+
+The Communications and Operating Systems Research Group (KBS) at the
+Technische Universitaet Berlin is currently working on a set of
+UNIX-based tools for computer-mediated telecooperation that will be
+made freely available.
+
+As part of this effort we are publishing an implementation of the
+European GSM 06.10 provisional standard for full-rate speech
+transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
+excitation/long term prediction) coding at 13 kbit/s.
+
+GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling
+rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility
+with typical UNIX applications, our implementation turns frames of 160
+16-bit linear samples into 33-byte frames (1650 Bytes/s).
+The quality of the algorithm is good enough for reliable speaker
+recognition; even music often survives transcoding in recognizable 
+form (given the bandwidth limitations of 8 kHz sampling rate).
+
+The interfaces offered are a front end modelled after compress(1), and
+a library API.  Compression and decompression run faster than realtime
+on most SPARCstations.  The implementation has been verified against the
+ETSI standard test patterns.
+
+Jutta Degener (jutta@cs.tu-berlin.de)
+Carsten Bormann (cabo@cs.tu-berlin.de)
+
+Communications and Operating Systems Research Group, TU Berlin
+Fax: +49.30.31425156, Phone: +49.30.31424315
+
+--
+Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
diff --git a/gr-gsm-fr-vocoder/src/python/.gitignore b/gr-gsm-fr-vocoder/src/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-howto-write-a-block/.gitignore b/gr-howto-write-a-block/.gitignore
new file mode 100644 (file)
index 0000000..543c391
--- /dev/null
@@ -0,0 +1,26 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/py-compile
+/depcomp
+/ltmain.sh
+/install-sh
diff --git a/gr-howto-write-a-block/AUTHORS b/gr-howto-write-a-block/AUTHORS
new file mode 100644 (file)
index 0000000..ee4560a
--- /dev/null
@@ -0,0 +1 @@
+Eric Blossom <eb@comsec.com>
diff --git a/gr-howto-write-a-block/COPYING b/gr-howto-write-a-block/COPYING
new file mode 100644 (file)
index 0000000..94a9ed0
--- /dev/null
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/gr-howto-write-a-block/ChangeLog b/gr-howto-write-a-block/ChangeLog
new file mode 100644 (file)
index 0000000..4b6c4f9
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# Copyright 2001,2002,2003,2004,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.
+# 
+
+For the blow by blow changes for each file, please consult
+http://gnuradio.org/trac/timeline
+       
+It's got everything that used to be in here ;)
diff --git a/gr-howto-write-a-block/INSTALL b/gr-howto-write-a-block/INSTALL
new file mode 100644 (file)
index 0000000..7d1c323
--- /dev/null
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
+
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/gr-howto-write-a-block/Makefile.am b/gr-howto-write-a-block/Makefile.am
new file mode 100644 (file)
index 0000000..98368c2
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Copyright 2004,2008,2009 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.
+# 
+
+ACLOCAL_AMFLAGS = -I config
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+       bootstrap \
+       configure \
+       config.h.in \
+       Makefile.swig \
+       Makefile.swig.gen.t \
+       version.sh \
+       README \
+       README.hacking
+
+SUBDIRS = config lib swig python grc apps
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
+
+DISTCLEANFILES = gr-howto-write-a-block*.tar.gz
diff --git a/gr-howto-write-a-block/Makefile.common b/gr-howto-write-a-block/Makefile.common
new file mode 100644 (file)
index 0000000..15a5216
--- /dev/null
@@ -0,0 +1,77 @@
+# -*- Makefile -*-
+#
+# Copyright 2004,2006,2009,2010 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.
+# 
+
+# The name of this "out-of-tree" module
+modname = howto
+
+# these flags are used when compiling non-SWIG-wrapper files
+# when going in to non-SWIG libraries
+AM_CXXFLAGS = @autoconf_default_CXXFLAGS@
+
+# Sets ABI version in SONAME and appends -LIBVER to filename
+LTVERSIONFLAGS = -version-info 0:0:0 -release $(LIBVER)
+
+# these flags are used when compiling any CXX file
+AM_CPPFLAGS = \
+       $(STD_DEFINES_AND_INCLUDES) \
+       $(PYTHON_CPPFLAGS) \
+       $(CPPUNIT_INCLUDES) \
+       $(GNURADIO_CORE_CPPFLAGS)
+
+# these are used by both SWIG and CXX
+STD_DEFINES_AND_INCLUDES = \
+       $(DEFINES) \
+       -I$(abs_top_srcdir)/lib \
+       -I$(GNURADIO_CORE_INCLUDEDIR) \
+       -I$(GNURADIO_CORE_INCLUDEDIR)/swig
+
+# includes
+modincludedir = $(includedir)/$(modname)
+
+# swig includes 
+swigincludedir = $(modincludedir)/swig
+
+# Install this stuff in the appropriate subdirectory
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/$(modname)
+
+modpythondir = $(pythondir)/$(modname)
+modpyexecdir = $(pyexecdir)/$(modname)
+
+# Data directory for grc block wrappers
+grc_blocksdir = $(prefix)/share/gnuradio/grc/blocks
+
+# Don't assume that make predefines $(RM), because BSD make does
+# not. We define it now in configure.ac using AM_PATH_PROG, but now
+# here have to add a -f to be like GNU make.
+RM=$(RM_PROG) -f
+
+# Other common defines; use "+=" to add to these
+STAMPS =
+MOSTLYCLEANFILES = $(BUILT_SOURCES) $(STAMPS) *.pyc *.pyo *~ *.tmp *.loT
+
+# Don't distribute the files defined in the variable 'no_dist_files'
+dist-hook:
+       @for file in $(no_dist_files); do \
+               echo $(RM) $(distdir)/$$file; \
+               $(RM) $(distdir)/$$file; \
+       done;
diff --git a/gr-howto-write-a-block/Makefile.swig b/gr-howto-write-a-block/Makefile.swig
new file mode 100644 (file)
index 0000000..9e14835
--- /dev/null
@@ -0,0 +1,117 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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 makefile should be included using 
+##     include $(top_srcdir)/Makefile.swig
+## in Makefile.am's which require SWIG wrapping / compilation.
+## For just installing .i files, this Makefile is not required.
+
+## swig flags
+## -w511 turns off keyword argument warning
+## "-outdir $(builddir)" writes all generated output files to
+##   the local builddir (which should always be '.')
+##   In some older autotools, $(builddir) is not defined, so
+##   just use '.' instead.
+
+SWIG_PYTHON_FLAGS =    \
+       -fvirtual       \
+       -python         \
+       -modern         \
+       -keyword        \
+       -w511           \
+       -outdir .
+
+## standard swig flags used by most components
+
+STD_SWIG_PYTHON_ARGS =                         \
+       $(SWIG_PYTHON_FLAGS)                    \
+       $(STD_DEFINES_AND_INCLUDES)             \
+       $(WITH_SWIG_INCLUDES)                   \
+       $(WITH_INCLUDES)
+
+## standard SWIG LD flags for library creation
+
+STD_SWIG_LA_LD_FLAGS =         \
+       $(PYTHON_LDFLAGS)       \
+       -module                 \
+       -avoid-version          \
+       $(NO_UNDEFINED)
+
+## standard SWIG library additions for library creation
+
+STD_SWIG_LA_LIB_ADD =                  \
+       -lstdc++
+
+## standard SWIG CXXFLAGS
+## This allows for code to be compiled with "-O1" instead of "-g -O2"
+## for some systems, avoiding some optimization issues.
+
+STD_SWIG_CXX_FLAGS = @swig_CXXFLAGS@
+
+## SWIG suffix for automake to know about
+
+SUFFIXES = .i
+
+## Create $(srcdir)/Makefile.swig.gen, containing all of the rules
+## for running SWIG to generate or re-generate outputs.  SWIG file
+## names are to be defined in TOP_SWIG_IFILES, and must include the
+## full path to the file and full filename including extension.  This
+## Makefile addition will be made only if either it does not exist or
+## if the top-level template has been modified.
+
+generate-makefile-swig $(srcdir)/Makefile.swig.gen: $(top_srcdir)/Makefile.swig.gen.t
+## recreate $(srcdir)/Makefile.swig.gen only if ...
+       @do_recreate=0; \
+       if test -f $(srcdir)/Makefile.swig.gen; then \
+## the file exists and can be removed; or ...
+               if $(RM) $(srcdir)/Makefile.swig.gen 2>/dev/null; then \
+                       if touch $(srcdir)/Makefile.swig.gen 2>/dev/null; then \
+                               do_recreate=1; \
+                       fi; \
+               fi; \
+       else \
+## the file doesn't exist, but can be created (e.g., by touching it).
+               if touch $(srcdir)/Makefile.swig.gen 2>/dev/null; then \
+                       do_recreate=1; \
+               fi; \
+       fi; \
+       if test "$$do_recreate" == "1"; then \
+               echo "Regenerating $(srcdir)/Makefile.swig.gen"; \
+               for TFILE in $(TOP_SWIG_IFILES); do \
+## retrieve just the filename, without path or extension
+                       TNAME=`python -c "import os.path as op; (dN, fN) = op.split ('$$TFILE'); (fbN, fE) = op.splitext (fN); print fbN;"`; \
+## Replace the @-named strings in the template Makefile for SWIG.
+                       $(SED) -e 's|@NAME@|'$$TNAME'|g;' < $(top_srcdir)/Makefile.swig.gen.t >> $(srcdir)/Makefile.swig.gen; \
+                       echo "" >> $(srcdir)/Makefile.swig.gen; \
+               done; \
+       else \
+               echo "Cannot recreate $(srcdir)/Makefile.swig.gen because the directory or file is write-protected."; \
+               exit -1; \
+       fi;
+
+swig_built_sources =
+
+## include the built Makefile.swig.gen, always the one from the
+## srcdir; this must be included as the last item, because it depends
+## on variables defined above.
+
+include $(srcdir)/Makefile.swig.gen
diff --git a/gr-howto-write-a-block/Makefile.swig.gen.t b/gr-howto-write-a-block/Makefile.swig.gen.t
new file mode 100644 (file)
index 0000000..686117f
--- /dev/null
@@ -0,0 +1,256 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for @NAME@.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/@NAME@
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/@NAME@
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+@NAME@_pythondir = $(pythondir)/@NAME@
+@NAME@_pylibdir = $(pyexecdir)/@NAME@
+
+## SWIG headers are always installed into the same directory.
+
+@NAME@_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/@NAME@-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += @NAME@_swig.py @NAME@_swig.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+@NAME@_swiginclude_HEADERS =           \
+       @NAME@.i                        \
+       $(@NAME@_swiginclude_headers)
+
+@NAME@_pylib_LTLIBRARIES =             \
+       _@NAME@_swig.la
+
+_@NAME@_swig_la_SOURCES =              \
+       @NAME@_swig.cc                  \
+       $(@NAME@_la_swig_sources)
+
+_@NAME@_swig_la_LIBADD =               \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(@NAME@_la_swig_libadd)
+
+_@NAME@_swig_la_LDFLAGS =              \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(@NAME@_la_swig_ldflags)
+
+_@NAME@_swig_la_CXXFLAGS =             \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(@NAME@_la_swig_cxxflags)
+
+@NAME@_python_PYTHON =                 \
+       @NAME@_swig.py                  \
+       $(@NAME@_python)
+
+## Entry rule for running SWIG
+
+@NAME@.h @NAME@_swig.py @NAME@_swig.cc: @NAME@.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/@NAME@-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/@NAME@-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/@NAME@-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/@NAME@-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/@NAME@-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/@NAME@-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/@NAME@-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/@NAME@-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/@NAME@-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(@NAME@_swig_args) \
+               -MD -MF $(DEPDIR)/@NAME@.Std \
+               -module @NAME@_swig -o @NAME@_swig.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/@NAME@.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/@NAME@.Std \
+                       > $(DEPDIR)/@NAME@.Sd; \
+               $(RM) $(DEPDIR)/@NAME@.Std; \
+               $(MV) $(DEPDIR)/@NAME@.Sd $(DEPDIR)/@NAME@.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/@NAME@.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/@NAME@.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/@NAME@.Std $(DEPDIR)/@NAME@.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/@NAME@.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/@NAME@.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/@NAME@.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/@NAME@.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/@NAME@-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/@NAME@.d@am__quote@
diff --git a/gr-howto-write-a-block/NEWS b/gr-howto-write-a-block/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-howto-write-a-block/README b/gr-howto-write-a-block/README
new file mode 100644 (file)
index 0000000..368e719
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Copyright 2005,2006,2009 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 directory (and the resulting tarball) contains a build tree with
+examples, Makefiles, etc that demonstrate how to write signal
+processing blocks for the GNU Radio system.  This directory is
+intentionally distributed separately from the unified tarball of the
+rest of GNU Radio in order to avoid problems for people who have begun
+to write blocks with a modified copy of gr-howto-write-a-block.
+
+This package requires that gnuradio-core is already installed.  It
+also depends on some GNU Radio prerequisites, such as Boost and
+cppunit.
+
+To build the examples from the tarball use the normal recipe:
+
+  $ ./configure
+  $ make
+  $ make check
+
+If you're building from git, you'll need to use this sequence, since
+git doesn't contain configure or the generated Makefiles.
+
+  $ ./bootstrap
+  $ ./configure
+  $ make
+  $ make check
diff --git a/gr-howto-write-a-block/README.hacking b/gr-howto-write-a-block/README.hacking
new file mode 100644 (file)
index 0000000..c670fd1
--- /dev/null
@@ -0,0 +1,95 @@
+#
+# Copyright 2009 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.
+# 
+
+The layout of this tree is as follows. The top-level directory contains
+the autoconf/automake build definition files:
+
+bootstrap
+config.guess
+config.sub
+configure.ac
+Makefile.am
+Makefile.common
+Makefile.swig
+Makefile.swig.gen.t
+version.sh
+
+Of these files, only configure.ac, Makefile.am, and Makefile.common  would
+likely need changing in order to customize this into a new out-of-tree
+project.
+
+Subdirectory Layout
+-------------------
+
+config  - autoconf configuration macros
+lib     - GNU Radio blocks C++ API, shared lib and headers and QA code
+swig    - Generates Python API from C++ blocks
+python  - Pure Python modules (hierarchical blocks, other classes)
+grc     - GNU Radio Companion block wrappers
+apps    - GRC applications, scripts, or other executables installed to bin
+
+The 'config' directory contains autoconf configuration files which help the
+configuration script discover various things about the software development
+environment during the execution of the 'configure' script.  These files
+would likely not need any changing to customize this tree.
+
+The 'lib' directory contains those files needed to generate GNU Radio
+signal processing blocks.  These take the form of a shared library that one
+dynamically links against, and header files that one would include in
+their C++ GNU Radio application.  This directory also contains the framework
+for adding QA tests that are executed during 'make check' using the cppunit
+unit testing framework.  The generated shared library is installed into
+$prefix/lib and the header files are installed into $prefix/include/gnuradio.
+
+Adding new blocks starts here, by adding new .cc and new .h files for each
+new block, and modifying Makefile.am to add them to the build and link.  If
+desired, one can add unit tests to the QA framework that get executed during
+'make check'.
+
+The 'swig' directory contains the SWIG machinery to create a Python module
+that exports the C++ API into a Python namespace.  Each GNU Radio block gets a
+.i file (using SWIG syntax).  The master howto.i file must also have a line
+to include the block header file and a line to import the block .i file. The
+resulting _howto_swig.so and _howto_swig.py files are installed into the
+system Python lib directory under gnuradio/howto and become part of the
+gnuradio.howto Python namespace.  The Makefile.am must be customized to
+recognize new files created here.
+
+The 'python' directory contains pure Python modules that get installed into
+the system Python lib directory under gnuradio/howto and the __init__.py
+module needed to turn the directory into the gnuradio.howto namespace.
+This is the appropriate place to put hierarchical blocks and utility classes.
+Be sure to edit the __init__.py to add your module/symbol imports as
+necessary, and to modify the Makefile.am accordingly.
+
+This directory also contains Python-based QA code, which is executed during
+'make check'.
+
+The 'grc' directory contains the XML-based wrappers that describe your blocks
+to the GNU Radio Companion graphical flowgraph editor.  These get installed
+into the $prefix/share/gnuradio/grc/blocks directory and require modification
+of the Makefile.am to recognize new files put here.  Note: GRC only scans the
+system directory for wrapper files, so you must do a 'make install' before
+GRC will see your new files or modifications to existing ones.
+
+The 'apps' directory contains those Python and C++ programs which are to be
+installed into the system $prefix/bin directory. (FIXME: there is not
+currently an example of building a C++ binary in this directory.)
diff --git a/gr-howto-write-a-block/apps/.gitignore b/gr-howto-write-a-block/apps/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-howto-write-a-block/apps/Makefile.am b/gr-howto-write-a-block/apps/Makefile.am
new file mode 100644 (file)
index 0000000..85ed222
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+if PYTHON
+
+dist_bin_SCRIPTS = \
+       howto_square.py
+
+EXTRA_DIST = \
+       howto_square.grc
+
+endif
diff --git a/gr-howto-write-a-block/apps/howto_square.grc b/gr-howto-write-a-block/apps/howto_square.grc
new file mode 100644 (file)
index 0000000..a856369
--- /dev/null
@@ -0,0 +1,325 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Nov 12 11:26:07 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>howto_square</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>10e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 170)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Input</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0.002</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(691, 222)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>howto_square_ff</key>
+    <param>
+      <key>id</key>
+      <value>sqr</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(709, 344)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>thr</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(497, 340)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_vector_source_x</key>
+    <param>
+      <key>id</key>
+      <value>src</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>vector</key>
+      <value>[float(n)-50 for n in range(100)]</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(246, 332)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>sink2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Output</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0.002</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(869, 324)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>thr</source_block_id>
+    <sink_block_id>sqr</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>src</source_block_id>
+    <sink_block_id>thr</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>thr</source_block_id>
+    <sink_block_id>sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>sqr</source_block_id>
+    <sink_block_id>sink2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-howto-write-a-block/apps/howto_square.py b/gr-howto-write-a-block/apps/howto_square.py
new file mode 100755 (executable)
index 0000000..f14e283
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Howto Square
+# Generated: Thu Nov 12 11:26:07 2009
+##################################################
+
+import howto
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import wx
+
+class howto_square(grc_wxgui.top_block_gui):
+
+       def __init__(self):
+               grc_wxgui.top_block_gui.__init__(self, title="Howto Square")
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.samp_rate = samp_rate = 10e3
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.sink = scopesink2.scope_sink_f(
+                       self.GetWin(),
+                       title="Input",
+                       sample_rate=samp_rate,
+                       v_scale=20,
+                       v_offset=0,
+                       t_scale=0.002,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.Add(self.sink.win)
+               self.sink2 = scopesink2.scope_sink_f(
+                       self.GetWin(),
+                       title="Output",
+                       sample_rate=samp_rate,
+                       v_scale=0,
+                       v_offset=0,
+                       t_scale=0.002,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.Add(self.sink2.win)
+               self.sqr = howto.square_ff()
+               self.src = gr.vector_source_f(([float(n)-50 for n in range(100)]), True, 1)
+               self.thr = gr.throttle(gr.sizeof_float*1, samp_rate)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.thr, 0), (self.sqr, 0))
+               self.connect((self.src, 0), (self.thr, 0))
+               self.connect((self.thr, 0), (self.sink, 0))
+               self.connect((self.sqr, 0), (self.sink2, 0))
+
+       def set_samp_rate(self, samp_rate):
+               self.samp_rate = samp_rate
+               self.sink.set_sample_rate(self.samp_rate)
+               self.sink2.set_sample_rate(self.samp_rate)
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       (options, args) = parser.parse_args()
+       tb = howto_square()
+       tb.Run(True)
+
diff --git a/gr-howto-write-a-block/bootstrap b/gr-howto-write-a-block/bootstrap
new file mode 100755 (executable)
index 0000000..2412a7a
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Copyright 2001,2005,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+
+rm -fr config.cache autom4te*.cache
+
+aclocal -I config
+autoconf
+autoheader
+libtoolize --automake -c -f
+automake --add-missing -c -f -Wno-portability
diff --git a/gr-howto-write-a-block/config.guess b/gr-howto-write-a-block/config.guess
new file mode 100755 (executable)
index 0000000..f32079a
--- /dev/null
@@ -0,0 +1,1526 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2008-01-23'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           sh5el) machine=sh5le-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       # Debian GNU/NetBSD machines have a different userland, and
+       # thus, need a distinct triplet. However, they do not need
+       # kernel version information, so it can be replaced with a
+       # suitable tag, in the style of linux-gnu.
+       case "${UNAME_VERSION}" in
+           Debian*)
+               release='-gnu'
+               ;;
+           *)
+               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               ;;
+       esac
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit ;;
+    *:OpenBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+       exit ;;
+    *:ekkoBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       exit ;;
+    *:SolidBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       exit ;;
+    macppc:MirBSD:*:*)
+       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    *:MirBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    alpha:OSF1:*:*)
+       case $UNAME_RELEASE in
+       *4.0)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+               ;;
+       *5.*)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               ;;
+       esac
+       # According to Compaq, /usr/sbin/psrinfo has been available on
+       # OSF/1 and Tru64 systems produced since 1995.  I hope that
+       # covers most systems running today.  This code pipes the CPU
+       # types through head -n 1, so we only detect the type of CPU 0.
+       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+       case "$ALPHA_CPU_TYPE" in
+           "EV4 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "EV4.5 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "LCA4 (21066/21068)")
+               UNAME_MACHINE="alpha" ;;
+           "EV5 (21164)")
+               UNAME_MACHINE="alphaev5" ;;
+           "EV5.6 (21164A)")
+               UNAME_MACHINE="alphaev56" ;;
+           "EV5.6 (21164PC)")
+               UNAME_MACHINE="alphapca56" ;;
+           "EV5.7 (21164PC)")
+               UNAME_MACHINE="alphapca57" ;;
+           "EV6 (21264)")
+               UNAME_MACHINE="alphaev6" ;;
+           "EV6.7 (21264A)")
+               UNAME_MACHINE="alphaev67" ;;
+           "EV6.8CB (21264C)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8AL (21264B)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8CX (21264D)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.9A (21264/EV69A)")
+               UNAME_MACHINE="alphaev69" ;;
+           "EV7 (21364)")
+               UNAME_MACHINE="alphaev7" ;;
+           "EV7.9 (21364A)")
+               UNAME_MACHINE="alphaev79" ;;
+       esac
+       # A Pn.n version is a patched version.
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit ;;
+    *:z/VM:*:*)
+       echo s390-ibm-zvmoe
+       exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+       exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+       echo arm-unknown-riscos
+       exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit ;;
+    DRS?6000:unix:4.0:6*)
+       echo sparc-icl-nx6
+       exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7; exit ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+       echo m68k-apple-machten${UNAME_RELEASE}
+       exit ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c &&
+         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+         SYSTEM_NAME=`$dummy $dummyarg` &&
+           { echo "$SYSTEM_NAME"; exit; }
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+               then
+                       echo "$SYSTEM_NAME"
+               else
+                       echo rs6000-ibm-aix3.2.5
+               fi
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit ;;
+    *:AIX:*:[456])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   test -z "$HP_ARCH" && HP_ARCH=hppa
+               fi ;;
+       esac
+       if [ ${HP_ARCH} = "hppa2.0w" ]
+       then
+           eval $set_cc_for_build
+
+           # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+           # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+           # generating 64-bit code.  GNU and HP use different nomenclature:
+           #
+           # $ CC_FOR_BUILD=cc ./config.guess
+           # => hppa2.0w-hp-hpux11.23
+           # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+           # => hppa64-hp-hpux11.23
+
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+               grep __LP64__ >/dev/null
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+               { echo "$SYSTEM_NAME"; exit; }
+       echo unknown-hitachi-hiuxwe2
+       exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    *:UNICOS/mp:*:*)
+       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:FreeBSD:*:*)
+       case ${UNAME_MACHINE} in
+           pc98)
+               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           amd64)
+               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           *)
+               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       esac
+       exit ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit ;;
+    *:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit ;;
+    i*:windows32*:*)
+       # uname -m includes "-pc" on this system.
+       echo ${UNAME_MACHINE}-mingw32
+       exit ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit ;;
+    *:Interix*:[3456]*)
+       case ${UNAME_MACHINE} in
+           x86)
+               echo i586-pc-interix${UNAME_RELEASE}
+               exit ;;
+           EM64T | authenticamd)
+               echo x86_64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+           IA64)
+               echo ia64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+       esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i586-pc-interix
+       exit ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+       echo x86_64-unknown-cygwin
+       exit ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    *:GNU:*:*)
+       # the GNU system
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit ;;
+    *:GNU/*:*:*)
+       # other systems with GNU libc and userland
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       exit ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit ;;
+    arm*:Linux:*:*)
+       eval $set_cc_for_build
+       if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+           | grep -q __ARM_EABI__
+       then
+           echo ${UNAME_MACHINE}-unknown-linux-gnu
+       else
+           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+       fi
+       exit ;;
+    avr32*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    cris:Linux:*:*)
+       echo cris-axis-linux-gnu
+       exit ;;
+    crisv32:Linux:*:*)
+       echo crisv32-axis-linux-gnu
+       exit ;;
+    frv:Linux:*:*)
+       echo frv-unknown-linux-gnu
+       exit ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m32r*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       ;;
+    mips64:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips64
+       #undef mips64el
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mips64el
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips64
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       ;;
+    or32:Linux:*:*)
+       echo or32-unknown-linux-gnu
+       exit ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit ;;
+    sh64*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    vax:Linux:*:*)
+       echo ${UNAME_MACHINE}-dec-linux-gnu
+       exit ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit ;;
+    xtensa*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^LIBC/{
+               s: ::g
+               p
+           }'`"
+       test x"${LIBC}" != x && {
+               echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+               exit
+       }
+       test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit ;;
+    i*86:syllable:*:*)
+       echo ${UNAME_MACHINE}-pc-syllable
+       exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit ;;
+    i*86:*:5:[678]*)
+       # UnixWare 7.x, OpenUNIX and OpenServer 6.
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit ;;
+    M68*:*:R3V[5678]*:*)
+       test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit ;;
+    i*86:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo ${UNAME_MACHINE}-stratus-vos
+       exit ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-7:SUPER-UX:*:*)
+       echo sx7-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8:SUPER-UX:*:*)
+       echo sx8-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8R:SUPER-UX:*:*)
+       echo sx8r-nec-superux${UNAME_RELEASE}
+       exit ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Darwin:*:*)
+       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+       case $UNAME_PROCESSOR in
+           unknown) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+       echo nse-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+       exit ;;
+    *:DragonFly:*:*)
+       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit ;;
+    *:*VMS:*:*)
+       UNAME_MACHINE=`(uname -p) 2>/dev/null`
+       case "${UNAME_MACHINE}" in
+           A*) echo alpha-dec-vms ; exit ;;
+           I*) echo ia64-dec-vms ; exit ;;
+           V*) echo vax-dec-vms ; exit ;;
+       esac ;;
+    *:XENIX:*:SysV)
+       echo i386-pc-xenix
+       exit ;;
+    i*86:skyos:*:*)
+       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+       exit ;;
+    i*86:rdos:*:*)
+       echo ${UNAME_MACHINE}-pc-rdos
+       exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+       { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit ;;
+    c34*)
+       echo c34-convex-bsd
+       exit ;;
+    c38*)
+       echo c38-convex-bsd
+       exit ;;
+    c4*)
+       echo c4-convex-bsd
+       exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/gr-howto-write-a-block/config.sub b/gr-howto-write-a-block/config.sub
new file mode 100755 (executable)
index 0000000..6759825
--- /dev/null
@@ -0,0 +1,1658 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2008-01-16'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis | -knuth | -cray)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco6)
+               os=-sco5v6
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5v6*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | am33_2.0 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+       | bfin \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fido | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32c | m32r | m32rle | m68000 | m68k | m88k \
+       | maxq | mb | microblaze | mcore | mep \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mips64vr5900 | mips64vr5900el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | mt \
+       | msp430 \
+       | nios | nios2 \
+       | ns16k | ns32k \
+       | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | score \
+       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+       | spu | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+       ms1)
+               basic_machine=mt-unknown
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* | avr32-* \
+       | bfin-* | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | craynv-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | m32c-* | m32r-* | m32rle-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mips64vr5900-* | mips64vr5900el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | mmix-* \
+       | mt-* \
+       | msp430-* \
+       | nios-* | nios2-* \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+       | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | xstormy16-* | xtensa*-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the basic CPU types without company name, with glob match.
+       xtensa*)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       abacus)
+               basic_machine=abacus-unknown
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amd64)
+               basic_machine=x86_64-pc
+               ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       blackfin)
+               basic_machine=bfin-unknown
+               os=-linux
+               ;;
+       blackfin-*)
+               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       craynv)
+               basic_machine=craynv-cray
+               os=-unicosmp
+               ;;
+       cr16)
+               basic_machine=cr16-unknown
+               os=-elf
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       crisv32 | crisv32-* | etraxfs*)
+               basic_machine=crisv32-axis
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       crx)
+               basic_machine=crx-unknown
+               os=-elf
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       djgpp)
+               basic_machine=i586-pc
+               os=-msdosdjgpp
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m68knommu)
+               basic_machine=m68k-unknown
+               os=-linux
+               ;;
+       m68knommu-*)
+               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       mingw32ce)
+               basic_machine=arm-unknown
+               os=-mingw32ce
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       ms1-*)
+               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       openrisc | openrisc-*)
+               basic_machine=or32-unknown
+               ;;
+       os400)
+               basic_machine=powerpc-ibm
+               os=-os400
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       parisc)
+               basic_machine=hppa-unknown
+               os=-linux
+               ;;
+       parisc-*)
+               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pc98)
+               basic_machine=i386-pc
+               ;;
+       pc98-*)
+               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2 | pentiumiii | pentium3)
+               basic_machine=i686-pc
+               ;;
+       pentium4)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium4-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rdos)
+               basic_machine=i386-pc
+               os=-rdos
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sde)
+               basic_machine=mipsisa32-sde
+               os=-elf
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sh5el)
+               basic_machine=sh5le-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tic55x | c55x*)
+               basic_machine=tic55x-unknown
+               os=-coff
+               ;;
+       tic6x | c6x*)
+               basic_machine=tic6x-unknown
+               os=-coff
+               ;;
+       tile*)
+               basic_machine=tile-unknown
+               os=-linux-gnu
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       tpf)
+               basic_machine=s390x-ibm
+               os=-tpf
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xbox)
+               basic_machine=i686-pc
+               os=-mingw32
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       mmix)
+               basic_machine=mmix-knuth
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -openbsd* | -solidbsd* \
+             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto-qnx*)
+               ;;
+       -nto*)
+               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux-dietlibc)
+               os=-linux-dietlibc
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+        -os400*)
+               os=-os400
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -syllable*)
+               os=-syllable
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+        -tpf*)
+               os=-tpf
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -aros*)
+               os=-aros
+               ;;
+       -kaos*)
+               os=-kaos
+               ;;
+       -zvmoe)
+               os=-zvmoe
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+               os=-elf
+               ;;
+        spu-*)
+               os=-elf
+               ;;
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        c4x-* | tic4x-*)
+               os=-coff
+               ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+        mep-*)
+               os=-elf
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-haiku)
+               os=-haiku
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-knuth)
+               os=-mmixware
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -os400*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -tpf*)
+                               vendor=ibm
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/gr-howto-write-a-block/config/.gitignore b/gr-howto-write-a-block/config/.gitignore
new file mode 100644 (file)
index 0000000..16f775e
--- /dev/null
@@ -0,0 +1,15 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/libtool.m4
+/lt~obsolete.m4
+/ltsugar.m4
+/ltversion.m4
+/ltoptions.m4
diff --git a/gr-howto-write-a-block/config/Makefile.am b/gr-howto-write-a-block/config/Makefile.am
new file mode 100644 (file)
index 0000000..23f4a4b
--- /dev/null
@@ -0,0 +1,83 @@
+#
+# Copyright 2001 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install m4 macros in this directory
+m4datadir = $(datadir)/aclocal
+
+# List your m4 macros here
+m4macros = \
+       acx_pthread.m4 \
+       ax_boost_base.m4 \
+       ax_boost_date_time.m4 \
+       ax_boost_filesystem.m4 \
+       ax_boost_iostreams.m4 \
+       ax_boost_program_options.m4 \
+       ax_boost_python.m4 \
+       ax_boost_regex.m4 \
+       ax_boost_serialization.m4 \
+       ax_boost_signals.m4 \
+       ax_boost_system.m4 \
+       ax_boost_test_exec_monitor.m4 \
+       ax_boost_thread.m4 \
+       ax_boost_unit_test_framework.m4 \
+       ax_boost_wserialization.m4 \
+       bnv_have_qt.m4 \
+       cppunit.m4 \
+       gr_check_createfilemapping.m4 \
+       gr_check_mc4020.m4 \
+       gr_check_shm_open.m4 \
+       gr_check_usrp.m4 \
+       gr_doxygen.m4 \
+       gr_fortran.m4 \
+       gr_git.m4 \
+       gr_gprof.m4 \
+       gr_lib64.m4 \
+       gr_libgnuradio_core_extra_ldflags.m4 \
+       gr_no_undefined.m4 \
+       gr_omnithread.m4 \
+       gr_pwin32.m4 \
+       gr_python.m4 \
+       gr_require_mc4020.m4 \
+       gr_scripting.m4 \
+       gr_set_md_cpu.m4 \
+       gr_standalone.m4 \
+       gr_subversion.m4 \
+       gr_swig.m4 \
+       gr_sysv_shm.m4 \
+       gr_version.m4 \
+       lf_cc.m4 \
+       lf_cxx.m4 \
+       lf_warnings.m4 \
+       lf_x11.m4 \
+       mkstemp.m4 \
+       onceonly.m4 \
+       pkg.m4 \
+       usrp_fusb_tech.m4 \
+       usrp_libusb.m4 \
+       usrp_sdcc.m4
+
+
+# Don't install m4 macros anymore
+# m4data_DATA = $(m4macros) 
+
+EXTRA_DIST = $(m4macros) 
diff --git a/gr-howto-write-a-block/config/acx_pthread.m4 b/gr-howto-write-a-block/config/acx_pthread.m4
new file mode 100644 (file)
index 0000000..eb09f5a
--- /dev/null
@@ -0,0 +1,275 @@
+# ===========================================================================
+#              http://autoconf-archive.cryp.to/acx_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#          LIBS="$PTHREAD_LIBS $LIBS"
+#          CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#          CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#
+#   This program 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 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+               pthread-config)
+               AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+               if test x"$acx_pthread_config" = xno; then continue; fi
+               PTHREAD_CFLAGS="`pthread-config --cflags`"
+               PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+               ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+       AC_MSG_CHECKING([for joinable pthread attribute])
+       attr_name=unknown
+       for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+           AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+       done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with xlc_r or cc_r
+       if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+       fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/gr-howto-write-a-block/config/ax_boost_base.m4 b/gr-howto-write-a-block/config/ax_boost_base.m4
new file mode 100644 (file)
index 0000000..e979022
--- /dev/null
@@ -0,0 +1,334 @@
+# ===========================================================================
+#             http://autoconf-archive.cryp.to/ax_boost_base.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_BASE([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+#   Test for the Boost C++ libraries of a particular version (or newer)
+#
+#   If no path to the installed boost library is given the macro searchs
+#   under /usr, /usr/local, /opt and /opt/local and evaluates the
+#   $BOOST_ROOT environment variable. Further documentation is available at
+#   <http://randspringer.de/boost/index.html>.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+#   And sets:
+#
+#     HAVE_BOOST
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_REQUIRE([GR_LIB64])
+AC_ARG_WITH([boost],
+    AS_HELP_STRING([--with-boost@<:@=DIR@:>@],
+                  [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
+    [
+    if test "$withval" = "no"; then
+        want_boost="no"
+    elif test "$withval" = "yes"; then
+        want_boost="yes"
+        ac_boost_path=""
+    else
+        want_boost="yes"
+        ac_boost_path="$withval"
+    fi
+    ],
+    [want_boost="yes"])
+
+
+AC_ARG_WITH([boost-libdir],
+        AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
+                      [Force given directory for boost libraries. Note that this
+                       will overwrite library path detection, so use this parameter
+                       only if default library detection fails and you know exactly
+                        where your boost libraries are located.]),
+        [
+        if test -d $withval
+        then
+                ac_boost_lib_path="$withval"
+        else
+                AC_MSG_ERROR(--with-boost-libdir expected directory name)
+        fi
+        ],
+        [ac_boost_lib_path=""]
+)
+
+if test "x$want_boost" = "xyes"; then
+    boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+    boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
+    boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
+    boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
+    boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+    if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+        boost_lib_version_req_sub_minor="0"
+        fi
+    WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+  $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+    AC_MSG_CHECKING(for boost >= $boost_lib_version_req)
+    succeeded=no
+
+    dnl first we check the system location for boost libraries
+    dnl this location ist chosen if boost libraries are installed with the --layout=system option
+    dnl or if you install boost with RPM
+    if test "$ac_boost_path" != ""; then
+       dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib.
+       dnl If that directory doesn't exist, fall back to the default behavior
+       if test -d "$ac_boost_path/lib${gr_libdir_suffix}"; then
+            BOOST_LDFLAGS="-L$ac_boost_path/lib${gr_libdir_suffix}"
+        else
+            BOOST_LDFLAGS="-L$ac_boost_path/lib"
+        fi
+        BOOST_CPPFLAGS="-I$ac_boost_path/include"
+    else
+        for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+            if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+               dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib.
+               dnl If that directory doesn't exist, fall back to the default behavior
+               if test -d "$ac_boost_path_tmp/lib${gr_libdir_suffix}"; then
+                    BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib${gr_libdir_suffix}"
+               else
+                   BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
+               fi
+                BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+                break;
+            fi
+        done
+    fi
+
+    dnl overwrite ld flags if we have required special directory with
+    dnl --with-boost-libdir parameter
+    if test "$ac_boost_lib_path" != ""; then
+       BOOST_LDFLAGS="-L$ac_boost_lib_path"
+    fi
+
+    CPPFLAGS_SAVED="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+    export CPPFLAGS
+
+    LDFLAGS_SAVED="$LDFLAGS"
+    LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+    export LDFLAGS
+
+    AC_LANG_PUSH(C++)
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+    @%:@include <boost/version.hpp>
+    ]], [[
+    #if BOOST_VERSION >= $WANT_BOOST_VERSION
+    // Everything is okay
+    #else
+    #  error Boost version is too old
+    #endif
+    ]])],[AC_MSG_RESULT(yes)
+         succeeded=yes
+         found_system=yes
+          ],
+         [])
+    AC_LANG_POP([C++])
+    CPPFLAGS="$CPPFLAGS_SAVED"
+    LDFLAGS="$LDFLAGS_SAVED"
+
+
+    dnl if we found no boost with system layout we search for boost libraries
+    dnl built and installed without the --layout=system option
+    if test "$succeeded" != "yes"; then
+        _version=0
+
+        if test "$ac_boost_path" != ""; then
+           path_list="$ac_boost_path"
+       else
+           path_list="/usr /usr/local /opt /opt/local"
+       fi
+        for ac_boost_path in $path_list ; do
+           if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+               for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+                   _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's,/include/boost-,,; s,_,.,'`
+                    V_CHECK=`expr $_version_tmp \> $_version`
+                    if test "$V_CHECK" = "1" ; then
+                        _version=$_version_tmp
+                        best_path=$ac_boost_path
+                   fi
+                done
+            fi
+       done
+
+        VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+        BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+
+        if test "$ac_boost_lib_path" = "";  then
+           dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib.
+           dnl If that directory doesn't exist, fall back to the default behavior
+           if test -d "$best_path/lib${gr_libdir_suffix}"; then
+                BOOST_LDFLAGS="-L$best_path/lib${gr_libdir_suffix}"
+           else
+                BOOST_LDFLAGS="-L$best_path/lib"
+           fi
+        fi
+
+        CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+        export CPPFLAGS
+        LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+        export LDFLAGS
+
+        AC_LANG_PUSH(C++)
+            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        @%:@include <boost/version.hpp>
+        ]], [[
+        #if BOOST_VERSION >= $WANT_BOOST_VERSION
+        // Everything is okay
+        #else
+        #  error Boost version is too old
+        #endif
+        ]])],[AC_MSG_RESULT(yes)
+             succeeded=yes
+              found_system=yes
+              ],
+            [])
+        AC_LANG_POP([C++])
+        CPPFLAGS="$CPPFLAGS_SAVED"
+        LDFLAGS="$LDFLAGS_SAVED"
+    fi
+
+    if test "$succeeded" != "yes" ; then
+       AC_MSG_RESULT([no])
+        if test "$_version" = "0" ; then
+            AC_MSG_ERROR([[we could not detect the boost libraries (version $boost_lib_version_req_shorten or higher).
+If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>.]])
+        else
+            AC_MSG_ERROR([your boost libraries seem to old (version $_version).])
+        fi
+    else
+        AC_SUBST(BOOST_CPPFLAGS)
+        AC_SUBST(BOOST_LDFLAGS)
+        AC_DEFINE(HAVE_BOOST,1,[Define if the Boost headers are available])
+    fi
+fi
+])
+
+dnl
+dnl Macros used by the boost items that need libraries.
+dnl
+
+dnl $1 is unit name.  E.g., boost_thread
+AC_DEFUN([_AX_BOOST_CHECK_LIB],[
+    _AX_BOOST_CHECK_LIB_($1,HAVE_[]m4_toupper($1),m4_toupper($1)_LIB)
+])
+
+dnl $1 is unit name.  E.g., boost_thread
+dnl $2 is AC_DEFINE name.  E.g., HAVE_BOOST_THREAD
+dnl $3 is lib var name.    E.g., BOOST_THREAD_LIB
+AC_DEFUN([_AX_BOOST_CHECK_LIB_],[
+    AC_LANG_PUSH([C++])
+    AC_DEFINE($2,1,[Define if the $1 library is available])
+    BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+    dnl See if we can find a usable library
+    link_ok="no"
+    if test "$ax_boost_user_lib" != ""; then
+        dnl use what the user supplied 
+        for ax_lib in $ax_boost_user_lib $1-${ax_boost_user_lib}; do
+           AC_CHECK_LIB($ax_lib, exit,
+                         [$3="-l$ax_lib"; AC_SUBST($3) link_ok="yes"; break])
+        done
+    else
+       dnl Look in BOOSTLIBDIR for possible candidates
+       head=$BOOSTLIBDIR/lib[]$1
+       for f in ${head}*.so* ${head}*.a* ${head}*.dll* ${head}*.dylib; do
+           dnl echo 1: $f
+           case $f in
+             *\**) continue;;
+           esac
+           f=`echo $f | sed -e 's,.*/,,' -e 's,^lib,,'`
+           dnl echo 2: $f
+           f=`echo $f | sed -e 's,\($1.*\)\.so.*$,\1,' -e 's,\($1.*\)\.a.*$,\1,' -e 's,\($1.*\)\.dll.*$,\1,' -e 's,\($1.*\)\.dylib.*$,\1,'`
+           dnl echo 3: $f
+
+           ax_lib=$f
+            AC_CHECK_LIB($ax_lib, exit,
+                        [$3="-l$ax_lib"; AC_SUBST($3) link_ok="yes"; break])
+       done
+    fi             
+                                   
+    if test "$link_ok" != "yes"; then
+       AC_MSG_ERROR([Could not link against lib[$1]!])
+    fi
+    AC_LANG_POP([C++])
+])
+
+
+dnl $1 is unit name.  E.g., boost_thread
+AC_DEFUN([_AX_BOOST_WITH],[
+    _AX_BOOST_WITH_($1,m4_bpatsubst($1,_,-))
+])
+
+dnl $1 is unit name.  E.g., boost_thread
+dnl $2 is hyphenated unit name.  E.g., boost-thread
+AC_DEFUN([_AX_BOOST_WITH_],[
+    AC_ARG_WITH([$2],
+               AC_HELP_STRING([--with-$2@<:@=special-lib@:>@],
+                              [Use the m4_substr($1,6) library from boost.  It is possible to specify a certain
+                               library to the linker.  E.g., --with-$2=$1-gcc41-mt-1_35]),
+               [
+               if test "$withval" = "no"; then
+                   want_boost="no"
+               elif test "$withval" = "yes"; then
+                   want_boost="yes"
+                   ax_boost_user_lib=""
+               else
+                   want_boost="yes"
+                   ax_boost_user_lib="$withval"
+               fi
+               ],
+               [want_boost="yes"])
+])
+
+dnl $1 is unit name.  E.g., boost_thread
+dnl $2 is AC_LANG_PROGRAM argument 1
+dnl $3 is AC_LANG_PROGRAM argument 2
+dnl $4 is cv variable name.  E.g., ax_cv_boost_thread
+AC_DEFUN([_AX_BOOST_CHECK_],[
+    _AX_BOOST_WITH($1)
+    if test "$want_boost" = "yes"; then
+        AC_REQUIRE([AC_PROG_CC])
+        AC_REQUIRE([AC_PROG_CXX])
+        CPPFLAGS_SAVED="$CPPFLAGS"
+        CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+        LDFLAGS_SAVED="$LDFLAGS"
+        LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+        AC_CACHE_CHECK([whether the boost::m4_substr([$1],6) includes are available], [$4],
+                      [AC_LANG_PUSH([C++])
+                        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([$2],[$3]),[$4]=yes,[$4]=no)
+                        AC_LANG_POP([C++])
+                       ])
+       if test "$[$4]" = "yes"; then
+           _AX_BOOST_CHECK_LIB([$1])
+       fi
+        CPPFLAGS="$CPPFLAGS_SAVED"
+        LDFLAGS="$LDFLAGS_SAVED"
+    fi
+])
+
+dnl $1 is unit name.  E.g., boost_thread
+dnl $2 is AC_LANG_PROGRAM argument 1
+dnl $3 is AC_LANG_PROGRAM argument 2
+AC_DEFUN([_AX_BOOST_CHECK],[
+    _AX_BOOST_CHECK_($1,$2,$3,ax_cv_$1)
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_date_time.m4 b/gr-howto-write-a-block/config/ax_boost_date_time.m4
new file mode 100644 (file)
index 0000000..7b3f0fe
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_DATE_TIME
+#
+# DESCRIPTION
+#
+#   Test for date_time library from the Boost C++ libraries.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_DATE_TIME_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_DATE_TIME
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_DATE_TIME],
+[
+    AC_REQUIRE([AX_BOOST_BASE])        
+    _AX_BOOST_CHECK([boost_date_time],
+                   [@%:@include <boost/date_time/gregorian/gregorian_types.hpp>],
+                   [using namespace boost::gregorian; date d(2002,Jan,10); return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_filesystem.m4 b/gr-howto-write-a-block/config/ax_boost_filesystem.m4
new file mode 100644 (file)
index 0000000..bcb3fa4
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_FILESYSTEM
+#
+# DESCRIPTION
+#
+#   Test for Filesystem library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE. 
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_FILESYSTEM_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_FILESYSTEM
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_FILESYSTEM],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+
+    dnl depends on boost_system
+    AC_REQUIRE([AX_BOOST_SYSTEM])
+    axbf_LDFLAGS_SAVED=$LDFLAGS
+    LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LIB"
+
+    _AX_BOOST_CHECK([boost_filesystem],
+                   [@%:@include <boost/filesystem/path.hpp>],
+                   [using namespace boost::filesystem;
+                     path my_path( "foo/bar/data.txt" );
+                     return 0;])
+
+   LDFLAGS=$axbf_LDFLAGS_SAVED
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_iostreams.m4 b/gr-howto-write-a-block/config/ax_boost_iostreams.m4
new file mode 100644 (file)
index 0000000..181b1e7
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_IOSTREAMS
+#
+# DESCRIPTION
+#
+#   Test for IOStreams library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_IOSTREAMS_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_IOSTREAMS
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_IOSTREAMS],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_iostreams],
+                    [@%:@include <boost/iostreams/filtering_stream.hpp>
+                     @%:@include <boost/range/iterator_range.hpp>],
+                    [std::string  input = "Hello World!";
+                     namespace io = boost::iostreams;
+                     io::filtering_istream  in(boost::make_iterator_range(input));
+                     return 0;])
+
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_program_options.m4 b/gr-howto-write-a-block/config/ax_boost_program_options.m4
new file mode 100644 (file)
index 0000000..3829373
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_PROGRAM_OPTIONS
+#
+# DESCRIPTION
+#
+#   Test for program options library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_PROGRAM_OPTIONS
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_program_options],
+                    [@%:@include <boost/program_options.hpp>],
+                    [boost::program_options::options_description generic("Generic options");
+                     return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_python.m4 b/gr-howto-write-a-block/config/ax_boost_python.m4
new file mode 100644 (file)
index 0000000..3c6c666
--- /dev/null
@@ -0,0 +1,92 @@
+# ===========================================================================
+#            http://autoconf-archive.cryp.to/ax_boost_python.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_PYTHON
+#
+# DESCRIPTION
+#
+#   This macro checks to see if the Boost.Python library is installed. It
+#   also attempts to guess the currect library name using several attempts.
+#   It tries to build the library name using a user supplied name or suffix
+#   and then just the raw library.
+#
+#   If the library is found, HAVE_BOOST_PYTHON is defined and
+#   BOOST_PYTHON_LIB is set to the name of the library.
+#
+#   This macro calls AC_SUBST(BOOST_PYTHON_LIB).
+#
+#   In order to ensure that the Python headers are specified on the include
+#   path, this macro requires AX_PYTHON to be called.
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Michael Tindal
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([AX_BOOST_PYTHON],
+[AC_REQUIRE([AX_PYTHON])dnl
+AC_CACHE_CHECK(whether the Boost::Python library is available,
+ac_cv_boost_python,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ CPPFLAGS_SAVE=$CPPFLAGS
+ if test x$PYTHON_INCLUDE_DIR != x; then
+   CPPFLAGS=-I$PYTHON_INCLUDE_DIR $CPPFLAGS
+ fi
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
+ #include <boost/python/module.hpp>
+ using namespace boost::python;
+ BOOST_PYTHON_MODULE(test) { throw "Boost::Python test."; }]],
+               [[return 0;]]),
+               ac_cv_boost_python=yes, ac_cv_boost_python=no)
+ AC_LANG_RESTORE
+ CPPFLAGS=$CPPFLAGS_SAVE
+])
+if test "$ac_cv_boost_python" = "yes"; then
+  AC_LANG_PUSH([C++])
+  AC_DEFINE(HAVE_BOOST_PYTHON,,[define if the Boost::Python library is available])
+  ax_python_lib=boost_python
+  AC_ARG_WITH([boost-python],AS_HELP_STRING([--with-boost-python],[specify the boost python library or suffix to use]),
+  [if test "x$with_boost_python" != "xno"; then
+     ax_python_lib=$with_boost_python
+     ax_boost_python_lib=boost_python-$with_boost_python
+   fi])
+  for ax_lib in $ax_python_lib $ax_boost_python_lib boost_python; do
+    AC_CHECK_LIB($ax_lib, exit, [BOOST_PYTHON_LIB=$ax_lib break])
+  done
+  AC_SUBST(BOOST_PYTHON_LIB)
+  AC_LANG_POP([C++])
+fi
+])dnl
diff --git a/gr-howto-write-a-block/config/ax_boost_regex.m4 b/gr-howto-write-a-block/config/ax_boost_regex.m4
new file mode 100644 (file)
index 0000000..32b5313
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_REGEX
+#
+# DESCRIPTION
+#
+#   Test for Regex library from the Boost C++ libraries. The macro requires
+#   a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_REGEX_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_REGEX
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_REGEX],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_regex],
+                   [@%:@include <boost/regex.hpp>],
+                    [boost::regex r(); return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_serialization.m4 b/gr-howto-write-a-block/config/ax_boost_serialization.m4
new file mode 100644 (file)
index 0000000..78c9500
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_SERIALIZATION
+#
+# DESCRIPTION
+#
+#   Test for Serialization library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_SERIALIZATION_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_SERIALIZATION
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_SERIALIZATION],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_serialization],
+                   [@%:@include <fstream>
+                     @%:@include <boost/archive/text_oarchive.hpp>
+                     @%:@include <boost/archive/text_iarchive.hpp>],
+                    [std::ofstream ofs("filename");
+                     boost::archive::text_oarchive oa(ofs);
+                     return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_signals.m4 b/gr-howto-write-a-block/config/ax_boost_signals.m4
new file mode 100644 (file)
index 0000000..3c49717
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_SIGNALS
+#
+# DESCRIPTION
+#
+#   Test for Signals library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_SIGNALS_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_SIGNALS
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_SIGNALS],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_signals],
+                   [@%:@include <boost/signal.hpp>],
+                    [boost::signal<void ()> sig; return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_system.m4 b/gr-howto-write-a-block/config/ax_boost_system.m4
new file mode 100644 (file)
index 0000000..cb73f25
--- /dev/null
@@ -0,0 +1,40 @@
+# ===========================================================================
+# started with this: http://autoconf-archive.cryp.to/ax_boost_system.html,
+# virtually nothing left
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_SYSTEM
+#
+# DESCRIPTION
+#
+#   Test for System library from the Boost C++ libraries. The macro requires
+#   a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_SYSTEM_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_SYSTEM
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_SYSTEM],
+[
+    AC_REQUIRE([AX_BOOST_BASE])        
+    _AX_BOOST_CHECK([boost_system],
+                   [@%:@include <boost/system/error_code.hpp>],
+                   [boost::system::system_category])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_test_exec_monitor.m4 b/gr-howto-write-a-block/config/ax_boost_test_exec_monitor.m4
new file mode 100644 (file)
index 0000000..2c30c0b
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_TEST_EXEC_MONITOR
+#
+# DESCRIPTION
+#
+#   Test for Test_Exec_Monitor library from the Boost C++ libraries. The
+#   macro requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_TEST_EXEC_MONITOR
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Dodji Seketeli <dodji@seketeli.org>
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_TEST_EXEC_MONITOR],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_test_exec_monitor],
+                   [@%:@include <boost/test/test_tools.hpp>],
+                    [int i=1 ; BOOST_REQUIRE(i==1); ; return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_thread.m4 b/gr-howto-write-a-block/config/ax_boost_thread.m4
new file mode 100644 (file)
index 0000000..4df2322
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_THREAD
+#
+# DESCRIPTION
+#
+#   Test for Thread library from the Boost C++ libraries.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_THREAD_LIB)
+#     AC_SUBST(BOOST_CXXFLAGS)
+#
+#   And sets:
+#
+#     HAVE_BOOST_THREAD
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+
+AC_DEFUN([AX_BOOST_THREAD],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    AC_REQUIRE([ACX_PTHREAD])
+    _AX_BOOST_WITH([boost_thread])
+
+    if test "$want_boost" = "yes"; then
+        AC_REQUIRE([AC_PROG_CC])
+        AC_REQUIRE([AC_PROG_CXX])
+        AC_REQUIRE([AC_CANONICAL_HOST])
+
+        CPPFLAGS_SAVED="$CPPFLAGS"
+        LDFLAGS_SAVED="$LDFLAGS"
+       CXXFLAGS_SAVED="$CXXFLAGS"
+
+        CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+        LDFLAGS="$LDFLAGS $BOOST_LDFLAGS $PTHREAD_LIBS"
+       CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
+
+        AC_CACHE_CHECK(whether the boost::thread includes are available,
+                       ax_cv_boost_thread,
+        [AC_LANG_PUSH([C++])
+             AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]],
+                                   [[boost::thread_group thrds;
+                                   return 0;]]),
+                   ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
+             AC_LANG_POP([C++])
+        ])
+
+        if test "$ax_cv_boost_thread" = "yes"; then
+           BOOST_CXXFLAGS="$PTHREAD_CFLAGS"
+            AC_SUBST(BOOST_CXXFLAGS)
+           _AX_BOOST_CHECK_LIB([boost_thread])
+           if test "$link_ok" = "yes" && test -n "$PTHREAD_LIBS"; then
+               BOOST_THREAD_LIB="$BOOST_THREAD_LIB $PTHREAD_LIBS"
+           fi
+        fi
+
+        CPPFLAGS="$CPPFLAGS_SAVED"
+        LDFLAGS="$LDFLAGS_SAVED"
+       CXXFLAGS="$CXXFLAGS_SAVED"
+    fi
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_unit_test_framework.m4 b/gr-howto-write-a-block/config/ax_boost_unit_test_framework.m4
new file mode 100644 (file)
index 0000000..73affcc
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_UNIT_TEST_FRAMEWORK
+#
+# DESCRIPTION
+#
+#   Test for Unit_Test_Framework library from the Boost C++ libraries. The
+#   macro requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_UNIT_TEST_FRAMEWORK
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+    _AX_BOOST_CHECK([boost_unit_test_framework],
+                   [@%:@include <boost/test/unit_test.hpp>],
+                   [using boost::unit_test::test_suite;
+                     test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" );
+                     return 0;])
+])
diff --git a/gr-howto-write-a-block/config/ax_boost_wserialization.m4 b/gr-howto-write-a-block/config/ax_boost_wserialization.m4
new file mode 100644 (file)
index 0000000..f384988
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# SYNOPSIS
+#
+#   AX_BOOST_WSERIALIZATION
+#
+# DESCRIPTION
+#
+#   Test for WSerialization library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_WSERIALIZATION_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_WSERIALIZATION
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Free Software Foundation, Inc.
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_WSERIALIZATION],
+[
+    AC_REQUIRE([AX_BOOST_BASE])
+
+    dnl depends on BOOST_SERIALIZATION
+    AC_REQUIRE([AX_BOOST_SERIALIZATION])
+    axbws_LDFLAGS_SAVED=$LDFLAGS
+    LDFLAGS="$LDFLAGS $BOOST_SERIALIZATION_LIB"
+
+    _AX_BOOST_CHECK([boost_wserialization],
+                   [@%:@include <fstream>
+                     @%:@include <boost/archive/text_oarchive.hpp>
+                     @%:@include <boost/archive/text_iarchive.hpp>],
+                    [std::ofstream ofs("filename");
+                     boost::archive::text_oarchive oa(ofs);
+                     return 0;])
+
+    LDFLAGS=$axbf_LDFLAGS_SAVED
+])
diff --git a/gr-howto-write-a-block/config/bnv_have_qt.m4 b/gr-howto-write-a-block/config/bnv_have_qt.m4
new file mode 100644 (file)
index 0000000..1469bfb
--- /dev/null
@@ -0,0 +1,404 @@
+dnl Available from the GNU Autoconf Macro Archive at:
+dnl http://www.gnu.org/software/ac-archive/htmldoc/bnv_have_qt.html
+dnl
+AC_DEFUN([BNV_HAVE_QT],
+[
+  dnl THANKS! This code includes bug fixes by:
+  dnl Tim McClarren.
+
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_REQUIRE([AC_PATH_X])
+  AC_REQUIRE([AC_PATH_XTRA])
+
+  AC_MSG_CHECKING(for Qt)
+
+  AC_ARG_WITH([Qt-dir],
+    [  --with-Qt-dir=DIR       DIR is equal to \$QTDIR if you have followed the
+                          installation instructions of Trolltech. Header
+                          files are in DIR/include, binary utilities are
+                          in DIR/bin and the library is in DIR/lib])
+  AC_ARG_WITH([Qt-include-dir],
+    [  --with-Qt-include-dir=DIR
+                          Qt header files are in DIR])
+  AC_ARG_WITH([Qt-bin-dir],
+    [  --with-Qt-bin-dir=DIR   Qt utilities such as moc and uic are in DIR])
+  AC_ARG_WITH([Qt-lib-dir],
+    [  --with-Qt-lib-dir=DIR   The Qt library is in DIR])
+  AC_ARG_WITH([Qt-lib],
+    [  --with-Qt-lib=LIB       Use -lLIB to link with the Qt library])
+  if test x"$with_Qt_dir" = x"no" ||
+     test x"$with_Qt_include-dir" = x"no" ||
+     test x"$with_Qt_bin_dir" = x"no" ||
+     test x"$with_Qt_lib_dir" = x"no" ||
+     test x"$with_Qt_lib" = x"no"; then
+    # user disabled Qt. Leave cache alone.
+    have_qt="User disabled Qt."
+  else
+    # "yes" is a bogus option
+    if test x"$with_Qt_dir" = xyes; then
+      with_Qt_dir=
+    fi
+    if test x"$with_Qt_include_dir" = xyes; then
+      with_Qt_include_dir=
+    fi
+    if test x"$with_Qt_bin_dir" = xyes; then
+      with_Qt_bin_dir=
+    fi
+    if test x"$with_Qt_lib_dir" = xyes; then
+      with_Qt_lib_dir=
+    fi
+    if test x"$with_Qt_lib" = xyes; then
+      with_Qt_lib=
+    fi
+    # No Qt unless we discover otherwise
+    have_qt=no
+    # Check whether we are requested to link with a specific version
+    if test x"$with_Qt_lib" != x; then
+      bnv_qt_lib="$with_Qt_lib"
+    fi
+    # Check whether we were supplied with an answer already
+    if test x"$with_Qt_dir" != x; then
+      have_qt=yes
+      bnv_qt_dir="$with_Qt_dir"
+      bnv_qt_include_dir="$with_Qt_dir/include"
+      bnv_qt_bin_dir="$with_Qt_dir/bin"
+      bnv_qt_lib_dir="$with_Qt_dir/lib"
+      # Only search for the lib if the user did not define one already
+      if test x"$bnv_qt_lib" = x; then
+        bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p |
+                     sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`"
+      fi
+      bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+    else
+      # Use cached value or do search, starting with suggestions from
+      # the command line
+      AC_CACHE_VAL(bnv_cv_have_qt,
+      [
+        # We are not given a solution and there is no cached value.
+        bnv_qt_dir=NO
+        bnv_qt_include_dir=NO
+        bnv_qt_lib_dir=NO
+        if test x"$bnv_qt_lib" = x; then
+          bnv_qt_lib=NO
+        fi
+        BNV_PATH_QT_DIRECT
+        if test "$bnv_qt_dir" = NO ||
+           test "$bnv_qt_include_dir" = NO ||
+           test "$bnv_qt_lib_dir" = NO ||
+           test "$bnv_qt_lib" = NO; then
+          # Problem with finding complete Qt.  Cache the known absence of Qt.
+          bnv_cv_have_qt="have_qt=no"
+        else
+          # Record where we found Qt for the cache.
+          bnv_cv_have_qt="have_qt=yes                  \
+                       bnv_qt_dir=$bnv_qt_dir          \
+               bnv_qt_include_dir=$bnv_qt_include_dir  \
+                   bnv_qt_bin_dir=$bnv_qt_bin_dir      \
+                      bnv_qt_LIBS=\"$bnv_qt_LIBS\""
+        fi
+      ])dnl
+      eval "$bnv_cv_have_qt"
+    fi # all $bnv_qt_* are set
+  fi   # $have_qt reflects the system status
+  if test x"$have_qt" = xyes; then
+    QT_CXXFLAGS="-I$bnv_qt_include_dir"
+    QT_DIR="$bnv_qt_dir"
+    QT_LIBS="$bnv_qt_LIBS"
+    # If bnv_qt_dir is defined, utilities are expected to be in the
+    # bin subdirectory
+    if test x"$bnv_qt_dir" != x; then
+        if test -x "$bnv_qt_dir/bin/uic"; then
+          QT_UIC="$bnv_qt_dir/bin/uic"
+        else
+          # Old versions of Qt don't have uic
+          QT_UIC=
+        fi
+      QT_MOC="$bnv_qt_dir/bin/moc"
+    else
+      # Or maybe we are told where to look for the utilities
+      if test x"$bnv_qt_bin_dir" != x; then
+        if test -x "$bnv_qt_bin_dir/uic"; then
+          QT_UIC="$bnv_qt_bin_dir/uic"
+        else
+          # Old versions of Qt don't have uic
+          QT_UIC=
+        fi
+        QT_MOC="$bnv_qt_bin_dir/moc"
+      else
+      # Last possibility is that they are in $PATH
+        QT_UIC="`which uic`"
+        QT_MOC="`which moc`"
+      fi
+    fi
+    # All variables are defined, report the result
+    AC_MSG_RESULT([$have_qt:
+    QT_CXXFLAGS=$QT_CXXFLAGS
+    QT_DIR=$QT_DIR
+    QT_LIBS=$QT_LIBS
+    QT_UIC=$QT_UIC
+    QT_MOC=$QT_MOC])
+  else
+    # Qt was not found
+    QT_CXXFLAGS=
+    QT_DIR=
+    QT_LIBS=
+    QT_UIC=
+    QT_MOC=
+    AC_MSG_RESULT($have_qt)
+  fi
+  AC_SUBST(QT_CXXFLAGS)
+  AC_SUBST(QT_DIR)
+  AC_SUBST(QT_LIBS)
+  AC_SUBST(QT_UIC)
+  AC_SUBST(QT_MOC)
+
+  #### Being paranoid:
+  if test x"$have_qt" = xyes; then
+    AC_MSG_CHECKING(correct functioning of Qt installation)
+    AC_CACHE_VAL(bnv_cv_qt_test_result,
+    [
+      cat > bnv_qt_test.h << EOF
+#include <qobject.h>
+class Test : public QObject
+{
+Q_OBJECT
+public:
+  Test() {}
+  ~Test() {}
+public slots:
+  void receive() {}
+signals:
+  void send();
+};
+EOF
+
+      cat > bnv_qt_main.$ac_ext << EOF
+#include "bnv_qt_test.h"
+#include <qapplication.h>
+int main( int argc, char **argv )
+{
+  QApplication app( argc, argv );
+  Test t;
+  QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) );
+}
+EOF
+
+      bnv_cv_qt_test_result="failure"
+      bnv_try_1="$QT_MOC bnv_qt_test.h -o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_1.out"
+      AC_TRY_EVAL(bnv_try_1)
+      bnv_err_1=`grep -v '^ *+' bnv_qt_test_1.out | grep -v "^bnv_qt_test.h\$"`
+      if test x"$bnv_err_1" != x; then
+        echo "$bnv_err_1" >&AC_FD_CC
+        echo "configure: could not run $QT_MOC on:" >&AC_FD_CC
+        cat bnv_qt_test.h >&AC_FD_CC
+      else
+        bnv_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_bnv_qt_test.o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_2.out"
+        AC_TRY_EVAL(bnv_try_2)
+        bnv_err_2=`grep -v '^ *+' bnv_qt_test_2.out | grep -v "^bnv_qt_test.{$ac_ext}\$"`
+        if test x"$bnv_err_2" != x; then
+          echo "$bnv_err_2" >&AC_FD_CC
+          echo "configure: could not compile:" >&AC_FD_CC
+          cat bnv_qt_test.$ac_ext >&AC_FD_CC
+        else
+          bnv_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o bnv_qt_main.o bnv_qt_main.$ac_ext >/dev/null 2>bnv_qt_test_3.out"
+          AC_TRY_EVAL(bnv_try_3)
+          bnv_err_3=`grep -v '^ *+' bnv_qt_test_3.out | grep -v "^bnv_qt_main.{$ac_ext}\$"`
+          if test x"$bnv_err_3" != x; then
+            echo "$bnv_err_3" >&AC_FD_CC
+            echo "configure: could not compile:" >&AC_FD_CC
+            cat bnv_qt_main.$ac_ext >&AC_FD_CC
+          else
+            bnv_try_4="$CXX $QT_LIBS $LIBS -o bnv_qt_main bnv_qt_main.o moc_bnv_qt_test.o >/dev/null 2>bnv_qt_test_4.out"
+            AC_TRY_EVAL(bnv_try_4)
+            bnv_err_4=`grep -v '^ *+' bnv_qt_test_4.out`
+            if test x"$bnv_err_4" != x; then
+              echo "$bnv_err_4" >&AC_FD_CC
+            else
+              bnv_cv_qt_test_result="success"
+            fi
+          fi
+        fi
+      fi
+    ])dnl AC_CACHE_VAL bnv_cv_qt_test_result
+    AC_MSG_RESULT([$bnv_cv_qt_test_result]);
+    if test x"$bnv_cv_qt_test_result" = "xfailure"; then
+      # working Qt was not found
+      QT_CXXFLAGS=
+      QT_DIR=
+      QT_LIBS=
+      QT_UIC=
+      QT_MOC=
+      have_qt=no
+      AC_MSG_WARN([Failed to find matching components of a complete
+                  Qt installation. Try using more options,
+                  see ./configure --help.])
+    fi
+
+    rm -f bnv_qt_test.h moc_bnv_qt_test.$ac_ext moc_bnv_qt_test.o \
+          bnv_qt_main.$ac_ext bnv_qt_main.o bnv_qt_main \
+          bnv_qt_test_1.out bnv_qt_test_2.out bnv_qt_test_3.out bnv_qt_test_4.out
+  fi
+])
+
+dnl Internal subroutine of BNV_HAVE_QT
+dnl Set bnv_qt_dir bnv_qt_include_dir bnv_qt_bin_dir bnv_qt_lib_dir bnv_qt_lib
+dnl Copyright 2001 Bastiaan N. Veelo <Bastiaan.N.Veelo@immtek.ntnu.no>
+AC_DEFUN([BNV_PATH_QT_DIRECT],
+[
+  ## Binary utilities ##
+  if test x"$with_Qt_bin_dir" != x; then
+    bnv_qt_bin_dir=$with_Qt_bin_dir
+  fi
+  ## Look for header files ##
+  if test x"$with_Qt_include_dir" != x; then
+    bnv_qt_include_dir="$with_Qt_include_dir"
+  else
+    # The following header file is expected to define QT_VERSION.
+    qt_direct_test_header=qglobal.h
+    # Look for the header file in a standard set of common directories.
+    bnv_include_path_list="
+      /usr/include
+      `ls -dr /usr/include/qt* 2>/dev/null`
+      `ls -dr /usr/lib/qt*/include 2>/dev/null`
+      `ls -dr /usr/local/qt*/include 2>/dev/null`
+      `ls -dr /opt/qt*/include 2>/dev/null`
+    "
+    for bnv_dir in $bnv_include_path_list; do
+      if test -r "$bnv_dir/$qt_direct_test_header"; then
+        bnv_dirs="$bnv_dirs $bnv_dir"
+      fi
+    done
+    # Now look for the newest in this list
+    bnv_prev_ver=0
+    for bnv_dir in $bnv_dirs; do
+      bnv_this_ver=`egrep -w '#define QT_VERSION' $bnv_dir/$qt_direct_test_header | sed s/'#define QT_VERSION'//`
+      if expr $bnv_this_ver '>' $bnv_prev_ver > /dev/null; then
+        bnv_qt_include_dir=$bnv_dir
+        bnv_prev_ver=$bnv_this_ver
+      fi
+    done
+  fi dnl Found header files.
+
+  # Are these headers located in a traditional Trolltech installation?
+  # That would be $bnv_qt_include_dir stripped from its last element:
+  bnv_possible_qt_dir=`dirname $bnv_qt_include_dir`
+  if test -x $bnv_possible_qt_dir/bin/moc &&
+     ls $bnv_possible_qt_dir/lib/libqt* > /dev/null; then
+    # Then the rest is a piece of cake
+    bnv_qt_dir=$bnv_possible_qt_dir
+    bnv_qt_bin_dir="$bnv_qt_dir/bin"
+    bnv_qt_lib_dir="$bnv_qt_dir/lib"
+    # Only look for lib if the user did not supply it already
+    if test x"$bnv_qt_lib" = xNO; then
+      bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p |
+                   sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`"
+    fi
+    bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+  else
+    # There is no valid definition for $QTDIR as Trolltech likes to see it
+    bnv_qt_dir=
+    ## Look for Qt library ##
+    if test x"$with_Qt_lib_dir" != x; then
+      bnv_qt_lib_dir="$with_Qt_lib_dir"
+      # Only look for lib if the user did not supply it already
+      if test x"$bnv_qt_lib" = xNO; then
+        bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p |
+                     sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`"
+      fi
+      bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+    else
+      # Normally, when there is no traditional Trolltech installation,
+      # the library is installed in a place where the linker finds it
+      # automatically.
+      # If the user did not define the library name, try with qt
+      if test x"$bnv_qt_lib" = xNO; then
+        bnv_qt_lib=qt
+      fi
+      qt_direct_test_header=qapplication.h
+      qt_direct_test_main="
+        int argc;
+        char ** argv;
+        QApplication app(argc,argv);
+      "
+      # See if we find the library without any special options.
+      # Don't add top $LIBS permanently yet
+      bnv_save_LIBS="$LIBS"
+      LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+      bnv_qt_LIBS="$LIBS"
+      bnv_save_CXXFLAGS="$CXXFLAGS"
+      CXXFLAGS="-I$bnv_qt_include_dir"
+      AC_TRY_LINK([#include <$qt_direct_test_header>],
+        $qt_direct_test_main,
+      [
+        # Success.
+        # We can link with no special library directory.
+        bnv_qt_lib_dir=
+      ], [
+        # That did not work. Try the multi-threaded version
+        echo "Non-critical error, please neglect the above." >&AC_FD_CC
+        bnv_qt_lib=qt-mt
+        LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+        AC_TRY_LINK([#include <$qt_direct_test_header>],
+          $qt_direct_test_main,
+        [
+          # Success.
+          # We can link with no special library directory.
+          bnv_qt_lib_dir=
+        ], [
+          # That did not work. Try the OpenGL version
+          echo "Non-critical error, please neglect the above." >&AC_FD_CC
+          bnv_qt_lib=qt-gl
+          LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+          AC_TRY_LINK([#include <$qt_direct_test_header>],
+            $qt_direct_test_main,
+          [
+            # Succes.
+            # We can link with no special library directory.
+            bnv_qt_lib_dir=
+          ], [
+            # That did not work. Maybe a library version I don't know about?
+            echo "Non-critical error, please neglect the above." >&AC_FD_CC
+            # Look for some Qt lib in a standard set of common directories.
+            bnv_dir_list="
+              `echo $bnv_qt_includes | sed ss/includess`
+              /lib
+              /usr/lib
+              /usr/local/lib
+              /opt/lib
+              `ls -dr /usr/lib/qt* 2>/dev/null`
+              `ls -dr /usr/local/qt* 2>/dev/null`
+              `ls -dr /opt/qt* 2>/dev/null`
+            "
+            for bnv_dir in $bnv_dir_list; do
+              if ls $bnv_dir/libqt*; then
+                # Gamble that it's the first one...
+                bnv_qt_lib="`ls $bnv_dir/libqt* | sed -n 1p |
+                            sed s@$bnv_dir/lib@@ | sed s/[.].*//`"
+                bnv_qt_lib_dir="$bnv_dir"
+                break
+              fi
+            done
+            # Try with that one
+            LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS"
+            AC_TRY_LINK([#include <$qt_direct_test_header>],
+              $qt_direct_test_main,
+            [
+              # Succes.
+              # We can link with no special library directory.
+              bnv_qt_lib_dir=
+            ], [
+              # Leave bnv_qt_lib_dir defined
+            ])
+          ])
+        ])
+      ])
+      if test x"$bnv_qt_lib_dir" != x; then
+        bnv_qt_LIBS="-l$bnv_qt_lib_dir $LIBS"
+      else
+        bnv_qt_LIBS="$LIBS"
+      fi
+      LIBS="$bnv_save_LIBS"
+      CXXFLAGS="$bnv_save_CXXFLAGS"
+    fi dnl $with_Qt_lib_dir was not given
+  fi dnl Done setting up for non-traditional Trolltech installation
+])
diff --git a/gr-howto-write-a-block/config/cppunit.m4 b/gr-howto-write-a-block/config/cppunit.m4
new file mode 100644 (file)
index 0000000..0991d51
--- /dev/null
@@ -0,0 +1,80 @@
+dnl
+dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl
+AC_DEFUN([AM_PATH_CPPUNIT],
+[
+
+AC_ARG_WITH(cppunit-prefix,[  --with-cppunit-prefix=PFX   Prefix where CppUnit is installed (optional)],
+            cppunit_config_prefix="$withval", cppunit_config_prefix="")
+AC_ARG_WITH(cppunit-exec-prefix,[  --with-cppunit-exec-prefix=PFX  Exec prefix where CppUnit is installed (optional)],
+            cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="")
+
+  if test x$cppunit_config_exec_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config
+     fi
+  fi
+  if test x$cppunit_config_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config
+     fi
+  fi
+
+  AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no)
+  cppunit_version_min=$1
+
+  AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min)
+  no_cppunit=""
+  if test "$CPPUNIT_CONFIG" = "no" ; then
+    no_cppunit=yes
+  else
+    CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags`
+    CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs`
+    cppunit_version=`$CPPUNIT_CONFIG --version`
+
+    cppunit_major_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    cppunit_minor_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    cppunit_micro_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+    cppunit_major_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    cppunit_minor_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    cppunit_micro_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+    cppunit_version_proper=`expr \
+        $cppunit_major_version \> $cppunit_major_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \> $cppunit_minor_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \= $cppunit_minor_min \& \
+        $cppunit_micro_version \>= $cppunit_micro_min `
+
+    if test "$cppunit_version_proper" = "1" ; then
+      AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version])
+    else
+      AC_MSG_RESULT(no)
+      no_cppunit=yes
+    fi
+  fi
+
+  if test "x$no_cppunit" = x ; then
+     ifelse([$2], , :, [$2])     
+  else
+     CPPUNIT_CFLAGS=""
+     CPPUNIT_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+
+  AC_SUBST(CPPUNIT_CFLAGS)
+  AC_SUBST(CPPUNIT_LIBS)
+])
+
+
+
diff --git a/gr-howto-write-a-block/config/gr_check_createfilemapping.m4 b/gr-howto-write-a-block/config/gr_check_createfilemapping.m4
new file mode 100644 (file)
index 0000000..5f9b4a4
--- /dev/null
@@ -0,0 +1,52 @@
+dnl
+dnl Copyright 2005 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+dnl AC_DEFUN([GR_CHECK_CREATEFILEMAPPING],
+dnl [
+dnl   AC_CHECK_FUNCS([CreateFileMapping])
+dnl ])
+
+AC_DEFUN([GR_CHECK_CREATEFILEMAPPING],[
+  AC_MSG_CHECKING([for CreateFileMapping function])
+  AC_COMPILE_IFELSE([
+#include <windows.h>
+int main (int argc, char **argv)
+{ 
+    HANDLE handle;
+    int size;
+    char               seg_name[[1024]];
+    handle = CreateFileMapping(
+                     INVALID_HANDLE_VALUE,    // use paging file
+                     NULL,                    // default security
+                     PAGE_READWRITE,          // read/write access
+                     0,                       // max. object size
+                     size,                // buffer size
+                     seg_name);                 // name of mapping object
+    return 0;
+}
+],[HAVE_CREATEFILEMAPPING=yes
+   AC_DEFINE(HAVE_CREATEFILEMAPPING,[1],[Define if you have the CreateFilemapping function(win32).])],
+  [HAVE_CREATEFILEMAPPING=no])
+
+  AC_MSG_RESULT($HAVE_CREATEFILEMAPPING)
+  AM_CONDITIONAL(HAVE_CREATEFILEMAPPING,     test x$HAVE_CREATEFILEMAPPING = xyes)
+])
+
+
diff --git a/gr-howto-write-a-block/config/gr_check_mc4020.m4 b/gr-howto-write-a-block/config/gr_check_mc4020.m4
new file mode 100644 (file)
index 0000000..28987c2
--- /dev/null
@@ -0,0 +1,37 @@
+dnl
+dnl Copyright 2003 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+AC_DEFUN([GR_CHECK_MC4020],[
+  AC_MSG_CHECKING([for mc4020 A/D driver include file])
+  AC_COMPILE_IFELSE([
+#include <mc4020.h>
+int main (int argc, char **argv)
+{ 
+    return 0;
+}
+],[HAVE_MC4020=yes
+   AC_DEFINE(HAVE_MC4020,[1],[Define if you have a Measurement Computing PCI-DAS4020/12 A/D])],
+  [HAVE_MC4020=no])
+
+  AC_MSG_RESULT($HAVE_MC4020)
+  AM_CONDITIONAL(HAVE_MC4020,     test x$HAVE_MC4020 = xyes)
+])
+
diff --git a/gr-howto-write-a-block/config/gr_check_shm_open.m4 b/gr-howto-write-a-block/config/gr_check_shm_open.m4
new file mode 100644 (file)
index 0000000..83d260b
--- /dev/null
@@ -0,0 +1,29 @@
+dnl
+dnl Copyright 2003 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GR_CHECK_SHM_OPEN],
+[
+  SHM_OPEN_LIBS=""
+  save_LIBS="$LIBS"
+  AC_SEARCH_LIBS([shm_open], [rt], [SHM_OPEN_LIBS="$LIBS"])
+  AC_CHECK_FUNCS([shm_open])
+  LIBS="$save_LIBS"
+  AC_SUBST(SHM_OPEN_LIBS)
+])
diff --git a/gr-howto-write-a-block/config/gr_check_usrp.m4 b/gr-howto-write-a-block/config/gr_check_usrp.m4
new file mode 100644 (file)
index 0000000..12a5d1c
--- /dev/null
@@ -0,0 +1,32 @@
+dnl
+dnl Copyright 2003 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+dnl Check for Universal Software Radio Peripheral
+
+AC_DEFUN([GR_CHECK_USRP],[
+  PKG_CHECK_MODULES(USRP, usrp >= 0.2,
+       [HAVE_USRP=yes
+          AC_DEFINE(HAVE_USRP,[1],[Define if you have a USRP])],
+       [HAVE_USRP=no])
+
+  AM_CONDITIONAL(HAVE_USRP,     test x$HAVE_USRP = xyes)
+])
+
diff --git a/gr-howto-write-a-block/config/gr_doxygen.m4 b/gr-howto-write-a-block/config/gr_doxygen.m4
new file mode 100644 (file)
index 0000000..15ece8b
--- /dev/null
@@ -0,0 +1,60 @@
+dnl
+dnl Copyright 2003,2005 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+AC_DEFUN([GR_CHECK_DOXYGEN],[
+  AC_ARG_ENABLE(doxygen,
+               AC_HELP_STRING([--enable-doxygen],
+                              [enable documentation generation with doxygen (no)]))
+  AC_ARG_ENABLE(dot, AC_HELP_STRING([--enable-dot],[use 'dot' to generate graphs in doxygen (auto)]))
+
+  if test "x$enable_doxygen" = xyes; then
+        AC_PATH_PROG(DOXYGEN, doxygen, , $PATH)
+        if test x$DOXYGEN = x; then
+                if test "x$enable_doxygen" = xyes; then
+                        AC_MSG_ERROR([could not find doxygen])
+                fi
+                enable_doc=no
+               generate_docs=
+        else
+                enable_doc=yes
+               generate_docs=docs
+                AC_PATH_PROG(DOT, dot, , $PATH)
+        fi
+  else 
+        enable_doc=no
+  fi
+
+  AM_CONDITIONAL(DOC, test x$enable_doc = xyes)
+
+  if test x$DOT = x; then
+        if test "x$enable_dot" = xyes; then
+                AC_MSG_ERROR([could not find dot])
+        fi
+        enable_dot=no
+  else
+        enable_dot=yes
+  fi
+  AC_SUBST(enable_dot)
+  AC_SUBST(enable_xml_docs, YES)
+  AC_SUBST(enable_html_docs, YES)
+  AC_SUBST(enable_latex_docs, NO)
+  AC_SUBST(generate_docs)
+])
diff --git a/gr-howto-write-a-block/config/gr_fortran.m4 b/gr-howto-write-a-block/config/gr_fortran.m4
new file mode 100644 (file)
index 0000000..033ef03
--- /dev/null
@@ -0,0 +1,33 @@
+dnl Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GR_FORTRAN],[
+    dnl if you want to generate a different table of interpolator taps, you need fortran.
+    dnl we default to off, since almost no one wants to do this.
+    AC_ARG_ENABLE(fortran, AC_HELP_STRING([--enable-fortran],[enable fortran (no)]),
+                 [], [enable_fortran=no])
+    AM_CONDITIONAL(ENABLE_FORTRAN, test "x$enable_fortran" = xyes)
+
+    if test "x$enable_fortran" = xyes
+    then
+        AC_PROG_F77
+        AC_F77_LIBRARY_LDFLAGS
+    fi
+    AC_PROG_CC dnl bug fix to restore $ac_ext
+])
diff --git a/gr-howto-write-a-block/config/gr_git.m4 b/gr-howto-write-a-block/config/gr_git.m4
new file mode 100644 (file)
index 0000000..c4f1ea0
--- /dev/null
@@ -0,0 +1,63 @@
+dnl Copyright 2009,2010 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+
+AC_DEFUN([GR_GIT],[
+  dnl Identify git binary
+  AC_PATH_PROG([GIT],[git])
+  
+  dnl If it exists, get either 'git describe' or fallback to current commit
+  if test x$GIT != x ; then
+    AC_MSG_CHECKING([existence of git version control directory])
+    if test -d $srcdir/.git ; then
+      AC_MSG_RESULT([ok])
+      AC_MSG_CHECKING([git description of current commit])
+      if (cd $srcdir && $GIT describe >/dev/null 2>&1); then
+        GIT_DESCRIBE=`cd $srcdir && $GIT describe --abbrev=8 --long`
+        # Release candidate tags create an extra -rcX field
+       case $GIT_DESCRIBE in
+         *-*-*-*)
+           GIT_TAG=`echo $GIT_DESCRIBE | cut -f -2 -d '-'`
+           GIT_SEQNO=`echo $GIT_DESCRIBE | cut -f 3 -d '-'`
+           GIT_COMMIT=`echo $GIT_DESCRIBE | cut -f 4 -d '-' | cut -f 2- -d 'g'`
+           ;;
+         *-*-*)
+           GIT_TAG=`echo $GIT_DESCRIBE | cut -f 1 -d '-'`
+           GIT_SEQNO=`echo $GIT_DESCRIBE | cut -f 2 -d '-'`
+           GIT_COMMIT=`echo $GIT_DESCRIBE | cut -f 3 -d '-' | cut -f 2- -d 'g'`
+           ;;
+       esac
+
+       AC_MSG_RESULT([$GIT_DESCRIBE])
+      else
+        AC_MSG_RESULT([no tag in history, using current commit])
+       GIT_TAG=''
+       GIT_SEQNO=''
+       GIT_COMMIT=`cd $srcdir && $GIT describe --always --abbrev=8`
+      fi
+    else
+      AC_MSG_RESULT([not found])
+    fi
+
+    AC_SUBST([GIT_DESCRIBE])
+    AC_SUBST([GIT_TAG])
+    AC_SUBST([GIT_SEQNO])
+    AC_SUBST([GIT_COMMIT])
+  fi
+])
diff --git a/gr-howto-write-a-block/config/gr_gprof.m4 b/gr-howto-write-a-block/config/gr_gprof.m4
new file mode 100644 (file)
index 0000000..20bacf3
--- /dev/null
@@ -0,0 +1,72 @@
+dnl
+dnl Copyright 2002 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+dnl FIXME probably need to add linker flag too...
+
+AC_DEFUN([GR_SET_GPROF],[
+  dnl Check for --with-gprof
+  AC_MSG_CHECKING([whether user wants gprof])
+  AC_ARG_WITH(gprof,
+              [  --with-gprof            Turn on gprof profiling],
+              [], [ with_gprof=no ])
+  AC_MSG_RESULT($with_gprof)
+  
+  dnl gprof profiling flags for the two main compilers
+  cc_profiling_flags="-pg"
+  cxx_profiling_flags="-pg"
+  ld_profiling_flags="-pg"
+  if test $with_gprof = yes
+  then
+    if test -n "${CC}"
+    then
+      LF_CHECK_CC_FLAG($cc_profiling_flags)
+    fi
+    if test -n "${CXX}" 
+    then
+      LF_CHECK_CXX_FLAG($cxx_profiling_flags)
+    fi
+  fi
+])
+
+AC_DEFUN([GR_SET_PROF],[
+  dnl Check for --with-prof
+  AC_MSG_CHECKING([whether user wants prof])
+  AC_ARG_WITH(prof,
+              [  --with-prof             Turn on prof profiling],
+              [], [ with_prof=no ])
+  AC_MSG_RESULT($with_prof)
+  
+  dnl prof profiling flags for the two main compilers
+  cc_profiling_flags="-p"
+  cxx_profiling_flags="-p"
+  ld_profiling_flags="-p"
+  if test $with_prof = yes
+  then
+    if test -n "${CC}"
+    then
+      LF_CHECK_CC_FLAG($cc_profiling_flags)
+    fi
+    if test -n "${CXX}" 
+    then
+      LF_CHECK_CXX_FLAG($cxx_profiling_flags)
+    fi
+  fi
+])
diff --git a/gr-howto-write-a-block/config/gr_lib64.m4 b/gr-howto-write-a-block/config/gr_lib64.m4
new file mode 100644 (file)
index 0000000..751f774
--- /dev/null
@@ -0,0 +1,85 @@
+dnl
+dnl Copyright 2005,2008 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+dnl GR_LIB64()
+dnl
+dnl Checks to see if we're on a x86_64 or powerpc64 machine, and if so, determine
+dnl if libdir should end in "64" or not.
+dnl
+dnl Sets gr_libdir_suffix to "" or "64" and calls AC_SUBST(gr_libdir_suffix)
+dnl May append "64" to libdir.
+dnl
+dnl The current heuristic is:
+dnl   if the host_cpu isn't x86_64 or powerpc64, then ""
+dnl   if the host_os isn't linux, then ""
+dnl   if we're cross-compiling, ask the linker, by way of the selected compiler
+dnl   if we're x86_64 and there's a /lib64 and it's not a symlink, then "64", else ""
+dnl   else ask the compiler
+dnl
+AC_DEFUN([GR_LIB64],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_PROG_CXX])
+
+  AC_MSG_CHECKING([gr_libdir_suffix])
+  gr_libdir_suffix=""
+  AC_SUBST(gr_libdir_suffix)
+
+  case "$host_os" in
+    linux*) is_linux=yes ;;
+    *)      is_linux=no  ;;
+  esac
+
+  if test "$is_linux" = no || test "$host_cpu" != "x86_64" && test "$host_cpu" != "powerpc64"; then
+    gr_libdir_suffix=""
+  elif test "$cross_compiling" = yes; then
+    _GR_LIB64_ASK_COMPILER
+  elif test "$host_cpu" = "x86_64"; then
+    if test -d /lib64 && test ! -L /lib64; then
+      gr_libdir_suffix=64
+    fi
+  else
+    _GR_LIB64_ASK_COMPILER  
+  fi
+  AC_MSG_RESULT([$gr_libdir_suffix])
+
+
+  AC_MSG_CHECKING([whether to append 64 to libdir])
+  t=${libdir##*/lib}
+  if test "$t" != 64 && test "$gr_libdir_suffix" = "64"; then
+    libdir=${libdir}64
+    AC_MSG_RESULT([yes. Setting libdir to $libdir])
+  else
+    AC_MSG_RESULT([no])
+  fi
+])
+
+dnl If we're using g++, extract the first SEARCH_DIR("...") entry from the linker script
+dnl and see if it contains a suffix after the final .../lib part of the path.
+dnl (This works because the linker script varies depending on whether we're generating
+dnl 32-bit or 64-bit executables)
+dnl
+AC_DEFUN([_GR_LIB64_ASK_COMPILER],[
+  if test "$ac_cv_cxx_compiler_gnu" = "yes";
+  then
+    gr_libdir_suffix=`$CXX -Wl,--verbose 2>/dev/null | sed -n -e '/SEARCH_DIR/{s/;.*$//; s,^.*/,,; s/".*$//; s/^lib//; p}'`
+  fi
+])
+
diff --git a/gr-howto-write-a-block/config/gr_libgnuradio_core_extra_ldflags.m4 b/gr-howto-write-a-block/config/gr_libgnuradio_core_extra_ldflags.m4
new file mode 100644 (file)
index 0000000..43f872c
--- /dev/null
@@ -0,0 +1,40 @@
+# Check for (MinGW)win32 extra ld options.             -*- Autoconf -*-
+
+# Copyright 2003,2004,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.
+
+dnl
+AC_DEFUN([GR_LIBGNURADIO_CORE_EXTRA_LDFLAGS], [
+AC_REQUIRE([AC_PROG_LD])
+# on Mingw32 extra LDFLAGS are required to ease global variable linking
+LIBGNURADIO_CORE_EXTRA_LDFLAGS=""
+
+AC_MSG_CHECKING([whether $LD accepts --enable-runtime-pseudo-reloc])
+if ${LD} --enable-runtime-pseudo-reloc --version >/dev/null 2>&1
+then
+        # libtool requires the quotes
+        LIBGNURADIO_CORE_EXTRA_LDFLAGS="\"-Wl,--enable-runtime-pseudo-reloc\""
+        AC_MSG_RESULT(yes)
+else
+        AC_MSG_RESULT(no)
+fi
+
+AC_SUBST(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+
+])
diff --git a/gr-howto-write-a-block/config/gr_no_undefined.m4 b/gr-howto-write-a-block/config/gr_no_undefined.m4
new file mode 100644 (file)
index 0000000..c8d745d
--- /dev/null
@@ -0,0 +1,44 @@
+dnl
+dnl Copyright 2005 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+# GR_NO_UNDEFINED()
+#
+# Detemine whether we need to use the -no-undefined linker flag
+# when building shared libraries.  
+# Sets NO_UNDEFINED to "" or "-no-undefined"
+# 
+# As far as I can tell, we need -no-undefined only when building
+# windows DLLs.  This occurs when using MinGW and Cygwin.
+#
+# For now, we stub this out.
+
+AC_DEFUN([GR_NO_UNDEFINED],[
+       AC_REQUIRE([AC_CANONICAL_HOST])
+       no_undefined=""
+       case "${host_os}" in
+               *mingw* | *cygwin*)
+
+               # on MinGW/Cygwin extra LDFLAGS are required
+               no_undefined="-no-undefined"
+               ;;
+       esac
+       AC_SUBST(NO_UNDEFINED,[$no_undefined])
+])
diff --git a/gr-howto-write-a-block/config/gr_omnithread.m4 b/gr-howto-write-a-block/config/gr_omnithread.m4
new file mode 100644 (file)
index 0000000..054f078
--- /dev/null
@@ -0,0 +1,52 @@
+# Check for Omnithread (pthread/NT) thread support.             -*- Autoconf -*-
+
+# Copyright 2003,2007 Free Software Foundation, Inc.
+
+# This program 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Boston, MA
+# 02110-1301, USA.
+
+AC_DEFUN([GR_OMNITHREAD],
+[
+  # Check first for POSIX
+  ACX_PTHREAD(
+  [ AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.])
+    ot_posix="yes"
+    DEFINES="$DEFINES -DOMNITHREAD_POSIX=1"
+  ],[
+    # If no POSIX support found, then check for NT threads
+    AC_MSG_CHECKING([for NT threads])
+
+    AC_LINK_IFELSE([
+        #include <windows.h>
+        #include <winbase.h>
+        int main() { InitializeCriticalSection(NULL); return 0; }
+      ],
+      [ 
+        ot_nt="yes"
+        DEFINES="$DEFINES -DOMNITHREAD_NT=1"
+      ],
+      [AC_MSG_FAILURE([GNU Radio requires POSIX threads.  pthreads not found.])]
+    )
+    AC_MSG_RESULT(yes)
+  ])
+  AM_CONDITIONAL(OMNITHREAD_POSIX, test "x$ot_posix" = xyes)
+  AM_CONDITIONAL(OMNITHREAD_NT, test "x$ot_nt" = xyes)
+
+  save_LIBS="$LIBS"
+  AC_SEARCH_LIBS([clock_gettime], [rt], [PTHREAD_LIBS="$PTHREAD_LIBS $LIBS"])
+  AC_CHECK_FUNCS([clock_gettime gettimeofday nanosleep])
+  LIBS="$save_LIBS"
+])
+
diff --git a/gr-howto-write-a-block/config/gr_pwin32.m4 b/gr-howto-write-a-block/config/gr_pwin32.m4
new file mode 100644 (file)
index 0000000..495e9dd
--- /dev/null
@@ -0,0 +1,149 @@
+# Check for (mingw)win32 POSIX replacements.             -*- Autoconf -*-
+
+# Copyright 2003,2004,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.
+
+
+AC_DEFUN([GR_PWIN32],
+[
+AC_REQUIRE([AC_HEADER_TIME])
+AC_CHECK_HEADERS([sys/types.h fcntl.h io.h])
+AC_CHECK_HEADERS([windows.h])
+AC_CHECK_HEADERS([winioctl.h winbase.h], [], [], [
+       #if HAVE_WINDOWS_H
+       #include <windows.h>
+       #endif
+])
+
+AC_CHECK_FUNCS([getopt usleep gettimeofday nanosleep rand srand random srandom sleep sigaction])
+AC_CHECK_TYPES([struct timezone, struct timespec, ssize_t],[],[],[
+     #if HAVE_SYS_TYPES_H
+     # include <sys/types.h>
+     #endif
+     #if TIME_WITH_SYS_TIME
+     # include <sys/time.h>
+     # include <time.h>
+     #else
+     # if HAVE_SYS_TIME_H
+     #  include <sys/time.h>
+     # else
+     #  include <time.h>
+     # endif
+     #endif
+])
+
+dnl Checks for replacements
+AC_REPLACE_FUNCS([getopt usleep gettimeofday])
+
+
+AC_MSG_CHECKING(for Sleep)
+AC_TRY_LINK([   #include <windows.h>
+                #include <winbase.h>
+                ], [ Sleep(0); ],
+                [AC_DEFINE(HAVE_SSLEEP,1,[Define to 1 if you have win32 Sleep])
+                AC_MSG_RESULT(yes)],
+                AC_MSG_RESULT(no)
+                )
+
+dnl Under Win32, mkdir prototype in io.h has only one arg
+AC_MSG_CHECKING(whether mkdir accepts only one arg)
+AC_TRY_COMPILE([#include <sys/types.h>
+       #include <sys/stat.h>
+       #include <fcntl.h>], [
+       mkdir("")
+ ], [ AC_MSG_RESULT(yes)
+     AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ],
+ [ AC_MSG_RESULT(no)
+ ])
+
+AH_BOTTOM(
+[
+/* Define missing prototypes, implemented in replacement lib */
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef HAVE_GETOPT
+int getopt (int argc, char * const argv[], const char * optstring);
+extern char * optarg;
+extern int optind, opterr, optopt;
+#endif
+
+#ifndef HAVE_USLEEP
+int usleep(unsigned long usec);        /* SUSv2 */
+#endif
+
+#ifndef HAVE_NANOSLEEP
+#ifndef HAVE_STRUCT_TIMESPEC
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>        /* need time_t */
+#endif
+struct timespec {
+       time_t  tv_sec;
+       long    tv_nsec;
+};
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); }
+#endif
+
+#if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP)
+#ifdef HAVE_WINBASE_H
+#include <windows.h>
+#include <winbase.h>
+#endif
+/* TODO: what about SleepEx? */
+static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; }
+#endif
+
+#ifndef HAVE_GETTIMEOFDAY
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifndef HAVE_STRUCT_TIMEZONE
+struct timezone {
+        int  tz_minuteswest;
+       int  tz_dsttime;
+};
+#endif
+int gettimeofday(struct timeval *tv, struct timezone *tz);
+#endif
+
+#if !defined(HAVE_RANDOM) && defined(HAVE_RAND)
+#include <stdlib.h>
+static inline long int random (void) { return rand(); }
+#endif
+
+#if !defined(HAVE_SRANDOM) && defined(HAVE_SRAND)
+static inline void srandom (unsigned int seed) { srand(seed); }
+#endif
+
+#ifndef HAVE_SSIZE_T
+typedef size_t ssize_t;
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+])
+
+
+])
diff --git a/gr-howto-write-a-block/config/gr_python.m4 b/gr-howto-write-a-block/config/gr_python.m4
new file mode 100644 (file)
index 0000000..43ccfc0
--- /dev/null
@@ -0,0 +1,172 @@
+dnl
+dnl Copyright 2003,2004,2005 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+# PYTHON_DEVEL()
+#
+# Checks for Python and tries to get the include path to 'Python.h'.
+# It sets the $(PYTHON_CPPFLAGS), $(PYTHON_LDFLAGS) and $(pythondir) output variables,
+#
+AC_DEFUN([PYTHON_DEVEL],[
+       AC_REQUIRE([AM_PATH_PYTHON])
+       AC_REQUIRE([AC_CANONICAL_HOST])
+
+       AC_ARG_WITH(pythondir,
+                    AC_HELP_STRING([--with-pythondir=DIR], 
+                       [python installation directory (cross-compiling) [[default=$prefix/lib/python2.5/site-packages]]]),
+                   [with_pythondir=${withval}],[with_pythondir=${prefix}/lib/python2.5/site-packages])
+
+       # if we're cross-compiling, asking the host python about any of
+       # this is completely useless...
+
+       if test x$cross_compiling != xno
+       then
+               pythondir=$with_pythondir
+               pyexecdir=$with_pythondir
+               AC_SUBST(PYTHON_CPPFLAGS)
+               AC_SUBST(PYTHON_LDFLAGS)
+        else
+
+           # For Fedora Core 5 and 6, see ticket:39 in Trac
+           if test -f '/etc/redhat-release'; then
+                   if  (echo $pyexecdir | grep -q lib64); then
+                           pythondir="$pyexecdir"
+                   fi
+           fi
+
+           # Check for Python include path
+           AC_MSG_CHECKING([for Python include path])
+           if test -z "$PYTHON" ; then
+                   AC_MSG_ERROR([cannot find Python path])
+           fi
+
+           # ask distutils which include path we should use
+           python_cmd='
+import distutils.sysconfig
+import os
+path = distutils.sysconfig.get_python_inc(plat_specific=False)
+if os.sep == "\\":
+  path = path.replace("\\", "/")
+print path
+'
+           python_path=`$PYTHON -c "$python_cmd"`
+           AC_MSG_RESULT([$python_path])
+           if test -z "$python_path" ; then
+                   AC_MSG_ERROR([cannot find Python include path])
+           fi
+
+           AC_SUBST(PYTHON_CPPFLAGS,[-I$python_path])
+
+           # Check for Python headers usability
+           python_save_CPPFLAGS=$CPPFLAGS
+           CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
+           AC_CHECK_HEADERS([Python.h], [],
+                           [AC_MSG_ERROR([cannot find usable Python headers])])
+           CPPFLAGS="$python_save_CPPFLAGS"
+
+           # Only set this on mingw and cygwin hosts, (only implemented
+           # for mingw host, for crosscompiling you need to trick this)
+
+           PYTHON_LDFLAGS=""
+           case $host_os in
+                *mingw* | *cygwin* )
+             AC_MSG_CHECKING([for Python LDFLAGS])
+
+           python_cmd='
+import distutils.sysconfig
+import os
+path = distutils.sysconfig.get_config_var("LIBPL")
+if path == None:
+  path = distutils.sysconfig.PREFIX + "/libs"
+if os.sep == "\\":
+  path = path.replace("\\", "/")
+print path
+'
+             python_stdlib_path=`$PYTHON -c "$python_cmd"`
+
+             python_version_nodot=`echo $PYTHON_VERSION | sed "s,\.,,"`
+             libpython_name="python$PYTHON_VERSION"
+
+             # Standard install of python for win32 has libpython24.a
+             # instead of libpython2.4.a so we check for the library
+             # without the dot in the version number.
+
+             python_stdlib_filename=`find $python_stdlib_path -type f -name libpython$python_version_nodot.* -print | sed "1q"`
+             if test -n "$python_stdlib_filename" ; then
+                   libpython_name="python$python_version_nodot"
+             fi
+
+             PYTHON_LDFLAGS="-L$python_stdlib_path -l$libpython_name"
+             AC_MSG_RESULT($PYTHON_LDFLAGS) 
+             # Replace all backslashes in PYTHON Paths with forward slashes
+             pythondir=`echo $pythondir |sed 's,\\\\,/,g'`
+             pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'`
+             pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'`
+             pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'`
+             ;;
+           esac
+
+           case $host_os in
+                *mingw* )
+             # Python 2.5 requires ".pyd" instead of ".dll" for extensions
+             PYTHON_LDFLAGS="-shrext .pyd ${PYTHON_LDFLAGS}"
+           esac
+
+           AC_SUBST(PYTHON_LDFLAGS)
+       fi
+])
+
+# PYTHON_CHECK_MODULE
+#
+# Determines if a particular Python module can be imported
+#
+# $1 - module name
+# $2 - module description
+# $3 - action if found
+# $4 - action if not found
+# $5 - test command
+
+AC_DEFUN([PYTHON_CHECK_MODULE],[
+    AC_MSG_CHECKING([for $2])
+    dnl ########################################
+    dnl # import and test checking
+    dnl ########################################
+    if test "$5"; then
+        python_cmd='
+try:
+    import $1
+    assert $5
+except: exit(1)'
+    dnl ########################################
+    dnl # import checking only
+    dnl ########################################
+    else
+        python_cmd='
+try: import $1
+except: exit(1)'
+    fi
+    if ! $PYTHON -c "$python_cmd" 2> /dev/null; then
+        AC_MSG_RESULT([no])
+        $4
+    else
+        AC_MSG_RESULT([yes])
+        $3
+    fi
+])
diff --git a/gr-howto-write-a-block/config/gr_require_mc4020.m4 b/gr-howto-write-a-block/config/gr_require_mc4020.m4
new file mode 100644 (file)
index 0000000..90774fd
--- /dev/null
@@ -0,0 +1,33 @@
+dnl
+dnl Copyright 2003,2004 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+AC_DEFUN([GR_REQUIRE_MC4020],[
+  AC_MSG_CHECKING([for mc4020 A/D driver include file])
+  AC_COMPILE_IFELSE([
+#include <mc4020.h>
+int main (int argc, char **argv)
+{ 
+    return 0;
+}
+],[AC_MSG_RESULT([yes])],
+  [AC_MSG_RESULT([no])
+  AC_MSG_ERROR([mc4020.h not found.])])
+])
diff --git a/gr-howto-write-a-block/config/gr_scripting.m4 b/gr-howto-write-a-block/config/gr_scripting.m4
new file mode 100644 (file)
index 0000000..e030a81
--- /dev/null
@@ -0,0 +1,30 @@
+dnl
+dnl Copyright 2003 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+AC_DEFUN([GR_SCRIPTING],[
+  AC_REQUIRE([AC_PROG_LN_S])
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_REQUIRE([AC_PROG_LIBTOOL])
+
+  SWIG_PROG(1.3.31)
+  SWIG_ENABLE_CXX
+  SWIG_PYTHON
+])
diff --git a/gr-howto-write-a-block/config/gr_set_md_cpu.m4 b/gr-howto-write-a-block/config/gr_set_md_cpu.m4
new file mode 100644 (file)
index 0000000..7ebf88a
--- /dev/null
@@ -0,0 +1,115 @@
+dnl
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+AC_DEFUN([_TRY_ADD_ALTIVEC],
+[
+  LF_CHECK_CC_FLAG([-mabi=altivec -maltivec])
+  LF_CHECK_CXX_FLAG([-mabi=altivec -maltivec])
+])
+
+AC_DEFUN([_FIND_ARM_ISA],
+[
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_5__
+    #error "Not armv5"
+    #endif
+  ]])],
+    [is_armv5=yes],
+    [is_armv5=no])
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_7A__
+    #error "Not armv7-a"
+    #endif
+  ]])],
+    [is_armv7_a=yes],
+    [is_armv7_a=no])
+
+])
+
+AC_DEFUN([GR_SET_MD_CPU],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(md-cpu,
+       AC_HELP_STRING([--with-md-cpu=ARCH],[set machine dependent speedups (auto)]),
+               [cf_with_md_cpu="$withval"],
+               [
+  dnl see if the user has specified --host or --build, via 'cross_compiling'
+  if test "$cross_compiling" != no; then
+    dnl when cross-compiling, because the user specified it either via
+    dnl --target or --build, just keep the user's specs & hope for the best.
+    cf_with_md_cpu="$host_cpu"
+  else
+    dnl when the user didn't specify --target or --build, on Darwin 10
+    dnl (OSX 10.6.0 and .1) and GNU libtoool 2.2.6, 'configure' doesn't
+    dnl figure out the CPU type correctly, so do it by hand here using
+    dnl the sizeof (void*): if 4 then use i386, and otherwise use x86_64.
+    case "$host_os" in
+     *darwin*10*)
+      AC_CHECK_SIZEOF(void*)
+      if test "$ac_cv_sizeof_voidp" = 4; then
+       cf_with_md_cpu="i386"
+      else
+       cf_with_md_cpu="x86_64"
+      fi
+      ;;
+     *)
+      cf_with_md_cpu="$host_cpu"
+      ;;
+    esac
+  fi
+  ])
+  case "$cf_with_md_cpu" in
+   x86 | i[[3-7]]86)   MD_CPU=x86      MD_SUBCPU=x86 ;;
+   x86_64)             MD_CPU=x86      MD_SUBCPU=x86_64 ;;
+   powerpc*)            MD_CPU=powerpc ;;
+   arm)
+       _FIND_ARM_ISA
+       if test $is_armv5 = yes; then MD_CPU=armv5;
+       elif test $is_armv7_a = yes; then MD_CPU=armv7_a;
+       else MD_CPU=generic; fi
+       ;;
+   *)                  MD_CPU=generic ;;
+  esac
+
+  AC_ARG_ENABLE(altivec,
+    AC_HELP_STRING([--enable-altivec],[enable altivec on PowerPC (yes)]),
+    [ if test $MD_CPU = powerpc; then
+        case "$enableval" in
+          (no)  MD_CPU=generic ;;
+          (yes) _TRY_ADD_ALTIVEC ;;
+          (*) AC_MSG_ERROR([Invalid argument ($enableval) to --enable-altivec]) ;;
+        esac
+      fi],
+    [ if test $MD_CPU = powerpc; then _TRY_ADD_ALTIVEC fi])
+
+
+  AC_MSG_CHECKING([for machine dependent speedups])
+  AC_MSG_RESULT($MD_CPU)
+  AC_SUBST(MD_CPU)
+  AC_SUBST(MD_SUBCPU) 
+
+  AM_CONDITIONAL(MD_CPU_x86,     test "$MD_CPU" = "x86")
+  AM_CONDITIONAL(MD_SUBCPU_x86_64,  test "$MD_SUBCPU" = "x86_64")
+  AM_CONDITIONAL(MD_CPU_powerpc, test "$MD_CPU" = "powerpc")
+  AM_CONDITIONAL(MD_CPU_armv5, test "$MD_CPU" = "armv5")
+  AM_CONDITIONAL(MD_CPU_armv7_a, test "$MD_CPU" = "armv7_a")
+  AM_CONDITIONAL(MD_CPU_generic, test "$MD_CPU" = "generic")
+])
diff --git a/gr-howto-write-a-block/config/gr_standalone.m4 b/gr-howto-write-a-block/config/gr_standalone.m4
new file mode 100644 (file)
index 0000000..3f8ddf1
--- /dev/null
@@ -0,0 +1,135 @@
+dnl
+dnl Copyright 2008,2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License along
+dnl with this program; if not, write to the Free Software Foundation, Inc.,
+dnl 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+dnl
+
+dnl
+dnl GR_STANDALONE([package],[version])
+dnl
+dnl Handles the bulk of the configure.ac work for an out-of-tree build
+dnl
+dnl N.B., this is an m4_define because if it were an AC_DEFUN it would
+dnl get called too late to be useful.
+
+m4_define([GR_STANDALONE],
+[
+  AC_CONFIG_SRCDIR([config/gr_standalone.m4])
+  AM_CONFIG_HEADER(config.h)
+
+  dnl Remember if the user explicity set CXXFLAGS
+  if test -n "${CXXFLAGS}"; then
+    user_set_cxxflags=yes
+  fi
+
+  LF_CONFIGURE_CC
+  LF_CONFIGURE_CXX
+  GR_LIB64             dnl check for lib64 suffix after choosing compilers
+
+  dnl The three macros above are known to override CXXFLAGS if the user
+  dnl didn't specify them.  Though I'm sure somebody thought this was
+  dnl a good idea, it makes it hard to use other than -g -O2 when compiling
+  dnl selected files.  Thus we "undo" the damage here...
+  dnl 
+  dnl If the user specified CXXFLAGS, we use them.  Otherwise when compiling
+  dnl the output of swig use use -O1 if we're using g++.
+  dnl See Makefile.common for the rest of the magic.
+  if test "$user_set_cxxflags" != yes; then
+    autoconf_default_CXXFLAGS="$CXXFLAGS"
+    if test "$GXX" = yes; then
+      case "$host_cpu" in
+       powerpc*)
+          dnl "-O1" is broken on the PPC for some reason
+          dnl (at least as of g++ 4.1.1)
+          swig_CXXFLAGS="-g1 -O2 -Wno-strict-aliasing -Wno-parentheses"
+       ;;
+       *) 
+       swig_CXXFLAGS="-g -O1 -Wno-strict-aliasing -Wno-parentheses"
+       ;;
+      esac
+    fi
+  fi
+  AC_SUBST(autoconf_default_CXXFLAGS)
+  AC_SUBST(swig_CXXFLAGS)
+
+  dnl add ${prefix}/lib${gr_libdir_suffix}/pkgconfig to the head of the PKG_CONFIG_PATH
+  if test x${PKG_CONFIG_PATH} = x; then
+      PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig
+  else
+      PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig:${PKG_CONFIG_PATH}
+  fi
+  export PKG_CONFIG_PATH
+
+  LF_SET_WARNINGS
+  GR_SET_GPROF
+  GR_SET_PROF
+  AM_PROG_AS
+  AC_PROG_LN_S
+  AC_PROG_MAKE_SET
+  AC_PROG_INSTALL
+  AC_PATH_PROG([RM_PROG], [rm])
+
+  AC_LIBTOOL_WIN32_DLL
+  AC_ENABLE_SHARED     dnl do build shared libraries
+  AC_DISABLE_STATIC    dnl don't build static libraries
+  m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL])
+  dnl GR_FORTRAN
+
+  GR_NO_UNDEFINED      dnl do we need the -no-undefined linker flag
+  GR_SCRIPTING         dnl Locate python, SWIG, etc
+
+  dnl Checks for header files.
+  AC_HEADER_STDC
+
+  dnl Checks for typedefs, structures, and compiler characteristics.
+  AC_C_CONST
+  AC_C_INLINE
+  AC_TYPE_SIZE_T
+  AC_HEADER_TIME
+  AC_C_BIGENDIAN
+
+  dnl Check for Mingw support
+  GR_PWIN32
+
+  AC_CHECK_PROG([XMLTO],[xmlto],[yes],[])
+  AM_CONDITIONAL([HAS_XMLTO], [test x$XMLTO = xyes])
+
+  PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 3)
+  LIBS="$LIBS $GNURADIO_CORE_LIBS"
+
+  dnl Allow user to choose whether to generate SWIG/Python 
+  dnl Default is enabled
+  AC_ARG_ENABLE([python],
+    [AS_HELP_STRING([--enable-python],
+      [generate SWIG/Python components (default is yes)])],
+    [case "${enableval}" in
+       yes) enable_python=yes ;;
+       no) enable_python=no ;;
+       *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
+     esac],
+    [enable_python=yes]  
+  )
+  AM_CONDITIONAL([PYTHON], [test x$enable_python = xyes])
+
+  dnl Define where to look for cppunit includes and libs
+  dnl sets CPPUNIT_CFLAGS and CPPUNIT_LIBS
+  dnl Try using pkg-config first, then fall back to cppunit-config.
+  PKG_CHECK_EXISTS(cppunit,
+    [PKG_CHECK_MODULES(CPPUNIT, cppunit >= 1.9.14)],
+    [AM_PATH_CPPUNIT([1.9.14],[],
+                    [AC_MSG_ERROR([GNU Radio requires cppunit.  Stop])])])
+])
diff --git a/gr-howto-write-a-block/config/gr_subversion.m4 b/gr-howto-write-a-block/config/gr_subversion.m4
new file mode 100644 (file)
index 0000000..849d7a9
--- /dev/null
@@ -0,0 +1,36 @@
+dnl
+dnl Copyright 2007 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+# GR_SUBVERSION()
+#
+# Test for presence of subversion, and create variables for 
+# current repository version and last changed date.
+
+AC_DEFUN([GR_SUBVERSION],[
+       AC_PATH_PROG([SVN],[svn])
+       if test "$SVN" != "" -a -d .svn ; then
+           SVNVERSION=`$SVN info . | grep '^Revision' | cut -f 2- -d ' '`
+           SVNDATE=`$SVN info . | grep 'Last Changed Date' | cut -f 4-6 -d ' '`
+       fi
+
+       AC_SUBST(SVNVERSION)
+       AC_SUBST(SVNDATE)
+])
diff --git a/gr-howto-write-a-block/config/gr_swig.m4 b/gr-howto-write-a-block/config/gr_swig.m4
new file mode 100644 (file)
index 0000000..cdb2805
--- /dev/null
@@ -0,0 +1,85 @@
+dnl
+dnl Copyright 2003 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+# SWIG_PROG([required-version])
+#
+# Checks for the SWIG program.  If found you can (and should) call SWIG via $(SWIG).
+# You can use the optional first argument to check if the version of the available SWIG
+# is greater or equal to the value of the argument.  It should have the format:
+# N[.N[.N]] (N is a number between 0 and 999.  Only the first N is mandatory.)
+AC_DEFUN([SWIG_PROG],[
+       AC_REQUIRE([AC_PROG_MAKE_SET])
+       AC_CHECK_PROG(SWIG,swig,[`which swig`])
+       if test -z "$SWIG" ; then
+               AC_MSG_ERROR([Cannot find 'swig' program.  SWIG version >= $1 required])
+               SWIG=false
+       elif test -n "$1" ; then
+               AC_MSG_CHECKING([for SWIG version])
+               swig_version=`$SWIG -version 2>&1 | \
+                       awk '/^SWIG Version [[0-9]+\.[0-9]+\.[0-9]]+.*$/ { split($[3],a,"[[^.0-9]]"); print a[[1]] }'`
+               AC_MSG_RESULT([$swig_version])
+               if test -n "$swig_version" ; then
+                       swig_version=`echo $swig_version | \
+                               awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null`
+                       swig_required_version=`echo $1 | \
+                               awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null`
+                       if test $swig_required_version -gt $swig_version ; then
+                               AC_MSG_ERROR([SWIG version >= $1 required])
+                       fi
+               else
+                       AC_MSG_ERROR([cannot determine SWIG version])
+               fi
+       fi
+])
+
+# SWIG_ENABLE_CXX()
+#
+# Enable swig C++ support.  This effects all invocations of $(SWIG).
+AC_DEFUN([SWIG_ENABLE_CXX],[
+       AC_REQUIRE([SWIG_PROG])
+       AC_REQUIRE([AC_PROG_CXX])
+       if test "$SWIG" != "false" ; then
+               SWIG="$SWIG -c++"
+       fi
+])
+
+# SWIG_PYTHON([use-shadow-classes])
+#
+# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS),
+# $(SWIG_PYTHON_LIB) and $(SWIG_PYTHON_OPT) output variables.
+# $(SWIG_PYTHON_OPT) contains all necessary swig options to generate
+# code for Python.  If you need multi module support use
+# $(SWIG_PYTHON_LIB) (provided by the SWIG_MULTI_MODULE_SUPPORT()
+# macro) to link against the appropriate library.  It contains the
+# SWIG Python runtime library that is needed by the type check system
+# for example.
+
+AC_DEFUN([SWIG_PYTHON],[
+       AC_REQUIRE([SWIG_PROG])
+       AC_REQUIRE([PYTHON_DEVEL])
+       if test "$SWIG" != "false" ; then
+               AC_SUBST(SWIG_PYTHON_LIB,[-lswigpy])
+dnl            test ! "x$1" = "xno" && swig_shadow=" -shadow" || swig_shadow=""
+dnl            AC_SUBST(SWIG_PYTHON_OPT,[-python$swig_shadow])
+               AC_SUBST(SWIG_PYTHON_OPT,[-python])
+       fi
+       AC_SUBST(SWIG_PYTHON_CPPFLAGS,[$PYTHON_CPPFLAGS])
+])
diff --git a/gr-howto-write-a-block/config/gr_sysv_shm.m4 b/gr-howto-write-a-block/config/gr_sysv_shm.m4
new file mode 100644 (file)
index 0000000..db5c835
--- /dev/null
@@ -0,0 +1,36 @@
+# Check for IPC System V shm support.             -*- Autoconf -*-
+
+# Copyright 2003 Free Software Foundation, Inc.
+
+# This program 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Boston, MA
+# 02110-1301, USA.
+
+AC_DEFUN([GR_SYSV_SHM],
+[
+       AC_LANG_SAVE
+       AC_LANG_C
+
+       AC_CHECK_HEADERS([sys/ipc.h sys/shm.h])
+
+        save_LIBS="$LIBS"
+       AC_SEARCH_LIBS(shmat, [cygipc ipc],
+         [ IPC_LIBS="$LIBS" ],
+         [ AC_MSG_WARN([SystemV IPC support not found. ]) ]
+       )
+        LIBS="$save_LIBS"
+
+       AC_LANG_RESTORE
+       AC_SUBST(IPC_LIBS)
+])
diff --git a/gr-howto-write-a-block/config/gr_version.m4 b/gr-howto-write-a-block/config/gr_version.m4
new file mode 100644 (file)
index 0000000..a7a2022
--- /dev/null
@@ -0,0 +1,73 @@
+dnl Copyright 2009,2010 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GR_VERSION],[
+  dnl Computed version based on version.sh
+  dnl Does not force recompile on rev change
+  dnl
+  dnl Source the variables describing the release version
+  dnl 
+  dnl MAJOR_VERSION          Major release generation (2.x, 3.x, etc.)
+  dnl API_COMPAT             API compatibility version (3.2.x, 3.3.x, etc.)
+  dnl MINOR_VERSION          Minor release version (3.3.0, 3.3.1, etc.)
+  dnl MAINT_VERSION          Pure bugfix additions to make maintenance release
+  dnl
+  dnl The last two fields can have 'git' instead of a number to indicate
+  dnl that this branch is between versions.
+  . $srcdir/version.sh
+  
+  dnl Get git version if available
+  GR_GIT
+
+  dnl Test if we should use git version
+  if test "$MINOR_VERSION" == "git"; then
+    dnl RELEASE: 3.3git-xxx-gxxxxxxxx
+    dnl DOCVER:  3.3git
+    dnl LIBVER:  3.3git
+    RELEASE=$GIT_DESCRIBE
+    DOCVER=$MAJOR_VERSION.$API_COMPAT$MINOR_VERSION
+    LIBVER=$MAJOR_VERSION.$API_COMPAT$MINOR_VERSION
+  else
+    if test "$MAINT_VERSION" == "git" ; then
+      dnl RELEASE: 3.3.1git-xxx-gxxxxxxxx
+      dnl DOCVER:  3.3.1git
+      dnl LIBVER:  3.3.1git
+      RELEASE=$GIT_DESCRIBE
+      DOCVER=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION$MAINT_VERSION
+      LIBVER=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION$MAINT_VERSION
+    else
+      dnl This is a numbered release.
+      dnl RELEASE: 3.3.1{.x}
+      dnl DOCVER:  3.3.1{.x}
+      dnl LIBVER:  3.3.1{.x}
+      RELEASE=$MAJOR_VERSION.$API_COMPAT.$MINOR_VERSION
+      if test "$MAINT_VERSION" != "0"; then
+        RELEASE=$RELEASE.$MAINT_VERSION
+      fi
+
+      DOCVER=$RELEASE
+      LIBVER=$RELEASE
+    fi
+  fi
+
+  AC_MSG_NOTICE([GNU Radio Release $RELEASE])
+  AC_SUBST(RELEASE)
+  AC_SUBST(DOCVER)
+  AC_SUBST(LIBVER)
+])
diff --git a/gr-howto-write-a-block/config/lf_cc.m4 b/gr-howto-write-a-block/config/lf_cc.m4
new file mode 100644 (file)
index 0000000..b75e1a4
--- /dev/null
@@ -0,0 +1,41 @@
+dnl Autoconf support for C++
+dnl Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
+dnl  
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software 
+dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.
+dnl 
+dnl As a special exception to the GNU General Public License, if you 
+dnl distribute this file as part of a program that contains a configuration 
+dnl script generated by Autoconf, you may include it under the same 
+dnl distribution terms that you use for the rest of that program.
+
+# -------------------------------------------------------------------------
+# Use this macro to configure your C compiler
+# When called the macro does the following things:
+# 1. It finds an appropriate C compiler.
+#    If you passed the flag --with-cc=foo then it uses that
+#    particular compiler
+# 2. Check whether the compiler works.
+# 3. Checks whether the compiler accepts the -g 
+# -------------------------------------------------------------------------
+
+AC_DEFUN([LF_CONFIGURE_CC],[
+  dnl Sing the song
+  AC_REQUIRE([AC_PROG_CC])dnl
+  AC_REQUIRE([AC_PROG_CPP])dnl
+  AC_REQUIRE([AC_AIX])dnl
+  AC_REQUIRE([AC_ISC_POSIX])dnl
+  AC_REQUIRE([AC_HEADER_STDC])dnl
+])
+
diff --git a/gr-howto-write-a-block/config/lf_cxx.m4 b/gr-howto-write-a-block/config/lf_cxx.m4
new file mode 100644 (file)
index 0000000..dfc6bfb
--- /dev/null
@@ -0,0 +1,67 @@
+dnl Autoconf support for C++
+dnl Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
+dnl  
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software 
+dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.
+dnl 
+dnl As a special exception to the GNU General Public License, if you 
+dnl distribute this file as part of a program that contains a configuration 
+dnl script generated by Autoconf, you may include it under the same 
+dnl distribution terms that you use for the rest of that program.
+
+# -----------------------------------------------------------------
+# This macro should be called to configure your C++ compiler.
+# When called, the macro does the following things:
+# 1. It finds an appropriate C++ compiler
+#    If you passed the flag --with-cxx=foo, then it uses that
+#    particular compiler
+# 2. Checks whether the compiler accepts the -g 
+# ------------------------------------------------------------------
+
+AC_DEFUN([LF_CONFIGURE_CXX],[
+ AC_REQUIRE([AC_PROG_CXX])dnl
+ AC_REQUIRE([AC_PROG_CXXCPP])dnl
+ LF_CXX_PORTABILITY
+])
+
+# -----------------------------------------------------------------------
+# This macro tests the C++ compiler for various portability problem.
+# -----------------------------------------------------------------------
+
+
+AC_DEFUN([LF_CXX_PORTABILITY],[
+
+  dnl
+  dnl Check for common C++ portability problems
+  dnl
+
+  dnl AC_LANG_PUSH
+  dnl AC_LANG_CPLUSPLUS
+  AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+
+
+  dnl Test whether C++ has std::isnan
+  AC_MSG_CHECKING(whether C++ has std::isnan)
+  AC_TRY_COMPILE([#include <cmath>], [
+   std::isnan(0);
+], [ AC_MSG_RESULT(yes)
+       AC_DEFINE(CXX_HAS_STD_ISNAN,[],[Define if has std::isnan]) ],
+   [ AC_MSG_RESULT(no) ])
+
+  dnl Done with the portability checks
+  dnl AC_LANG_POP([C++])
+  AC_LANG_RESTORE
+])
+
diff --git a/gr-howto-write-a-block/config/lf_warnings.m4 b/gr-howto-write-a-block/config/lf_warnings.m4
new file mode 100644 (file)
index 0000000..d40c77f
--- /dev/null
@@ -0,0 +1,121 @@
+dnl Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
+dnl Copyright (C) 2009 Free Software Foundation, Inc.
+dnl  
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software 
+dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.
+dnl 
+dnl As a special exception to the GNU General Public License, if you 
+dnl distribute this file as part of a program that contains a configuration 
+dnl script generated by Autoconf, you may include it under the same 
+dnl distribution terms that you use for the rest of that program.
+
+# --------------------------------------------------------------------------
+# Check whether the C++ compiler accepts a certain flag
+# If it does it adds the flag to lf_CXXFLAGS
+# If it does not then it returns an error to lf_ok
+# Usage:
+#   LF_CHECK_CXX_FLAG(-flag1 -flag2 -flag3 ...)
+# -------------------------------------------------------------------------
+
+AC_DEFUN([LF_CHECK_CXX_FLAG],[
+  echo 'void f(){}' > conftest.cc
+  for i in $1
+  do
+    AC_MSG_CHECKING([whether $CXX accepts $i])
+    if test -z "`${CXX} $i -c conftest.cc 2>&1`"
+    then
+      lf_CXXFLAGS="${lf_CXXFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.cc conftest.o
+  AC_SUBST(lf_CXXFLAGS)
+])
+
+# --------------------------------------------------------------------------
+# Check whether the C compiler accepts a certain flag
+# If it does it adds the flag to lf_CFLAGS
+# If it does not then it returns an error to lf_ok
+# Usage:
+#  LF_CHECK_CC_FLAG(-flag1 -flag2 -flag3 ...)
+# -------------------------------------------------------------------------
+
+AC_DEFUN([LF_CHECK_CC_FLAG],[
+  echo 'void f(){}' > conftest.c
+  for i in $1
+  do
+    AC_MSG_CHECKING([whether $CC accepts $i])
+    if test -z "`${CC} $i -c conftest.c 2>&1`"
+    then
+      lf_CFLAGS="${lf_CFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.c conftest.o
+  AC_SUBST(lf_CFLAGS)
+])
+
+# --------------------------------------------------------------------------
+# Check whether the Fortran compiler accepts a certain flag
+# If it does it adds the flag to lf_FFLAGS
+# If it does not then it returns an error to lf_ok
+# Usage:
+#  LF_CHECK_F77_FLAG(-flag1 -flag2 -flag3 ...)
+# -------------------------------------------------------------------------
+
+AC_DEFUN([LF_CHECK_F77_FLAG],[
+  cat << EOF > conftest.f
+c....:++++++++++++++++++++++++
+      PROGRAM MAIN
+      PRINT*,'Hello World!'
+      END
+EOF
+  for i in $1
+  do
+    AC_MSG_CHECKING([whether $F77 accepts $i])
+    if test -z "`${F77} $i -c conftest.f 2>&1`"
+    then
+      lf_FFLAGS="${lf_FFLAGS} $i"
+      AC_MSG_RESULT(yes)  
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.f conftest.o
+  AC_SUBST(lf_FFLAGS)
+])
+
+# ----------------------------------------------------------------------
+# Enable compiler warnings. 
+# Call this command AFTER you have configured ALL your compilers. 
+# ----------------------------------------------------------------------
+
+AC_DEFUN([LF_SET_WARNINGS],[
+  dnl Warnings for the two main compilers
+  dnl add -Wextra when you're got time to fix a bunch of them ;-)
+  cc_warning_flags="-Wall -Werror-implicit-function-declaration"
+  cxx_warning_flags="-Wall -Woverloaded-virtual"
+  if test -n "${CC}"
+  then
+    LF_CHECK_CC_FLAG($cc_warning_flags)
+  fi
+  if test -n "${CXX}" 
+  then
+    LF_CHECK_CXX_FLAG($cxx_warning_flags)
+  fi
+])
diff --git a/gr-howto-write-a-block/config/lf_x11.m4 b/gr-howto-write-a-block/config/lf_x11.m4
new file mode 100644 (file)
index 0000000..460cd60
--- /dev/null
@@ -0,0 +1,39 @@
+dnl Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
+dnl  
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software 
+dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.
+dnl 
+dnl As a special exception to the GNU General Public License, if you 
+dnl distribute this file as part of a program that contains a configuration 
+dnl script generated by Autoconf, you may include it under the same 
+dnl distribution terms that you use for the rest of that program.
+
+#-----------------------------------------------------------------------
+# This macro searches for Xlib and when it finds it it adds the 
+# appropriate flags to CXXFLAGS and export the link sequence to 
+# the variable XLIB. 
+# In your configure.in file add:
+#   LF_PATH_XLIB
+# In your Makefile.am add
+#   program_LDADD = .... $(XLIB)
+#------------------------------------------------------------------------
+
+AC_DEFUN([LF_PATH_XLIB],[
+  AC_PATH_XTRA
+  CXXFLAGS="$CXXFLAGS $X_CFLAGS"
+  XLIB="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+  AC_SUBST(XLIB)
+])
+
diff --git a/gr-howto-write-a-block/config/mkstemp.m4 b/gr-howto-write-a-block/config/mkstemp.m4
new file mode 100644 (file)
index 0000000..4af0f0a
--- /dev/null
@@ -0,0 +1,89 @@
+#serial 4
+
+# On some hosts (e.g., HP-UX 10.20, SunOS 4.1.4, Solaris 2.5.1), mkstemp has a
+# silly limit that it can create no more than 26 files from a given template.
+# Other systems lack mkstemp altogether.
+# On OSF1/Tru64 V4.0F, the system-provided mkstemp function can create
+# only 32 files per process.
+# On systems like the above, arrange to use the replacement function.
+AC_DEFUN([UTILS_FUNC_MKSTEMP],
+[dnl
+  AC_REPLACE_FUNCS(mkstemp)
+  if test $ac_cv_func_mkstemp = no; then
+    utils_cv_func_mkstemp_limitations=yes
+  else
+    AC_CACHE_CHECK([for mkstemp limitations],
+      utils_cv_func_mkstemp_limitations,
+      [
+       AC_TRY_RUN([
+#         include <stdlib.h>
+         int main ()
+         {
+           int i;
+           for (i = 0; i < 70; i++)
+             {
+               char template[] = "conftestXXXXXX";
+               int fd = mkstemp (template);
+               if (fd == -1)
+                 exit (1);
+               close (fd);
+             }
+           exit (0);
+         }
+         ],
+       utils_cv_func_mkstemp_limitations=no,
+       utils_cv_func_mkstemp_limitations=yes,
+       utils_cv_func_mkstemp_limitations=yes
+       )
+      ]
+    )
+  fi
+
+  if test $utils_cv_func_mkstemp_limitations = yes; then
+    AC_LIBOBJ(mkstemp)
+    AC_LIBOBJ(tempname)
+    AC_DEFINE(mkstemp, rpl_mkstemp,
+      [Define to rpl_mkstemp if the replacement function should be used.])
+    gl_PREREQ_MKSTEMP
+    jm_PREREQ_TEMPNAME
+  fi
+])
+
+# Prerequisites of lib/mkstemp.c.
+AC_DEFUN([gl_PREREQ_MKSTEMP],
+[
+  AH_BOTTOM(
+  [
+  #ifndef HAVE_MKSTEMP
+  #ifdef  __cplusplus
+  extern "C" {
+  #endif
+  int rpl_mkstemp (char *templ);
+  #ifdef  __cplusplus
+  }
+  #endif
+  #endif
+  ])
+])
+
+# Prerequisites of lib/tempname.c.
+AC_DEFUN([jm_PREREQ_TEMPNAME],
+[
+  AC_REQUIRE([AC_HEADER_STAT])
+  AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h unistd.h)
+  AC_CHECK_HEADERS(stdint.h)
+  AC_CHECK_FUNCS(__secure_getenv gettimeofday lstat)
+  AC_CHECK_DECLS_ONCE(getenv)
+  # AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])
+
+  dnl Under Win32, mkdir prototype in io.h has only one arg
+  AC_MSG_CHECKING(whether mkdir accepts only one arg)
+  AC_TRY_COMPILE([#include <sys/types.h>
+       #include <sys/stat.h>
+       #include <fcntl.h>], [
+       mkdir("")
+  ], [ AC_MSG_RESULT(yes)
+     AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ],
+   [ AC_MSG_RESULT(no)
+     ])
+])
diff --git a/gr-howto-write-a-block/config/onceonly.m4 b/gr-howto-write-a-block/config/onceonly.m4
new file mode 100644 (file)
index 0000000..f6fec37
--- /dev/null
@@ -0,0 +1,63 @@
+# onceonly.m4 serial 3
+dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl This file defines some "once only" variants of standard autoconf macros.
+dnl   AC_CHECK_HEADERS_ONCE         like  AC_CHECK_HEADERS
+dnl   AC_CHECK_FUNCS_ONCE           like  AC_CHECK_FUNCS
+dnl   AC_CHECK_DECLS_ONCE           like  AC_CHECK_DECLS
+dnl   AC_REQUIRE([AC_HEADER_STDC])  like  AC_HEADER_STDC
+dnl The advantage is that the check for each of the headers/functions/decls
+dnl will be put only once into the 'configure' file. It keeps the size of
+dnl the 'configure' file down, and avoids redundant output when 'configure'
+dnl is run.
+dnl The drawback is that the checks cannot be conditionalized. If you write
+dnl   if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi
+dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to
+dnl empty, and the check will be inserted before the body of the AC_DEFUNed
+dnl function.
+
+dnl Autoconf version 2.57 or newer is recommended.
+AC_PREREQ(2.54)
+
+# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of
+# AC_CHECK_HEADERS(HEADER1 HEADER2 ...).
+AC_DEFUN([AC_CHECK_HEADERS_ONCE], [
+  :
+  AC_FOREACH([gl_HEADER_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(defn([gl_HEADER_NAME]),
+                                                 [-./], [___])), [
+      AC_CHECK_HEADERS(gl_HEADER_NAME)
+    ])
+    AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME,
+                                                   [-./], [___])))
+  ])
+])
+
+# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of
+# AC_CHECK_FUNCS(FUNC1 FUNC2 ...).
+AC_DEFUN([AC_CHECK_FUNCS_ONCE], [
+  :
+  AC_FOREACH([gl_FUNC_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_FUNC_]defn([gl_FUNC_NAME]), [
+      AC_CHECK_FUNCS(defn([gl_FUNC_NAME]))
+    ])
+    AC_REQUIRE([gl_CHECK_FUNC_]defn([gl_FUNC_NAME]))
+  ])
+])
+
+# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of
+# AC_CHECK_DECLS(DECL1, DECL2, ...).
+AC_DEFUN([AC_CHECK_DECLS_ONCE], [
+  :
+  AC_FOREACH([gl_DECL_NAME], [$1], [
+    AC_DEFUN([gl_CHECK_DECL_]defn([gl_DECL_NAME]), [
+      AC_CHECK_DECLS(defn([gl_DECL_NAME]))
+    ])
+    AC_REQUIRE([gl_CHECK_DECL_]defn([gl_DECL_NAME]))
+  ])
+])
diff --git a/gr-howto-write-a-block/config/pkg.m4 b/gr-howto-write-a-block/config/pkg.m4
new file mode 100644 (file)
index 0000000..80bdfed
--- /dev/null
@@ -0,0 +1,188 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# 
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>.
+# Copyright Â© 2008 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=m4_default([$1], [0.18])
+       AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               PKG_CONFIG=""
+       fi
+               
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+    if test -n "$$1"; then
+        pkg_cv_[]$1="$$1"
+    else
+        PKG_CHECK_EXISTS([$3],
+                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                        [pkg_failed=yes])
+    fi
+else
+       pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+# E.g.,
+#   PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+#   defines:
+#
+#     GSTUFF_LIBS
+#     GSTUFF_CFLAGS
+#     GSTUFF_INCLUDEDIR
+#     GSTUFF_CPPFLAGS    # the -I, -D and -U's out of CFLAGS
+#
+# see pkg-config man page also defines GSTUFF_PKG_ERRORS on error
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_INCLUDEDIR], [includedir for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+
+if test x$cross_compiling = xyes
+then
+  _PKG_CONFIG([$1][_LIBS], [libs-only-l --static], [$2])
+else
+  _PKG_CONFIG([$1][_LIBS], [libs --static], [$2])
+fi
+
+_PKG_CONFIG([$1][_INCLUDEDIR], [variable=includedir], [$2])
+
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+        else 
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+       ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+               [AC_MSG_RESULT([no])
+                $4])
+elif test $pkg_failed = untried; then
+       ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
+               [$4])
+else
+       $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+       $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+       $1[]_INCLUDEDIR=$pkg_cv_[]$1[]_INCLUDEDIR
+
+       $1[]_CPPFLAGS=""
+       for flag in $$1[]_CFLAGS; do
+         case $flag in
+          -I* | -D* | -U*) $1[]_CPPFLAGS="$$1[]_CPPFLAGS $flag" ;;
+          esac
+        done
+       pkg_cv_[]$1[]_CPPFLAGS=$$1[]_CPPFLAGS
+       AC_SUBST($1[]_CPPFLAGS)
+
+        AC_MSG_RESULT([yes])
+       ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
diff --git a/gr-howto-write-a-block/config/usrp_fusb_tech.m4 b/gr-howto-write-a-block/config/usrp_fusb_tech.m4
new file mode 100644 (file)
index 0000000..b99cf24
--- /dev/null
@@ -0,0 +1,87 @@
+dnl
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+dnl 
+
+# $1 is $enable_usrp:
+#   yes : do these tests
+#   no  : do not do these tests
+#   ""  : do these tests
+
+AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
+  req_libusb1=no
+  USE_LIBUSB1=0
+  AC_ARG_WITH([fusb-tech],
+              AC_HELP_STRING([--with-fusb-tech=OS],
+                            [Set fast USB technique (default=auto)]),
+             [cf_with_fusb_tech="$withval"],
+             [cf_with_fusb_tech="$host_os"])
+  if test [x]$1 != xno; then
+      case "$cf_with_fusb_tech" in
+        libusb1*)
+          FUSB_TECH=libusb1
+          req_libusb1=yes
+         USE_LIBUSB1=1
+          ;;
+        linux*)
+          AC_CHECK_HEADER([linux/usbdevice_fs.h],
+                         [x_have_usbdevice_fs_h=yes],
+                          [x_have_usbdevice_fs_h=no])
+          if test x${x_have_usbdevice_fs_h} = xyes; then
+              FUSB_TECH=linux
+          else
+              FUSB_TECH=generic
+          fi
+          ;;
+        darwin*)
+          FUSB_TECH=darwin
+          ;;
+        cygwin*|win*|mingw*)
+          FUSB_TECH=win32
+          ;;
+        *bsd*)
+          AC_MSG_CHECKING([for RA/WB])
+          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <dev/usb/usb.h>]],
+                                            [[struct usb_bulk_ra_wb_opt o;
+                                              ioctl(0, USB_SET_BULK_RA, &o);]])],
+                           [FUSB_TECH=ra_wb],
+                           [FUSB_TECH=generic])
+          ;;
+        *)
+          FUSB_TECH=generic
+          ;;
+      esac
+
+      AC_MSG_CHECKING([for fast usb technique to use])
+      AC_MSG_RESULT($FUSB_TECH)
+      AC_SUBST(FUSB_TECH)
+  fi
+
+  AM_CONDITIONAL(FUSB_TECH_darwin,   test x$FUSB_TECH = xdarwin)
+  AM_CONDITIONAL(FUSB_TECH_win32,    test x$FUSB_TECH = xwin32)
+  AM_CONDITIONAL(FUSB_TECH_generic,  test x$FUSB_TECH = xgeneric)
+  AM_CONDITIONAL(FUSB_TECH_linux,    test x$FUSB_TECH = xlinux)
+  AM_CONDITIONAL(FUSB_TECH_libusb1,  test x$FUSB_TECH = xlibusb1)
+  AM_CONDITIONAL(FUSB_TECH_ra_wb,    test x$FUSB_TECH = xra_wb)
+
+  AC_SUBST(USE_LIBUSB1)
+  AC_CONFIG_FILES([\
+       usrp/host/include/usrp/libusb_types.h \
+  ])
+])
diff --git a/gr-howto-write-a-block/config/usrp_libusb.m4 b/gr-howto-write-a-block/config/usrp_libusb.m4
new file mode 100644 (file)
index 0000000..cb3130c
--- /dev/null
@@ -0,0 +1,48 @@
+dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([USRP_LIBUSB], [
+    libusbok=yes
+    PKG_CHECK_MODULES(USB, libusb, [], [
+        AC_LANG_PUSH(C)
+
+       AC_CHECK_HEADERS([usb.h], [], [libusbok=no; AC_MSG_RESULT([USRP requires libusb. usb.h not found. See http://libusb.sf.net])])
+
+       save_LIBS="$LIBS"
+       case "$host_os" in
+         darwin*)
+           LIBS="$LIBS -lIOKit"
+            ;;
+         *) ;;
+        esac
+
+       AC_SEARCH_LIBS(usb_bulk_write, [usb], [USB_LIBS="$LIBS"], [libusbok=no; AC_MSG_RESULT([USRP requires libusb. usb_bulk_write not found. See http://libusb.sf.net])])
+
+        LIBS="$save_LIBS"
+
+        AC_LANG_POP
+    ])
+
+    if test x$libusbok = xyes; then
+        AC_SUBST(USB_LIBS)
+       ifelse([$1], , :, [$1])
+    else
+        ifelse([$2], , :, [$2])
+    fi
+])
diff --git a/gr-howto-write-a-block/config/usrp_sdcc.m4 b/gr-howto-write-a-block/config/usrp_sdcc.m4
new file mode 100644 (file)
index 0000000..86f6429
--- /dev/null
@@ -0,0 +1,75 @@
+# Check for sdcc support.                      -*- Autoconf -*-
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# This program 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Boston, MA
+# 02110-1301, USA.
+
+AC_DEFUN([USRP_SDCC],
+[
+       sdccok=yes
+       AC_CHECK_PROG(XCC, sdcc, sdcc -mmcs51 --no-xinit-opt,no)
+       AC_CHECK_PROG(XAS, asx8051, asx8051 -plosgff,no)
+
+       if test "$XCC" = "no" -o "$XAS" = "no" ; then
+               AC_MSG_RESULT([USRP requires sdcc. sdcc not found. See http://sdcc.sf.net])
+               sdccok=no
+       else
+               sdcc_version_min=$1
+
+               sdcc_version=`sdcc --version 2>&1 | \
+                       sed  's/\(SDCC.* \)\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\)\( .*$\)/\2/'`
+
+               AC_MSG_CHECKING([sdcc_version "$sdcc_version"])
+
+               sdcc_major_version=`echo $sdcc_version | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+               sdcc_minor_version=`echo $sdcc_version | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+               sdcc_micro_version=`echo $sdcc_version | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+               sdcc_major_min=`echo $sdcc_version_min | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+               sdcc_minor_min=`echo $sdcc_version_min | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+               sdcc_micro_min=`echo $sdcc_version_min | \
+                       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+               sdcc_version_proper=`expr \
+                       "$sdcc_major_version" \> "$sdcc_major_min" \| \
+                       "$sdcc_major_version" \= "$sdcc_major_min" \& \
+                       "$sdcc_minor_version" \> "$sdcc_minor_min" \| \
+                       "$sdcc_major_version" \= "$sdcc_major_min" \& \
+                       "$sdcc_minor_version" \= "$sdcc_minor_min" \& \
+                       "$sdcc_micro_version" \>= "$sdcc_micro_min" `
+
+               if test "$sdcc_version_proper" = "1" ; then
+                       AC_MSG_RESULT([$sdcc_major_version.$sdcc_minor_version.$sdcc_micro_version])
+               else
+                       sdccok=no
+                       AC_MSG_RESULT([USRP requires sdcc >= $sdcc_version_min. sdcc not found. See http://sdcc.sf.net])
+               fi
+
+               AC_SUBST(XCC)
+               AC_SUBST(XAS)
+       fi
+
+       if test $sdccok = yes; then
+               ifelse([$2], , :, [$2])
+       else
+               ifelse([$3], , :, [$3])
+       fi
+])
diff --git a/gr-howto-write-a-block/configure.ac b/gr-howto-write-a-block/configure.ac
new file mode 100644 (file)
index 0000000..52c4639
--- /dev/null
@@ -0,0 +1,88 @@
+dnl 
+dnl  Copyright 2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+dnl  
+dnl  This file is part of GNU Radio
+dnl  
+dnl  GNU Radio is free software; you can redistribute it and/or modify
+dnl  it under the terms of the GNU General Public License as published by
+dnl  the Free Software Foundation; either version 3, or (at your option)
+dnl  any later version.
+dnl  
+dnl  GNU Radio is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl  GNU General Public License for more details.
+dnl  
+dnl  You should have received a copy of the GNU General Public License
+dnl  along with GNU Radio; see the file COPYING.  If not, write to
+dnl  the Free Software Foundation, Inc., 51 Franklin Street,
+dnl  Boston, MA 02110-1301, USA.
+dnl 
+
+
+AC_INIT
+AC_PREREQ(2.57)
+AC_CONFIG_AUX_DIR([.]) 
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+GR_VERSION
+dnl ustar required to have pathnames > 99 chars
+_AM_SET_OPTION([tar-ustar])
+AM_INIT_AUTOMAKE(gr-howto-write-a-block,$RELEASE)
+
+dnl This is kind of non-standard, but it sure shortens up this file :-)
+m4_include([config/gr_standalone.m4])
+GR_STANDALONE
+
+dnl Check for any libraries you need
+dnl AC_CHECK_LIBRARY
+
+dnl Check for header files you need
+dnl AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h unistd.h)
+dnl AC_CHECK_HEADERS(sys/mman.h)
+
+dnl Checks for library functions.
+dnl AC_CHECK_FUNCS([])
+
+dnl We pick up the boost cppflags, cxxflags and thread lib via GNURADIO_CORE
+dnl
+dnl If you need additional boost libraries, you'll need to
+dnl uncomment AX_BOOST_BASE, plus some of the following:
+dnl
+dnl calls AC_SUBST(BOOST_CPPFLAGS), AC_SUBST(BOOST_LDFLAGS) and defines HAVE_BOOST
+dnl AX_BOOST_BASE([1.35])
+dnl
+dnl All the rest of these call AC_SUBST(BOOST_<foo>_LIB) and define HAVE_BOOST_<foo>
+dnl
+dnl AX_BOOST_DATE_TIME
+dnl AX_BOOST_FILESYSTEM
+dnl AX_BOOST_IOSTREAMS
+dnl AX_BOOST_PROGRAM_OPTIONS
+dnl AX_BOOST_REGEX
+dnl AX_BOOST_SERIALIZATION
+dnl AX_BOOST_SIGNALS
+dnl AX_BOOST_SYSTEM
+dnl AX_BOOST_TEST_EXEC_MONITOR
+dnl AX_BOOST_UNIT_TEST_FRAMEWORK
+dnl AX_BOOST_WSERIALIZATION
+
+AC_CONFIG_FILES([\
+         Makefile \
+         apps/Makefile \
+         config/Makefile \
+         grc/Makefile \
+         lib/Makefile \
+         python/Makefile \
+         python/run_tests \
+         swig/Makefile \
+       ])
+
+dnl run_tests is created from run_tests.in.  Make it executable.
+AC_CONFIG_COMMANDS([run_tests], [chmod +x python/run_tests])
+
+AC_OUTPUT
+
+echo Configured gr-howto-write-a-block release $RELEASE for build.
diff --git a/gr-howto-write-a-block/grc/.gitignore b/gr-howto-write-a-block/grc/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-howto-write-a-block/grc/Makefile.am b/gr-howto-write-a-block/grc/Makefile.am
new file mode 100644 (file)
index 0000000..32dcf1b
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+grcblocksdir = $(grc_blocksdir)
+
+dist_grcblocks_DATA = \
+       howto_square_ff.xml \
+       howto_square2_ff.xml
+
diff --git a/gr-howto-write-a-block/grc/howto_square2_ff.xml b/gr-howto-write-a-block/grc/howto_square2_ff.xml
new file mode 100644 (file)
index 0000000..c58ef00
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<block>
+  <name>Square2</name>
+  <key>howto_square2_ff</key>
+  <category>HOWTO</category>
+  <import>import howto</import>
+  <make>howto.square2_ff()</make>
+
+  <sink>
+    <name>in</name>
+    <type>float</type>
+  </sink>
+
+  <source>
+    <name>out</name>
+    <type>float</type>
+  </source>
+</block>
diff --git a/gr-howto-write-a-block/grc/howto_square_ff.xml b/gr-howto-write-a-block/grc/howto_square_ff.xml
new file mode 100644 (file)
index 0000000..34a0b0a
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<block>
+  <name>Square</name>
+  <key>howto_square_ff</key>
+  <category>HOWTO</category>
+  <import>import howto</import>
+  <make>howto.square_ff()</make>
+
+  <sink>
+    <name>in</name>
+    <type>float</type>
+  </sink>
+
+  <source>
+    <name>out</name>
+    <type>float</type>
+  </source>
+</block>
diff --git a/gr-howto-write-a-block/lib/.gitignore b/gr-howto-write-a-block/lib/.gitignore
new file mode 100644 (file)
index 0000000..b1e56d3
--- /dev/null
@@ -0,0 +1,12 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/howto.cc
+/howto.py
+/test_all
\ No newline at end of file
diff --git a/gr-howto-write-a-block/lib/Makefile.am b/gr-howto-write-a-block/lib/Makefile.am
new file mode 100644 (file)
index 0000000..f0a1835
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# Copyright 2004,2005,2006,2008,2009,2010 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# list of programs run by "make check" and "make distcheck"
+TESTS = test_all
+
+# ----------------------------------------------------------------
+# howto C++ library: libgnuradio-howto.so
+# ----------------------------------------------------------------
+
+# C/C++ headers get installed in ${prefix}/include/$(modname)
+modinclude_HEADERS = \
+       howto_square_ff.h \
+       howto_square2_ff.h
+
+lib_LTLIBRARIES = libgnuradio-howto.la
+
+libgnuradio_howto_la_SOURCES = \
+       howto_square_ff.cc \
+       howto_square2_ff.cc
+
+libgnuradio_howto_la_LIBADD = \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_howto_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+# ----------------------------------------------------------------
+# howto C++ QA library: libgnuradio-howto-qa.so (not installed)
+# ----------------------------------------------------------------
+
+noinst_LTLIBRARIES = libgnuradio-howto-qa.la
+
+libgnuradio_howto_qa_la_SOURCES = \
+       qa_howto.cc \
+       qa_howto_square_ff.cc \
+       qa_howto_square2_ff.cc
+
+libgnuradio_howto_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libgnuradio_howto_qa_la_LIBADD = \
+       libgnuradio-howto.la \
+       $(CPPUNIT_LIBS)
+
+# ----------------------------------------------------------------
+# headers that don't get installed
+# ----------------------------------------------------------------
+noinst_HEADERS = \
+       qa_howto.h \
+       qa_howto_square_ff.h \
+       qa_howto_square2_ff.h
+
+# ----------------------------------------------------------------
+# test program
+# ----------------------------------------------------------------
+noinst_PROGRAMS = \
+       test_all
+
+test_all_SOURCES = test_all.cc
+test_all_LDADD   = libgnuradio-howto-qa.la
diff --git a/gr-howto-write-a-block/lib/howto_square2_ff.cc b/gr-howto-write-a-block/lib/howto_square2_ff.cc
new file mode 100644 (file)
index 0000000..e86db93
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+/*
+ * config.h is generated by configure.  It contains the results
+ * of probing for features, options etc.  It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <howto_square2_ff.h>
+#include <gr_io_signature.h>
+
+/*
+ * Create a new instance of howto_square2_ff and return
+ * a boost shared_ptr.  This is effectively the public constructor.
+ */
+howto_square2_ff_sptr 
+howto_make_square2_ff ()
+{
+  return howto_square2_ff_sptr (new howto_square2_ff ());
+}
+
+/*
+ * Specify constraints on number of input and output streams.
+ * This info is used to construct the input and output signatures
+ * (2nd & 3rd args to gr_block's constructor).  The input and
+ * output signatures are used by the runtime system to
+ * check that a valid number and type of inputs and outputs
+ * are connected to this block.  In this case, we accept
+ * only 1 input and 1 output.
+ */
+static const int MIN_IN = 1;   // mininum number of input streams
+static const int MAX_IN = 1;   // maximum number of input streams
+static const int MIN_OUT = 1;  // minimum number of output streams
+static const int MAX_OUT = 1;  // maximum number of output streams
+
+/*
+ * The private constructor
+ */
+howto_square2_ff::howto_square2_ff ()
+  : gr_sync_block ("square2_ff",
+                  gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
+                  gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
+{
+  // nothing else required in this example
+}
+
+/*
+ * Our virtual destructor.
+ */
+howto_square2_ff::~howto_square2_ff ()
+{
+  // nothing else required in this example
+}
+
+int 
+howto_square2_ff::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = in[i] * in[i];
+  }
+
+  // Tell runtime system how many output items we produced.
+  return noutput_items;
+}
diff --git a/gr-howto-write-a-block/lib/howto_square2_ff.h b/gr-howto-write-a-block/lib/howto_square2_ff.h
new file mode 100644 (file)
index 0000000..536b04f
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_HOWTO_SQUARE2_FF_H
+#define INCLUDED_HOWTO_SQUARE2_FF_H
+
+#include <gr_sync_block.h>
+
+class howto_square2_ff;
+
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures).  The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues.  This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<howto_square2_ff> howto_square2_ff_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of howto_square2_ff.
+ *
+ * To avoid accidental use of raw pointers, howto_square2_ff's
+ * constructor is private.  howto_make_square2_ff is the public
+ * interface for creating new instances.
+ */
+howto_square2_ff_sptr howto_make_square2_ff ();
+
+/*!
+ * \brief square2 a stream of floats.
+ * \ingroup block
+ *
+ * This uses the preferred technique: subclassing gr_sync_block.
+ */
+class howto_square2_ff : public gr_sync_block
+{
+private:
+  // The friend declaration allows howto_make_square2_ff to
+  // access the private constructor.
+
+  friend howto_square2_ff_sptr howto_make_square2_ff ();
+
+  howto_square2_ff ();         // private constructor
+
+ public:
+  ~howto_square2_ff ();        // public destructor
+
+  // Where all the action really happens
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_HOWTO_SQUARE2_FF_H */
diff --git a/gr-howto-write-a-block/lib/howto_square_ff.cc b/gr-howto-write-a-block/lib/howto_square_ff.cc
new file mode 100644 (file)
index 0000000..5ab45d1
--- /dev/null
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+/*
+ * config.h is generated by configure.  It contains the results
+ * of probing for features, options etc.  It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <howto_square_ff.h>
+#include <gr_io_signature.h>
+
+/*
+ * Create a new instance of howto_square_ff and return
+ * a boost shared_ptr.  This is effectively the public constructor.
+ */
+howto_square_ff_sptr 
+howto_make_square_ff ()
+{
+  return howto_square_ff_sptr (new howto_square_ff ());
+}
+
+/*
+ * Specify constraints on number of input and output streams.
+ * This info is used to construct the input and output signatures
+ * (2nd & 3rd args to gr_block's constructor).  The input and
+ * output signatures are used by the runtime system to
+ * check that a valid number and type of inputs and outputs
+ * are connected to this block.  In this case, we accept
+ * only 1 input and 1 output.
+ */
+static const int MIN_IN = 1;   // mininum number of input streams
+static const int MAX_IN = 1;   // maximum number of input streams
+static const int MIN_OUT = 1;  // minimum number of output streams
+static const int MAX_OUT = 1;  // maximum number of output streams
+
+/*
+ * The private constructor
+ */
+howto_square_ff::howto_square_ff ()
+  : gr_block ("square_ff",
+             gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
+             gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
+{
+  // nothing else required in this example
+}
+
+/*
+ * Our virtual destructor.
+ */
+howto_square_ff::~howto_square_ff ()
+{
+  // nothing else required in this example
+}
+
+int 
+howto_square_ff::general_work (int noutput_items,
+                              gr_vector_int &ninput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = in[i] * in[i];
+  }
+
+  // Tell runtime system how many input items we consumed on
+  // each input stream.
+
+  consume_each (noutput_items);
+
+  // Tell runtime system how many output items we produced.
+  return noutput_items;
+}
diff --git a/gr-howto-write-a-block/lib/howto_square_ff.h b/gr-howto-write-a-block/lib/howto_square_ff.h
new file mode 100644 (file)
index 0000000..092b936
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_HOWTO_SQUARE_FF_H
+#define INCLUDED_HOWTO_SQUARE_FF_H
+
+#include <gr_block.h>
+
+class howto_square_ff;
+
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures).  The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues.  This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<howto_square_ff> howto_square_ff_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of howto_square_ff.
+ *
+ * To avoid accidental use of raw pointers, howto_square_ff's
+ * constructor is private.  howto_make_square_ff is the public
+ * interface for creating new instances.
+ */
+howto_square_ff_sptr howto_make_square_ff ();
+
+/*!
+ * \brief square a stream of floats.
+ * \ingroup block
+ *
+ * \sa howto_square2_ff for a version that subclasses gr_sync_block.
+ */
+class howto_square_ff : public gr_block
+{
+private:
+  // The friend declaration allows howto_make_square_ff to
+  // access the private constructor.
+
+  friend howto_square_ff_sptr howto_make_square_ff ();
+
+  howto_square_ff ();          // private constructor
+
+ public:
+  ~howto_square_ff (); // public destructor
+
+  // Where all the action really happens
+
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_HOWTO_SQUARE_FF_H */
diff --git a/gr-howto-write-a-block/lib/qa_howto.cc b/gr-howto-write-a-block/lib/qa_howto.cc
new file mode 100644 (file)
index 0000000..f1411a3
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 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 class gathers together all the test cases for the example
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_howto.h>
+#include <qa_howto_square_ff.h>
+#include <qa_howto_square2_ff.h>
+
+CppUnit::TestSuite *
+qa_howto::suite()
+{
+  CppUnit::TestSuite *s = new CppUnit::TestSuite("howto");
+
+  s->addTest(qa_howto_square_ff::suite());
+  s->addTest(qa_howto_square2_ff::suite());
+
+  return s;
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto.h b/gr-howto-write-a-block/lib/qa_howto.h
new file mode 100644 (file)
index 0000000..fa5a42f
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 Example 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 Example Public License for more details.
+ * 
+ * You should have received a copy of the GNU Example 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.
+ */
+
+#ifndef INCLUDED_QA_HOWTO_H
+#define INCLUDED_QA_HOWTO_H
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the example directory
+
+class qa_howto {
+ public:
+  //! return suite of tests for all of example directory
+  static CppUnit::TestSuite *suite ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_H */
diff --git a/gr-howto-write-a-block/lib/qa_howto_square2_ff.cc b/gr-howto-write-a-block/lib/qa_howto_square2_ff.cc
new file mode 100644 (file)
index 0000000..a374651
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <qa_howto_square2_ff.h>
+#include <cppunit/TestAssert.h>
+
+void
+qa_howto_square2_ff::t1()
+{
+  // Insert CPPUNIT tests/asserts here
+}
+
+void
+qa_howto_square2_ff::t2()
+{
+  // Insert CPPUNIT tests/asserts here
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto_square2_ff.h b/gr-howto-write-a-block/lib/qa_howto_square2_ff.h
new file mode 100644 (file)
index 0000000..c74d086
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_HOWTO_SQUARE2_FF_H
+#define INCLUDED_QA_HOWTO_SQUARE2_FF_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_howto_square2_ff : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_howto_square2_ff);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+  void t2 ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_SQUARE2_FF_H */
diff --git a/gr-howto-write-a-block/lib/qa_howto_square_ff.cc b/gr-howto-write-a-block/lib/qa_howto_square_ff.cc
new file mode 100644 (file)
index 0000000..2f0b597
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <qa_howto_square_ff.h>
+#include <cppunit/TestAssert.h>
+
+void
+qa_howto_square_ff::t1()
+{
+  // Insert CPPUNIT tests/asserts here
+}
+
+void
+qa_howto_square_ff::t2()
+{
+  // Insert CPPUNIT tests/asserts here
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto_square_ff.h b/gr-howto-write-a-block/lib/qa_howto_square_ff.h
new file mode 100644 (file)
index 0000000..1b7c5e9
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_HOWTO_SQUARE_FF_H
+#define INCLUDED_QA_HOWTO_SQUARE_FF_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_howto_square_ff : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_howto_square_ff);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+  void t2 ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_SQUARE_FF_H */
diff --git a/gr-howto-write-a-block/lib/test_all.cc b/gr-howto-write-a-block/lib/test_all.cc
new file mode 100644 (file)
index 0000000..192c537
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+
+#include <qa_howto.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner runner;
+
+  runner.addTest(qa_howto::suite ());
+  
+  bool was_successful = runner.run("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gr-howto-write-a-block/python/.gitignore b/gr-howto-write-a-block/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-howto-write-a-block/python/Makefile.am b/gr-howto-write-a-block/python/Makefile.am
new file mode 100644 (file)
index 0000000..ae36ea6
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Copyright 2004,2010 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+modpython_PYTHON = \
+       __init__.py
+
+noinst_PYTHON = \
+       qa_howto.py                     
diff --git a/gr-howto-write-a-block/python/__init__.py b/gr-howto-write-a-block/python/__init__.py
new file mode 100644 (file)
index 0000000..d4a41c2
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright 2008,2009 Free Software Foundation, Inc.
+# 
+# This application 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.
+# 
+# This application is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+# ----------------------------------------------------------------
+# Temporary workaround for ticket:181 (swig+python problem)
+import sys
+_RTLD_GLOBAL = 0
+try:
+    from dl import RTLD_GLOBAL as _RTLD_GLOBAL
+except ImportError:
+    try:
+       from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL
+    except ImportError:
+       pass
+    
+if _RTLD_GLOBAL != 0:
+    _dlopenflags = sys.getdlopenflags()
+    sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL)
+# ----------------------------------------------------------------
+
+
+# import swig generated symbols into the howto namespace
+from howto_swig import *
+
+# import any pure python here
+#
+
+# ----------------------------------------------------------------
+# Tail of workaround
+if _RTLD_GLOBAL != 0:
+    sys.setdlopenflags(_dlopenflags)      # Restore original flags
+# ----------------------------------------------------------------
diff --git a/gr-howto-write-a-block/python/qa_howto.py b/gr-howto-write-a-block/python/qa_howto.py
new file mode 100755 (executable)
index 0000000..630f57b
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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, gr_unittest
+import howto_swig
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_square_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto_swig.square_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+
+    def test_002_square2_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto_swig.square2_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-howto-write-a-block/python/run_tests.in b/gr-howto-write-a-block/python/run_tests.in
new file mode 100644 (file)
index 0000000..2c32539
--- /dev/null
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+# All this strange PYTHONPATH manipulation is required to run our
+# tests using our just built shared library and swig-generated python
+# code prior to installation.
+
+# build tree == src tree unless you're doing a VPATH build.  
+# If you don't know what a VPATH build is, you're not doing one.  Relax...
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+# Where to look in the build tree for our shared library
+libbld=@abs_top_builddir@/lib
+# Where to look in the build tree for swig generated python code
+libswig=@abs_top_builddir@/swig
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/python
+
+# Where to look for installed GNU Radio python modules
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+installed_pythondir=@pythondir@
+installed_pyexecdir=@pyexecdir@
+
+PYTHONPATH="$libbld:$libbld/.libs:$libswig:$libswig/.libs:$py:$installed_pythondir:$installed_pyexecdir:$PYTHONPATH"
+echo $PYTHONPATH
+
+export PYTHONPATH
+
+case "@host_os@" in
+  darwin*)
+    # FIXME: Code for Darwin guessed but not tested
+    # Special Code for executing on Darwin / Mac OS X only
+    if [ "$DYLD_LIBRARY_PATH" = "" ]
+    then
+       DYLD_LIBRARY_PATH=$libbld/.libs
+    else
+       DYLD_LIBRARY_PATH=$libbld/.libs:$DYLD_LIBRARY_PATH
+    fi
+    export DYLD_LIBRARY_PATH
+    ;;
+  cygwin*|win*|mingw*)
+    # Special Code for executing on Win32 variants only
+    if [ "$PATH" = "" ]
+    then
+       PATH=$libbld/.libs
+    else
+       PATH=$libbld/.libs:$PATH
+    fi
+    export PATH
+    ;;
+esac
+
+#
+# This is the simple part...
+# Run everything that matches qa_*.py and return the final result.
+#
+
+ok=yes
+for file in @srcdir@/qa_*.py
+do
+  if ! $file
+  then
+    ok=no
+  fi  
+done
+
+if [ $ok = yes ]
+then
+  exit 0
+else
+  exit 1
+fi
diff --git a/gr-howto-write-a-block/swig/.gitignore b/gr-howto-write-a-block/swig/.gitignore
new file mode 100644 (file)
index 0000000..7f4c478
--- /dev/null
@@ -0,0 +1,6 @@
+/.deps
+/.libs
+/Makefile.in
+/Makefile
+/howto_swig.cc
+/howto_swig.py
diff --git a/gr-howto-write-a-block/swig/Makefile.am b/gr-howto-write-a-block/swig/Makefile.am
new file mode 100644 (file)
index 0000000..4737ad6
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Copyright 2004,2005,2006,2008,2009,2010 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS += -I$(top_srcdir)/lib
+
+if PYTHON
+###################################
+# SWIG Python interface and library
+
+TOP_SWIG_IFILES = \
+       howto.i
+
+# Install so that they end up available as:
+#   import howto
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/$(modname)
+
+howto_la_swig_libadd =         \
+       $(top_builddir)/lib/libgnuradio-howto.la
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+
+# additional SWIG files to be installed
+howto_swiginclude_headers = \
+       howto_square_ff.i \
+       howto_square2_ff.i
+
+endif
diff --git a/gr-howto-write-a-block/swig/Makefile.swig.gen b/gr-howto-write-a-block/swig/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..6c6e662
--- /dev/null
@@ -0,0 +1,257 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for howto.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/howto
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/howto
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+howto_pythondir = $(pythondir)/howto
+howto_pylibdir = $(pyexecdir)/howto
+
+## SWIG headers are always installed into the same directory.
+
+howto_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/howto-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += howto_swig.py howto_swig.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+howto_swiginclude_HEADERS =            \
+       howto.i                 \
+       $(howto_swiginclude_headers)
+
+howto_pylib_LTLIBRARIES =              \
+       _howto_swig.la
+
+_howto_swig_la_SOURCES =               \
+       howto_swig.cc                   \
+       $(howto_la_swig_sources)
+
+_howto_swig_la_LIBADD =                \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(howto_la_swig_libadd)
+
+_howto_swig_la_LDFLAGS =               \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(howto_la_swig_ldflags)
+
+_howto_swig_la_CXXFLAGS =              \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(howto_la_swig_cxxflags)
+
+howto_python_PYTHON =                  \
+       howto_swig.py                   \
+       $(howto_python)
+
+## Entry rule for running SWIG
+
+howto.h howto_swig.py howto_swig.cc: howto.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/howto-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/howto-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/howto-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/howto-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/howto-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/howto-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/howto-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/howto-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/howto-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(howto_swig_args) \
+               -MD -MF $(DEPDIR)/howto.Std \
+               -module howto_swig -o howto_swig.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/howto.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/howto.Std \
+                       > $(DEPDIR)/howto.Sd; \
+               $(RM) $(DEPDIR)/howto.Std; \
+               $(MV) $(DEPDIR)/howto.Sd $(DEPDIR)/howto.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/howto.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/howto.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/howto.Std $(DEPDIR)/howto.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/howto.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/howto.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/howto.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/howto.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/howto-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/howto.d@am__quote@
+
diff --git a/gr-howto-write-a-block/swig/howto.i b/gr-howto-write-a-block/swig/howto.i
new file mode 100644 (file)
index 0000000..8dc5020
--- /dev/null
@@ -0,0 +1,11 @@
+/* -*- c++ -*- */
+
+%include "gnuradio.i"                  // the common stuff
+
+%{
+#include "howto_square_ff.h"
+#include "howto_square2_ff.h"
+%}
+
+%include "howto_square_ff.i"
+%include "howto_square2_ff.i"
diff --git a/gr-howto-write-a-block/swig/howto_square2_ff.i b/gr-howto-write-a-block/swig/howto_square2_ff.i
new file mode 100644 (file)
index 0000000..683a93d
--- /dev/null
@@ -0,0 +1,9 @@
+GR_SWIG_BLOCK_MAGIC(howto,square2_ff);
+
+howto_square2_ff_sptr howto_make_square2_ff ();
+
+class howto_square2_ff : public gr_sync_block
+{
+private:
+  howto_square2_ff ();
+};
diff --git a/gr-howto-write-a-block/swig/howto_square_ff.i b/gr-howto-write-a-block/swig/howto_square_ff.i
new file mode 100644 (file)
index 0000000..f8ae769
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * First arg is the package prefix.
+ * Second arg is the name of the class minus the prefix.
+ *
+ * This does some behind-the-scenes magic so we can
+ * access howto_square_ff from python as howto.square_ff
+ */
+GR_SWIG_BLOCK_MAGIC(howto,square_ff);
+
+howto_square_ff_sptr howto_make_square_ff ();
+
+class howto_square_ff : public gr_block
+{
+private:
+  howto_square_ff ();
+};
diff --git a/gr-howto-write-a-block/version.sh b/gr-howto-write-a-block/version.sh
new file mode 100644 (file)
index 0000000..01a47b5
--- /dev/null
@@ -0,0 +1,4 @@
+MAJOR_VERSION=3
+API_COMPAT=3
+MINOR_VERSION=0
+MAINT_VERSION=0
diff --git a/gr-msdd6000/.gitignore b/gr-msdd6000/.gitignore
new file mode 100644 (file)
index 0000000..a37fc0c
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pc
diff --git a/gr-msdd6000/Makefile.am b/gr-msdd6000/Makefile.am
new file mode 100644 (file)
index 0000000..89405d0
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-msdd6000.pc
diff --git a/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf b/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf
new file mode 100644 (file)
index 0000000..34356da
Binary files /dev/null and b/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf differ
diff --git a/gr-msdd6000/gnuradio-msdd6000.pc.in b/gr-msdd6000/gnuradio-msdd6000.pc.in
new file mode 100644 (file)
index 0000000..5654207
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-comedi
+Description: GNU Radio blocks for the Softronics MSDD 6000
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-msdd6000
+Cflags: -I${includedir}
diff --git a/gr-msdd6000/src/.gitignore b/gr-msdd6000/src/.gitignore
new file mode 100644 (file)
index 0000000..ca4a54f
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/msdd.cc
+/msdd.py
+/msdd_rs.cc
+/msdd_rs.py
diff --git a/gr-msdd6000/src/Makefile.am b/gr-msdd6000/src/Makefile.am
new file mode 100644 (file)
index 0000000..f6dbd2f
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# Copyright 2007,2008,2009 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 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \
+       $(WITH_INCLUDES)
+
+# C/C++ headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       msdd_source_simple.h            \
+       msdd_buffer_copy_behaviors.h    \
+       msdd6000.h                      \
+       msdd_rs_source_simple.h         \
+       msdd6000_rs.h
+
+lib_LTLIBRARIES = libgnuradio-msdd6000.la \
+       libgnuradio-msdd6000_rs.la
+
+libgnuradio_msdd6000_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+libgnuradio_msdd6000_rs_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+libgnuradio_msdd6000_la_SOURCES =      \
+       msdd_source_simple.cc           \
+       msdd6000.cc
+
+
+libgnuradio_msdd6000_rs_la_SOURCES =   \
+       msdd_rs_source_simple.cc                \
+       msdd6000_rs.cc
+
+libgnuradio_msdd6000_la_LIBADD =       \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_msdd6000_rs_la_LIBADD =    \
+       $(GNURADIO_CORE_LA)
+
+
+if PYTHON
+#################################
+# SWIG interface and library
+
+TOP_SWIG_IFILES =                      \
+       msdd.i msdd_rs.i
+
+# Install so that they end up available as:
+#   import gnuradio.msdd
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+msdd_pythondir_category =              \
+       gnuradio
+
+msdd_rs_pythondir_category =   \
+       gnuradio
+
+# additional libraries for linking with the SWIG-generated library
+msdd_la_swig_libadd =                  \
+       libgnuradio-msdd6000.la
+
+msdd_rs_la_swig_libadd =                       \
+       libgnuradio-msdd6000_rs.la
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-msdd6000/src/Makefile.swig.gen b/gr-msdd6000/src/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..ced3979
--- /dev/null
@@ -0,0 +1,444 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for msdd.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/msdd
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/msdd
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+
+msdd_pythondir_category ?= gnuradio/msdd
+msdd_pylibdir_category ?= $(msdd_pythondir_category)
+msdd_pythondir = $(pythondir)/$(msdd_pythondir_category)
+msdd_pylibdir = $(pyexecdir)/$(msdd_pylibdir_category)
+
+msdd_rs_pythondir_category ?= gnuradio/msdd_rs
+msdd_rs_pylibdir_category ?= $(msdd_rs_pythondir_category)
+msdd_rs_pythondir = $(pythondir)/$(msdd_rs_pythondir_category)
+msdd_rs_pylibdir = $(pyexecdir)/$(msdd_rs_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+msdd_swigincludedir = $(swigincludedir)
+msdd_rs_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/msdd-generate-*
+STAMPS += $(DEPDIR)/msdd_rs-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += msdd.py msdd_rs.py msdd.cc msdd_rs.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+msdd_swiginclude_HEADERS =             \
+       msdd.i                          \
+       msdd_rs.i                       \
+       $(msdd_swiginclude_headers)
+
+msdd_pylib_LTLIBRARIES =               \
+       _msdd.la
+
+msdd_rs_pylib_LTLIBRARIES =            \
+        _msdd_rs.la
+
+_msdd_la_SOURCES =                     \
+       msdd.cc                         \
+       $(msdd_la_swig_sources)
+
+_msdd_rs_la_SOURCES =                          \
+    msdd_rs.cc                                 \
+    $(msdd_la_swig_sources)
+
+
+_msdd_la_LIBADD =                      \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(msdd_la_swig_libadd)
+
+_msdd_rs_la_LIBADD =                           \
+    $(STD_SWIG_LA_LIB_ADD)             \
+    $(msdd_rs_la_swig_libadd)
+
+_msdd_la_LDFLAGS =                     \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(msdd_la_swig_ldflags)
+
+_msdd_la_CXXFLAGS =                    \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(msdd_la_swig_cxxflags)
+
+_msdd_rs_la_LDFLAGS =                          \
+    $(STD_SWIG_LA_LD_FLAGS)            \
+    $(msdd_rs_la_swig_ldflags)
+
+_msdd_rs_la_CXXFLAGS =                         \
+    $(STD_SWIG_CXX_FLAGS)              \
+    $(msdd_rs_la_swig_cxxflags)
+
+msdd_python_PYTHON =                   \
+       msdd.py                         \
+       $(msdd_python)
+
+msdd_rs_python_PYTHON =                        \
+    msdd_rs.py                                 \
+    $(msdd_rs_python)
+
+## Entry rule for running SWIG
+
+msdd.h msdd.py msdd.cc: msdd.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/msdd-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/msdd-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/msdd-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/msdd-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/msdd-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/msdd-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/msdd-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/msdd-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/msdd-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(msdd_swig_args) \
+               -MD -MF $(DEPDIR)/msdd.Std \
+               -module msdd -o msdd.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/msdd.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/msdd.Std \
+                       > $(DEPDIR)/msdd.Sd; \
+               $(RM) $(DEPDIR)/msdd.Std; \
+               $(MV) $(DEPDIR)/msdd.Sd $(DEPDIR)/msdd.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/msdd.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/msdd.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/msdd.Std $(DEPDIR)/msdd.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/msdd.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/msdd.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/msdd.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/msdd.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/msdd-generate-stamp
+
+
+
+
+
+
+msdd_rs.h msdd_rs.py msdd_rs.cc: msdd_rs.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/msdd-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/msdd_rs-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/msdd_rs-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/msdd_rs-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/msdd_rs-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/msdd_rs-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/msdd_rs-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/msdd_rs-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/msdd_rs-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(msdd_rs_swig_args) \
+               -MD -MF $(DEPDIR)/msdd_rs.Std \
+               -module msdd_rs -o msdd_rs.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/msdd_rs.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/msdd_rs.Std \
+                       > $(DEPDIR)/msdd_rs.Sd; \
+               $(RM) $(DEPDIR)/msdd_rs.Std; \
+               $(MV) $(DEPDIR)/msdd_rs.Sd $(DEPDIR)/msdd_rs.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/msdd_rs.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/msdd_rs.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/msdd_rs.Std $(DEPDIR)/msdd_rs.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/msdd_rs.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/msdd_rs.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/msdd_rs.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/msdd_rs.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/msdd_rs-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+
+@am__include@ @am__quote@./$(DEPDIR)/msdd.d@am__quote@
+@am__include@ @am__quote@./$(DEPDIR)/msdd_rs.d@am__quote@
+
+
diff --git a/gr-msdd6000/src/README b/gr-msdd6000/src/README
new file mode 100644 (file)
index 0000000..230b7b6
--- /dev/null
@@ -0,0 +1,34 @@
+This block implements an interface between the Softronics MSDD6000 and GR
+
+Jul 13, 2008
+
+Tools / Waveforms
+       
+
+       - python-examples/new_msdd/fft.py
+               A clone of the original usrp_fft.py
+               adapted to work with the new msdd.source_simple
+               source block.
+               run ./new_msdd_fft.py -W 
+               for waterfall mode.
+               
+
+GNU Radio Blocks,
+
+       - msdd.source_simple
+               this block produces a stream of
+               interleaved complex shorts and 
+               currently works with FAPP.LDR
+               
+               if you want complex floats,
+               put a gr.interleaved_short_to_complex()
+               block immidiately following.
+
+       
+       - msdd.source_s / source_c / source_base
+               These were written with the
+               old TCP based app.ldr protocol
+               and will no longer work.
+               data was never streamed
+               without discontinuities
+               through this method.
diff --git a/gr-msdd6000/src/msdd.i b/gr-msdd6000/src/msdd.i
new file mode 100644 (file)
index 0000000..935bf2b
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"  // the common stuff
+
+%{
+#include "msdd_source_simple.h"
+%}
+
+
+GR_SWIG_BLOCK_MAGIC(msdd,source_simple)
+
+msdd_source_simple_sptr
+msdd_make_source_simple (
+       const char *src,
+       unsigned short port_src
+       );
+
+class msdd_source_simple : public gr_sync_block {
+  protected:
+    msdd_source_simple(
+       const char *src,
+       unsigned short port_src
+       );
+  public:
+    ~msdd_source_c(); 
+  int work (int noutput_items,
+      gr_vector_const_void_star &input_items,
+      gr_vector_void_star &output_items);
+
+  bool start();
+  bool stop();
+
+  long adc_freq();
+  int decim_rate();
+  gr_vector_int gain_range();
+  gr_vector_float freq_range();
+
+  bool set_decim_rate(unsigned int);
+  bool set_rx_freq(int,double);
+  bool set_pga(int,double);
+  
+
+  };
diff --git a/gr-msdd6000/src/msdd6000.cc b/gr-msdd6000/src/msdd6000.cc
new file mode 100644 (file)
index 0000000..f0a1393
--- /dev/null
@@ -0,0 +1,209 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <msdd6000.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#define DEBUG(A)       printf("=debug=> %s\n", A)
+
+static void 
+optimize_socket(int socket);
+
+/*
+ * Holds types that need autoconf help.  They're here and not in the .h file because
+ * here we've got access to config.h
+ */
+class MSDD6000::detail {
+public:
+  struct sockaddr_in d_sockaddr;
+};
+
+
+MSDD6000::MSDD6000(char* addr)
+  : d_detail(new MSDD6000::detail())
+{
+       d_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+       
+       optimize_socket(d_sock);
+       
+       
+       // set up remote sockaddr
+//     int s = inet_aton(addr, &d_adx); 
+       d_detail->d_sockaddr.sin_family = AF_INET;
+       d_detail->d_sockaddr.sin_port = htons(10000);
+       int s = inet_aton(addr, &d_detail->d_sockaddr.sin_addr);
+       
+       // set up local sockaddr
+       struct in_addr d_myadx;
+       struct sockaddr_in d_mysockaddr;
+       short int port = 10010;
+       d_myadx.s_addr = INADDR_ANY;
+       d_mysockaddr.sin_family = AF_INET;
+       d_mysockaddr.sin_port = htons(port);
+       memcpy(&d_mysockaddr.sin_addr.s_addr, &d_myadx.s_addr, sizeof(in_addr));
+       //d_sockaddr.sin_addr = INADDR_ANY;
+       s = bind(d_sock, (const sockaddr*) &d_mysockaddr, sizeof(d_mysockaddr));
+       
+       // set default values
+       d_decim = 2;
+       d_ddc_gain = 2;
+       d_rf_attn = 0;
+       d_state = STATE_STOPPED;
+}
+
+MSDD6000::~MSDD6000()
+{
+    // printf("MSDD6000::Destructing\n");
+    close(d_sock);
+}
+
+
+static void
+optimize_socket(int socket){
+#define BANDWIDTH      1000000000/8
+#define DELAY          0.5
+       int ret;
+
+       int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY);
+       char textbuf[512];
+       snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size);
+       printf("sock_buf_size = %d\n", sock_buf_size);
+       
+       ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
+                        &sock_buf_size, sizeof(sock_buf_size));
+
+       ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
+                        &sock_buf_size, sizeof(sock_buf_size));
+       
+       int uid = getuid();
+       if(uid!=0){
+               printf(" ****** COULD NOT OPTIMIZE SYSTEM NETWORK PARAMETERS BECAUSE YOU ARE NOT RUNNING AS ROOT *******\n ****** YOUR MSDD6000 RECIEVER PERFORMANCE IS GOING TO BE TERRIBLE *******\n");
+               return;
+       }
+
+
+       // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS
+       // FIXME seems like kind of a big hammer.  Are you sure you need this?
+       FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w");
+       if (fd){
+         fwrite("10000", 1, strlen("10000"), fd);
+         fclose(fd);
+       }
+
+       fd = fopen("/proc/sys/net/core/rmem_max", "w");
+       if (fd){
+         fwrite(textbuf, 1, strlen(textbuf), fd);
+         fclose(fd);
+       }
+
+       fd = fopen("/proc/sys/net/core/wmem_max", "w");
+       if (fd){
+         fwrite(textbuf, 1, strlen(textbuf), fd);
+         fclose(fd);
+       }
+
+       // just incase these were rejected before because of max sizes...
+
+       ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF,
+                   (char *)&sock_buf_size, sizeof(sock_buf_size) );
+
+       ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF,
+                   (char *)&sock_buf_size, sizeof(sock_buf_size) );
+       
+}
+
+
+void MSDD6000::set_decim(int decim_pow2){
+       DEBUG("SETTING NEW DECIM");
+       d_decim = decim_pow2;
+
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+}
+
+void MSDD6000::set_rf_attn(int attn){
+       DEBUG("SETTING NEW RF ATTN");
+       d_rf_attn = attn;
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+}
+
+void MSDD6000::set_ddc_gain(int gain){
+       DEBUG("SETTING NEW DDC GAIN");
+       d_ddc_gain = gain;
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+}
+
+void MSDD6000::set_fc(int center_mhz, int offset_hz){
+       DEBUG("SETTING NEW FC");
+       d_fc_mhz = center_mhz;
+       d_offset_hz = offset_hz;
+       
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+}
+
+
+void MSDD6000::start(){
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+       d_state = STATE_STARTED;
+       }
+
+
+void MSDD6000::stop(){
+       // new request with 0 decim tells it to halt
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, 0, d_offset_hz);
+       d_state = STATE_STOPPED;
+       }
+
+
+void MSDD6000::send_request(float freq_mhz, float rf_attn, float ddc_gain, float ddc_dec, float ddc_offset_hz){
+       static char buff[512];
+       sprintf(buff, "%f %f %f %f %f\n",freq_mhz, rf_attn, ddc_gain, ddc_dec, ddc_offset_hz);
+       printf("sending: %s\n", buff);
+        int flags = 0;
+       sendto( d_sock, buff, strlen(buff)+1, flags,
+               (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr));
+       }
+
+
+int  MSDD6000::read(char* buf, int size){
+       int flags = 0;
+       return recv(d_sock, buf, size, flags);
+       }
+
+
diff --git a/gr-msdd6000/src/msdd6000.h b/gr-msdd6000/src/msdd6000.h
new file mode 100644 (file)
index 0000000..808a838
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef MSDD6000_H
+#define MSDD6000_H
+
+#include <boost/scoped_ptr.hpp>
+
+class MSDD6000 {
+  class detail;
+
+  //! holds objects with system dependent types
+  boost::scoped_ptr<detail>    d_detail;  
+
+public:
+
+  enum state {
+    STATE_STOPPED, STATE_STARTED,
+  };
+
+  MSDD6000(char* ip_addr);
+  ~MSDD6000();
+
+  void set_decim(int decim_pow2);
+  void set_fc(int center_mhz, int offset_hz);  
+  void set_ddc_gain(int gain);
+  void set_rf_attn(int attn);
+
+  void set_output(int mode, void* arg);
+
+  void start();
+  void stop();
+       
+  void send_request(float,float,float,float,float);    
+  int read(char*, int);
+
+  int d_decim;
+  int d_fc_mhz;
+  int d_offset_hz;
+  int d_rf_attn;
+  int d_ddc_gain;
+  int d_sock;
+  state d_state;
+
+};
+
+
+#endif
diff --git a/gr-msdd6000/src/msdd6000_rs.cc b/gr-msdd6000/src/msdd6000_rs.cc
new file mode 100644 (file)
index 0000000..d78f2b4
--- /dev/null
@@ -0,0 +1,286 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <msdd6000_rs.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#define DEBUG(A)       printf("=debug=> %s\n", A)
+
+static void 
+optimize_socket(int socket);
+
+/*
+ * Holds types that need autoconf help.  They're here and not in the .h file because
+ * here we've got access to config.h
+ */
+class MSDD6000_RS::detail {
+public:
+  struct sockaddr_in d_sockaddr;
+};
+
+
+MSDD6000_RS::MSDD6000_RS(char* addr)
+  : d_detail(new MSDD6000_RS::detail())
+{
+       d_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+       
+       optimize_socket(d_sock);
+       
+       
+       // set up remote sockaddr
+//     int s = inet_aton(addr, &d_adx); 
+       d_detail->d_sockaddr.sin_family = AF_INET;
+       d_detail->d_sockaddr.sin_port = htons(10000);
+       int s = inet_aton(addr, &d_detail->d_sockaddr.sin_addr);
+       
+       // set up local sockaddr
+       struct in_addr d_myadx;
+       struct sockaddr_in d_mysockaddr;
+       short int port = 10010;
+       d_myadx.s_addr = INADDR_ANY;
+       d_mysockaddr.sin_family = AF_INET;
+       d_mysockaddr.sin_port = htons(port);
+       memcpy(&d_mysockaddr.sin_addr.s_addr, &d_myadx.s_addr, sizeof(in_addr));
+       //d_sockaddr.sin_addr = INADDR_ANY;
+       s = bind(d_sock, (const sockaddr*) &d_mysockaddr, sizeof(d_mysockaddr));
+       
+       // set default values
+       //d_decim = 2;
+       d_ddc_gain      = 2;
+       d_rf_attn       = 0;
+       d_fc_mhz        = 3500;
+       d_offset_hz = 0;
+        d_ddc_gain  = 0;
+        d_ddc_sample_rate_khz = 25600;
+        d_ddc_bw_khz          = 25600;
+        d_start               = 0;
+       d_state = STATE_STOPPED;
+}
+
+MSDD6000_RS::~MSDD6000_RS()
+{
+       //printf("MSDD6000_RS::Destructing\n");
+       close(d_sock);
+}
+
+
+static void
+optimize_socket(int socket){
+#define BANDWIDTH      1000000000/8
+#define DELAY          0.5
+       int ret;
+
+       int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY);
+       char textbuf[512];
+       snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size);
+       printf("sock_buf_size = %d\n", sock_buf_size);
+       
+       ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
+                        &sock_buf_size, sizeof(sock_buf_size));
+
+       ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
+                        &sock_buf_size, sizeof(sock_buf_size));
+       
+       int uid = getuid();
+       if(uid!=0){
+               printf(" ****** COULD NOT OPTIMIZE SYSTEM NETWORK PARAMETERS BECAUSE YOU ARE NOT RUNNING AS ROOT *******\n ****** YOUR MSDD6000_RS RECIEVER PERFORMANCE IS GOING TO BE TERRIBLE *******\n");
+               return;
+       }
+
+
+       // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS
+       // FIXME seems like kind of a big hammer.  Are you sure you need this?
+       FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w");
+       if (fd){
+         fwrite("10000", 1, strlen("10000"), fd);
+         fclose(fd);
+       }
+
+       fd = fopen("/proc/sys/net/core/rmem_max", "w");
+       if (fd){
+         fwrite(textbuf, 1, strlen(textbuf), fd);
+         fclose(fd);
+       }
+
+       fd = fopen("/proc/sys/net/core/wmem_max", "w");
+       if (fd){
+         fwrite(textbuf, 1, strlen(textbuf), fd);
+         fclose(fd);
+       }
+
+       // just incase these were rejected before because of max sizes...
+
+       ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF,
+                   (char *)&sock_buf_size, sizeof(sock_buf_size) );
+
+       ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF,
+                   (char *)&sock_buf_size, sizeof(sock_buf_size) );
+       
+}
+
+
+//void MSDD6000_RS::set_decim(int decim_pow2){
+//     DEBUG("SETTING NEW DECIM");
+//     d_decim = decim_pow2;
+//
+//     if(d_state==STATE_STARTED)
+//             send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+//}
+
+void MSDD6000_RS::set_rf_attn(int attn){
+       DEBUG("SETTING NEW RF ATTN");
+       d_rf_attn = attn;
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
+}
+
+void MSDD6000_RS::set_ddc_gain(int gain){
+       DEBUG("SETTING NEW DDC GAIN");
+       d_ddc_gain = gain;
+       if(d_state==STATE_STARTED)
+               send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
+}
+
+void MSDD6000_RS::set_fc(int center_mhz, int offset_hz){
+       DEBUG("SETTING NEW FC");
+       d_fc_mhz = center_mhz;
+       d_offset_hz = offset_hz;
+       
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
+//     if(d_state==STATE_STARTED)
+//             send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
+//             send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
+//             
+}
+
+void MSDD6000_RS::set_ddc_samp_rate(float sample_rate_khz){
+       DEBUG("SETTING NEW SAMPLE RATE");
+       d_ddc_sample_rate_khz = sample_rate_khz;
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);               
+}
+
+void MSDD6000_RS::set_ddc_bw(float bw_khz){
+       DEBUG("SETTING NEW DDC BW");
+       d_ddc_bw_khz = bw_khz;
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);               
+}
+
+void MSDD6000_RS::start(){
+    send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);       
+    return;
+}
+
+void MSDD6000_RS::stop(){
+       // new request with 0 decim tells it to halt
+       stop_data();
+}
+
+
+int MSDD6000_RS::start_data(){
+       d_start = 1;
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);       
+       d_state = STATE_STARTED;
+    return 0;
+       }
+
+
+int MSDD6000_RS::stop_data(){
+       // new request with 0 decim tells it to halt
+       d_start = 0;
+       send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);       
+       d_state = STATE_STOPPED;
+    return 0;
+       }
+       
+/* Query functions */
+float MSDD6000_RS::pull_ddc_samp_rate(){
+  return d_ddc_sample_rate_khz;
+}
+float MSDD6000_RS::pull_ddc_bw(){
+       return d_ddc_bw_khz;
+}
+
+float MSDD6000_RS::pull_rx_freq(){
+       return d_fc_mhz;
+}
+int   MSDD6000_RS::pull_ddc_gain(){
+       return d_ddc_gain;
+}
+
+int   MSDD6000_RS::pull_rf_atten(){
+       return d_rf_attn;
+}
+
+
+void MSDD6000_RS::send_request(float freq_mhz, float rf_attn, float ddc_gain, float ddc_offset_hz, float ddc_samp_rate_khz, float ddc_input_bw_khz, float ddc_start){
+       static char buff[512];
+       // Send MSDD6000_RS control frame.
+       sprintf(buff, "%f %f %f %f %f %f %f\n",freq_mhz, rf_attn, ddc_gain, ddc_offset_hz, ddc_samp_rate_khz, ddc_input_bw_khz, ddc_start); //ddc_dec, ddc_offset_hz);
+       printf("sending: %s\n", buff);
+        int flags = 0;
+       sendto( d_sock, buff, strlen(buff)+1, flags,
+               (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr));
+       }
+
+
+int  MSDD6000_RS::read(char* buf, int size){
+       int flags = 0;
+       return recv(d_sock, buf, size, flags);
+       }
+       
+int MSDD6000_RS::parse_control(char* buf, int size){
+    //packet_len = sprintf(&txbuff[6], "%f %f %f %f %f %f %f",downsamp,ddc_dec_rate,ddc_step_int,ddc_step_frac,ddc_samp_rate_khz,ddc_input_bw_khz,ddc_start);    
+
+    float downsamp;
+    float ddc_dec_rate;
+    float ddc_step_int;
+    float ddc_step_frac;
+    float ddc_samp_rate_khz;
+    float ddc_input_bw_khz;
+    float ddc_start;
+
+    sscanf(&buf[6],"%f %f %f %f %f %f %f",&downsamp,&ddc_dec_rate,&ddc_step_int,&ddc_step_frac,&ddc_samp_rate_khz,&ddc_input_bw_khz,&ddc_start);
+  
+    // pull off sample rate  
+    d_ddc_sample_rate_khz = ddc_samp_rate_khz;
+    printf("Sample Rate %f\n",d_ddc_sample_rate_khz);
+    // pull off bw
+    d_ddc_bw_khz  =  ddc_input_bw_khz;
+    printf("BW %f\n", d_ddc_bw_khz);
+    return 0;
+}
+
+
diff --git a/gr-msdd6000/src/msdd6000_rs.h b/gr-msdd6000/src/msdd6000_rs.h
new file mode 100644 (file)
index 0000000..4be4624
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef MSDD_RS__RS_6000_H
+#define MSDD_RS__RS_6000_H
+
+#include <boost/scoped_ptr.hpp>
+
+class MSDD6000_RS {
+  class detail;
+
+  //! holds objects with system dependent types
+  boost::scoped_ptr<detail>    d_detail;  
+
+public:
+
+  enum state {
+    STATE_STOPPED, STATE_STARTED
+  };
+
+  MSDD6000_RS(char* ip_addr);
+  ~MSDD6000_RS();
+
+  /* set functions -- sets digitizer parameters */
+ // void set_output(int mode, void* arg);
+
+  void set_rf_attn(int attn);
+  void set_ddc_gain(int gain);
+  void set_fc(int center_mhz, int offset_hz);
+  void set_ddc_samp_rate(float sample_rate_khz);
+  void set_ddc_bw(float bw_khz);
+
+  void start();
+  void stop();
+
+  /* function starts the flow of data from the digitizer */
+  int start_data();
+  /* function stops the flow of data from the digitizer */
+  int stop_data();
+  
+  /* query functions -- queries digitizer 'actual' parameters */
+  float pull_ddc_samp_rate();
+  float pull_ddc_bw();
+  float pull_rx_freq();
+  int   pull_ddc_gain();
+  int   pull_rf_atten();
+       
+  void send_request(float,float,float,float,float,float,float);        
+  int read(char*, int);
+
+  int parse_control(char*, int);
+
+private:
+  // parameters for a receiver object.
+  int   d_fc_mhz;
+  int   d_offset_hz;
+  int   d_rf_attn;
+  int   d_ddc_gain;
+  float d_ddc_sample_rate_khz;
+  float d_ddc_bw_khz;
+  int   d_start;
+  int   d_sock;
+  state d_state;
+
+};
+
+
+#endif
diff --git a/gr-msdd6000/src/msdd_buffer_copy_behaviors.h b/gr-msdd6000/src/msdd_buffer_copy_behaviors.h
new file mode 100644 (file)
index 0000000..398f8ae
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef MSDD_BUFFER_COPY_BEHAVIORS_H_
+#define MSDD_BUFFER_COPY_BEHAVIORS_H_
+
+namespace msdd {
+       
+       class BufferCopyBehavior 
+         {
+         public: 
+           virtual void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) = 0;
+           virtual ~BufferCopyBehavior() {};
+         };
+         
+       template <class Tin, class Tout> 
+       class BufferCopyBehaviorGeneric : public BufferCopyBehavior {
+               void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) {
+                       Tout    *out(&(reinterpret_cast<Tout *>(a[0]))[output_index]);  // sloppy
+                       const Tin       *in(reinterpret_cast<const Tin *>(b)); // equisloppy
+                       
+                   for (unsigned int i = 0; i < nitems; ++i) {
+                       out[i] = in[i];
+                   }
+               }
+       };
+       
+       template <class Tin>
+       class BufferCopyBehaviorComplex : public BufferCopyBehavior {
+               void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) {
+               gr_complex      *out(&(reinterpret_cast<gr_complex *>(a[0]))[output_index]);    // sloppy
+               const Tin       *in(reinterpret_cast<const Tin *>(b)); // equisloppy
+               
+                   for (unsigned int i = 0; i < nitems; ++i) {
+                       out[i] = gr_complex (in[4*i+1],in[4*i+3]);
+                   }
+               }
+       };
+}
+
+#endif /*MSDD_BUFFER_COPY_BEHAVIORS_H_*/
diff --git a/gr-msdd6000/src/msdd_rs.i b/gr-msdd6000/src/msdd_rs.i
new file mode 100644 (file)
index 0000000..16a1bec
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"  // the common stuff
+
+%{
+#include "msdd_rs_source_simple.h"
+%}
+
+
+GR_SWIG_BLOCK_MAGIC(msdd_rs,source_simple)
+
+msdd_rs_source_simple_sptr
+msdd_rs_make_source_simple (
+       const char *src,
+       unsigned short port_src
+       );
+
+class msdd_rs_source_simple : public gr_sync_block {
+  protected:
+    msdd_rs_source_simple(
+       const char *src,
+       unsigned short port_src
+       );
+  public:
+    ~msdd_rs_source_c(); 
+  int work (int noutput_items,
+      gr_vector_const_void_star &input_items,
+      gr_vector_void_star &output_items);
+
+  bool start();
+  bool stop();
+
+  /* function starts the flow of data */
+  int start_data();
+
+  /* function stops the flow of data */
+  int stop_data();
+
+  long pull_adc_freq();
+  /* Request the current ddc sample rate */
+  float pull_ddc_samp_rate();
+  /* Request the current ddc bandwidth */
+  float pull_ddc_bw();
+  /* Request the current rx freq */
+  float pull_rx_freq();
+  /* Request current ddc gain */
+  int pull_ddc_gain();
+  /* Request current RF attenuation */
+  int pull_rf_atten();
+
+
+  /*  int decim_rate(); */
+  gr_vector_int gain_range();
+  gr_vector_float freq_range();
+
+  /* Set Functions */
+  /*  bool set_decim_rate(unsigned int); */
+  bool set_rx_freq(double); /* set_rx_freq(int,double); */
+  /*  bool set_pga(int,double); */
+
+  bool set_ddc_gain(double);
+  /* Set desired sample rate of MSDD6000 -- Note bounds checking is 
+  done by the module and it will return the value actually used in the hardware. */
+  bool set_ddc_samp_rate(double);
+  /* Set desired input BW of MSDD6000 -- Note bounds checking is 
+  // done by the module and it will return the value actually used in the hardware. */
+  bool set_ddc_bw(double);
+
+  bool set_rf_atten(double);
+
+
+  };
diff --git a/gr-msdd6000/src/msdd_rs_source_simple.cc b/gr-msdd6000/src/msdd_rs_source_simple.cc
new file mode 100644 (file)
index 0000000..2ffc642
--- /dev/null
@@ -0,0 +1,237 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <msdd_rs_source_simple.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <cstdio>
+
+
+msdd_rs_source_simple_sptr
+msdd_rs_make_source_simple ( const char *src, unsigned short port_src) 
+{
+  return msdd_rs_source_simple_sptr (new msdd_rs_source_simple ( src, port_src)); 
+}
+
+
+msdd_rs_source_simple::msdd_rs_source_simple (
+                   const char *src, 
+                   unsigned short port_src) 
+               : gr_sync_block("MSDD_RS_SOURCE_SIMPLE",
+                               gr_make_io_signature (0,0,0),
+                               gr_make_io_signature (1, 1, sizeof (short))),
+                  rcv(new MSDD6000_RS((char*) src)), d_lastseq(0)
+{
+}
+
+msdd_rs_source_simple::~msdd_rs_source_simple ()
+{
+}
+
+
+int
+msdd_rs_source_simple::work (int noutput_items,
+                         gr_vector_const_void_star &input_items,
+                         gr_vector_void_star &output_items)
+{
+       
+#define BUF_LEN        (366*sizeof(short)*2 + 6)
+
+       float* out1 =(float*) output_items[0];
+
+       char buffer[BUF_LEN];
+       /* Read a buffer out -- looking at UDP payload at this point.*/
+       rcv->read( &buffer[0], BUF_LEN );
+       
+       int seq = *((int*) &buffer[2]);
+       char type = buffer[0];
+       //printf("Sequence %d\n",seq);
+       
+       // FIXME get rid of these magic 366's!
+       if(d_lastseq == -366)
+       {
+        if (type != 0){
+            /* Received control packet -- parse and update locally stored parameters */
+            printf("Parsing control Packet\n");
+            rcv->parse_control(&buffer[0], seq);       
+        }
+        else{   
+            // not started case
+            if(seq == 0){
+                d_lastseq = 0;
+            } 
+            else 
+            {
+                // THROW AWAY SAMPLES WE ARE NOT STARTED YET!
+                return 0;
+            }
+        }
+       } 
+       // Started case
+       else 
+       {
+        if (type != 0){
+                        /* Received control packet -- parse and update locally stored parameters */
+            printf("Parsing control Packet\n");
+            rcv->parse_control(&buffer[0], seq);       
+        }
+            
+        else {
+            int samples_missed = seq - d_lastseq - 366;
+            if(samples_missed > 0)
+            {
+                printf("dropped %d samples.\n", samples_missed);
+            }
+            d_lastseq = seq;
+        }
+       }
+       
+       if(noutput_items< 366*2){
+               printf("NOT ENOUGH SPACE IN OUTPUT BUFFER!!! >:-(\n");
+               }
+       
+       memcpy(&out1[0], &buffer[6], BUF_LEN - 6);
+       
+//     for(int i = 0; i < 366*2; i++){
+//             out1[i] = (float)  (*((short*) &buffer[6+2*i]) );
+//     }
+       
+       return 366*2;
+}
+
+//bool msdd_rs_source_simple::set_decim_rate(unsigned int rate)
+//{
+//     // FIXME seems buggy.  How about a floor or ceil?
+//        rcv->set_decim((int) log2(rate));
+//     return true;
+//}
+
+bool msdd_rs_source_simple::set_rx_freq(double freq)
+{
+       long new_fc = (long)freq;
+       rcv->set_fc( new_fc/1000000, new_fc%1000000);
+       return true;
+}
+
+
+bool msdd_rs_source_simple::set_ddc_gain(double gain)
+{
+       if(gain < 0 || gain > 7){ // only 3 bits available.
+               printf("GAIN IS OUTSIDE ACCEPTABLE RANGE!\n");
+               return false;
+       }
+       //decimation gain
+       rcv->set_ddc_gain((int)gain);
+       return true;
+}
+
+// Set desired sample rate of MSDD6000 -- Note bounds checking is 
+// done by the module and it will return the value actually used in the hardware.
+bool msdd_rs_source_simple::set_ddc_samp_rate(double rate)
+{
+       rcv->set_ddc_samp_rate((float) rate);
+       return true;            
+}
+
+// Set desired input BW of MSDD6000 -- Note bounds checking is 
+// done by the module and it will return the value actually used in the hardware.
+bool msdd_rs_source_simple::set_ddc_bw(double bw)
+{
+       rcv->set_ddc_bw((float) bw);
+       return true;            
+}
+
+bool msdd_rs_source_simple::set_rf_atten(double rf_atten)
+{
+        rcv->set_rf_attn((int) rf_atten);
+        return true;
+}
+
+bool msdd_rs_source_simple::start()
+{
+       rcv->start();
+    rcv->stop_data();
+       return true;
+}
+
+bool msdd_rs_source_simple::stop()
+{
+       rcv->stop();
+       return true;
+}
+
+int msdd_rs_source_simple::start_data()
+{
+       return rcv->start_data();
+}
+
+int msdd_rs_source_simple::stop_data()
+{
+       return rcv->stop_data();
+}
+
+/* Query functions */
+long msdd_rs_source_simple::pull_adc_freq(){
+       return 102400000;
+}
+
+/* Request the current ddc sample rate */
+float msdd_rs_source_simple::pull_ddc_samp_rate(){
+       return(rcv->pull_ddc_samp_rate());
+}
+
+/* Request the current ddc bandwidth */
+float msdd_rs_source_simple::pull_ddc_bw(){
+       return(rcv->pull_ddc_bw());
+       
+}
+
+/* Request the current rx freq */
+float msdd_rs_source_simple::pull_rx_freq(){
+       return(rcv->pull_rx_freq());
+}
+
+/* Request current ddc gain */
+int msdd_rs_source_simple::pull_ddc_gain(){
+       return(rcv->pull_ddc_gain());
+}
+
+/* Request current RF attenuation */
+int msdd_rs_source_simple::pull_rf_atten(){
+       return(rcv->pull_rf_atten());
+}
+
+std::vector<int> msdd_rs_source_simple::gain_range(){
+       static std::vector<int> r;
+       r.push_back(0);
+       r.push_back(12);
+       return r;
+}
+
+std::vector<float> msdd_rs_source_simple::freq_range(){
+       std::vector<float> r;
+       r.push_back(30.0*1000*1000);
+       r.push_back(6.0*1000*1000*1000);
+       return r;
+}
diff --git a/gr-msdd6000/src/msdd_rs_source_simple.h b/gr-msdd6000/src/msdd_rs_source_simple.h
new file mode 100644 (file)
index 0000000..f320cbb
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_MSDD_RS_SOURCE_SIMPLE_H
+#define INCLUDED_MSDD_RS_SOURCE_SIMPLE_H
+
+#include <gr_sync_block.h>
+#include <msdd6000_rs.h>
+#include <boost/scoped_ptr.hpp>
+
+class msdd_rs_source_simple;
+typedef boost::shared_ptr<msdd_rs_source_simple> msdd_rs_source_simple_sptr;
+
+
+// public shared_ptr constructor
+
+msdd_rs_source_simple_sptr msdd_rs_make_source_simple ( const char *src, unsigned short port_src);
+
+
+class msdd_rs_source_simple : public gr_sync_block {
+ private:
+  friend msdd_rs_source_simple_sptr
+  msdd_rs_make_source_simple ( const char *src, unsigned short port_src);
+
+  boost::scoped_ptr<MSDD6000_RS> rcv;
+  int d_lastseq;
+
+ protected:
+  msdd_rs_source_simple (const char *src, unsigned short port_src);
+
+ public:
+  ~msdd_rs_source_simple ();
+  bool stop();
+  bool start();
+
+  /* function starts the flow of data from the digitizer */
+  int start_data();
+  /* function stops the flow of data from the digitizer */
+  int stop_data();
+
+  // Do not need this //
+//  bool set_decim_rate(unsigned int);
+  /* Adding functions for setting the sample rate and
+  * receiver bandwidth
+  */
+  
+  /* hardware commands -- change current state of digitizer */
+  bool set_ddc_samp_rate(double);
+  bool set_ddc_bw(double);
+  
+  bool set_rx_freq(double);
+  bool set_ddc_gain(double);
+  bool set_rf_atten(double);
+
+  int work(int, gr_vector_const_void_star&, gr_vector_void_star&);
+  
+  /* Query methods -- query current state of digitizer */
+  long  pull_adc_freq();
+  float pull_ddc_samp_rate();
+  float pull_ddc_bw();
+  float pull_rx_freq();
+  int   pull_ddc_gain();
+  int   pull_rf_atten();
+  
+  /* Pulling back gain and frequency ranges */
+  std::vector<int> gain_range();
+  std::vector<float> freq_range();
+};
+
+#endif /* INCLUDED_MSDD_RS__RS__SOURCE_C_H */
diff --git a/gr-msdd6000/src/msdd_source_simple.cc b/gr-msdd6000/src/msdd_source_simple.cc
new file mode 100644 (file)
index 0000000..0ee2505
--- /dev/null
@@ -0,0 +1,166 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <msdd_source_simple.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <cstdio>
+
+
+msdd_source_simple_sptr
+msdd_make_source_simple (const char *src, unsigned short port_src) 
+{
+  return msdd_source_simple_sptr (new msdd_source_simple ( src, port_src)); 
+}
+
+
+msdd_source_simple::msdd_source_simple (const char *src, 
+                                       unsigned short port_src) 
+  : gr_sync_block("MSDD_SOURCE_SIMPLE",
+                 gr_make_io_signature (0,0,0),
+                 gr_make_io_signature (1, 1, sizeof (short))),
+    rcv(new MSDD6000((char*) src)), d_lastseq(0), d_firstrun(true)
+{
+  set_output_multiple(MSDD_COMPLEX_SAMPLES_PER_PACKET*2);
+}
+
+msdd_source_simple::~msdd_source_simple ()
+{
+}
+
+
+int
+msdd_source_simple::work (int noutput_items,
+                         gr_vector_const_void_star &input_items,
+                         gr_vector_void_star &output_items)
+{
+       
+#define BUF_LEN        (MSDD_COMPLEX_SAMPLES_PER_PACKET*sizeof(short)*2 + 6)
+
+  signed short* out1 =(signed short*) output_items[0];
+
+  for(int i=0; i<floor(noutput_items*1.0/(2*MSDD_COMPLEX_SAMPLES_PER_PACKET));i++){
+    char buffer[BUF_LEN];
+    rcv->read( &buffer[0], BUF_LEN );
+
+    int seq = *((int*) &buffer[2]);
+
+    if(d_lastseq == -MSDD_COMPLEX_SAMPLES_PER_PACKET){
+      // not started case
+      if(seq == 0){
+       d_lastseq = 0;
+      } else {
+       // THROW AWAY SAMPLES WE ARE NOT STARTED YET!
+       return 0;
+      }
+
+    } else {
+      // started case
+      int samples_missed = seq - d_lastseq - MSDD_COMPLEX_SAMPLES_PER_PACKET;
+      if(samples_missed > 0){
+       if(d_firstrun == true){
+         // we may have missed some initial samples off the beginning of
+         // a stream but there are no drop outs in the middle of what we have
+       } else {
+         printf("dropped %d samples.\n", samples_missed);
+       }
+      }
+      d_lastseq = seq;
+    }
+
+    int out_idx = i*MSDD_COMPLEX_SAMPLES_PER_PACKET*2;
+    memcpy(&out1[out_idx], &buffer[6], BUF_LEN - 6);
+    d_firstrun = false;
+  }
+
+  return noutput_items;
+
+}
+
+bool msdd_source_simple::set_decim_rate(unsigned int rate)
+{
+  rcv->set_decim((int) floor(log2(rate)));
+  return true;
+}
+
+
+bool msdd_source_simple::set_rx_freq(int channel, double freq)
+{
+  long new_fc = (long)freq;
+  rcv->set_fc( new_fc/1000000, new_fc%1000000);
+  return true;
+}
+
+
+bool msdd_source_simple::set_pga(int which, double gain)
+{
+  if(gain < 0 || gain > 10){
+    printf("GAIN IS OUTSIDE ACCEPTABLE RANGE!\n");
+    return false;
+  }
+  // ok i lied this is not really a pga, its decimation gain
+  rcv->set_ddc_gain((int)gain);
+  return true;
+}
+
+
+bool msdd_source_simple::start()
+{
+  rcv->start();
+  return true;
+}
+
+
+bool msdd_source_simple::stop()
+{
+  rcv->stop();
+  return true;
+}
+
+long msdd_source_simple::adc_freq()
+{
+  return 102400000;
+}
+
+int msdd_source_simple::decim_rate()
+{
+  return 1 << rcv->d_decim;
+}
+
+
+std::vector<int> msdd_source_simple::gain_range()
+{
+  static std::vector<int> r;
+  r.push_back(0);
+  r.push_back(12);
+  return r;
+}
+
+std::vector<float> msdd_source_simple::freq_range()
+{
+  std::vector<float> r;
+  r.push_back(30.0*1000*1000);
+  r.push_back(6.0*1000*1000*1000);
+  return r;
+}
diff --git a/gr-msdd6000/src/msdd_source_simple.h b/gr-msdd6000/src/msdd_source_simple.h
new file mode 100644 (file)
index 0000000..142c544
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_MSDD_SOURCE_SIMPLE_H
+#define INCLUDED_MSDD_SOURCE_SIMPLE_H
+
+#include <gr_sync_block.h>
+#include <msdd6000.h>
+#include <boost/scoped_ptr.hpp>
+
+#define     MSDD_COMPLEX_SAMPLES_PER_PACKET        366
+
+class msdd_source_simple;
+typedef boost::shared_ptr<msdd_source_simple> msdd_source_simple_sptr;
+
+
+// public shared_ptr constructor
+
+msdd_source_simple_sptr msdd_make_source_simple(const char *src, unsigned short port_src);
+
+
+class msdd_source_simple : public gr_sync_block {
+ private:
+  friend msdd_source_simple_sptr
+  msdd_make_source_simple(const char *src, unsigned short port_src);
+
+  boost::scoped_ptr<MSDD6000> rcv;
+  int d_lastseq;
+  bool d_firstrun;
+
+ protected:
+  msdd_source_simple(const char *src, unsigned short port_src);
+
+ public:
+  ~msdd_source_simple();
+  bool stop();
+  bool start();
+
+  bool set_decim_rate(unsigned int);
+  bool set_rx_freq(int,double);
+  bool set_pga(int,double);
+
+  int work(int, gr_vector_const_void_star&, gr_vector_void_star&);
+  
+  long adc_freq();
+  int decim_rate();
+  std::vector<int> gain_range();
+  std::vector<float> freq_range();
+};
+
+#endif /* INCLUDED_MSDD_SOURCE_C_H */
diff --git a/gr-msdd6000/src/python-examples/msdd_dynamics.py b/gr-msdd6000/src/python-examples/msdd_dynamics.py
new file mode 100755 (executable)
index 0000000..8cd1e52
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import time
+
+class benchmark_msdd6000(gr.top_block):
+    def __init__(self, address, options):
+        gr.top_block.__init__(self)
+
+        # Extract the initial options
+        self.frequency = options.frequency
+        self.filename  = options.filename
+        self.decim     = options.decim
+        self.gain      = options.gain
+        self.address   = address
+
+        # Set up and initialize the MSDD receiver
+        self.port = 10001 # required port
+        self.src = msdd.source_c(0, 1, self.address, self.port)
+        self.src.set_decim_rate(self.decim)
+        self.src.set_desired_packet_size(0, 1460)
+        self.src.set_pga(0, self.gain)
+        self.src.set_rx_freq(0, self.frequency)
+
+        # Display some info
+        print "Min PGA: ", self.src.pga_min()
+        print "Max PGA: ", self.src.pga_max()
+        print "PGA:     ", self.src.pga(0)
+        print "Decim:   ", self.src.decim_rate()
+        print "Freq:    ", self.src.rx_freq(0)
+        
+        # Build a file sink to save the info for post analysis
+        self.snk = gr.file_sink(gr.sizeof_gr_complex, self.filename)
+
+        # Connect the reciever source to file sink
+        self.connect(self.src, self.snk)
+        
+def main():
+    ''' This is a simple little script to play with retunning of the MSDD board.
+    You can cycle through frequencies or the attenuation of the board here.
+    '''
+
+    usage="%prog: [options] host_address"
+    parser = OptionParser(usage=usage, option_class=eng_option, conflict_handler="resolve")
+    parser.add_option("-f", "--frequency", type="eng_float", default=100e6,
+                      help="set frequency (Hz) [default=%default]")
+    parser.add_option("-d", "--decim", type="int", default=256,
+                      help="set decimation rate [default=%default]")
+    parser.add_option("-g", "--gain", type="int", default=32,
+                      help="set receiver gain (dB) [default=%default]")
+    parser.add_option("-F", "--filename", type="string", default="output.dat",
+                      help="set output filename [default=%default]")
+    (options, args) = parser.parse_args ()
+    host_address = args[0]
+
+    # Set up benchmark system that simply connects the MSDD source to a file sink
+    tb = benchmark_msdd6000(host_address, options)
+    tb.start() # start it here
+
+    # Adjust your parameters here. Use the time.sleep(x) function to set a wait period
+    # between adjusting the parameter.
+    for i in range(7):
+        time.sleep(0.5)
+        if 0:
+            freq = (tb.src.rx_freq(0) + 1) * 1e6
+            tb.src.set_rx_freq(0, freq)
+            print "Setting frequency: ", freq
+        if 1:
+            pga = tb.src.pga(0)+10
+            tb.src.set_pga(0, pga)
+            print "Setting PGA: ", pga
+
+    tb.stop()  # stop the radio
+
+if __name__ == '__main__':
+    main()
diff --git a/gr-msdd6000/src/python-examples/msdd_fft.py b/gr-msdd6000/src/python-examples/msdd_fft.py
new file mode 100755 (executable)
index 0000000..813a77d
--- /dev/null
@@ -0,0 +1,277 @@
+#!/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 msdd
+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("-w", "--which", type="int", default=0,
+                          help="select which MSDD (0, 1, ...) default is %default",
+                         metavar="NUM")
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select MSDD Rx side A or B (default=first one with a daughterboard)")
+        parser.add_option("-A", "--antenna", default=None,
+                          help="select Rx Antenna (only on RFX-series boards)")
+        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
+        
+        # build the graph
+
+        #self.u = MSDD.source_simo(which=options.which, decim_rate=options.decim)
+        self.u = msdd.source_simple("192.168.1.200", 0)
+        self.u.set_decim_rate(options.decim) #(16)
+
+#        msdd_src = gr.file_source(gr.sizeof_gr_complex, 'msdd.dat')
+#        thr = gr.throttle(gr.sizeof_gr_complex, 200000)
+#        self.connect(msdd_src, thr)
+
+#        if options.rx_subdev_spec is None:
+#           options.rx_subdev_spec = pick_subdevice(self.u)
+#        self.u.set_mux(MSDD.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 = MSDD.selected_subdev(self.u, options.rx_subdev_spec)
+
+#        print "Initial Freq", self.u.rx_freq(0), "deci: ", self.u.decim_rate()
+#        input_rate = 50e6 / self.u.decim_rate()
+        input_rate = 50e6 / options.decim;
+
+        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)
+               
+        msdd_sink = gr.file_sink(gr.sizeof_gr_complex, 'schmen1.dat')
+       
+       self.conv = gr.interleaved_short_to_complex();
+        self.connect(self.u, self.conv,  msdd_sink)
+        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()
+            self.gain_range = (20,70,.5);
+           options.gain = float(self.gain_range[0]+self.gain_range[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            #r = self.subdev.freq_range()
+           r = (30e6,6e9,1e6)
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+#
+#      if options.antenna is not None:
+#            print "Selecting antenna %s" % (options.antenna,)
+#            self.subdev.select_rx_antenna(options.antenna)
+
+        if self.show_debug_info:
+            #self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['decim'].set_value(options.decim)
+ #           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.gain_range = (20,50,.5);
+        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.set_rx_freq  (0, target_freq)
+        #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)
+        self.u.set_pga(0, gain)
+
+    def set_decim(self, decim):
+        ok = self.u.set_decim_rate(decim)
+        if not ok:
+            print "set_decim failed"
+        #input_rate = 20e6 / self.u.decim_rate()
+        #self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(decim)
+            #self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+        return ok
+
+def main ():
+    app = stdgui2.stdapp(app_top_block, "MSDD FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-msdd6000/src/python-examples/msdd_rcv.py b/gr-msdd6000/src/python-examples/msdd_rcv.py
new file mode 100755 (executable)
index 0000000..cc2f3e4
--- /dev/null
@@ -0,0 +1,287 @@
+#!/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
+from gnuradio import msdd
+from gnuradio import blks2
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui2, form
+from gnuradio.wxgui import fftsink2
+from optparse import OptionParser
+#from usrpm import usrp_dbid
+import sys
+import math
+import wx
+
+class wfm_rx_block (stdgui2.std_top_block):
+    def __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,
+#                          help="select MSDD Rx side A or B (default=A)")
+        parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
+                          help="set frequency to FREQ", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=40,
+                          help="set gain in dB (default is midpoint)")
+#        parser.add_option("-V", "--volume", type="eng_float", default=None,
+#                          help="set volume (default is midpoint)")
+#        parser.add_option("-O", "--audio-output", type="string", default="",
+#                          help="pcm device name.  E.g., hw:0,0 or surround51 or /dev/dsp")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+        
+        self.frame = frame
+        self.panel = panel
+        
+        self.vol = 0
+        self.gain_range = (10, 70, .5)
+        self.state = "FREQ"
+        self.freq = 0
+        msdd_decim = 2
+
+        # build graph
+        self.fft_size = 8192
+        self.sample_rate = 200
+        self.u = msdd.source_c(0, 1, "10.45.4.44", 10000)
+        self.u.set_decim_rate(4)
+        self.u.set_desired_packet_size(0, 1460*100)        
+
+
+        #self.u.set_decim_rate(msdd_decim)
+#        usrp_rate = adc_rate / msdd_decim           # 320 kS/s
+#        chanfilt_decim = 1
+#        demod_rate = usrp_rate / chanfilt_decim
+#        audio_decimation = 10
+#        audio_rate = demod_rate / audio_decimation  # 32 kHz
+#
+#        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))
+#        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+#        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+#
+#
+#        chan_filt_coeffs = optfir.low_pass (1,           # gain
+#                                            usrp_rate,   # sampling rate
+#                                            80e3,        # passband cutoff
+#                                            115e3,       # stopband cutoff
+#                                            0.1,         # passband ripple
+#                                            60)          # stopband attenuation
+#        #print len(chan_filt_coeffs)
+#        chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+#
+#        self.guts = blks2.wfm_rcv (demod_rate, audio_decimation)
+#
+#        self.volume_control = gr.multiply_const_ff(self.vol)
+#
+#        # sound card as final sink
+#        audio_sink = audio.sink (int (audio_rate),
+#                                 options.audio_output,
+#                                 False)  # ok_to_block
+        
+        # now wire it all together
+        #self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
+
+        self._build_gui(vbox)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            #g = self.subdev.gain_range()
+            g = self.gain_range
+            options.gain = float(g[0]+g[1])/2
+#
+#        if options.volume is None:
+#            g = self.volume_range()
+#            options.volume = float(g[0]+g[1])/2
+#            
+#        if abs(options.freq) < 1e6:
+#            options.freq *= 1e6
+
+        # set initial values
+#
+        self.set_gain(options.gain)
+#        self.set_vol(options.volume)
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+        print "Frequency: ", self.u.rx_freq(0)
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+        self.src_fft = None
+        if 1:
+            self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from MSDD",
+                                               fft_size=512, sample_rate=512)
+#            self.s2f1 = gr.short_to_float()
+#            self.scope = scopesink2.scope_sink_f(self.panel, sample_rate=self.sample_rate*self.fft_size)
+            
+            self.connect (self.u, self.src_fft)
+            #self.connect (self.s2f1, self.scope)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+#
+#        if 1:
+#            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 = 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)
+#            vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+        
+        # control area form at bottom
+        self.myform = myform = form.form()
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        hbox.Add((5,0), 0)
+        myform['freq_slider'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+                                        range=(30e6, 6e9, 1e6),
+                                        callback=self.set_freq)
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+#
+#        myform['volume'] = \
+#            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+#                                        weight=3, range=self.volume_range(),
+#                                        callback=self.set_vol)
+#        hbox.Add((5,0), 1)
+
+        myform['gain'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                        weight=3, range=self.gain_range,
+                                        callback=self.set_gain)
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+#
+#        try:
+#            self.knob = powermate.powermate(self.frame)
+#            self.rot = 0
+#            powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+#            powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+#        except:
+#            print "FYI: No Powermate or Contour Knob found"
+
+
+    def on_rotate (self, event):
+        self.rot += event.delta
+        if (self.state == "FREQ"):
+            if self.rot >= 3:
+                self.set_freq(self.freq + .1e6)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_freq(self.freq - .1e6)
+                self.rot += 3
+        else:
+            step = self.volume_range()[2]
+            if self.rot >= 3:
+                self.set_vol(self.vol + step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_vol(self.vol - step)
+                self.rot += 3
+            
+    def on_button (self, event):
+        if event.value == 0:        # button up
+            return
+        self.rot = 0
+        if self.state == "FREQ":
+            self.state = "VOL"
+        else:
+            self.state = "FREQ"
+        self.update_status_bar ()
+#        
+#
+#    def set_vol (self, vol):
+#        g = self.volume_range()
+#        self.vol = max(g[0], min(g[1], vol))
+#        self.volume_control.set_k(10**(self.vol/10))
+#        self.myform['volume'].set_value(self.vol)
+#        self.update_status_bar ()
+                                        
+    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.set_rx_freq(0, target_freq);
+        
+        if r:
+            self.freq = target_freq
+            self.myform['freq'].set_value(target_freq)         # update displayed value
+            self.myform['freq_slider'].set_value(target_freq)  # update displayed value
+            self.update_status_bar()
+            self._set_status_msg("OK", 0)
+            return True
+
+        self._set_status_msg("Failed", 0)
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.u.set_pga(0,gain)
+        
+    def update_status_bar (self):
+        msg = "Volume:%r  Setting:%s" % (self.vol, self.state)
+        self._set_status_msg(msg, 1)
+        #self.src_fft.set_baseband_freq(self.freq)
+#
+#    def volume_range(self):
+#        return (-20.0, 0.0, 0.5)
+        
+
+if __name__ == '__main__':
+    app = stdgui2.stdapp (wfm_rx_block, "MSDD FFT RX")
+    app.MainLoop ()
diff --git a/gr-msdd6000/src/python-examples/msdd_rs_spec_an.py b/gr-msdd6000/src/python-examples/msdd_rs_spec_an.py
new file mode 100755 (executable)
index 0000000..4855375
--- /dev/null
@@ -0,0 +1,350 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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 msdd_rs
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.qtgui import qtgui
+from optparse import OptionParser
+import sys,time
+
+try:
+    from gnuradio.qtgui import qtgui
+    from PyQt4 import QtGui, QtCore
+    import sip
+except ImportError:
+    print "Please install gr-qtgui."
+    sys.exit(1)
+
+try:
+    from msdd_display_qtgui import Ui_MainWindow
+except ImportError:
+    print "Error: could not find msdd_display_qtgui.py:"
+    print "\t\"pyuic4 msdd_display_qtgui.ui -o msdd_display_qtgui.py\""
+    sys.exit(1)
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the QT Interface and Control Dialog
+# ////////////////////////////////////////////////////////////////////
+
+
+class main_window(QtGui.QMainWindow):
+    def __init__(self, snk, fg, parent=None):
+
+        QtGui.QWidget.__init__(self, parent)
+        self.gui = Ui_MainWindow()
+        self.gui.setupUi(self)
+
+        self.fg = fg
+
+        # Add the qtsnk widgets to the layout box
+        self.gui.sinkLayout.addWidget(snk)
+
+        self.gui.dcGainEdit.setText(QtCore.QString("%1").arg(0.001))
+
+        # Connect up some signals
+        self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
+                     self.pauseFg)
+        self.connect(self.gui.frequencyEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.frequencyEditText)
+        self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.gainEditText)
+        self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.bandwidthEditText)
+        self.connect(self.gui.amplifierEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.amplifierEditText)
+
+        self.connect(self.gui.actionSaveData, QtCore.SIGNAL("activated()"),
+                     self.saveData)
+        self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save)
+
+        self.connect(self.gui.dcGainEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.dcGainEditText)
+        self.connect(self.gui.dcCancelCheckBox, QtCore.SIGNAL("clicked(bool)"),
+                     self.dcCancelClicked)
+
+    def pauseFg(self):
+        if(self.gui.pauseButton.text() == "Pause"):
+            self.fg.stop()
+            self.fg.wait()
+            self.fg.stop_data()
+            self.gui.pauseButton.setText("Unpause")
+        else:
+            self.fg.start()
+            self.fg.start_data()
+            self.gui.pauseButton.setText("Pause")
+      
+
+    # Functions to set the values in the GUI
+    def set_frequency(self, freq):
+        self.freq = freq
+        sfreq = eng_notation.num_to_str(self.freq)
+        self.gui.frequencyEdit.setText(QtCore.QString("%1").arg(sfreq))
+        
+    def set_gain(self, gain):
+        self.gain = gain
+        self.gui.gainEdit.setText(QtCore.QString("%1").arg(self.gain))
+
+    def set_bandwidth(self, bw):
+        self.bw = bw
+        sbw = eng_notation.num_to_str(self.bw)
+        self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(sbw))
+
+    def set_amplifier(self, amp):
+        self.amp = amp
+        self.gui.amplifierEdit.setText(QtCore.QString("%1").arg(self.amp))
+
+
+    # Functions called when signals are triggered in the GUI
+    def frequencyEditText(self):
+        try:
+            freq = eng_notation.str_to_num(self.gui.frequencyEdit.text().toAscii()) 
+            self.fg.set_frequency(freq)
+            self.freq = freq
+        except RuntimeError:
+            pass
+
+    def gainEditText(self):
+        try:
+            gain = float(self.gui.gainEdit.text())
+            self.fg.set_gain(gain)
+            self.gain = gain
+        except ValueError:
+            pass
+                
+    def bandwidthEditText(self):
+        try:
+            bw = eng_notation.str_to_num(self.gui.bandwidthEdit.text().toAscii())
+            self.fg.set_bandwidth(bw)
+            self.bw = bw
+        except ValueError:
+            pass
+        
+    def amplifierEditText(self):
+        try:
+            amp = float(self.gui.amplifierEdit.text())
+            self.fg.set_amplifier_gain(amp)
+            self.amp = amp
+        except ValueError:
+            pass
+
+    def saveData(self):
+        fileName = QtGui.QFileDialog.getSaveFileName(self, "Save data to file", ".");
+        if(len(fileName)):
+            self.fg.save_to_file(str(fileName))
+
+    def dcGainEditText(self):
+        gain = float(self.gui.dcGainEdit.text())
+        self.fg.set_dc_gain(gain)
+        
+    def dcCancelClicked(self, state):
+        self.dcGainEditText()
+        self.fg.cancel_dc(state)
+        
+
+        
+class my_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-e", "--interface", type="string", default="eth0",
+                          help="select Ethernet interface, default is eth0")
+        parser.add_option("-m", "--mac-addr", type="string", default="",
+                          help="select USRP by MAC address, default is auto-select")
+        parser.add_option("-W", "--bw", type="float", default=1e6,
+                          help="set bandwidth of receiver [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default="2.4G",
+                          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("--fft-size", type="int", default=2048,
+                          help="Set number of FFT bins [default=%default]")
+        (options, args) = parser.parse_args()
+
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+       self.options = options
+        self.show_debug_info = True
+        
+        self.qapp = QtGui.QApplication(sys.argv)
+
+#        self.u = usrp2.source_32fc(options.interface, options.mac_addr)
+       self.u = msdd_rs.source_simple("192.168.1.20", 10000);
+       self.conv = gr.interleaved_short_to_complex();
+        self._adc_rate = self.u.pull_adc_freq()
+        self.set_bandwidth(options.bw)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+#            g = self.u.gain_range()   
+           g = [0, 10]
+            #options.gain = float(g[0]+g[1])/2
+            options.gain = float(0)
+        self.set_gain(options.gain)
+
+        if options.freq is None:
+               options.freq = 2.4e9;
+#            # if no frequency was specified, use the mid-point of the subdev
+#            f = self.u.freq_range()
+#            options.freq = float(f[0]+f[1])/2
+
+       self.set_frequency(options.freq)
+
+        self._fftsize = options.fft_size
+
+
+       self._freq = options.freq;
+       self._bandwidth = 400;
+        
+       self.set_bandwidth(self._bandwidth);
+
+        self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                self._freq, self._bandwidth,
+                                "USRP2 Display",
+                                True, True, False, True, False)
+
+        # Set up internal amplifier
+        self.amp = gr.multiply_const_cc(0.0)
+        self.set_amplifier_gain(0.01)
+
+        # Create a single-pole IIR filter to remove DC
+        #   but don't connect it yet
+        self.dc_gain = 0.001
+        self.dc = gr.single_pole_iir_filter_cc(self.dc_gain)
+        self.dc_sub = gr.sub_cc()
+
+       self.agc = gr.agc2_cc(1e-3, 1e-5, 0.01, 0.01, 10);
+
+        self.connect(self.u, self.conv, self.snk)
+        #self.connect(self.u, self.conv, self.amp, self.snk)
+
+        if self.show_debug_info:
+            print "Decimation rate: ", self._decim
+            print "Bandwidth: ", self._bandwidth
+#            print "D'board: ", self.u.daughterboard_id()
+
+        # Get the reference pointer to the SpectrumDisplayForm QWidget
+        # Wrap the pointer as a PyQt SIP object
+        #     This can now be manipulated as a PyQt4.QtGui.QWidget
+        self.pysink = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
+
+        self.main_win = main_window(self.pysink, self)
+
+        self.main_win.set_frequency(self._freq)
+        self.main_win.set_gain(self._gain)
+        self.main_win.set_bandwidth(self._bandwidth)
+        self.main_win.set_amplifier(self._amp_value)
+
+        self.main_win.show()
+
+
+    def save_to_file(self, name):
+        self.lock()
+
+        # Add file sink to save data
+        self.file_sink = gr.file_sink(gr.sizeof_gr_complex, name)
+        self.connect(self.conv, self.file_sink)
+
+        self.unlock()
+
+    def set_gain(self, gain):
+        self._gain = gain
+        self.u.set_ddc_gain(self._gain)
+
+    def set_frequency(self, freq):
+        self._freq = freq
+        r = self.u.set_rx_freq(freq)
+
+        try:
+            self.snk.set_frequency_range(self._freq, self._bandwidth)
+        except:
+            pass
+
+    def set_bandwidth(self, bw):
+        self._bandwidth = bw
+        self._decim = int(self._adc_rate / self._bandwidth)
+#        self.u.set_decim_rate(self._decim)
+       r1 = self.u.set_ddc_samp_rate( bw );
+       r2 = self.u.set_ddc_bw( bw );
+       self.u.start_data();
+
+       print r1
+       print r2;
+       
+       time.sleep(0.05);
+       bw = self.u.pull_ddc_bw();
+       sr = self.u.pull_ddc_samp_rate();
+       fc = self.u.pull_rx_freq();
+       
+       #self.snk.d_bandwidth = sr;
+
+       print bw;
+       print sr;
+       print fc;
+
+#      sys.exit(-1);
+
+        try:
+            self.snk.set_frequency_range(self._freq, self._bandwidth)
+        except:
+            pass
+
+    def set_amplifier_gain(self, amp):
+        self._amp_value = amp
+        self.amp.set_k(self._amp_value)
+
+    def set_dc_gain(self, gain):
+        self.dc.set_taps(gain)
+        
+    def cancel_dc(self, state):
+        self.lock()
+
+        if(state):
+            self.disconnect(self.u, self.amp)
+            self.connect(self.u, (self.dc_sub,0))
+            self.connect(self.u, self.dc, (self.dc_sub,1))
+            self.connect(self.dc_sub, self.amp)
+        else:
+            self.disconnect(self.dc_sub, self.amp)
+            self.disconnect(self.dc, (self.dc_sub,1))
+            self.disconnect(self.u, self.dc)
+            self.disconnect(self.u, (self.dc_sub,0))
+            self.connect(self.u, self.amp)
+
+        self.unlock()
+
+def main ():
+    tb = my_top_block()
+    tb.start()
+    tb.u.start_data();
+    tb.snk.exec_();
+
+if __name__ == '__main__':
+    try:
+        main ()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py b/gr-msdd6000/src/python-examples/msdd_spectrum_sense.py
new file mode 100755 (executable)
index 0000000..e3d182b
--- /dev/null
@@ -0,0 +1,296 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, eng_notation, optfir, window
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+import struct
+from pylab import *
+from numpy import array
+import time
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class tune(gr.feval_dd):
+    """
+    This class allows C++ code to callback into python.
+    """
+    def __init__(self, tb):
+        gr.feval_dd.__init__(self)
+        self.tb = tb
+
+    def eval(self, ignore):
+        """
+        This method is called from gr.bin_statistics_f when it wants to change
+        the center frequency.  This method tunes the front end to the new center
+        frequency, and returns the new frequency as its result.
+        """
+        try:
+            # We use this try block so that if something goes wrong from here 
+            # down, at least we'll have a prayer of knowing what went wrong.
+            # Without this, you get a very mysterious:
+            #
+            #   terminate called after throwing an instance of 'Swig::DirectorMethodException'
+            #   Aborted
+            #
+            # message on stderr.  Not exactly helpful ;)
+
+            new_freq = self.tb.set_next_freq()
+            return new_freq
+
+        except Exception, e:
+            print "tune: Exception: ", e
+
+
+class parse_msg(object):
+    def __init__(self, sample_rate, percent, alpha=0.01):
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+
+        self.fig = figure(1, facecolor="w", figsize=(12,9))
+        self.sp  = self.fig.add_subplot(1,1,1)
+        self.pl  = self.sp.plot(range(100), 100*[1,])
+
+        params = {'backend': 'ps',
+                  'xtick.labelsize': self.axis_font_size,
+                  'ytick.labelsize': self.axis_font_size,
+                  'text.usetex': False}
+        rcParams.update(params)
+
+        self.sp.set_title(("FFT"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp.set_ylabel("Magnitude (dB)", fontsize=self.label_font_size, fontweight="bold")
+        self.text_alpha = figtext(0.10, 0.94, ('Moving average alpha: %s' % alpha), weight="heavy", size=self.text_size)
+
+        self.cfreqs = list()
+        self.freqrange = list()
+        self.data = list() #array('f')
+
+        self.alpha = alpha
+
+        self.index = 0
+        self.full = False
+        self.last_cfreq = 0
+        
+        self.sample_rate = sample_rate
+        self.percent = (1.0-percent)/2.0
+        
+    def parse(self, msg):
+        self.center_freq = msg.arg1()
+        self.vlen = int(msg.arg2())
+        assert(msg.length() == self.vlen * gr.sizeof_float)
+
+
+        if(self.center_freq < self.last_cfreq):
+            print "Plotting spectrum\n"
+            self.full = True
+
+            self.pl[0].set_data([self.freqrange, self.data])
+            self.sp.set_ylim([min(self.data), max(self.data)])
+            self.sp.set_xlim([min(self.freqrange), max(self.freqrange)])
+            draw()
+
+            self.index = 0
+            del self.freqrange
+            self.freqrange = list()
+            #raw_input()
+
+        self.last_cfreq = self.center_freq
+
+        startind = int(self.percent * self.vlen)
+        endind = int((1.0 - self.percent) * self.vlen)
+        
+        fstep = self.sample_rate / self.vlen
+        f = [self.center_freq - self.sample_rate/2.0 + i*fstep for i in range(startind, endind)]
+        self.freqrange += f
+
+        t = msg.to_string()
+        d = struct.unpack('%df' % (self.vlen,), t)
+
+        if self.full:
+            for i in range(startind, endind):
+                self.data[self.index] = (1.0-self.alpha)*self.data[self.index] + (self.alpha)*d[i]
+                self.index += 1
+        else:
+            self.data += [di for di in d[startind:endind]]
+        
+
+class my_top_block(gr.top_block):
+
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        usage = "usage: %prog [options] host min_freq max_freq"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, metavar="SECS",
+                          help="time to delay (in seconds) after changing frequency [default=%default]")
+        parser.add_option("", "--dwell-delay", type="eng_float", default=50e-5, metavar="SECS",
+                          help="time to dwell (in seconds) at a given frequncy [default=%default]")
+        parser.add_option("-F", "--fft-size", type="int", default=256,
+                          help="specify number of FFT bins [default=%default]")
+        parser.add_option("-d", "--decim", type="intx", default=16,
+                          help="set decimation to DECIM [default=%default]")
+        parser.add_option("", "--real-time", action="store_true", default=False,
+                          help="Attempt to enable real-time scheduling")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 3:
+            parser.print_help()
+            sys.exit(1)
+
+        self.address  = args[0]
+        self.min_freq = eng_notation.str_to_num(args[1])
+        self.max_freq = eng_notation.str_to_num(args[2])
+
+        self.decim = options.decim
+        self.gain  = options.gain
+        
+        if self.min_freq > self.max_freq:
+            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them
+
+       self.fft_size = options.fft_size
+
+        if not options.real_time:
+            realtime = False
+        else:
+            # 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"
+
+        adc_rate = 102.4e6
+        self.int_rate = adc_rate / self.decim
+        print "Sampling rate: ", self.int_rate
+
+        # build graph
+        self.port = 10001
+        self.src = msdd.source_simple(self.address, self.port)
+        self.src.set_decim_rate(self.decim)
+
+        self.set_gain(self.gain)
+        self.set_freq(self.min_freq)
+
+       s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
+
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vcc(self.fft_size, True, mywindow, True)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+        
+        norm = gr.multiply_const_cc(1.0/self.fft_size)
+        c2mag = gr.complex_to_mag_squared(self.fft_size)
+
+        # FIXME the log10 primitive is dog slow
+        log = gr.nlog10_ff(10, self.fft_size,
+                           -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+               
+        # Set the freq_step to % of the actual data throughput.
+        # This allows us to discard the bins on both ends of the spectrum.
+        self.percent = 0.4
+
+        self.freq_step = self.percent * self.int_rate
+        self.min_center_freq = self.min_freq + self.freq_step/2
+        nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step)
+        self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
+
+        self.next_freq = self.min_center_freq
+        
+        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / self.fft_size)))  # in fft_frames
+        dwell_delay = max(1, int(round(options.dwell_delay * self.int_rate / self.fft_size))) # in fft_frames
+
+        self.msgq = gr.msg_queue(16)
+        self._tune_callback = tune(self)        # hang on to this to keep it from being GC'd
+        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
+                                    self._tune_callback, tune_delay, dwell_delay)
+
+        # FIXME leave out the log10 until we speed it up
+       self.connect(self.src, s2v, fft, c2mag, log, stats)
+
+
+    def set_next_freq(self):
+        target_freq = self.next_freq
+        self.next_freq = self.next_freq + self.freq_step
+        if self.next_freq >= self.max_center_freq:
+            self.next_freq = self.min_center_freq
+
+        if not self.set_freq(target_freq):
+            print "Failed to set frequency to", target_freq
+
+        return target_freq
+                          
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        """
+        return self.src.set_rx_freq(0, target_freq)
+
+
+    def set_gain(self, gain):
+        self.src.set_pga(0, gain)
+
+
+def main_loop(tb):
+    msgparser = parse_msg(tb.int_rate, tb.percent)
+    
+    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
+        msgparser.parse(tb.msgq.delete_head())
+
+        # Print center freq so we know that something is happening...
+        print msgparser.center_freq
+
+        # FIXME do something useful with the data...
+        
+        # m.data are the mag_squared of the fft output (they are in the
+        # standard order.  I.e., bin 0 == DC.)
+        # You'll probably want to do the equivalent of "fftshift" on them
+        # m.raw_data is a string that contains the binary floats.
+        # You could write this as binary to a file.
+
+    
+if __name__ == '__main__':
+    tb = my_top_block()
+    try:
+        tb.start()              # start executing flow graph in another thread...
+        main_loop(tb)
+        
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py b/gr-msdd6000/src/python-examples/msdd_spectrum_waterfall.py
new file mode 100755 (executable)
index 0000000..05f047e
--- /dev/null
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, eng_notation, optfir, window
+from gnuradio import msdd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+import struct
+from pylab import *
+from numpy import array
+import time
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class tune(gr.feval_dd):
+    """
+    This class allows C++ code to callback into python.
+    """
+    def __init__(self, tb):
+        gr.feval_dd.__init__(self)
+        self.tb = tb
+
+    def eval(self, ignore):
+        """
+        This method is called from gr.bin_statistics_f when it wants to change
+        the center frequency.  This method tunes the front end to the new center
+        frequency, and returns the new frequency as its result.
+        """
+        try:
+            # We use this try block so that if something goes wrong from here 
+            # down, at least we'll have a prayer of knowing what went wrong.
+            # Without this, you get a very mysterious:
+            #
+            #   terminate called after throwing an instance of 'Swig::DirectorMethodException'
+            #   Aborted
+            #
+            # message on stderr.  Not exactly helpful ;)
+
+            new_freq = self.tb.set_next_freq()
+            return new_freq
+
+        except Exception, e:
+            print "tune: Exception: ", e
+
+
+class parse_msg(object):
+    def __init__(self, sample_rate, percent):
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+
+        # Set up figures and subplots
+        self.fig = figure(1, facecolor="w", figsize=(12,9))
+        self.sp  = self.fig.add_subplot(1,1,1)
+        self.pl  = self.sp.matshow(100*[range(100),])
+
+        params = {'xtick.labelsize': self.axis_font_size,
+                  'ytick.labelsize': self.axis_font_size}
+        rcParams.update(params)
+
+        # Throw up some title info
+        self.sp.set_title(("FFT"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp.set_ylabel("Sample index (should be time)", fontsize=self.label_font_size, fontweight="bold")
+
+        self.freqrange = list()
+        self.data = list()
+        self.data3 = list()
+
+        self.index = 0
+        self.last_cfreq = 0
+
+        # So we know how to splice the data
+        self.sample_rate = sample_rate
+        self.percent = (1.0-percent)/2.0
+        
+    def parse(self, msg):
+        self.center_freq = msg.arg1()    # read the current center frequency
+        self.vlen = int(msg.arg2())      # read the length of the data set received
+
+        # wait until we wrap around before plotting the entire collected band
+        if(self.center_freq < self.last_cfreq):
+            #print "Plotting spectrum\n"
+
+            # If we have 100 sets, start dropping the oldest
+            if(len(self.data3) > 100):
+                self.data3.pop(0)
+            self.data3.append(self.data)
+
+            # add the new data to the plot
+            self.pl.set_data(self.data3)
+            draw()
+
+            # reset lists to collect next round
+            self.index = 0
+            del self.freqrange
+            self.freqrange = list()
+            del self.data
+            self.data = list()
+            #raw_input()
+
+        self.last_cfreq = self.center_freq
+
+        startind = int(self.percent * self.vlen)
+        endind = int((1.0 - self.percent) * self.vlen)
+        
+        fstep = self.sample_rate / self.vlen
+        f = [self.center_freq - self.sample_rate/2.0 + i*fstep for i in range(startind, endind)]
+        self.freqrange += f
+
+        t = msg.to_string();
+
+        d = struct.unpack('%df' % (self.vlen,), t)
+
+        self.data += [di for di in d[startind:endind]]
+        
+
+class my_top_block(gr.top_block):
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        # Build an options parser to bring in information from the user on usage
+        usage = "usage: %prog [options] host min_freq max_freq"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-g", "--gain", type="eng_float", default=32,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("", "--tune-delay", type="eng_float", default=5e-5, metavar="SECS",
+                          help="time to delay (in seconds) after changing frequency [default=%default]")
+        parser.add_option("", "--dwell-delay", type="eng_float", default=50e-5, metavar="SECS",
+                          help="time to dwell (in seconds) at a given frequncy [default=%default]")
+        parser.add_option("-F", "--fft-size", type="int", default=256,
+                          help="specify number of FFT bins [default=%default]")
+        parser.add_option("-d", "--decim", type="intx", default=16,
+                          help="set decimation to DECIM [default=%default]")
+        parser.add_option("", "--real-time", action="store_true", default=False,
+                          help="Attempt to enable real-time scheduling")
+
+        (options, args) = parser.parse_args()
+        if len(args) != 3:
+            parser.print_help()
+            sys.exit(1)
+
+        # get user-provided info on address of MSDD and frequency to sweep
+        self.address  = args[0]
+        self.min_freq = eng_notation.str_to_num(args[1])
+        self.max_freq = eng_notation.str_to_num(args[2])
+
+        self.decim = options.decim
+        self.gain  = options.gain
+        
+        if self.min_freq > self.max_freq:
+            self.min_freq, self.max_freq = self.max_freq, self.min_freq   # swap them
+
+       self.fft_size = options.fft_size
+
+        if not options.real_time:
+            realtime = False
+        else:
+            # 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"
+
+        # Sampling rate is hardcoded and cannot be read off device
+        adc_rate = 102.4e6
+        self.int_rate = adc_rate / self.decim
+        print "Sampling rate: ", self.int_rate
+
+        # build graph
+        self.port = 10001   # required port for UDP packets
+       
+       #       which board,    op mode,        adx,    port
+#        self.src = msdd.source_c(0, 1, self.address, self.port)  # build source object
+
+       self.conv = gr.interleaved_short_to_complex();
+
+       self.src = msdd.source_simple(self.address,self.port);
+        self.src.set_decim_rate(self.decim)                      # set decimation rate
+#        self.src.set_desired_packet_size(0, 1460)                # set packet size to collect
+
+        self.set_gain(self.gain)                                 # set receiver's attenuation
+        self.set_freq(self.min_freq)                             # set receiver's rx frequency
+        
+        # restructure into vector format for FFT input
+       s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
+
+        # set up FFT processing block
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vcc(self.fft_size, True, mywindow, True)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+        
+        # calculate magnitude squared of output of FFT
+        c2mag = gr.complex_to_mag_squared(self.fft_size)
+
+        # FIXME the log10 primitive is dog slow
+        log = gr.nlog10_ff(10, self.fft_size,
+                           -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+               
+        # Set the freq_step to % of the actual data throughput.
+        # This allows us to discard the bins on both ends of the spectrum.
+        self.percent = 0.4
+
+        # Calculate the frequency steps to use in the collection over the whole bandwidth
+        self.freq_step = self.percent * self.int_rate
+        self.min_center_freq = self.min_freq + self.freq_step/2
+        nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step)
+        self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step)
+
+        self.next_freq = self.min_center_freq
+        
+        # use these values to set receiver settling time between samples and sampling time
+        # the default values provided seem to work well with the MSDD over 100 Mbps ethernet
+        tune_delay  = max(0, int(round(options.tune_delay * self.int_rate / self.fft_size)))  # in fft_frames
+        dwell_delay = max(1, int(round(options.dwell_delay * self.int_rate / self.fft_size))) # in fft_frames
+
+        # set up message callback routine to get data from bin_statistics_f block
+        self.msgq = gr.msg_queue(16)
+        self._tune_callback = tune(self)        # hang on to this to keep it from being GC'd
+
+        # FIXME this block doesn't like to work with negatives because of the "d_max[i]=0" on line
+        # 151 of gr_bin_statistics_f.cc file. Set this to -10000 or something to get it to work.
+        stats = gr.bin_statistics_f(self.fft_size, self.msgq,
+                                    self._tune_callback, tune_delay, dwell_delay)
+
+        # FIXME there's a concern over the speed of the log calculation
+        # We can probably calculate the log inside the stats block
+       self.connect(self.src, self.conv, s2v, fft, c2mag, log, stats)
+
+
+    def set_next_freq(self):
+        ''' Find and set the next frequency of the reciver. After going past the maximum frequency,
+        the frequency is wrapped around to the start again'''
+        target_freq = self.next_freq
+        self.next_freq = self.next_freq + self.freq_step
+        if self.next_freq >= self.max_center_freq:
+            self.next_freq = self.min_center_freq
+
+        if not self.set_freq(target_freq):
+            print "Failed to set frequency to", target_freq
+
+        return target_freq
+                          
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        """
+        return self.src.set_rx_freq(0, target_freq)
+
+
+    def set_gain(self, gain):
+        self.src.set_pga(0, gain)
+
+
+def main_loop(tb):
+    # Set up parser to get data from stats block and display them.
+    msgparser = parse_msg(tb.int_rate, tb.percent)
+    
+    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
+       d = tb.msgq.delete_head();
+       print d.to_string();
+        msgparser.parse(d)
+        #print msgparser.center_freq
+    
+if __name__ == '__main__':
+    tb = my_top_block()
+    try:
+        tb.start()              # start executing flow graph in another thread...
+        main_loop(tb)
+        
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-msdd6000/src/python-examples/new_msdd_fft.py b/gr-msdd6000/src/python-examples/new_msdd_fft.py
new file mode 100755 (executable)
index 0000000..782ecb6
--- /dev/null
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2008,2010 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 msdd
+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
+import numpy
+
+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.
+    """
+    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("-w", "--which", type="int", default=0,
+                          help="select which USRP (0, 1, ...) default is %default",
+                         metavar="NUM")
+        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("-A", "--antenna", default=None,
+                          help="select Rx Antenna (only on RFX-series boards)")
+        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( "--no-hb", action="store_true", default=False,
+                          help="don't use halfband filter in usrp")
+        parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+                          help="Enable oscilloscope display")
+       parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
+                         help="Set fftsink averaging factor, default=[%default]")
+       parser.add_option("", "--ref-scale", type="eng_float", default=13490.0,
+                         help="Set dBFS=0dB input value, default=[%default]")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+       self.options = options
+        self.show_debug_info = True
+        
+        # build the graph
+        if options.no_hb or (options.decim<8):
+          #Min decimation of this firmware is 4. 
+          #contains 4 Rx paths without halfbands and 0 tx paths.
+          self.fpga_filename="std_4rx_0tx.rbf"
+#          self.u = usrp.source_c(which=options.which, decim_rate=options.decim, fpga_filename=self.fpga_filename)
+         self.u = msdd.source_simple("192.168.1.200",0);
+        else:
+          #Min decimation of standard firmware is 8. 
+          #standard fpga firmware "std_2rxhb_2tx.rbf" 
+          #contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+          #self.u = usrp.source_c(which=options.which, decim_rate=options.decim)
+         self.u = msdd.source_simple("192.168.1.200",0);
+
+            
+        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, 
+                                             ref_scale=options.ref_scale, ref_level=0.0, y_divs = 10,
+                                             avg_alpha=options.avg_alpha)
+
+       self.conv = gr.interleaved_short_to_complex();
+        self.connect(self.u, self.conv,  self.scope)
+
+        self._build_gui(vbox)
+       self._setup_events()
+       
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            #g = self.subdev.gain_range()
+            #g = self.u.gain_range()
+            g = [0,10]
+            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()
+            #r = self.u.freq_range()
+           r = [30e6, 6e9]
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+       if options.antenna is not None:
+            print "Selecting antenna %s" % (options.antenna,)
+            self.subdev.select_rx_antenna(options.antenna)
+
+        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("no subdevs used")
+            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()
+        #g = self.u.gain_range()
+        g = [0,10]
+        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@gigE")
+
+        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)
+        r = self.u.set_rx_freq(0, 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)
+           if not self.options.waterfall and not self.options.oscilloscope:
+               self.scope.set_baseband_freq(target_freq)
+           return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.u.set_pga(0,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 _setup_events(self):
+       if not self.options.waterfall and not self.options.oscilloscope:
+           self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
+           
+    def evt_left_dclick(self, event):
+       (ux, uy) = self.scope.win.GetXY(event)
+       if event.CmdDown():
+           # Re-center on maximum power
+           points = self.scope.win._points
+           if self.scope.win.peak_hold:
+               if self.scope.win.peak_vals is not None:
+                   ind = numpy.argmax(self.scope.win.peak_vals)
+               else:
+                   ind = int(points.shape()[0]/2)
+           else:
+               ind = numpy.argmax(points[:,1])
+            (freq, pwr) = points[ind]
+           target_freq = freq/self.scope.win._scale_factor
+           print ind, freq, pwr
+            self.set_freq(target_freq)            
+       else:
+           # Re-center on clicked frequency
+           target_freq = ux/self.scope.win._scale_factor
+           self.set_freq(target_freq)
+           
+       
+def main ():
+    app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-msdd6000/src/python-examples/ofdm/benchmark_ofdm_rx.py b/gr-msdd6000/src/python-examples/ofdm/benchmark_ofdm_rx.py
new file mode 100755 (executable)
index 0000000..deb82e1
--- /dev/null
@@ -0,0 +1,184 @@
+#!/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.
+# 
+
+from gnuradio import gr, blks2
+from gnuradio import msdd
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import struct, sys
+
+# from current dir
+from receive_path import receive_path
+
+class my_top_block(gr.top_block):
+    def __init__(self, address, callback, options):
+        gr.top_block.__init__(self)
+
+        self._address = address
+        self._rx_freq = options.rx_freq         # receiver's center frequency
+        self._rx_gain = options.rx_gain         # receiver's gain
+        self._decim   = options.decim           # Decimating rate for the USRP (prelim)
+
+        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
+        self._setup_source()
+
+        #taps = gr.firdes.low_pass(1, 1, 0.4, 0.2)
+        #self.resample = gr.rational_resampler_base_ccf(5, 8, taps)
+        self.resample = blks2.rational_resampler_ccf(5, 8)
+
+        # Set up receive path
+        self.rxpath = receive_path(callback, options)
+
+        self.connect(self.src, self.resample, self.rxpath)
+        #self.connect(self.src, gr.file_sink(gr.sizeof_gr_complex, "receive.dat"))
+        #self.connect(self.resample, gr.file_sink(gr.sizeof_gr_complex, "resampled.dat"))
+        
+    def _setup_source(self):
+        # build graph
+        self._port = 10001
+        self.src = msdd.source_c(0, 1, self._address, self._port)
+        self.src.set_decim_rate(self._decim)
+        self.src.set_desired_packet_size(0, 1460)
+
+        self.set_gain(self._rx_gain)
+        self.set_freq(self._rx_freq)
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+        """
+        r = self.src.set_rx_freq(0, target_freq)
+        if r:
+            return True
+        return False
+
+    def set_gain(self, gain):
+        """
+        Sets the analog gain in the USRP
+        """
+        return self.src.set_pga(0, gain)
+
+    def decim(self):
+        return self._decim
+
+    def add_options(normal, expert):
+        """
+        Adds usrp-specific options to the Options Parser
+        """
+        add_freq_option(normal)
+        normal.add_option("", "--rx-gain", type="eng_float", default=32, metavar="GAIN",
+                          help="set receiver gain in dB [default=%default].")
+        normal.add_option("-v", "--verbose", action="store_true", default=False)
+
+        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=128,
+                          help="set fpga decimation rate to DECIM [default=%default]")
+        expert.add_option("", "--snr", type="eng_float", default=30,
+                          help="set the SNR of the channel in dB [default=%default]")
+   
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+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")
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+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
+        (pktno,) = struct.unpack('!H', payload[0:2])
+        if ok:
+            n_right += 1
+        print "ok: %r \t pktno: %d \t n_rcvd: %d \t n_right: %d" % (ok, pktno, n_rcvd, n_right)
+
+        if 0:
+            printlst = list()
+            for x in payload[2:]:
+                t = hex(ord(x)).replace('0x', '')
+                if(len(t) == 1):
+                    t = '0' + t
+                printlst.append(t)
+            printable = ''.join(printlst)
+
+            print printable
+            print "\n"
+
+    usage = "usage: %prog [options] host"
+    parser = OptionParser(usage=usage, option_class=eng_option, conflict_handler="resolve")
+    expert_grp = parser.add_option_group("Expert")
+    parser.add_option("","--discontinuous", action="store_true", default=False,
+                      help="enable discontinuous")
+
+    my_top_block.add_options(parser, expert_grp)
+    receive_path.add_options(parser, expert_grp)
+    blks2.ofdm_mod.add_options(parser, expert_grp)
+    blks2.ofdm_demod.add_options(parser, expert_grp)
+
+    (options, args) = parser.parse_args ()
+    address = args[0]
+
+    # build the graph
+    tb = my_top_block(address, rx_callback, options)
+
+    #r = gr.enable_realtime_scheduling()
+    #if r != gr.RT_OK:
+    #    print "Warning: failed to enable realtime scheduling"
+
+    tb.start()                      # start flow graph
+    tb.wait()                       # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-msdd6000/src/python-examples/ofdm/gr_plot_ofdm.py b/gr-msdd6000/src/python-examples/ofdm/gr_plot_ofdm.py
new file mode 100755 (executable)
index 0000000..0bca410
--- /dev/null
@@ -0,0 +1,268 @@
+#!/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 scipy, pylab, math
+import struct, sys
+from pylab import *
+from matplotlib.font_manager import fontManager, FontProperties
+from optparse import OptionParser
+from scipy import fftpack
+from math import log10
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_constellation:
+    def __init__(self, options):
+        derot_file = "ofdm_frame_sink_c.dat"
+        acq_file = "ofdm_frame_acq_c.dat"
+        fft_file = "fft_out_c.dat"
+
+        self.h_derot_file = open(derot_file, "r")
+        self.h_acq_file = open(acq_file, "r")
+        self.h_fft_file = open(fft_file, "r")
+
+        self.occ_tones = options.occ_tones
+        self.fft_size  = options.fft_size
+        self.symbol = options.start
+        self.sample_rate = options.sample_rate
+        
+        self.axis_font_size = 16
+        self.label_font_size = 18
+        self.title_font_size = 20
+        self.text_size = 22
+        
+        # Setup PLOT
+        self.fig = figure(1, figsize=(14, 9), facecolor='w')
+        rcParams['xtick.labelsize'] = self.axis_font_size
+        rcParams['ytick.labelsize'] = self.axis_font_size
+
+        self.text_sym = figtext(0.05, 0.95, ("Symbol: %s" % self.symbol), weight="heavy", size=self.text_size)
+
+        self.make_plots()
+
+        self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05], frameon=True)
+        self.button_left = Button(self.button_left_axes, "<")
+        self.button_left_callback = self.button_left.on_clicked(self.button_left_click)
+
+        self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05], frameon=True)
+        self.button_right = Button(self.button_right_axes, ">")
+        self.button_right_callback = self.button_right.on_clicked(self.button_right_click)
+
+        self.xlim = self.sp_eq.get_xlim()
+
+        self.manager = get_current_fig_manager()
+        #connect('draw_event', self.zoom)
+        connect('key_press_event', self.click)
+        show()
+
+    def get_data(self):
+        self.text_sym.set_text("Symbol: %d" % (self.symbol))
+
+        derot_data = scipy.fromfile(self.h_derot_file, dtype=scipy.complex64, count=self.occ_tones)
+        acq_data = scipy.fromfile(self.h_acq_file, dtype=scipy.complex64, count=self.occ_tones)
+        fft_data = scipy.fromfile(self.h_fft_file, dtype=scipy.complex64, count=self.fft_size)
+        if(len(acq_data) == 0):
+            print "End of File"
+        else:
+            self.acq_data_reals = [r.real for r in acq_data]
+            self.acq_data_imags = [i.imag for i in acq_data]
+            self.derot_data_reals = [r.real for r in derot_data]
+            self.derot_data_imags = [i.imag for i in derot_data]
+
+            self.unequalized_angle = [math.atan2(x.imag, x.real) for x in fft_data]
+            self.equalized_angle = [math.atan2(x.imag, x.real) for x in acq_data]
+            self.derot_equalized_angle = [math.atan2(x.imag, x.real) for x in derot_data]
+
+            self.time = [i*(1/self.sample_rate) for i in range(len(acq_data))]
+            ffttime = [i*(1/self.sample_rate) for i in range(len(fft_data))]
+
+            self.freq = self.get_freq(ffttime, self.sample_rate)
+
+            for i in range(len(fft_data)):
+                if(abs(fft_data[i]) == 0.0):
+                    fft_data[i] = complex(1e-6,1e-6)
+            self.fft_data = [20*log10(abs(f)) for f in fft_data]
+              
+    def get_freq(self, time, sample_rate, T=1):
+        N = len(time)
+        Fs = 1.0 / (max(time) - min(time))
+        Fn = 0.5 * sample_rate
+        freq = [-Fn + i*Fs for i in range(N)]
+        return freq
+
+    def make_plots(self):
+        self.h_acq_file.seek(8*self.symbol*self.occ_tones, 0)
+        self.h_fft_file.seek(8*self.symbol*self.fft_size, 0)
+        self.h_derot_file.seek(8*self.symbol*self.occ_tones, 0)
+
+        self.get_data()
+        
+        # Subplot:  constellation of rotated symbols
+        self.sp_const = self.fig.add_subplot(4,1,1, position=[0.15, 0.55, 0.3, 0.35])
+        self.sp_const.set_title(("Constellation"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_const.set_xlabel("Inphase", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_const.set_ylabel("Qaudrature", fontsize=self.label_font_size, fontweight="bold")
+        self.plot_const = plot(self.acq_data_reals, self.acq_data_imags, 'bo')
+        self.plot_const += plot(self.derot_data_reals, self.derot_data_imags, 'ro')
+        self.sp_const.axis([-2, 2, -2, 2])
+
+        # Subplot: unequalized angle
+        self.sp_uneq = self.fig.add_subplot(4,2,1, position=[0.575, 0.55, 0.3, 0.35])
+        self.sp_uneq.set_title(("Unequalized Angle"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_uneq.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_uneq.set_ylabel("Angle", fontsize=self.label_font_size, fontweight="bold")
+        uneqscale = range(len(self.unequalized_angle))
+        self.plot_uneq = plot(uneqscale, self.unequalized_angle, 'bo')
+
+        # Subplot: equalized angle
+        self.sp_eq = self.fig.add_subplot(4,1,2, position=[0.15, 0.1, 0.3, 0.35])
+        self.sp_eq.set_title(("Equalized Angle"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_eq.set_xlabel("Time (s)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_eq.set_ylabel("Angle", fontsize=self.label_font_size, fontweight="bold")
+        eqscale = range(len(self.equalized_angle))
+        self.plot_eq = plot(eqscale, self.equalized_angle, 'bo')
+        self.plot_eq += plot(eqscale, self.derot_equalized_angle, 'ro', markersize=4)
+
+        # Subplot: FFT
+        self.sp_fft = self.fig.add_subplot(4,2,2, position=[0.575, 0.1, 0.3, 0.35])
+        self.sp_fft.set_title(("FFT"), fontsize=self.title_font_size, fontweight="bold")
+        self.sp_fft.set_xlabel("Frequency (MHz)", fontsize=self.label_font_size, fontweight="bold")
+        self.sp_fft.set_ylabel("Power (dBm)", fontsize=self.label_font_size, fontweight="bold")
+        self.plot_fft = plot(self.freq, self.fft_data, '-bo')
+
+        draw()
+
+    def update_plots(self):
+        eqscale = range(len(self.equalized_angle))
+        uneqscale = range(len(self.unequalized_angle))
+        self.plot_eq[0].set_data([eqscale, self.equalized_angle])
+        self.plot_eq[1].set_data([eqscale, self.derot_equalized_angle])
+        self.plot_uneq[0].set_data([uneqscale, self.unequalized_angle])
+        self.sp_eq.set_ylim([-4, 4])
+        self.sp_uneq.set_ylim([-4, 4])
+
+        #self.sp_iq.axis([min(self.time), max(self.time),
+        #                 1.5*min([min(self.acq_data_reals), min(self.acq_data_imags)]),
+        #                 1.5*max([max(self.acq_data_reals), max(self.acq_data_imags)])])
+
+        self.plot_const[0].set_data([self.acq_data_reals, self.acq_data_imags])
+        self.plot_const[1].set_data([self.derot_data_reals, self.derot_data_imags])
+        self.sp_const.axis([-2, 2, -2, 2])
+
+        self.plot_fft[0].set_data([self.freq, self.fft_data])
+
+        draw()
+        
+    def zoom(self, event):
+        newxlim = self.sp_eq.get_xlim()
+        if(newxlim != self.xlim):
+            self.xlim = newxlim
+            r = self.reals[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+            i = self.imags[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+
+            self.plot_const[0].set_data(r, i)
+            self.sp_const.axis([-2, 2, -2, 2])
+            self.manager.canvas.draw()
+            draw()
+
+    def click(self, event):
+        forward_valid_keys = [" ", "down", "right"]
+        backward_valid_keys = ["up", "left"]
+
+        if(find(event.key, forward_valid_keys)):
+            self.step_forward()
+            
+        elif(find(event.key, backward_valid_keys)):
+            self.step_backward()
+
+    def button_left_click(self, event):
+        self.step_backward()
+
+    def button_right_click(self, event):
+        self.step_forward()
+
+    def step_forward(self):
+        self.symbol += 1
+        self.get_data()
+        self.update_plots()
+
+    def step_backward(self):
+        # Step back in file position
+        self.symbol -= 1
+        if(self.h_acq_file.tell() >= 16*self.occ_tones):
+            self.h_acq_file.seek(-16*self.occ_tones, 1)
+        else:
+            self.symbol = 0
+            self.h_acq_file.seek(-self.h_acq_file.tell(),1)
+
+
+        if(self.h_derot_file.tell() >= 16*self.occ_tones):
+            self.h_derot_file.seek(-16*self.occ_tones, 1)
+        else:
+            self.symbol = 0
+            self.h_derot_file.seek(-self.h_derot_file.tell(),1)
+
+
+        if(self.h_fft_file.tell() >= 16*self.fft_size):
+            self.h_fft_file.seek(-16*self.fft_size, 1)
+        else:
+            self.symbol = 0
+            self.h_fft_file.seek(-self.h_fft_file.tell(),1)
+
+        self.get_data()
+        self.update_plots()
+        
+            
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+    for l in list_search:
+        if item_in == l:
+            return True
+    return False
+
+def main():
+    usage="%prog: [options]"
+
+    parser = OptionParser(conflict_handler="resolve", usage=usage)
+    parser.add_option("", "--fft-size", type="int", default=512,
+                      help="Specify the size of the FFT [default=%default]")
+    parser.add_option("", "--occ-tones", type="int", default=200,
+                      help="Specify the number of occupied tones [default=%default]")
+    parser.add_option("-s", "--start", type="int", default=0,
+                      help="Specify the starting symbol to plot [default=%default]")
+    parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+                      help="Set the sampler rate of the data [default=%default]")
+    
+    (options, args) = parser.parse_args ()
+
+    dc = draw_constellation(options)
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+    
+
+
diff --git a/gr-msdd6000/src/python-examples/ofdm/receive_path.py b/gr-msdd6000/src/python-examples/ofdm/receive_path.py
new file mode 100644 (file)
index 0000000..11c714a
--- /dev/null
@@ -0,0 +1,102 @@
+#!/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 usrp
+from gnuradio import eng_notation
+import copy
+import sys
+
+# /////////////////////////////////////////////////////////////////////////////
+#                              receive path
+# /////////////////////////////////////////////////////////////////////////////
+
+class receive_path(gr.hier_block2):
+    def __init__(self, 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._log         = options.log
+        self._rx_callback = rx_callback      # this callback is fired when there's a packet available
+
+        # receiver
+        self.ofdm_rx = \
+                     blks2.ofdm_demod(options, callback=self._rx_callback)
+
+        # Carrier Sensing Blocks
+        alpha = 0.001
+        thresh = 30   # in dB, will have to adjust
+        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
+
+        self.connect(self, self.ofdm_rx)
+        self.connect(self.ofdm_rx, self.probe)
+        
+        # Display some information about the setup
+        if self._verbose:
+            self._print_verbage()
+        
+    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
+        """
+        normal.add_option("-v", "--verbose", action="store_true", default=False)
+        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
+        """
+        pass
diff --git a/gr-msdd6000/src/python-examples/playback_samples.m b/gr-msdd6000/src/python-examples/playback_samples.m
new file mode 100644 (file)
index 0000000..332296e
--- /dev/null
@@ -0,0 +1,12 @@
+t = read_complex_binary('msdd.dat',10000000);
+
+fftsize=256;
+w = [0:pi/fftsize:pi];
+
+for i = 0:length(t)/fftsize
+       fftdata = fft(i*fftsize:i*fftsize+fftsize);
+       clear plot;
+       plot(w,fftdata);
+endfor
+
+pause;
diff --git a/gr-msdd6000/src/python-examples/read_complex_binary.m b/gr-msdd6000/src/python-examples/read_complex_binary.m
new file mode 100644 (file)
index 0000000..67158b5
--- /dev/null
@@ -0,0 +1,48 @@
+%
+% Copyright 2001 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.
+% 
+
+function v = read_complex_binary (filename, count)
+
+  %% usage: read_complex_binary (filename, [count])
+  %%
+  %%  open filename and return the contents as a column vector, 
+  %%  treating them as 32 bit complex numbers
+  %%
+
+  m = nargchk (1,2,nargin);
+  if (m)
+    usage (m);
+  end
+
+  if (nargin < 2)
+    count = Inf;
+  end
+
+  f = fopen (filename, 'rb');
+  if (f < 0)
+    v = 0;
+  else
+    t = fread (f, [2, count], 'float');
+    fclose (f);
+    v = t(1,:) + t(2,:)*i;
+    [r, c] = size (v);
+    v = reshape (v, c, r);
+  end
diff --git a/gr-msdd6000/src/python_test/capture_tcp_one_set.py b/gr-msdd6000/src/python_test/capture_tcp_one_set.py
new file mode 100644 (file)
index 0000000..7a106a6
--- /dev/null
@@ -0,0 +1,156 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+port = 10000
+host = "10.45.4.46"
+#host = "10.45.4.41"
+myaddr = ('',myport);
+
+buf = 100000;
+
+TCPSock = socket(AF_INET,SOCK_STREAM);
+TCPSock.bind(myaddr);
+TCPSock.connect((host,port));
+
+#f_mhz = 2647; # roof ofdm
+if(len(sys.argv)!= 3):
+       print "usage: %s  fc_ghz   decim_pow2_exponent"%(sys.argv[0]);
+       sys.exit(-1);
+
+f_mhz = float(sys.argv[1])*1000;
+decim = int(sys.argv[2]);
+
+#f_mhz = 3500;
+#f_mhz = 2600;
+f_hz = 0;      # offset        
+gain = 0;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+samples = 65536;
+#samples = 16777216;
+samples = samples*4;   #bytes of data we are requesting
+samples=samples*2;
+#decim = 2;    #0-8   (3 => 2^3 = 8)  
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+sets = 1;
+
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+TCPSock.send(data);
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+while(TCPSock):
+       if(state==0):
+               data = TCPSock.recv(4);
+               [opcode] = struct.unpack("<I", data);
+               print "Opcode = %d"%(opcode);
+               if(opcode==1):
+                       state = 1;
+
+       elif(state==1):
+               data = TCPSock.recv(7*4);
+               args = struct.unpack("<IIIIIII", data);
+               print ["reply_len", "freq_mhz", "offset_hz", "gain", "sample_bytes", "decim", "sets_remain"];
+               print args;
+               IQ_bytes = args[0] - 7*4;
+               state =2;
+
+       elif(state==2):
+               data = TCPSock.recv(4);
+               [i,q] = struct.unpack("<hh", data);
+               tmp = complex(i,q);
+
+               re.append(i);
+               vals.append(tmp);
+               mags.append(abs(tmp));
+
+
+               sample_count = sample_count + 1;
+#              print "sample count %d"%(sample_count)  
+
+               IQ_bytes = IQ_bytes - 4;
+               if(IQ_bytes < 4):
+                       print "got all data (total %d)"%(sample_count);
+                       print "remaining: %d"%(IQ_bytes);
+                       break;
+
+
+TCPSock.close();
+
+print "done"
+nmags = []
+for i in mags:
+       if i == 0:
+               i=1;
+       nmags.append(i);
+
+
+subplot(2,1,1);
+plot(nmags);
+#plot(10*log10(nmags));
+
+dlen = len(vals);
+fftlen = (dlen-1024)/1024;
+
+fft_data = []
+for i in range(1, dlen-1025, 1024):
+
+       t_in = [];
+       for ind in range(i, i+1024):
+               t_in.append(vals[ind]);
+
+       #tmp = 20*log10(fftshift(fft(t_in)));
+       tmp = (fftshift(fft(t_in)));
+
+       if(len(fft_data) == 0):
+               for ind in range(0,1024):
+                       fft_data.append( tmp[ind] );
+       else:
+               for ind in range(0,1024):
+                       fft_data[ind] = fft_data[ind] + tmp[ind];
+
+#fft_data = 20*log10(fftshift(fft(vals)));
+
+
+subplot(2,1,2);
+plot(fft_data);
+show();
+
+f = open(filename, "w");
+for sample in vals:
+       binchunk = struct.pack("<ff",float(sample.real), float(sample.imag) );
+       f.write(binchunk);
+f.close();
+
+
diff --git a/gr-msdd6000/src/python_test/flood_udp.py b/gr-msdd6000/src/python_test/flood_udp.py
new file mode 100644 (file)
index 0000000..e59208a
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+msdd_port = 10001
+msdd_host = "10.45.4.43"
+
+my_udp_addr = ("10.45.1.229",10001);
+
+buf = 1024;
+
+#myport = random.randint(1025,65535);
+#my_tcp_addr = ("10.45.1.229",myport);
+#TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock.bind(my_tcp_addr);
+#TCPSock.connect((msdd_host,msdd_port));
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+SETS_STREAM = 0xffffffff;
+
+f_mhz = 2400;
+f_hz = 1;
+gain = 3;
+samples = 512;
+decim = 4;
+#sets = 16;
+sets = SETS_STREAM;
+window =  3;
+mode = 1;
+
+
+
+for first_byte in range(0,0xff):
+       for second_byte in range(0,0xff):
+               for third_byte in range(0,0xff):
+                       data = struct.pack("!III", first_byte, second_byte,third_byte);
+                       UDPSock.sendto(data, (msdd_host,msdd_port))
+
+       
+# construct the 3 different request type packets
+#fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+#raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+#stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+# send appropriate udp request packet
+
+
+
+
+
+
+
+
+
diff --git a/gr-msdd6000/src/python_test/halt.py b/gr-msdd6000/src/python_test/halt.py
new file mode 100644 (file)
index 0000000..0285f78
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.43"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+halt_data = struct.pack("<II", 0x04, 0x00);
+halt_data = struct.pack("<II", 0x04, 0x00);
+
+data = halt_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+UDPSock.close();
+
+
+
diff --git a/gr-msdd6000/src/python_test/newtest.py b/gr-msdd6000/src/python_test/newtest.py
new file mode 100644 (file)
index 0000000..9596a06
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.43"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+#f_mhz = 3500; 
+#f_mhz = 3500; 
+f_mhz = 100;   
+f_hz = 0;      
+gain = 0;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+samples = 12000;
+samples = samples*4;   #bytes of data we are requesting
+
+decim = 2;     #0-8   (3 => 2^3 = 8)  
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+#raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain, samples, decim, sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+while(True):
+       print state;
+       if(state==0):
+               data = UDPSock.recv(4);
+               [opcode] = struct.unpack("<I", data);
+               print "Opcode = %d"%(opcode);
+               if(opcode==1):
+
+                       # if UDP mode and sets_stream requested,
+                       # we do not get a header reply back, only data
+                       if(sets == 0):
+                               state = 1;
+                       else:
+                               state = 2;
+
+       elif(state==1):
+               data = UDPSock.recv(7*4);
+               args = struct.unpack("<IIIIIII", data);
+               print ["reply_len", "freq_mhz", "offset_hz", "gain", "sample_bytes", "decim", "sets_remain"];
+               print args;
+               IQ_bytes = args[0] - 7*4;
+               state =2;
+
+       elif(state==2):
+               data = UDPSock.recv(4);
+               [i,q] = struct.unpack("<hh", data);
+               tmp = complex(i,q);
+
+               re.append(i);
+               vals.append(tmp);
+               mags.append(abs(tmp));
+
+
+               sample_count = sample_count + 1;
+#              print "sample count %d"%(sample_count)  
+
+               IQ_bytes = IQ_bytes - 4;
+               if(IQ_bytes < 4):
+                       print "got all data (total %d)"%(sample_count);
+                       print "remaining: %d"%(IQ_bytes);
+                       break;
+
+
+UDPSock.close();
+
+print "done"
+nmags = []
+for i in mags:
+       if i == 0:
+               i=1;
+       nmags.append(i);
+
+
+subplot(2,1,1);
+plot(20*log10(nmags));
+
+fft_data = 20*log10(fftshift(fft(vals)));
+
+subplot(2,1,2);
+plot(fft_data);
+show();
+
+f = open(filename, "w");
+for sample in vals:
+       binchunk = struct.pack("<ff",float(sample.real), float(sample.imag) );
+       f.write(binchunk);
+f.close();
+
+
diff --git a/gr-msdd6000/src/python_test/spectrogram.py b/gr-msdd6000/src/python_test/spectrogram.py
new file mode 100644 (file)
index 0000000..015dd91
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+
+fft_bins = 1024;
+stride = 256;
+
+#filename = "output.dat";
+#decim = 4;
+#Fs = (102.4/decim) * 1e6;
+
+
+from gnuradio import gr;
+from Numeric import *;
+import FFT;
+import numpy.fft;
+from numpy import *;
+from pylab import *;
+import sys;
+
+if len(sys.argv) <2: 
+       print "usage:  %s filename <sample_rate_in_MSPS> <stride_samples>"%(sys.argv[0]);
+       sys.exit(-1);
+
+filename = sys.argv[1];
+fs = 0;
+if(len(sys.argv)>2):
+       fs = float(sys.argv[2])*1000000;
+print "opening %s.\n"%(filename);
+
+if(len(sys.argv)>=4):
+       stride = int(sys.argv[3]);
+       print "using stride = %d"%(stride);
+
+tb = gr.top_block();
+src = gr.file_source(gr.sizeof_gr_complex, filename, False)
+sink = gr.vector_sink_c();
+tb.connect(src,sink);
+tb.run();
+
+data = sink.data();
+dataa = array(data);
+datalen = len( data );
+
+time_bins = (datalen - fft_bins) / stride;
+
+print "output vector :: fft_bins = %d, time_bins = %d\n"%(fft_bins,time_bins);
+
+start_idx = 0;
+
+b = numpy.zeros((time_bins, fft_bins), complex);
+l = [];
+
+window = numpy.blackman(fft_bins);
+
+for i in range(0,time_bins):
+       
+       time_chunk = take( dataa, range(start_idx,start_idx + fft_bins), 0);
+       time_chunk = time_chunk * window;
+       fft_chunk = numpy.fft.fftshift(numpy.fft.fft(time_chunk));
+       psd = 10*log10(fft_chunk * conj(fft_chunk)+0.001);
+
+       b[i] = psd.real;
+       l.append( psd.real.tolist() );
+
+       start_idx = start_idx + stride;
+
+#c = array(b, 10);
+
+print b[0];
+c = array(b);
+#l = c.tolist();
+print size(l);
+
+x = range(0,time_bins);
+print size(x);
+y = range(0,fft_bins);
+print size(y);
+
+print size(l);
+
+contourf(l);
+#contourf([x,y], l);
+colorbar();
+show();
+
+#print c[1,1];
+
+
diff --git a/gr-msdd6000/src/python_test/test_tcp.py b/gr-msdd6000/src/python_test/test_tcp.py
new file mode 100755 (executable)
index 0000000..b02db81
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+myport = random.randint(1025,65535);
+
+port = 10000
+host = "10.45.4.43"
+myaddr = ("10.45.1.229",myport);
+
+buf = 100000;
+
+TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock = socket(AF_INET,SOCK_DGRAM);
+TCPSock.bind(myaddr);
+TCPSock.connect((host,port));
+
+f_mhz = 2400;  
+f_hz = 0;      
+gain = 2;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+#samples = 0xffffffff;         #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+samples = 2;   #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+decim = 2;     #0-8  
+#decim = decim+16;     # +16 to use 16bit instead of 32 bit 
+mode = 1;      #0=IQ, 1=MAG, 2=MAGDB
+sets = 0xffffffff;     
+#sets = 1;
+
+fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+data = raw_data;
+
+#TCPSock.sendto(data, (host,port))
+TCPSock.send(data);
+
+print "sent"
+
+
+
+count = 0;
+while(1):
+       data,addr = TCPSock.recvfrom(buf);
+       
+       print "got response"
+       
+       print "Data length: %d bytes."%(len(data));
+       if(len(data)==12):
+               a,b,c = struct.unpack("!III",data);
+               print "%x,%x,%x"%(a,b,c);
+
+       datavector = [];
+
+       for d in data:
+               a = struct.unpack("<b",d);
+               datavector.append(a);
+
+       print datavector;
+               
+       count = count + 1;
+       
+       if(count > 1):
+               sets = 3;
+               raw_data_2 = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+               TCPSock.send(raw_data_2);
+               
+               
+               
+TCPSock.close();
+
+
+
diff --git a/gr-msdd6000/src/python_test/test_tcp_fft.py b/gr-msdd6000/src/python_test/test_tcp_fft.py
new file mode 100644 (file)
index 0000000..b02db81
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+myport = random.randint(1025,65535);
+
+port = 10000
+host = "10.45.4.43"
+myaddr = ("10.45.1.229",myport);
+
+buf = 100000;
+
+TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock = socket(AF_INET,SOCK_DGRAM);
+TCPSock.bind(myaddr);
+TCPSock.connect((host,port));
+
+f_mhz = 2400;  
+f_hz = 0;      
+gain = 2;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+#samples = 0xffffffff;         #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+samples = 2;   #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+decim = 2;     #0-8  
+#decim = decim+16;     # +16 to use 16bit instead of 32 bit 
+mode = 1;      #0=IQ, 1=MAG, 2=MAGDB
+sets = 0xffffffff;     
+#sets = 1;
+
+fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+data = raw_data;
+
+#TCPSock.sendto(data, (host,port))
+TCPSock.send(data);
+
+print "sent"
+
+
+
+count = 0;
+while(1):
+       data,addr = TCPSock.recvfrom(buf);
+       
+       print "got response"
+       
+       print "Data length: %d bytes."%(len(data));
+       if(len(data)==12):
+               a,b,c = struct.unpack("!III",data);
+               print "%x,%x,%x"%(a,b,c);
+
+       datavector = [];
+
+       for d in data:
+               a = struct.unpack("<b",d);
+               datavector.append(a);
+
+       print datavector;
+               
+       count = count + 1;
+       
+       if(count > 1):
+               sets = 3;
+               raw_data_2 = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+               TCPSock.send(raw_data_2);
+               
+               
+               
+TCPSock.close();
+
+
+
diff --git a/gr-msdd6000/src/python_test/test_udp.py b/gr-msdd6000/src/python_test/test_udp.py
new file mode 100755 (executable)
index 0000000..fd93847
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+msdd_port = 10001
+msdd_host = "10.45.4.43"
+
+my_udp_addr = ("10.45.1.229",10001);
+
+buf = 1024;
+
+#myport = random.randint(1025,65535);
+#my_tcp_addr = ("10.45.1.229",myport);
+#TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock.bind(my_tcp_addr);
+#TCPSock.connect((msdd_host,msdd_port));
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+SETS_STREAM = 0xffffffff;
+
+f_mhz = 2400;
+f_hz = 1;
+gain = 3;
+samples = 512;
+
+decim = 2;
+
+#sets = 16;
+sets = SETS_STREAM;
+window =  3;
+mode = 1;
+
+
+# construct the 3 different request type packets
+fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+# send appropriate udp request packet
+UDPSock.sendto(raw_data, (msdd_host,msdd_port))
+
+#TCPSock.send(raw_data);
+
+
+print "sent request"
+
+
+print "waiting for response"
+data,addr = UDPSock.recvfrom(buf);
+
+print "got response"
+
+print data;
diff --git a/gr-msdd6000/src/python_test/udp_stream_cap.py b/gr-msdd6000/src/python_test/udp_stream_cap.py
new file mode 100644 (file)
index 0000000..6326f27
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.43"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+#f_mhz = 3500; 
+#f_mhz = 3500; 
+f_mhz = 1000;  
+f_hz = 0;      
+gain = 0;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+#samples = 65535;
+samples = 16384;
+#samples = samples*4;  #bytes of data we are requesting
+
+decim = 4;     #0-8   (3 => 2^3 = 8)  
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+
+numtocap = 1000;
+IQ_bytes = 4 * numtocap;
+
+numbytes = 100 * 65536;
+
+num_rx = 0;
+start =  time.time();
+
+d = [];
+while(num_rx < numbytes):
+       data = UDPSock.recv(65536);
+       num_rx = num_rx + len(data);
+       d.append(data);
+
+mags = [];
+for i in range(0, len(d)/4):
+       v = struct.unpack_from("<f",d, i*4);
+       mags.append(abs(v));
+plot(mags);
+show();
+
+end = time.time();
+print "recieved %d bytes in %f sec"%(numbytes, end-start);
+
+bytes_per_sec = numbytes / (end-start);
+samples_per_sec = bytes_per_sec / 4;
+MSPS = samples_per_sec / 1000000.0;
+
+print "Got %f MSPS"%(MSPS);
+print "Expected %f MSPS"%(102.4/math.pow(2,(1+decim-16)));
+       
+
+halt_data = struct.pack("<II", 0x04, 0x00);
+UDPSock.sendto(halt_data, (msdd_host, msdd_port));
+
+
+UDPSock.close();
+
diff --git a/gr-msdd6000/src/python_test/udp_stream_rate_test.py b/gr-msdd6000/src/python_test/udp_stream_rate_test.py
new file mode 100644 (file)
index 0000000..0b75f23
--- /dev/null
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.46"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+#f_mhz = 3500; 
+#f_mhz = 3500; 
+f_mhz = 1000;  
+f_hz = 0;      
+gain = 0;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+#samples = 65535;
+samples = 16384;
+#samples = samples*4;  #bytes of data we are requesting
+
+decim = 2;     #0-8   (3 => 2^3 = 8)   # ok
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+
+numtocap = 1000;
+IQ_bytes = numtocap * numtocap;
+
+numbytes = 1000 * 65536;
+
+num_rx = 0;
+start = -1;
+while(num_rx < numbytes):
+       data = UDPSock.recv(65536);
+
+       if(start==-1):
+               start =  time.time();
+
+       num_rx = num_rx + len(data);
+#      print num_rx;
+
+
+end = time.time();
+print "recieved %d bytes in %f sec"%(numbytes, end-start);
+
+bytes_per_sec = numbytes / (end-start);
+samples_per_sec = bytes_per_sec / 4;
+MSPS = samples_per_sec / 1000000.0;
+
+print "Got %f MSPS"%(MSPS);
+print "Expected %f MSPS"%(102.4/math.pow(2,(decim-16)));
+       
+
+halt_data = struct.pack("<II", 0x04, 0x00);
+UDPSock.sendto(halt_data, (msdd_host, msdd_port));
+
+
+UDPSock.close();
+
diff --git a/gr-msdd6000/src/python_test/udp_stream_rate_test_plot.py b/gr-msdd6000/src/python_test/udp_stream_rate_test_plot.py
new file mode 100644 (file)
index 0000000..eef78f5
--- /dev/null
@@ -0,0 +1,161 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+from random import *;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.46"
+
+buf = 100000;
+
+my_udp_addr = ('',randint(1025,65535));
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+f_mhz = 2500;  
+
+print "fc = %d"%(f_mhz);
+
+f_hz = 0;      
+gain = 20;     # attenuation
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+samples = 65535*4*2;
+#samples = 16384;
+#samples = 16*1024*1024;
+#samples = samples*4;  #bytes of data we are requesting
+
+# decim 0-8 ( 3 - 8 )
+#decim = 5;    # rate ok
+decim = 8;
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+
+numtocap = 1000;
+IQ_bytes = 4 * numtocap;
+
+numbytes = 65536*100;
+#numbytes = 65536*2;
+#numbytes = 1024;
+
+num_rx = 0;
+start =  time.time();
+l = [];
+arr = [];
+
+while(num_rx < numbytes):
+       data = UDPSock.recv(1024);
+       l.append(data);
+       num_rx = num_rx + len(data);
+
+
+end = time.time();
+
+# send stop command
+halt_data = struct.pack(">II", 0x04, 0x00);
+UDPSock.sendto(halt_data, (msdd_host, msdd_port));
+
+# perform timing analysis
+print "recieved %d bytes in %f sec"%(numbytes, end-start);
+bytes_per_sec = numbytes / (end-start);
+samples_per_sec = bytes_per_sec / 4;
+MSPS = samples_per_sec / 1000000.0;
+
+print "Got %f MSPS"%(MSPS);
+print "Expected %f MSPS"%(102.4/math.pow(2,(decim-16)));
+
+
+# plot data
+val_arr = [];
+mag_arr = [];
+mag_arr2 = [];
+
+print "Repacking data..."
+f = open("out.dat","w");
+for li in l:
+       for p in range(0, len(li)/4):
+               [i,q] = struct.unpack_from("<hh", li, p*4);
+               val = complex(i,q);
+               mag_arr.append((val*conj(val)).real);
+               val_arr.append(val);
+               binchunk = struct.pack("<ff",float(val.real), float(val.imag) );
+               f.write(binchunk);
+f.close();
+               
+
+dlen = len(val_arr)-1;
+fft_data = [];
+for i in range(1, dlen-1024, 1024*1024):
+
+        t_in = [];
+        for ind in range(i, i+1024):
+                t_in.append(val_arr[ind]);
+
+        tmp = 20*log10(fftshift(fft(t_in)));
+        #tmp = (fftshift(fft(t_in)));
+
+        if(len(fft_data) == 0):
+                for ind in range(0,1024):
+                        fft_data.append( tmp[ind] );
+        else:
+                for ind in range(0,1024):
+                        fft_data[ind] = fft_data[ind] + tmp[ind];
+
+
+
+
+print "Plotting..."
+subplot(2,1,1);
+plot(mag_arr);
+title("T power");
+subplot(2,1,2);
+plot(10*log10(fft_data));
+title("PSD");
+show();
+
+
+
+UDPSock.close();
+
diff --git a/gr-msdd6000/src/python_test/udp_stream_rate_test_plot_loop.py b/gr-msdd6000/src/python_test/udp_stream_rate_test_plot_loop.py
new file mode 100644 (file)
index 0000000..185afc4
--- /dev/null
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+#msdd_host = "10.45.4.43"
+msdd_host = "10.45.4.45"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+#f_mhz = 3500; 
+f_mhz = 1500;  
+#f_mhz = 1000; 
+f_hz = 0;      
+gain = 80;     
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+#samples = 65535;
+samples = 16384;
+#samples = samples*4;  #bytes of data we are requesting
+
+# decim 0-8 ( 3 - 8 )
+#decim = 5;    # rate ok
+decim = 4;
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+start =  time.time();
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+
+numtocap = 1000;
+IQ_bytes = 4 * numtocap;
+
+#numbytes = 65536*100;
+numbytes = 65536;
+
+
+
+while(True):
+
+       data = [];
+       l = [];
+       num_rx = 0;
+       while(num_rx < numbytes):
+               data = UDPSock.recv(65536);
+               num_rx = num_rx + len(data);
+               l.append(data);
+
+       end = time.time();
+       
+       # send stop command
+       #halt_data = struct.pack("<II", 0x04, 0x00);
+       #UDPSock.sendto(halt_data, (msdd_host, msdd_port));
+       
+       # perform timing analysis
+       print "recieved %d bytes in %f sec"%(numbytes, end-start);
+       bytes_per_sec = numbytes / (end-start);
+       samples_per_sec = bytes_per_sec / 4;
+       MSPS = samples_per_sec / 1000000.0;
+       
+       print "Got %f MSPS"%(MSPS);
+       print "Expected %f MSPS"%(102.4/math.pow(2,(decim-16)));
+       
+       
+       # plot data
+       val_arr = [];
+       mag_arr = [];
+       
+       print "Repacking data..."
+       for li in l:
+               for p in range(0, len(li)/4):
+                       [i,q] = struct.unpack_from("<hh", li, p);
+                       val = complex(i,q);
+                       mag_arr.append(abs(val));
+                       val_arr.append(val);
+       
+       
+       print "Calculating Time Domain Power..."
+       tpwr = [];
+       for i in val_arr:
+               tpwr.append( (i*conj(i)).real );
+       
+       print "Calculating PSD..."
+       freqz = fft(val_arr);
+       
+       #freqz = [];
+       #
+       #for i in range(0, floor(len(val_arr)/2048)):
+       #       tmp = val_arr(range(i,i+2048));
+       #       if len(freqz) == 0:
+       #               freqz = tmp;
+       #       
+       
+       psd = (freqz * conj(freqz)).real;
+       
+       print "Plotting..."
+       subplot(2,1,1);
+       plot(tpwr);
+       subplot(2,1,2);
+       plot(10*log10(psd));
+       show();
+       
+UDPSock.close();
+
diff --git a/gr-msdd6000/src/python_test/udp_stream_test.py b/gr-msdd6000/src/python_test/udp_stream_test.py
new file mode 100644 (file)
index 0000000..6136d16
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+import array;
+import cmath;
+from numpy import *;
+from numpy.fft import *;
+from pylab import *;
+
+myport = random.randint(1025,65535);
+filename = "output.dat";
+
+msdd_port = 10001
+msdd_host = "10.45.4.46"
+
+buf = 100000;
+
+my_udp_addr = ('',10001);
+my_udp_addr = ('10.45.1.229 ',10001);
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(my_udp_addr);
+
+#f_mhz = 3500; 
+#f_mhz = 3500; 
+f_mhz = 2500;  
+f_hz = 0;      
+gain = 0;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+
+samples = 65535;
+samples = samples*4;   #bytes of data we are requesting
+
+decim = 2;     #0-8   (3 => 2^3 = 8)  
+decim = decim+16;      # +16 to use 16bit floats instead of 32 bit floats
+mode = 0;      #0=IQ, 1=MAG, 2=MAGDB
+#sets = 0;
+sets = 0xffffffff;
+
+size_int = 4;
+request_len = 6*size_int;      # 6 int items not including the 8 bytes for opcode and length fields
+print "request len = %d"%(request_len);
+
+raw_data = struct.pack("<IIIIIIII", 0x01, request_len, f_mhz, f_hz, gain, samples, decim, sets);
+
+data = raw_data;
+
+UDPSock.sendto(data, (msdd_host, msdd_port));
+
+print "sent"
+
+
+
+count = 0;
+
+total_data = [];
+
+state = 0;
+
+vals = [];
+mags = [];
+re = [];
+
+sample_count = 0;
+IQ_bytes=0;
+
+
+numtocap = 1000;
+IQ_bytes = 4 * numtocap;
+
+while(True):
+       data = UDPSock.recv(4);
+       [i,q] = struct.unpack("<hh", data);
+       tmp = complex(i,q);
+
+       re.append(i);
+       vals.append(tmp);
+       mags.append(abs(tmp));
+
+
+       sample_count = sample_count + 1;
+#      print "sample count %d"%(sample_count)  
+
+       IQ_bytes = IQ_bytes - 4;
+       if(IQ_bytes % 200 == 0):
+               print IQ_bytes;
+       if(IQ_bytes < 4):
+               print "got all data (total %d)"%(sample_count);
+               print "remaining: %d"%(IQ_bytes);
+               break;
+
+
+halt_data = struct.pack("<II", 0x04, 0x00);
+UDPSock.sendto(halt_data, (msdd_host, msdd_port));
+
+
+
+UDPSock.close();
+
+print "done"
+nmags = []
+for i in mags:
+       if i == 0:
+               i=1;
+       nmags.append(i);
+
+
+subplot(2,1,1);
+plot(20*log10(nmags));
+
+fft_data = 20*log10(fftshift(fft(vals)));
+
+subplot(2,1,2);
+plot(fft_data);
+show();
+
+f = open(filename, "w");
+for sample in vals:
+       binchunk = struct.pack("<ff",float(sample.real), float(sample.imag) );
+       f.write(binchunk);
+f.close();
+
+
diff --git a/gr-msdd6000/src/qa_msdd_source_simple.py b/gr-msdd6000/src/qa_msdd_source_simple.py
new file mode 100755 (executable)
index 0000000..5262fce
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+from pylab import *;
+#from scipy.fftpack import fftshift;
+
+import math;
+
+from gnuradio import msdd,gr;
+
+
+tb = gr.top_block();
+
+
+src = msdd.source_simple("10.45.4.43",0);
+convert = gr.interleaved_short_to_complex();
+sink = gr.vector_sink_c();
+
+gain = 40;
+
+fc = 2.4e9;
+
+src.set_decim_rate(8);
+#src.set_rx_freq(0,3500000000);
+src.set_rx_freq(0,fc);
+src.set_pga(0,gain);
+
+
+tb.connect(src, convert, sink);
+
+
+tb.start();
+
+v = []
+for i in range(0,10000):
+       b = math.sqrt(i);
+       v.append(b);
+
+tb.stop();
+
+#print sink.data();
+
+data = sink.data();
+
+plot(10*log10(fftshift(fft(sink.data()))));
+show();
diff --git a/gr-noaa/.gitignore b/gr-noaa/.gitignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/gr-noaa/Makefile.am b/gr-noaa/Makefile.am
new file mode 100644 (file)
index 0000000..854ce14
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = lib grc oct
+
+if PYTHON
+SUBDIRS += swig python apps
+endif
+
diff --git a/gr-noaa/README b/gr-noaa/README
new file mode 100644 (file)
index 0000000..f00d2d2
--- /dev/null
@@ -0,0 +1,70 @@
+This component implements an NOAA POES HRPT receiver.  After installation,
+the scripts described below will be install in the users PATH.
+
+As the scripts are generated using GRC, GRC must be installed at runtime
+in order for them to operate.
+
+
+HRPT OPERATION
+
+usrp_rx_hrpt.py
+---------------
+
+This GUI script will receive HRPT RF, demodulate, synchronize, and deframe
+HRPT minor frames into a file.  The file stores a series of 11090 word,
+16-bits per word corresponding to the HRPT minor frame format (only the
+lower 10-bits per word are significant.)
+
+The script file by default uses USRP side A, 1698 MHz, at decimation 16. The
+gnuradio configuration file ~/.gnuradio/config.conf, section 'usrp_rx_hrpt.cfg',
+will allow changing this, as well as implementing persistent storage of GUI
+entered parameters from invocation to invocation.
+
+The present HRPT demodulator is only tested at decimation 16.  The only other
+valid decimation rates are 24 and 32, which may work but with more bit
+errors.  No other decimation rates will work.
+
+
+file_rx_hrpt.py
+---------------
+
+This GUI script operates like usrp_rx_hrpt.py, but reads from a pre-captured
+data file supplied by -F on the command line.
+
+
+usrp_rx_hrpt_nogui.py
+---------------------
+
+This non-GUI script operates without a display and requires that all parameters
+be set in the configuration file prior to running.  It has no command-line
+parameters, and works identically to the GUI scripts.
+
+
+hrpt_demod_file.py
+------------------
+
+This non-GUI script will operate on a file generated with
+usrp_rx_cfile.py and output frames in the same format as above.  It does
+*not* use the configuration file above; instead you must pass parameters to
+it on the command line.  To exit the program, press Enter.
+
+Usage: demod_hrpt_file.py: [options]
+
+Options:
+  -h, --help            show this help message and exit
+  -d DECIM, --decim=DECIM
+                        Set Decimation [default=16]
+  -p PLL_ALPHA, --pll-alpha=PLL_ALPHA
+                        Set pll_alpha [default=50m]
+  -s CLOCK_ALPHA, --clock-alpha=CLOCK_ALPHA
+                        Set clock_alpha [default=50m]
+  -F INPUT_FILENAME, --input-filename=INPUT_FILENAME
+                        Set Filename [default=usrp.dat]
+  -o OUTPUT_FILENAME, --output-filename=OUTPUT_FILENAME
+                        Set Output [default=frames.dat]
+
+
+LRIT Operation
+--------------
+
+The work-in-progress LRIT GRC script is not currently in a usable state.
diff --git a/gr-noaa/apps/.gitignore b/gr-noaa/apps/.gitignore
new file mode 100644 (file)
index 0000000..cd8d543
--- /dev/null
@@ -0,0 +1,3 @@
+*.dat
+*.txt
+*.hrpt
diff --git a/gr-noaa/apps/Makefile.am b/gr-noaa/apps/Makefile.am
new file mode 100644 (file)
index 0000000..8fb6fbe
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+if PYTHON
+
+dist_bin_SCRIPTS = \
+       hrpt_decode.py \
+       hrpt_demod.py \
+       file_rx_hrpt.py \
+       file_rx_lrit.py \
+       usrp_rx_hrpt.py \
+       usrp_rx_hrpt_nogui.py \
+       usrp_rx_lrit.py
+
+EXTRA_DIST = \
+       hrpt_decode.grc \
+       hrpt_demod.grc \
+       file_rx_hrpt.grc \
+       file_rx_lrit.grc \
+       usrp_rx_hrpt.grc \
+       usrp_rx_hrpt_nogui.grc \
+       usrp_rx_lrit.grc
+endif
diff --git a/gr-noaa/apps/file_rx_hrpt.grc b/gr-noaa/apps/file_rx_hrpt.grc
new file mode 100644 (file)
index 0000000..e3cccd3
--- /dev/null
@@ -0,0 +1,1194 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Mon Nov  9 07:47:17 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>file_rx_hrpt</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP HRPT Receiver</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4096,4096</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>run</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sym_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>600*1109</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(301, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/sym_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_source</key>
+    <param>
+      <key>id</key>
+      <value>virtual_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(173, 971)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>demod_scope</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Post-Demod</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sym_rate*2.0</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>10.0/sym_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(666, 542)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_clock_recovery_mm_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps/2.0</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>clock_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(873, 696)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_moving_average_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_moving_average_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>length</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>scale</key>
+      <value>1.0/hs</value>
+    </param>
+    <param>
+      <key>max_iter</key>
+      <value>4000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(682, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_pll_cf</key>
+    <param>
+      <key>id</key>
+      <value>pll</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>pll_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>max_offset</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(469, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_sink</key>
+    <param>
+      <key>id</key>
+      <value>virtual_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1142, 728)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ['HOME']+'/.gnuradio/config.conf'</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 159)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math, os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 110)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>agc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(301, 705)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_interleaved_short_to_complex</key>
+    <param>
+      <key>id</key>
+      <value>gr_interleaved_short_to_complex_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(73, 733)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_source</key>
+    <param>
+      <key>id</key>
+      <value>gr_file_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(76, 613)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Spectrum','Demod']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1,0,1,2</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 249)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RX Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-5</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value>640, 360</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(471, 450)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_binary_slicer_fb</key>
+    <param>
+      <key>id</key>
+      <value>gr_binary_slicer_fb_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(393, 975)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>throttle</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>2*sample_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(75, 679)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>usrp.dat</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>F</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(196, 98)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>intx</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>d</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(307, 98)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>PLL Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_pll_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 98)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Clock Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_clock_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(540, 98)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sps/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(499, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*math.pi*100e3/sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(575, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(705, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'frames.hrpt'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'filename'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(521, 254)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'pll_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(195, 253)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'clock_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(360, 255)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_deframer</key>
+    <param>
+      <key>id</key>
+      <value>deframer</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(579, 975)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_decoder</key>
+    <param>
+      <key>id</key>
+      <value>decoder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>output</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(849, 925)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_sink</key>
+    <param>
+      <key>id</key>
+      <value>frame_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(848, 1007)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>gr_binary_slicer_fb_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>frame_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>decoder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>virtual_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>demod_scope</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_moving_average_xx_0</source_block_id>
+    <sink_block_id>gr_clock_recovery_mm_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pll</source_block_id>
+    <sink_block_id>gr_moving_average_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>pll</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>rx_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_interleaved_short_to_complex_0</source_block_id>
+    <sink_block_id>agc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>throttle</source_block_id>
+    <sink_block_id>gr_interleaved_short_to_complex_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_file_source_0</source_block_id>
+    <sink_block_id>throttle</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_binary_slicer_fb_0</source_block_id>
+    <sink_block_id>deframer</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/file_rx_hrpt.py b/gr-noaa/apps/file_rx_hrpt.py
new file mode 100755 (executable)
index 0000000..13b8876
--- /dev/null
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: USRP HRPT Receiver
+# Generated: Mon Nov  9 07:47:17 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import noaa
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import fftsink2
+from gnuradio.wxgui import forms
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import ConfigParser
+import math, os
+import wx
+
+class file_rx_hrpt(grc_wxgui.top_block_gui):
+
+       def __init__(self, input_filename="usrp.dat", decim=32):
+               grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver")
+
+               ##################################################
+               # Parameters
+               ##################################################
+               self.input_filename = input_filename
+               self.decim = decim
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.sym_rate = sym_rate = 600*1109
+               self.sample_rate = sample_rate = 64e6/decim
+               self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
+               self.sps = sps = sample_rate/sym_rate
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(config_filename)
+               try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha')
+               except: saved_pll_alpha = 0.01
+               self.saved_pll_alpha = saved_pll_alpha
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(config_filename)
+               try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha')
+               except: saved_clock_alpha = 0.01
+               self.saved_clock_alpha = saved_clock_alpha
+               self.pll_alpha = pll_alpha = saved_pll_alpha
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(config_filename)
+               try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
+               except: output_filename = 'frames.hrpt'
+               self.output_filename = output_filename
+               self.max_clock_offset = max_clock_offset = 100e-6
+               self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
+               self.hs = hs = int(sps/2.0)
+               self.clock_alpha = clock_alpha = saved_clock_alpha
+
+               ##################################################
+               # Notebooks
+               ##################################################
+               self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
+               self.GridAdd(self.displays, 1, 0, 1, 2)
+
+               ##################################################
+               # Controls
+               ##################################################
+               _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._pll_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_pll_alpha_sizer,
+                       value=self.pll_alpha,
+                       callback=self.set_pll_alpha,
+                       label="PLL Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._pll_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_pll_alpha_sizer,
+                       value=self.pll_alpha,
+                       callback=self.set_pll_alpha,
+                       minimum=0.0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_pll_alpha_sizer, 0, 0, 1, 1)
+               _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._clock_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_clock_alpha_sizer,
+                       value=self.clock_alpha,
+                       callback=self.set_clock_alpha,
+                       label="Clock Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._clock_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_clock_alpha_sizer,
+                       value=self.clock_alpha,
+                       callback=self.set_clock_alpha,
+                       minimum=0.0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_clock_alpha_sizer, 0, 1, 1, 1)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
+               self.decoder = noaa.hrpt_decoder(True,False)
+               self.deframer = noaa.hrpt_deframer()
+               self.demod_scope = scopesink2.scope_sink_f(
+                       self.displays.GetPage(1).GetWin(),
+                       title="Post-Demod",
+                       sample_rate=sym_rate*2.0,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=10.0/sym_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1)
+               self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
+               self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
+               self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset)
+               self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, input_filename, False)
+               self.gr_interleaved_short_to_complex_0 = gr.interleaved_short_to_complex()
+               self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
+               self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
+               self.rx_fft = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=5,
+                       y_divs=8,
+                       ref_level=-5,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=True,
+                       avg_alpha=0.1,
+                       title="RX Spectrum",
+                       peak_hold=False,
+                       size=(640, 360),
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
+               self.throttle = gr.throttle(gr.sizeof_short*1, 2*sample_rate)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
+               self.connect((self.deframer, 0), (self.frame_sink, 0))
+               self.connect((self.deframer, 0), (self.decoder, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0))
+               self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
+               self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
+               self.connect((self.agc, 0), (self.pll, 0))
+               self.connect((self.agc, 0), (self.rx_fft, 0))
+               self.connect((self.gr_interleaved_short_to_complex_0, 0), (self.agc, 0))
+               self.connect((self.throttle, 0), (self.gr_interleaved_short_to_complex_0, 0))
+               self.connect((self.gr_file_source_0, 0), (self.throttle, 0))
+               self.connect((self.gr_binary_slicer_fb_0, 0), (self.deframer, 0))
+
+       def set_input_filename(self, input_filename):
+               self.input_filename = input_filename
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+
+       def set_sym_rate(self, sym_rate):
+               self.sym_rate = sym_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+               self.demod_scope.set_sample_rate(self.sym_rate*2.0)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+               self.rx_fft.set_sample_rate(self.sample_rate)
+               self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(self.config_filename)
+               if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(self.config_filename)
+               if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
+               self.set_hs(int(self.sps/2.0))
+
+       def set_saved_pll_alpha(self, saved_pll_alpha):
+               self.saved_pll_alpha = saved_pll_alpha
+               self.set_pll_alpha(self.saved_pll_alpha)
+
+       def set_saved_clock_alpha(self, saved_clock_alpha):
+               self.saved_clock_alpha = saved_clock_alpha
+               self.set_clock_alpha(self.saved_clock_alpha)
+
+       def set_pll_alpha(self, pll_alpha):
+               self.pll_alpha = pll_alpha
+               self.pll.set_alpha(self.pll_alpha)
+               self.pll.set_beta(self.pll_alpha**2/4.0)
+               self._pll_alpha_slider.set_value(self.pll_alpha)
+               self._pll_alpha_text_box.set_value(self.pll_alpha)
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(self.config_filename)
+               if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
+
+       def set_output_filename(self, output_filename):
+               self.output_filename = output_filename
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+
+       def set_max_clock_offset(self, max_clock_offset):
+               self.max_clock_offset = max_clock_offset
+
+       def set_max_carrier_offset(self, max_carrier_offset):
+               self.max_carrier_offset = max_carrier_offset
+               self.pll.set_max_offset(self.max_carrier_offset)
+
+       def set_hs(self, hs):
+               self.hs = hs
+               self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
+
+       def set_clock_alpha(self, clock_alpha):
+               self.clock_alpha = clock_alpha
+               self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
+               self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
+               self._clock_alpha_slider.set_value(self.clock_alpha)
+               self._clock_alpha_text_box.set_value(self.clock_alpha)
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(self.config_filename)
+               if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default="usrp.dat",
+               help="Set usrp.dat [default=%default]")
+       parser.add_option("-d", "--decim", dest="decim", type="intx", default=32,
+               help="Set decim [default=%default]")
+       (options, args) = parser.parse_args()
+       tb = file_rx_hrpt(input_filename=options.input_filename, decim=options.decim)
+       tb.Run(True)
+
diff --git a/gr-noaa/apps/file_rx_lrit.grc b/gr-noaa/apps/file_rx_lrit.grc
new file mode 100644 (file)
index 0000000..ee6da2a
--- /dev/null
@@ -0,0 +1,1372 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Dec 16 09:14:28 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>file_rx_lrit</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>LRIT Receiver (from capture file)</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4095, 4095</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>293e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(347, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/symbol_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(445, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ['HOME']+'/.gnuradio/config.conf'</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 136)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 82)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(249, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Baseband Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(267, 556)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_source</key>
+    <param>
+      <key>id</key>
+      <value>gr_file_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>lrit.dat</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(79, 729)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(60, 824)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Baseband Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(267, 915)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Gain Mu</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_gain_mu</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(478, 91)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>costas_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>PLL Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>window.hanning</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(916, 535)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_clock_recovery_mm_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>(gain_mu**2)/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>50e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(915, 789)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>costas_spectrum_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Bit Sync Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>window.hanning</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1160, 539)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['USRP RX', 'RRC Filter', 'PLL', 'MM']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 2</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(15, 206)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Costas Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_costas_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(338, 90)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>costas_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>PLL Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(915, 928)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>mm_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Constellation</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/symbol_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1160, 922)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_costas_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.2</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'costas_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(251, 244)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_gain_mu</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.2</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'gain_mu'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(411, 242)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Decim</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>160</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>intx</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>d</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(249, 90)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rrc_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RRC Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>window.hanning</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(705, 534)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_agc_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0/32767.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(273, 800)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_waveform_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RRC Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(706, 927)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_costas_loop_cc</key>
+    <param>
+      <key>id</key>
+      <value>costas</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>(costas_alpha**2)/4.0</value>
+    </param>
+    <param>
+      <key>max_freq</key>
+      <value>50e-6*sps</value>
+    </param>
+    <param>
+      <key>min_freq</key>
+      <value>-50e-6*sps</value>
+    </param>
+    <param>
+      <key>order</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(706, 792)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>root_raised_cosine_filter</key>
+    <param>
+      <key>id</key>
+      <value>rrc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>fir_filter_ccf</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>interp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>sym_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>0.25</value>
+    </param>
+    <param>
+      <key>ntaps</key>
+      <value>int(11*sample_rate/symbol_rate)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(448, 784)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>rrc</source_block_id>
+    <sink_block_id>rx_waveform_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>rrc</source_block_id>
+    <sink_block_id>rrc_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_agc_xx_0</source_block_id>
+    <sink_block_id>rrc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>rx_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>rx_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>gr_agc_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_file_source_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>rrc</source_block_id>
+    <sink_block_id>costas</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>costas_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>costas_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>gr_clock_recovery_mm_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>costas_spectrum_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>mm_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/file_rx_lrit.py b/gr-noaa/apps/file_rx_lrit.py
new file mode 100755 (executable)
index 0000000..9a50631
--- /dev/null
@@ -0,0 +1,337 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: LRIT Receiver (from capture file)
+# Generated: Wed Dec 16 09:16:13 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import fftsink2
+from gnuradio.wxgui import forms
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import ConfigParser
+import os
+import wx
+
+class file_rx_lrit(grc_wxgui.top_block_gui):
+
+       def __init__(self, decim=160):
+               grc_wxgui.top_block_gui.__init__(self, title="LRIT Receiver (from capture file)")
+
+               ##################################################
+               # Parameters
+               ##################################################
+               self.decim = decim
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
+               self.symbol_rate = symbol_rate = 293e3
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(config_filename)
+               try: saved_gain_mu = self._saved_gain_mu_config.getfloat('usrp_rx_lrit', 'gain_mu')
+               except: saved_gain_mu = 0.2
+               self.saved_gain_mu = saved_gain_mu
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(config_filename)
+               try: saved_costas_alpha = self._saved_costas_alpha_config.getfloat('usrp_rx_lrit', 'costas_alpha')
+               except: saved_costas_alpha = 0.2
+               self.saved_costas_alpha = saved_costas_alpha
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/symbol_rate
+               self.gain_mu = gain_mu = saved_gain_mu
+               self.costas_alpha = costas_alpha = saved_costas_alpha
+
+               ##################################################
+               # Notebooks
+               ##################################################
+               self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "USRP RX")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "RRC Filter")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "PLL")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "MM")
+               self.GridAdd(self.displays, 1, 0, 1, 2)
+
+               ##################################################
+               # Controls
+               ##################################################
+               _gain_mu_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._gain_mu_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_gain_mu_sizer,
+                       value=self.gain_mu,
+                       callback=self.set_gain_mu,
+                       label="Gain Mu",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._gain_mu_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_gain_mu_sizer,
+                       value=self.gain_mu,
+                       callback=self.set_gain_mu,
+                       minimum=0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_gain_mu_sizer, 0, 1, 1, 1)
+               _costas_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._costas_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_costas_alpha_sizer,
+                       value=self.costas_alpha,
+                       callback=self.set_costas_alpha,
+                       label="Costas Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._costas_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_costas_alpha_sizer,
+                       value=self.costas_alpha,
+                       callback=self.set_costas_alpha,
+                       minimum=0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_costas_alpha_sizer, 0, 0, 1, 1)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.costas = gr.costas_loop_cc(costas_alpha, (costas_alpha**2)/4.0, 50e-6*sps, -50e-6*sps, 2)
+               self.costas_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(2).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=True,
+                       avg_alpha=None,
+                       title="PLL Spectrum",
+                       peak_hold=False,
+                       win=window.hanning,
+               )
+               self.displays.GetPage(2).GridAdd(self.costas_spectrum.win, 0, 0, 1, 1)
+               self.costas_spectrum_0 = fftsink2.fft_sink_c(
+                       self.displays.GetPage(3).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=symbol_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=True,
+                       avg_alpha=None,
+                       title="Bit Sync Spectrum",
+                       peak_hold=False,
+                       win=window.hanning,
+               )
+               self.displays.GetPage(3).GridAdd(self.costas_spectrum_0.win, 0, 0, 1, 1)
+               self.costas_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(2).GetWin(),
+                       title="PLL Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(2).GridAdd(self.costas_waveform.win, 1, 0, 1, 1)
+               self.gr_agc_xx_0 = gr.agc_cc(1e-6, 1.0, 1.0/32767.0, 1.0)
+               self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_cc(sps, (gain_mu**2)/4.0, 0.5, gain_mu, 50e-6)
+               self.gr_file_source_0 = gr.file_source(gr.sizeof_gr_complex*1, "lrit.dat", False)
+               self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*1, sample_rate)
+               self.mm_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(3).GetWin(),
+                       title="Constellation",
+                       sample_rate=symbol_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/symbol_rate,
+                       ac_couple=False,
+                       xy_mode=True,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(3).GridAdd(self.mm_waveform.win, 1, 0, 1, 1)
+               self.rrc = gr.fir_filter_ccf(1, firdes.root_raised_cosine(
+                       1, sample_rate, symbol_rate, 0.25, int(11*sample_rate/symbol_rate)))
+               self.rrc_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(1).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=True,
+                       avg_alpha=None,
+                       title="RRC Spectrum",
+                       peak_hold=False,
+                       win=window.hanning,
+               )
+               self.displays.GetPage(1).GridAdd(self.rrc_spectrum.win, 0, 0, 1, 1)
+               self.rx_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=5,
+                       y_divs=10,
+                       ref_level=50,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=True,
+                       avg_alpha=None,
+                       title="Baseband Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_spectrum.win, 0, 0, 1, 1)
+               self.rx_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       title="Baseband Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_waveform.win, 1, 0, 1, 1)
+               self.rx_waveform_0 = scopesink2.scope_sink_c(
+                       self.displays.GetPage(1).GetWin(),
+                       title="RRC Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(1).GridAdd(self.rx_waveform_0.win, 1, 0, 1, 1)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.rrc, 0), (self.rx_waveform_0, 0))
+               self.connect((self.rrc, 0), (self.rrc_spectrum, 0))
+               self.connect((self.gr_agc_xx_0, 0), (self.rrc, 0))
+               self.connect((self.gr_throttle_0, 0), (self.rx_waveform, 0))
+               self.connect((self.gr_throttle_0, 0), (self.rx_spectrum, 0))
+               self.connect((self.gr_throttle_0, 0), (self.gr_agc_xx_0, 0))
+               self.connect((self.gr_file_source_0, 0), (self.gr_throttle_0, 0))
+               self.connect((self.rrc, 0), (self.costas, 0))
+               self.connect((self.costas, 0), (self.costas_spectrum, 0))
+               self.connect((self.costas, 0), (self.costas_waveform, 0))
+               self.connect((self.costas, 0), (self.gr_clock_recovery_mm_xx_0, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.costas_spectrum_0, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.mm_waveform, 0))
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(self.config_filename)
+               if not self._saved_costas_alpha_config.has_section('usrp_rx_lrit'):
+                       self._saved_costas_alpha_config.add_section('usrp_rx_lrit')
+               self._saved_costas_alpha_config.set('usrp_rx_lrit', 'costas_alpha', str(self.costas_alpha))
+               self._saved_costas_alpha_config.write(open(self.config_filename, 'w'))
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(self.config_filename)
+               if not self._saved_gain_mu_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_mu_config.add_section('usrp_rx_lrit')
+               self._saved_gain_mu_config.set('usrp_rx_lrit', 'gain_mu', str(self.gain_mu))
+               self._saved_gain_mu_config.write(open(self.config_filename, 'w'))
+
+       def set_symbol_rate(self, symbol_rate):
+               self.symbol_rate = symbol_rate
+               self.set_sps(self.sample_rate/self.symbol_rate)
+               self.costas_spectrum_0.set_sample_rate(self.symbol_rate)
+               self.mm_waveform.set_sample_rate(self.symbol_rate)
+               self.rrc.set_taps(firdes.root_raised_cosine(1, self.sample_rate, self.symbol_rate, 0.25, int(11*self.sample_rate/self.symbol_rate)))
+
+       def set_saved_gain_mu(self, saved_gain_mu):
+               self.saved_gain_mu = saved_gain_mu
+               self.set_gain_mu(self.saved_gain_mu)
+
+       def set_saved_costas_alpha(self, saved_costas_alpha):
+               self.saved_costas_alpha = saved_costas_alpha
+               self.set_costas_alpha(self.saved_costas_alpha)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_sps(self.sample_rate/self.symbol_rate)
+               self.rx_spectrum.set_sample_rate(self.sample_rate)
+               self.rx_waveform.set_sample_rate(self.sample_rate)
+               self.costas_spectrum.set_sample_rate(self.sample_rate)
+               self.costas_waveform.set_sample_rate(self.sample_rate)
+               self.rrc_spectrum.set_sample_rate(self.sample_rate)
+               self.rx_waveform_0.set_sample_rate(self.sample_rate)
+               self.rrc.set_taps(firdes.root_raised_cosine(1, self.sample_rate, self.symbol_rate, 0.25, int(11*self.sample_rate/self.symbol_rate)))
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.gr_clock_recovery_mm_xx_0.set_omega(self.sps)
+
+       def set_gain_mu(self, gain_mu):
+               self.gain_mu = gain_mu
+               self._gain_mu_slider.set_value(self.gain_mu)
+               self._gain_mu_text_box.set_value(self.gain_mu)
+               self.gr_clock_recovery_mm_xx_0.set_gain_omega((self.gain_mu**2)/4.0)
+               self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.gain_mu)
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(self.config_filename)
+               if not self._saved_gain_mu_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_mu_config.add_section('usrp_rx_lrit')
+               self._saved_gain_mu_config.set('usrp_rx_lrit', 'gain_mu', str(self.gain_mu))
+               self._saved_gain_mu_config.write(open(self.config_filename, 'w'))
+
+       def set_costas_alpha(self, costas_alpha):
+               self.costas_alpha = costas_alpha
+               self._costas_alpha_slider.set_value(self.costas_alpha)
+               self._costas_alpha_text_box.set_value(self.costas_alpha)
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(self.config_filename)
+               if not self._saved_costas_alpha_config.has_section('usrp_rx_lrit'):
+                       self._saved_costas_alpha_config.add_section('usrp_rx_lrit')
+               self._saved_costas_alpha_config.set('usrp_rx_lrit', 'costas_alpha', str(self.costas_alpha))
+               self._saved_costas_alpha_config.write(open(self.config_filename, 'w'))
+               self.costas.set_alpha(self.costas_alpha)
+               self.costas.set_beta((self.costas_alpha**2)/4.0)
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       parser.add_option("-d", "--decim", dest="decim", type="intx", default=160,
+               help="Set Decim [default=%default]")
+       (options, args) = parser.parse_args()
+       tb = file_rx_lrit(decim=options.decim)
+       tb.Run(True)
+
diff --git a/gr-noaa/apps/hrpt_decode.grc b/gr-noaa/apps/hrpt_decode.grc
new file mode 100644 (file)
index 0000000..39fe195
--- /dev/null
@@ -0,0 +1,428 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sun Nov  8 10:48:59 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>hrpt_decode</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4096,4096</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>no_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>run</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*math.pi*100e3/sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(575, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sps/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(499, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math, os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 103)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(710, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sym_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>600*1109</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(307, 18)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/sym_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(400, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>intx</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>d</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(202, 102)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>eng_float</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>p</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(294, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>eng_float</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(395, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_source</key>
+    <param>
+      <key>id</key>
+      <value>file_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(231, 419)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_decoder</key>
+    <param>
+      <key>id</key>
+      <value>decoder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>output</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(462, 419)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>frames.hrpt</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>F</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(522, 100)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>file_source</source_block_id>
+    <sink_block_id>decoder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/hrpt_decode.py b/gr-noaa/apps/hrpt_decode.py
new file mode 100755 (executable)
index 0000000..158780b
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Hrpt Decode
+# Generated: Sun Nov  8 10:49:01 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import noaa
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from optparse import OptionParser
+import math, os
+
+class hrpt_decode(gr.top_block):
+
+       def __init__(self, decim=32, pll_alpha=0.01, clock_alpha=0.01, input_filename="frames.hrpt"):
+               gr.top_block.__init__(self, "Hrpt Decode")
+
+               ##################################################
+               # Parameters
+               ##################################################
+               self.decim = decim
+               self.pll_alpha = pll_alpha
+               self.clock_alpha = clock_alpha
+               self.input_filename = input_filename
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.sym_rate = sym_rate = 600*1109
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/sym_rate
+               self.max_clock_offset = max_clock_offset = 100e-6
+               self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
+               self.hs = hs = int(sps/2.0)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.decoder = noaa.hrpt_decoder(True,True)
+               self.file_source = gr.file_source(gr.sizeof_short*1, input_filename, False)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.file_source, 0), (self.decoder, 0))
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+
+       def set_pll_alpha(self, pll_alpha):
+               self.pll_alpha = pll_alpha
+
+       def set_clock_alpha(self, clock_alpha):
+               self.clock_alpha = clock_alpha
+
+       def set_input_filename(self, input_filename):
+               self.input_filename = input_filename
+
+       def set_sym_rate(self, sym_rate):
+               self.sym_rate = sym_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.set_hs(int(self.sps/2.0))
+
+       def set_max_clock_offset(self, max_clock_offset):
+               self.max_clock_offset = max_clock_offset
+
+       def set_max_carrier_offset(self, max_carrier_offset):
+               self.max_carrier_offset = max_carrier_offset
+
+       def set_hs(self, hs):
+               self.hs = hs
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       parser.add_option("-d", "--decim", dest="decim", type="intx", default=32,
+               help="Set decim [default=%default]")
+       parser.add_option("-p", "--pll-alpha", dest="pll_alpha", type="eng_float", default=eng_notation.num_to_str(0.01),
+               help="Set pll_alpha [default=%default]")
+       parser.add_option("-s", "--clock-alpha", dest="clock_alpha", type="eng_float", default=eng_notation.num_to_str(0.01),
+               help="Set clock_alpha [default=%default]")
+       parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default="frames.hrpt",
+               help="Set frames.hrpt [default=%default]")
+       (options, args) = parser.parse_args()
+       tb = hrpt_decode(decim=options.decim, pll_alpha=options.pll_alpha, clock_alpha=options.clock_alpha, input_filename=options.input_filename)
+       tb.run()
+
diff --git a/gr-noaa/apps/hrpt_demod.grc b/gr-noaa/apps/hrpt_demod.grc
new file mode 100644 (file)
index 0000000..8af3d82
--- /dev/null
@@ -0,0 +1,747 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Sun Nov  8 10:41:07 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>hrpt_demod</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4096,4096</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>no_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>run</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*math.pi*100e3/sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(575, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sps/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(499, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math, os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 103)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>usrp.dat</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>F</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(618, 102)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>frames.dat</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>o</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(726, 102)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_source</key>
+    <param>
+      <key>id</key>
+      <value>file_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>input_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(63, 277)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_interleaved_short_to_complex</key>
+    <param>
+      <key>id</key>
+      <value>cs2cf</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(275, 289)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>agc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-5</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0/32768.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(117, 394)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_pll_cf</key>
+    <param>
+      <key>id</key>
+      <value>pll</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>pll_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>max_offset</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(292, 402)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_moving_average_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_moving_average_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>length</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>scale</key>
+      <value>1.0/hs</value>
+    </param>
+    <param>
+      <key>max_iter</key>
+      <value>4000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(504, 402)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_clock_recovery_mm_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps/2.0</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>clock_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(703, 386)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_deframer</key>
+    <param>
+      <key>id</key>
+      <value>noaa_hrpt_deframer_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1142, 422)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_binary_slicer_fb</key>
+    <param>
+      <key>id</key>
+      <value>gr_binary_slicer_fb_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(960, 422)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(710, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sym_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>600*1109</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(307, 18)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/sym_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(400, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>intx</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>d</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(202, 102)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>eng_float</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>p</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(294, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>parameter</key>
+    <param>
+      <key>id</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>eng_float</value>
+    </param>
+    <param>
+      <key>short_id</key>
+      <value>s</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(395, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_decoder</key>
+    <param>
+      <key>id</key>
+      <value>decoder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>output</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1150, 341)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_file_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1144, 489)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>file_source</source_block_id>
+    <sink_block_id>cs2cf</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>gr_binary_slicer_fb_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_moving_average_xx_0</source_block_id>
+    <sink_block_id>gr_clock_recovery_mm_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pll</source_block_id>
+    <sink_block_id>gr_moving_average_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>cs2cf</source_block_id>
+    <sink_block_id>agc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>pll</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>noaa_hrpt_deframer_0</source_block_id>
+    <sink_block_id>gr_file_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>noaa_hrpt_deframer_0</source_block_id>
+    <sink_block_id>decoder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_binary_slicer_fb_0</source_block_id>
+    <sink_block_id>noaa_hrpt_deframer_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/hrpt_demod.py b/gr-noaa/apps/hrpt_demod.py
new file mode 100755 (executable)
index 0000000..38d0316
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Hrpt Demod
+# Generated: Sun Nov  8 10:41:08 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import noaa
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from optparse import OptionParser
+import math, os
+
+class hrpt_demod(gr.top_block):
+
+       def __init__(self, input_filename="usrp.dat", output_filename="frames.dat", decim=32, pll_alpha=0.01, clock_alpha=0.01):
+               gr.top_block.__init__(self, "Hrpt Demod")
+
+               ##################################################
+               # Parameters
+               ##################################################
+               self.input_filename = input_filename
+               self.output_filename = output_filename
+               self.decim = decim
+               self.pll_alpha = pll_alpha
+               self.clock_alpha = clock_alpha
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.sym_rate = sym_rate = 600*1109
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/sym_rate
+               self.max_clock_offset = max_clock_offset = 100e-6
+               self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
+               self.hs = hs = int(sps/2.0)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.agc = gr.agc_cc(1e-5, 1.0, 1.0/32768.0, 1.0)
+               self.cs2cf = gr.interleaved_short_to_complex()
+               self.decoder = noaa.hrpt_decoder(True,False)
+               self.file_source = gr.file_source(gr.sizeof_short*1, input_filename, False)
+               self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
+               self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset)
+               self.gr_file_sink_0 = gr.file_sink(gr.sizeof_short*1, output_filename)
+               self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
+               self.noaa_hrpt_deframer_0 = noaa.hrpt_deframer()
+               self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.file_source, 0), (self.cs2cf, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
+               self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
+               self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
+               self.connect((self.cs2cf, 0), (self.agc, 0))
+               self.connect((self.agc, 0), (self.pll, 0))
+               self.connect((self.noaa_hrpt_deframer_0, 0), (self.gr_file_sink_0, 0))
+               self.connect((self.noaa_hrpt_deframer_0, 0), (self.decoder, 0))
+               self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_deframer_0, 0))
+
+       def set_input_filename(self, input_filename):
+               self.input_filename = input_filename
+
+       def set_output_filename(self, output_filename):
+               self.output_filename = output_filename
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+
+       def set_pll_alpha(self, pll_alpha):
+               self.pll_alpha = pll_alpha
+               self.pll.set_alpha(self.pll_alpha)
+               self.pll.set_beta(self.pll_alpha**2/4.0)
+
+       def set_clock_alpha(self, clock_alpha):
+               self.clock_alpha = clock_alpha
+               self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
+               self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
+
+       def set_sym_rate(self, sym_rate):
+               self.sym_rate = sym_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.set_hs(int(self.sps/2.0))
+               self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
+
+       def set_max_clock_offset(self, max_clock_offset):
+               self.max_clock_offset = max_clock_offset
+
+       def set_max_carrier_offset(self, max_carrier_offset):
+               self.max_carrier_offset = max_carrier_offset
+               self.pll.set_max_offset(self.max_carrier_offset)
+
+       def set_hs(self, hs):
+               self.hs = hs
+               self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default="usrp.dat",
+               help="Set usrp.dat [default=%default]")
+       parser.add_option("-o", "--output-filename", dest="output_filename", type="string", default="frames.dat",
+               help="Set frames.dat [default=%default]")
+       parser.add_option("-d", "--decim", dest="decim", type="intx", default=32,
+               help="Set decim [default=%default]")
+       parser.add_option("-p", "--pll-alpha", dest="pll_alpha", type="eng_float", default=eng_notation.num_to_str(0.01),
+               help="Set pll_alpha [default=%default]")
+       parser.add_option("-s", "--clock-alpha", dest="clock_alpha", type="eng_float", default=eng_notation.num_to_str(0.01),
+               help="Set clock_alpha [default=%default]")
+       (options, args) = parser.parse_args()
+       tb = hrpt_demod(input_filename=options.input_filename, output_filename=options.output_filename, decim=options.decim, pll_alpha=options.pll_alpha, clock_alpha=options.clock_alpha)
+       tb.run()
+
diff --git a/gr-noaa/apps/usrp_rx_hrpt.grc b/gr-noaa/apps/usrp_rx_hrpt.grc
new file mode 100644 (file)
index 0000000..990855f
--- /dev/null
@@ -0,0 +1,1442 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Mon Nov  9 07:56:11 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_rx_hrpt</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP HRPT Receiver</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4096,4096</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*math.pi*100e3/sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(575, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sym_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>600*1109</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(301, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/sym_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sps/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(499, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>RX Gain</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_gain</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(340, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_text_box</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_freq</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(199, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>PLL Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_pll_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 2, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(479, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>side_text</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>USRP Side</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>str_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(828, 20)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>decim_text</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Decimation</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(973, 20)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ['HOME']+'/.gnuradio/config.conf'</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 129)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math, os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 76)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1698e6</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'freq'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(507, 258)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>35</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'gain'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(664, 259)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Clock Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_clock_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 3, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(618, 106)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'A'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'side'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(194, 253)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Spectrum','Demod']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2,0,1,4</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(12, 249)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_sink</key>
+    <param>
+      <key>id</key>
+      <value>frame_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(973, 1024)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_source</key>
+    <param>
+      <key>id</key>
+      <value>virtual_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(173, 971)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>demod_scope</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Post-Demod</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sym_rate*2.0</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>10.0/sym_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(666, 542)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_clock_recovery_mm_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps/2.0</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>clock_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(873, 696)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_moving_average_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_moving_average_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>length</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>scale</key>
+      <value>1.0/hs</value>
+    </param>
+    <param>
+      <key>max_iter</key>
+      <value>4000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(682, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_pll_cf</key>
+    <param>
+      <key>id</key>
+      <value>pll</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>pll_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>max_offset</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(469, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_sink</key>
+    <param>
+      <key>id</key>
+      <value>virtual_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1142, 728)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>agc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(301, 705)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>RXA</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(89, 689)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_fft</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RX Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-5</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0.1</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value>640, 360</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(477, 457)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_binary_slicer_fb</key>
+    <param>
+      <key>id</key>
+      <value>gr_binary_slicer_fb_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(393, 975)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_deframer</key>
+    <param>
+      <key>id</key>
+      <value>deframer</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(762, 975)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'decim'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(351, 255)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'pll_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(823, 258)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'clock_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(981, 258)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'frames.hrpt'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'filename'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1139, 259)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_decoder</key>
+    <param>
+      <key>id</key>
+      <value>decoder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>output</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(974, 925)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(705, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>gr_binary_slicer_fb_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>frame_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>decoder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>virtual_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>demod_scope</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_moving_average_xx_0</source_block_id>
+    <sink_block_id>gr_clock_recovery_mm_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pll</source_block_id>
+    <sink_block_id>gr_moving_average_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>pll</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_source</source_block_id>
+    <sink_block_id>agc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>rx_fft</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_binary_slicer_fb_0</source_block_id>
+    <sink_block_id>deframer</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/usrp_rx_hrpt.py b/gr-noaa/apps/usrp_rx_hrpt.py
new file mode 100755 (executable)
index 0000000..48c5f9d
--- /dev/null
@@ -0,0 +1,427 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: USRP HRPT Receiver
+# Generated: Mon Nov  9 07:56:11 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import noaa
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import fftsink2
+from gnuradio.wxgui import forms
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import usrp as grc_usrp
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import ConfigParser
+import math, os
+import wx
+
+class usrp_rx_hrpt(grc_wxgui.top_block_gui):
+
+       def __init__(self):
+               grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver")
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(config_filename)
+               try: decim = self._decim_config.getfloat('usrp_rx_hrpt', 'decim')
+               except: decim = 32
+               self.decim = decim
+               self.sym_rate = sym_rate = 600*1109
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/sym_rate
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(config_filename)
+               try: side = self._side_config.get('usrp_rx_hrpt', 'side')
+               except: side = 'A'
+               self.side = side
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(config_filename)
+               try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha')
+               except: saved_pll_alpha = 0.01
+               self.saved_pll_alpha = saved_pll_alpha
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(config_filename)
+               try: saved_gain = self._saved_gain_config.getfloat('usrp_rx_hrpt', 'gain')
+               except: saved_gain = 35
+               self.saved_gain = saved_gain
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(config_filename)
+               try: saved_freq = self._saved_freq_config.getfloat('usrp_rx_hrpt', 'freq')
+               except: saved_freq = 1698e6
+               self.saved_freq = saved_freq
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(config_filename)
+               try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha')
+               except: saved_clock_alpha = 0.01
+               self.saved_clock_alpha = saved_clock_alpha
+               self.side_text = side_text = side
+               self.pll_alpha = pll_alpha = saved_pll_alpha
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(config_filename)
+               try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
+               except: output_filename = 'frames.hrpt'
+               self.output_filename = output_filename
+               self.max_clock_offset = max_clock_offset = 100e-6
+               self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
+               self.hs = hs = int(sps/2.0)
+               self.gain = gain = saved_gain
+               self.freq = freq = saved_freq
+               self.decim_text = decim_text = decim
+               self.clock_alpha = clock_alpha = saved_clock_alpha
+
+               ##################################################
+               # Notebooks
+               ##################################################
+               self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
+               self.GridAdd(self.displays, 2, 0, 1, 4)
+
+               ##################################################
+               # Controls
+               ##################################################
+               self._side_text_static_text = forms.static_text(
+                       parent=self.GetWin(),
+                       value=self.side_text,
+                       callback=self.set_side_text,
+                       label="USRP Side",
+                       converter=forms.str_converter(),
+               )
+               self.GridAdd(self._side_text_static_text, 1, 0, 1, 1)
+               _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._pll_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_pll_alpha_sizer,
+                       value=self.pll_alpha,
+                       callback=self.set_pll_alpha,
+                       label="PLL Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._pll_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_pll_alpha_sizer,
+                       value=self.pll_alpha,
+                       callback=self.set_pll_alpha,
+                       minimum=0.0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_pll_alpha_sizer, 0, 2, 1, 1)
+               _gain_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._gain_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_gain_sizer,
+                       value=self.gain,
+                       callback=self.set_gain,
+                       label="RX Gain",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._gain_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_gain_sizer,
+                       value=self.gain,
+                       callback=self.set_gain,
+                       minimum=0,
+                       maximum=100,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_gain_sizer, 0, 1, 1, 1)
+               self._freq_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       value=self.freq,
+                       callback=self.set_freq,
+                       label="Frequency",
+                       converter=forms.float_converter(),
+               )
+               self.GridAdd(self._freq_text_box, 0, 0, 1, 1)
+               self._decim_text_static_text = forms.static_text(
+                       parent=self.GetWin(),
+                       value=self.decim_text,
+                       callback=self.set_decim_text,
+                       label="Decimation",
+                       converter=forms.float_converter(),
+               )
+               self.GridAdd(self._decim_text_static_text, 1, 1, 1, 1)
+               _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._clock_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_clock_alpha_sizer,
+                       value=self.clock_alpha,
+                       callback=self.set_clock_alpha,
+                       label="Clock Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._clock_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_clock_alpha_sizer,
+                       value=self.clock_alpha,
+                       callback=self.set_clock_alpha,
+                       minimum=0.0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_clock_alpha_sizer, 0, 3, 1, 1)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
+               self.decoder = noaa.hrpt_decoder(True,True)
+               self.deframer = noaa.hrpt_deframer()
+               self.demod_scope = scopesink2.scope_sink_f(
+                       self.displays.GetPage(1).GetWin(),
+                       title="Post-Demod",
+                       sample_rate=sym_rate*2.0,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=10.0/sym_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1)
+               self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
+               self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
+               self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset)
+               self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
+               self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
+               self.rx_fft = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=freq,
+                       y_per_div=5,
+                       y_divs=8,
+                       ref_level=-5,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=True,
+                       avg_alpha=0.1,
+                       title="RX Spectrum",
+                       peak_hold=False,
+                       size=(640, 360),
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
+               self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA")
+               self.usrp_source.set_decim_rate(decim)
+               self.usrp_source.set_frequency(freq, verbose=True)
+               self.usrp_source.set_gain(gain)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
+               self.connect((self.deframer, 0), (self.frame_sink, 0))
+               self.connect((self.deframer, 0), (self.decoder, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0))
+               self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
+               self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
+               self.connect((self.agc, 0), (self.pll, 0))
+               self.connect((self.usrp_source, 0), (self.agc, 0))
+               self.connect((self.agc, 0), (self.rx_fft, 0))
+               self.connect((self.gr_binary_slicer_fb_0, 0), (self.deframer, 0))
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(self.config_filename)
+               if not self._saved_freq_config.has_section('usrp_rx_hrpt'):
+                       self._saved_freq_config.add_section('usrp_rx_hrpt')
+               self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
+               self._saved_freq_config.write(open(self.config_filename, 'w'))
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(self.config_filename)
+               if not self._saved_gain_config.has_section('usrp_rx_hrpt'):
+                       self._saved_gain_config.add_section('usrp_rx_hrpt')
+               self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
+               self._saved_gain_config.write(open(self.config_filename, 'w'))
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_hrpt'):
+                       self._side_config.add_section('usrp_rx_hrpt')
+               self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(self.config_filename)
+               if not self._decim_config.has_section('usrp_rx_hrpt'):
+                       self._decim_config.add_section('usrp_rx_hrpt')
+               self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
+               self._decim_config.write(open(self.config_filename, 'w'))
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(self.config_filename)
+               if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(self.config_filename)
+               if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+               self.set_decim_text(self.decim)
+               self.usrp_source.set_decim_rate(self.decim)
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(self.config_filename)
+               if not self._decim_config.has_section('usrp_rx_hrpt'):
+                       self._decim_config.add_section('usrp_rx_hrpt')
+               self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
+               self._decim_config.write(open(self.config_filename, 'w'))
+
+       def set_sym_rate(self, sym_rate):
+               self.sym_rate = sym_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+               self.demod_scope.set_sample_rate(self.sym_rate*2.0)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
+               self.set_sps(self.sample_rate/self.sym_rate)
+               self.rx_fft.set_sample_rate(self.sample_rate)
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.set_hs(int(self.sps/2.0))
+               self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
+
+       def set_side(self, side):
+               self.side = side
+               self.set_side_text(self.side)
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_hrpt'):
+                       self._side_config.add_section('usrp_rx_hrpt')
+               self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+
+       def set_saved_pll_alpha(self, saved_pll_alpha):
+               self.saved_pll_alpha = saved_pll_alpha
+               self.set_pll_alpha(self.saved_pll_alpha)
+
+       def set_saved_gain(self, saved_gain):
+               self.saved_gain = saved_gain
+               self.set_gain(self.saved_gain)
+
+       def set_saved_freq(self, saved_freq):
+               self.saved_freq = saved_freq
+               self.set_freq(self.saved_freq)
+
+       def set_saved_clock_alpha(self, saved_clock_alpha):
+               self.saved_clock_alpha = saved_clock_alpha
+               self.set_clock_alpha(self.saved_clock_alpha)
+
+       def set_side_text(self, side_text):
+               self.side_text = side_text
+               self._side_text_static_text.set_value(self.side_text)
+
+       def set_pll_alpha(self, pll_alpha):
+               self.pll_alpha = pll_alpha
+               self._pll_alpha_slider.set_value(self.pll_alpha)
+               self._pll_alpha_text_box.set_value(self.pll_alpha)
+               self.pll.set_alpha(self.pll_alpha)
+               self.pll.set_beta(self.pll_alpha**2/4.0)
+               self._saved_pll_alpha_config = ConfigParser.ConfigParser()
+               self._saved_pll_alpha_config.read(self.config_filename)
+               if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
+
+       def set_output_filename(self, output_filename):
+               self.output_filename = output_filename
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+
+       def set_max_clock_offset(self, max_clock_offset):
+               self.max_clock_offset = max_clock_offset
+
+       def set_max_carrier_offset(self, max_carrier_offset):
+               self.max_carrier_offset = max_carrier_offset
+               self.pll.set_max_offset(self.max_carrier_offset)
+
+       def set_hs(self, hs):
+               self.hs = hs
+               self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
+
+       def set_gain(self, gain):
+               self.gain = gain
+               self._gain_slider.set_value(self.gain)
+               self._gain_text_box.set_value(self.gain)
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(self.config_filename)
+               if not self._saved_gain_config.has_section('usrp_rx_hrpt'):
+                       self._saved_gain_config.add_section('usrp_rx_hrpt')
+               self._saved_gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
+               self._saved_gain_config.write(open(self.config_filename, 'w'))
+               self.usrp_source.set_gain(self.gain)
+
+       def set_freq(self, freq):
+               self.freq = freq
+               self._freq_text_box.set_value(self.freq)
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(self.config_filename)
+               if not self._saved_freq_config.has_section('usrp_rx_hrpt'):
+                       self._saved_freq_config.add_section('usrp_rx_hrpt')
+               self._saved_freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
+               self._saved_freq_config.write(open(self.config_filename, 'w'))
+               self.usrp_source.set_frequency(self.freq)
+               self.rx_fft.set_baseband_freq(self.freq)
+
+       def set_decim_text(self, decim_text):
+               self.decim_text = decim_text
+               self._decim_text_static_text.set_value(self.decim_text)
+
+       def set_clock_alpha(self, clock_alpha):
+               self.clock_alpha = clock_alpha
+               self._clock_alpha_slider.set_value(self.clock_alpha)
+               self._clock_alpha_text_box.set_value(self.clock_alpha)
+               self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
+               self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
+               self._saved_clock_alpha_config = ConfigParser.ConfigParser()
+               self._saved_clock_alpha_config.read(self.config_filename)
+               if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       (options, args) = parser.parse_args()
+       tb = usrp_rx_hrpt()
+       tb.Run(True)
+
diff --git a/gr-noaa/apps/usrp_rx_hrpt_nogui.grc b/gr-noaa/apps/usrp_rx_hrpt_nogui.grc
new file mode 100644 (file)
index 0000000..22bd3bd
--- /dev/null
@@ -0,0 +1,947 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Mon Nov  9 08:03:25 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_rx_hrpt_nogui</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4096,4096</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>no_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*math.pi*100e3/sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(575, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sym_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>600*1109</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(301, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/sym_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(397, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sps/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(499, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ['HOME']+'/.gnuradio/config.conf'</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(13, 162)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import math, os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(11, 109)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>35</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'gain'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(668, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1698e6</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'freq'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(511, 100)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'A'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'side'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(198, 95)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>agc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(339, 434)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>RXA</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(127, 418)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_clock_recovery_mm_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps/2.0</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>clock_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(920, 426)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_moving_average_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_moving_average_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>length</key>
+      <value>hs</value>
+    </param>
+    <param>
+      <key>scale</key>
+      <value>1.0/hs</value>
+    </param>
+    <param>
+      <key>max_iter</key>
+      <value>4000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(720, 442)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_pll_cf</key>
+    <param>
+      <key>id</key>
+      <value>pll</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>pll_alpha**2/4.0</value>
+    </param>
+    <param>
+      <key>max_offset</key>
+      <value>max_carrier_offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(507, 442)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_sink</key>
+    <param>
+      <key>id</key>
+      <value>virtual_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1180, 457)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_sink</key>
+    <param>
+      <key>id</key>
+      <value>frame_sink</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>short</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1026, 722)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_source</key>
+    <param>
+      <key>id</key>
+      <value>virtual_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(226, 669)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_binary_slicer_fb</key>
+    <param>
+      <key>id</key>
+      <value>gr_binary_slicer_fb_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(446, 673)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_deframer</key>
+    <param>
+      <key>id</key>
+      <value>deframer</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(815, 673)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'decim'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(355, 97)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'pll_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>pll_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(827, 100)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.01</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'clock_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>clock_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(986, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'frames.hrpt'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_hrpt'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'filename'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>output_filename</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1143, 101)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>max_clock_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>100e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(705, 19)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>noaa_hrpt_decoder</key>
+    <param>
+      <key>id</key>
+      <value>decoder</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>verbose</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>output</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1027, 623)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>usrp_source</source_block_id>
+    <sink_block_id>agc</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>agc</source_block_id>
+    <sink_block_id>pll</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pll</source_block_id>
+    <sink_block_id>gr_moving_average_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_moving_average_xx_0</source_block_id>
+    <sink_block_id>gr_clock_recovery_mm_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_clock_recovery_mm_xx_0</source_block_id>
+    <sink_block_id>virtual_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>gr_binary_slicer_fb_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>frame_sink</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>deframer</source_block_id>
+    <sink_block_id>decoder</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_binary_slicer_fb_0</source_block_id>
+    <sink_block_id>deframer</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/usrp_rx_hrpt_nogui.py b/gr-noaa/apps/usrp_rx_hrpt_nogui.py
new file mode 100755 (executable)
index 0000000..1b510bd
--- /dev/null
@@ -0,0 +1,247 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Usrp Rx Hrpt Nogui
+# Generated: Mon Nov  9 08:03:25 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import noaa
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from grc_gnuradio import usrp as grc_usrp
+from optparse import OptionParser
+import ConfigParser
+import math, os
+
+class usrp_rx_hrpt_nogui(gr.top_block):
+
+       def __init__(self):
+               gr.top_block.__init__(self, "Usrp Rx Hrpt Nogui")
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(config_filename)
+               try: decim = self._decim_config.getfloat('usrp_rx_hrpt', 'decim')
+               except: decim = 32
+               self.decim = decim
+               self.sym_rate = sym_rate = 600*1109
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/sym_rate
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(config_filename)
+               try: side = self._side_config.get('usrp_rx_hrpt', 'side')
+               except: side = 'A'
+               self.side = side
+               self._pll_alpha_config = ConfigParser.ConfigParser()
+               self._pll_alpha_config.read(config_filename)
+               try: pll_alpha = self._pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha')
+               except: pll_alpha = 0.01
+               self.pll_alpha = pll_alpha
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(config_filename)
+               try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
+               except: output_filename = 'frames.hrpt'
+               self.output_filename = output_filename
+               self.max_clock_offset = max_clock_offset = 100e-6
+               self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
+               self.hs = hs = int(sps/2.0)
+               self._gain_config = ConfigParser.ConfigParser()
+               self._gain_config.read(config_filename)
+               try: gain = self._gain_config.getfloat('usrp_rx_hrpt', 'gain')
+               except: gain = 35
+               self.gain = gain
+               self._freq_config = ConfigParser.ConfigParser()
+               self._freq_config.read(config_filename)
+               try: freq = self._freq_config.getfloat('usrp_rx_hrpt', 'freq')
+               except: freq = 1698e6
+               self.freq = freq
+               self._clock_alpha_config = ConfigParser.ConfigParser()
+               self._clock_alpha_config.read(config_filename)
+               try: clock_alpha = self._clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha')
+               except: clock_alpha = 0.01
+               self.clock_alpha = clock_alpha
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
+               self.decoder = noaa.hrpt_decoder(True,True)
+               self.deframer = noaa.hrpt_deframer()
+               self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
+               self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
+               self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset)
+               self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
+               self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
+               self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA")
+               self.usrp_source.set_decim_rate(decim)
+               self.usrp_source.set_frequency(freq, verbose=True)
+               self.usrp_source.set_gain(gain)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.usrp_source, 0), (self.agc, 0))
+               self.connect((self.agc, 0), (self.pll, 0))
+               self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
+               self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
+               self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
+               self.connect((self.deframer, 0), (self.frame_sink, 0))
+               self.connect((self.deframer, 0), (self.decoder, 0))
+               self.connect((self.gr_binary_slicer_fb_0, 0), (self.deframer, 0))
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._gain_config = ConfigParser.ConfigParser()
+               self._gain_config.read(self.config_filename)
+               if not self._gain_config.has_section('usrp_rx_hrpt'):
+                       self._gain_config.add_section('usrp_rx_hrpt')
+               self._gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
+               self._gain_config.write(open(self.config_filename, 'w'))
+               self._freq_config = ConfigParser.ConfigParser()
+               self._freq_config.read(self.config_filename)
+               if not self._freq_config.has_section('usrp_rx_hrpt'):
+                       self._freq_config.add_section('usrp_rx_hrpt')
+               self._freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
+               self._freq_config.write(open(self.config_filename, 'w'))
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_hrpt'):
+                       self._side_config.add_section('usrp_rx_hrpt')
+               self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(self.config_filename)
+               if not self._decim_config.has_section('usrp_rx_hrpt'):
+                       self._decim_config.add_section('usrp_rx_hrpt')
+               self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
+               self._decim_config.write(open(self.config_filename, 'w'))
+               self._pll_alpha_config = ConfigParser.ConfigParser()
+               self._pll_alpha_config.read(self.config_filename)
+               if not self._pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._pll_alpha_config.write(open(self.config_filename, 'w'))
+               self._clock_alpha_config = ConfigParser.ConfigParser()
+               self._clock_alpha_config.read(self.config_filename)
+               if not self._clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._clock_alpha_config.write(open(self.config_filename, 'w'))
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+               self.usrp_source.set_decim_rate(self.decim)
+               self._decim_config = ConfigParser.ConfigParser()
+               self._decim_config.read(self.config_filename)
+               if not self._decim_config.has_section('usrp_rx_hrpt'):
+                       self._decim_config.add_section('usrp_rx_hrpt')
+               self._decim_config.set('usrp_rx_hrpt', 'decim', str(self.decim))
+               self._decim_config.write(open(self.config_filename, 'w'))
+
+       def set_sym_rate(self, sym_rate):
+               self.sym_rate = sym_rate
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
+               self.set_sps(self.sample_rate/self.sym_rate)
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.set_hs(int(self.sps/2.0))
+               self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
+
+       def set_side(self, side):
+               self.side = side
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_hrpt'):
+                       self._side_config.add_section('usrp_rx_hrpt')
+               self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+
+       def set_pll_alpha(self, pll_alpha):
+               self.pll_alpha = pll_alpha
+               self.pll.set_alpha(self.pll_alpha)
+               self.pll.set_beta(self.pll_alpha**2/4.0)
+               self._pll_alpha_config = ConfigParser.ConfigParser()
+               self._pll_alpha_config.read(self.config_filename)
+               if not self._pll_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._pll_alpha_config.add_section('usrp_rx_hrpt')
+               self._pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
+               self._pll_alpha_config.write(open(self.config_filename, 'w'))
+
+       def set_output_filename(self, output_filename):
+               self.output_filename = output_filename
+               self._output_filename_config = ConfigParser.ConfigParser()
+               self._output_filename_config.read(self.config_filename)
+               if not self._output_filename_config.has_section('usrp_rx_hrpt'):
+                       self._output_filename_config.add_section('usrp_rx_hrpt')
+               self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
+               self._output_filename_config.write(open(self.config_filename, 'w'))
+
+       def set_max_clock_offset(self, max_clock_offset):
+               self.max_clock_offset = max_clock_offset
+
+       def set_max_carrier_offset(self, max_carrier_offset):
+               self.max_carrier_offset = max_carrier_offset
+               self.pll.set_max_offset(self.max_carrier_offset)
+
+       def set_hs(self, hs):
+               self.hs = hs
+               self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
+
+       def set_gain(self, gain):
+               self.gain = gain
+               self._gain_config = ConfigParser.ConfigParser()
+               self._gain_config.read(self.config_filename)
+               if not self._gain_config.has_section('usrp_rx_hrpt'):
+                       self._gain_config.add_section('usrp_rx_hrpt')
+               self._gain_config.set('usrp_rx_hrpt', 'gain', str(self.gain))
+               self._gain_config.write(open(self.config_filename, 'w'))
+               self.usrp_source.set_gain(self.gain)
+
+       def set_freq(self, freq):
+               self.freq = freq
+               self._freq_config = ConfigParser.ConfigParser()
+               self._freq_config.read(self.config_filename)
+               if not self._freq_config.has_section('usrp_rx_hrpt'):
+                       self._freq_config.add_section('usrp_rx_hrpt')
+               self._freq_config.set('usrp_rx_hrpt', 'freq', str(self.freq))
+               self._freq_config.write(open(self.config_filename, 'w'))
+               self.usrp_source.set_frequency(self.freq)
+
+       def set_clock_alpha(self, clock_alpha):
+               self.clock_alpha = clock_alpha
+               self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
+               self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
+               self._clock_alpha_config = ConfigParser.ConfigParser()
+               self._clock_alpha_config.read(self.config_filename)
+               if not self._clock_alpha_config.has_section('usrp_rx_hrpt'):
+                       self._clock_alpha_config.add_section('usrp_rx_hrpt')
+               self._clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
+               self._clock_alpha_config.write(open(self.config_filename, 'w'))
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       (options, args) = parser.parse_args()
+       if gr.enable_realtime_scheduling() != gr.RT_OK:
+               print "Error: failed to enable realtime scheduling."
+       tb = usrp_rx_hrpt_nogui()
+       tb.start()
+       raw_input('Press Enter to quit: ')
+       tb.stop()
+
diff --git a/gr-noaa/apps/usrp_rx_lrit.grc b/gr-noaa/apps/usrp_rx_lrit.grc
new file mode 100644 (file)
index 0000000..aca1003
--- /dev/null
@@ -0,0 +1,1825 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Wed Dec 16 09:47:16 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_rx_lrit</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP LRIT Receiver</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4095, 4095</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(245, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>293e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(351, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>sample_rate/symbol_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(456, 9)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import os</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(9, 83)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ['HOME']+'/.gnuradio/config.conf'</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 142)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_text_box</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_freq</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(247, 149)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1691e6</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'freq'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(246, 299)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'offset'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(406, 300)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_offset</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-50e3</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>50e3</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(390, 149)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Costas Alpha</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_costas_alpha</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(813, 152)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Gain Mu</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_gain_mu</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 2, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(957, 151)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>33</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'gain'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(565, 300)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>160</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'decim'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(725, 300)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_text_box</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Decim</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_decim</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>int_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 2, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(672, 151)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_costas_alpha</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'costas_alpha'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(885, 298)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_gain_mu</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.005</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'gain_mu'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1046, 298)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>'A'</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>string</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>'usrp_rx_lrit'</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>'side'</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1102, 152)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_agc_xx</key>
+    <param>
+      <key>id</key>
+      <value>gr_agc_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>rate</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>reference</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1.0/32767.0</value>
+    </param>
+    <param>
+      <key>max_gain</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(286, 729)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RX Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(281, 862)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rx_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RX Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>50</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(280, 468)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>root_raised_cosine_filter</key>
+    <param>
+      <key>id</key>
+      <value>root_raised_cosine_filter_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>fir_filter_ccf</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>interp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>sym_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>0.25</value>
+    </param>
+    <param>
+      <key>ntaps</key>
+      <value>int(11*sample_rate/symbol_rate)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(472, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>rrc_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RRC Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(768, 866)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>rrc_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>RRC Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>freq+offset</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(767, 499)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_costas_loop_cc</key>
+    <param>
+      <key>id</key>
+      <value>costas</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>costas_alpha</value>
+    </param>
+    <param>
+      <key>beta</key>
+      <value>(costas_alpha**2.0)/4.0</value>
+    </param>
+    <param>
+      <key>max_freq</key>
+      <value>50e-6*sps</value>
+    </param>
+    <param>
+      <key>min_freq</key>
+      <value>-50e-6*sps</value>
+    </param>
+    <param>
+      <key>order</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(767, 721)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>costas_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>PLL Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>freq+offset</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(969, 502)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>mm_spectrum</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Bit Sync Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>-15</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1225, 503)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>costas_waveform</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>PLL Waveform</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/sample_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 2</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(968, 852)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_clock_recovery_mm_xx</key>
+    <param>
+      <key>id</key>
+      <value>mm_sync</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>omega</key>
+      <value>sps</value>
+    </param>
+    <param>
+      <key>gain_omega</key>
+      <value>(gain_mu**2)/4.0</value>
+    </param>
+    <param>
+      <key>mu</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>gain_mu</key>
+      <value>gain_mu</value>
+    </param>
+    <param>
+      <key>omega_relative_limit</key>
+      <value>50e-6*sps</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(969, 722)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>mm_const</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Constellation</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>20.0/symbol_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1225, 859)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['USRP RX','RRC','PLL','Const']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>2, 0, 1, 3</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 228)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Gain</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_gain</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>115</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>115</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(532, 150)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_throttle</key>
+    <param>
+      <key>id</key>
+      <value>gr_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(63, 859)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_file_source</key>
+    <param>
+      <key>id</key>
+      <value>gr_file_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>file</key>
+      <value>lrit.dat</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>repeat</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(36, 943)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_simple_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>freq+offset</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>gain</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>side</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>RXA</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(19, 713)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_agc_xx_0</source_block_id>
+    <sink_block_id>root_raised_cosine_filter_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>gr_agc_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_file_source_0</source_block_id>
+    <sink_block_id>gr_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_simple_source_x_0</source_block_id>
+    <sink_block_id>gr_agc_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_simple_source_x_0</source_block_id>
+    <sink_block_id>rx_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>rx_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_simple_source_x_0</source_block_id>
+    <sink_block_id>rx_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_throttle_0</source_block_id>
+    <sink_block_id>rx_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>root_raised_cosine_filter_0</source_block_id>
+    <sink_block_id>rrc_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>root_raised_cosine_filter_0</source_block_id>
+    <sink_block_id>rrc_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>root_raised_cosine_filter_0</source_block_id>
+    <sink_block_id>costas</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>costas_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>costas_waveform</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>costas</source_block_id>
+    <sink_block_id>mm_sync</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>mm_sync</source_block_id>
+    <sink_block_id>mm_spectrum</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>mm_sync</source_block_id>
+    <sink_block_id>mm_const</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-noaa/apps/usrp_rx_lrit.py b/gr-noaa/apps/usrp_rx_lrit.py
new file mode 100755 (executable)
index 0000000..9a3d702
--- /dev/null
@@ -0,0 +1,523 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: USRP LRIT Receiver
+# Generated: Wed Dec 16 09:49:15 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import fftsink2
+from gnuradio.wxgui import forms
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import usrp as grc_usrp
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import ConfigParser
+import os
+import wx
+
+class usrp_rx_lrit(grc_wxgui.top_block_gui):
+
+       def __init__(self):
+               grc_wxgui.top_block_gui.__init__(self, title="USRP LRIT Receiver")
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
+               self._saved_decim_config = ConfigParser.ConfigParser()
+               self._saved_decim_config.read(config_filename)
+               try: saved_decim = self._saved_decim_config.getint('usrp_rx_lrit', 'decim')
+               except: saved_decim = 160
+               self.saved_decim = saved_decim
+               self.decim = decim = saved_decim
+               self.symbol_rate = symbol_rate = 293e3
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(config_filename)
+               try: saved_offset = self._saved_offset_config.getfloat('usrp_rx_lrit', 'offset')
+               except: saved_offset = 0
+               self.saved_offset = saved_offset
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(config_filename)
+               try: saved_gain_mu = self._saved_gain_mu_config.getfloat('usrp_rx_lrit', 'gain_mu')
+               except: saved_gain_mu = 0.005
+               self.saved_gain_mu = saved_gain_mu
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(config_filename)
+               try: saved_gain = self._saved_gain_config.getfloat('usrp_rx_lrit', 'gain')
+               except: saved_gain = 33
+               self.saved_gain = saved_gain
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(config_filename)
+               try: saved_freq = self._saved_freq_config.getfloat('usrp_rx_lrit', 'freq')
+               except: saved_freq = 1691e6
+               self.saved_freq = saved_freq
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(config_filename)
+               try: saved_costas_alpha = self._saved_costas_alpha_config.getfloat('usrp_rx_lrit', 'costas_alpha')
+               except: saved_costas_alpha = 0.005
+               self.saved_costas_alpha = saved_costas_alpha
+               self.sample_rate = sample_rate = 64e6/decim
+               self.sps = sps = sample_rate/symbol_rate
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(config_filename)
+               try: side = self._side_config.get('usrp_rx_lrit', 'side')
+               except: side = 'A'
+               self.side = side
+               self.offset = offset = saved_offset
+               self.gain_mu = gain_mu = saved_gain_mu
+               self.gain = gain = saved_gain
+               self.freq = freq = saved_freq
+               self.costas_alpha = costas_alpha = saved_costas_alpha
+
+               ##################################################
+               # Notebooks
+               ##################################################
+               self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "USRP RX")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "RRC")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "PLL")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Const")
+               self.GridAdd(self.displays, 2, 0, 1, 3)
+
+               ##################################################
+               # Controls
+               ##################################################
+               self._decim_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       value=self.decim,
+                       callback=self.set_decim,
+                       label="Decim",
+                       converter=forms.int_converter(),
+               )
+               self.GridAdd(self._decim_text_box, 0, 2, 1, 1)
+               _offset_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._offset_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_offset_sizer,
+                       value=self.offset,
+                       callback=self.set_offset,
+                       label="Offset",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._offset_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_offset_sizer,
+                       value=self.offset,
+                       callback=self.set_offset,
+                       minimum=-50e3,
+                       maximum=50e3,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_offset_sizer, 0, 1, 1, 1)
+               _gain_mu_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._gain_mu_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_gain_mu_sizer,
+                       value=self.gain_mu,
+                       callback=self.set_gain_mu,
+                       label="Gain Mu",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._gain_mu_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_gain_mu_sizer,
+                       value=self.gain_mu,
+                       callback=self.set_gain_mu,
+                       minimum=0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_gain_mu_sizer, 1, 2, 1, 1)
+               _gain_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._gain_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_gain_sizer,
+                       value=self.gain,
+                       callback=self.set_gain,
+                       label="Gain",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._gain_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_gain_sizer,
+                       value=self.gain,
+                       callback=self.set_gain,
+                       minimum=0,
+                       maximum=115,
+                       num_steps=115,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_gain_sizer, 1, 0, 1, 1)
+               self._freq_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       value=self.freq,
+                       callback=self.set_freq,
+                       label="Frequency",
+                       converter=forms.float_converter(),
+               )
+               self.GridAdd(self._freq_text_box, 0, 0, 1, 1)
+               _costas_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._costas_alpha_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_costas_alpha_sizer,
+                       value=self.costas_alpha,
+                       callback=self.set_costas_alpha,
+                       label="Costas Alpha",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._costas_alpha_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_costas_alpha_sizer,
+                       value=self.costas_alpha,
+                       callback=self.set_costas_alpha,
+                       minimum=0,
+                       maximum=0.5,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_costas_alpha_sizer, 1, 1, 1, 1)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.costas = gr.costas_loop_cc(costas_alpha, (costas_alpha**2.0)/4.0, 50e-6*sps, -50e-6*sps, 2)
+               self.costas_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(2).GetWin(),
+                       baseband_freq=freq+offset,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=False,
+                       avg_alpha=None,
+                       title="PLL Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(2).GridAdd(self.costas_spectrum.win, 0, 0, 1, 1)
+               self.costas_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(2).GetWin(),
+                       title="PLL Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(2).GridAdd(self.costas_waveform.win, 1, 0, 1, 1)
+               self.gr_agc_xx_0 = gr.agc_cc(1e-6, 1.0, 1.0/32767.0, 1.0)
+               self.mm_const = scopesink2.scope_sink_c(
+                       self.displays.GetPage(3).GetWin(),
+                       title="Constellation",
+                       sample_rate=symbol_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/symbol_rate,
+                       ac_couple=False,
+                       xy_mode=True,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(3).GridAdd(self.mm_const.win, 1, 0, 1, 1)
+               self.mm_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(3).GetWin(),
+                       baseband_freq=0,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=symbol_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=False,
+                       avg_alpha=None,
+                       title="Bit Sync Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(3).GridAdd(self.mm_spectrum.win, 0, 0, 1, 1)
+               self.mm_sync = gr.clock_recovery_mm_cc(sps, (gain_mu**2)/4.0, 0.5, gain_mu, 50e-6*sps)
+               self.root_raised_cosine_filter_0 = gr.fir_filter_ccf(1, firdes.root_raised_cosine(
+                       1, sample_rate, symbol_rate, 0.25, int(11*sample_rate/symbol_rate)))
+               self.rrc_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(1).GetWin(),
+                       baseband_freq=freq+offset,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=-15,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=15,
+                       average=False,
+                       avg_alpha=None,
+                       title="RRC Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(1).GridAdd(self.rrc_spectrum.win, 0, 0, 1, 1)
+               self.rrc_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(1).GetWin(),
+                       title="RRC Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0.5,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(1).GridAdd(self.rrc_waveform.win, 1, 0, 1, 1)
+               self.rx_spectrum = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=freq,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=50,
+                       ref_scale=2.0,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=False,
+                       avg_alpha=None,
+                       title="RX Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_spectrum.win, 0, 0, 1, 1)
+               self.rx_waveform = scopesink2.scope_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       title="RX Waveform",
+                       sample_rate=sample_rate,
+                       v_scale=0,
+                       v_offset=0,
+                       t_scale=20.0/sample_rate,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(0).GridAdd(self.rx_waveform.win, 1, 0, 1, 1)
+               self.usrp_simple_source_x_0 = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA")
+               self.usrp_simple_source_x_0.set_decim_rate(decim)
+               self.usrp_simple_source_x_0.set_frequency(freq+offset, verbose=True)
+               self.usrp_simple_source_x_0.set_gain(gain)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.gr_agc_xx_0, 0), (self.root_raised_cosine_filter_0, 0))
+               self.connect((self.usrp_simple_source_x_0, 0), (self.gr_agc_xx_0, 0))
+               self.connect((self.usrp_simple_source_x_0, 0), (self.rx_spectrum, 0))
+               self.connect((self.usrp_simple_source_x_0, 0), (self.rx_waveform, 0))
+               self.connect((self.root_raised_cosine_filter_0, 0), (self.rrc_waveform, 0))
+               self.connect((self.root_raised_cosine_filter_0, 0), (self.rrc_spectrum, 0))
+               self.connect((self.root_raised_cosine_filter_0, 0), (self.costas, 0))
+               self.connect((self.costas, 0), (self.costas_spectrum, 0))
+               self.connect((self.costas, 0), (self.costas_waveform, 0))
+               self.connect((self.costas, 0), (self.mm_sync, 0))
+               self.connect((self.mm_sync, 0), (self.mm_spectrum, 0))
+               self.connect((self.mm_sync, 0), (self.mm_const, 0))
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(self.config_filename)
+               if not self._saved_freq_config.has_section('usrp_rx_lrit'):
+                       self._saved_freq_config.add_section('usrp_rx_lrit')
+               self._saved_freq_config.set('usrp_rx_lrit', 'freq', str(self.freq))
+               self._saved_freq_config.write(open(self.config_filename, 'w'))
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(self.config_filename)
+               if not self._saved_offset_config.has_section('usrp_rx_lrit'):
+                       self._saved_offset_config.add_section('usrp_rx_lrit')
+               self._saved_offset_config.set('usrp_rx_lrit', 'offset', str(self.offset))
+               self._saved_offset_config.write(open(self.config_filename, 'w'))
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(self.config_filename)
+               if not self._saved_gain_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_config.add_section('usrp_rx_lrit')
+               self._saved_gain_config.set('usrp_rx_lrit', 'gain', str(self.gain))
+               self._saved_gain_config.write(open(self.config_filename, 'w'))
+               self._saved_decim_config = ConfigParser.ConfigParser()
+               self._saved_decim_config.read(self.config_filename)
+               if not self._saved_decim_config.has_section('usrp_rx_lrit'):
+                       self._saved_decim_config.add_section('usrp_rx_lrit')
+               self._saved_decim_config.set('usrp_rx_lrit', 'decim', str(self.decim))
+               self._saved_decim_config.write(open(self.config_filename, 'w'))
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(self.config_filename)
+               if not self._saved_costas_alpha_config.has_section('usrp_rx_lrit'):
+                       self._saved_costas_alpha_config.add_section('usrp_rx_lrit')
+               self._saved_costas_alpha_config.set('usrp_rx_lrit', 'costas_alpha', str(self.costas_alpha))
+               self._saved_costas_alpha_config.write(open(self.config_filename, 'w'))
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(self.config_filename)
+               if not self._saved_gain_mu_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_mu_config.add_section('usrp_rx_lrit')
+               self._saved_gain_mu_config.set('usrp_rx_lrit', 'gain_mu', str(self.gain_mu))
+               self._saved_gain_mu_config.write(open(self.config_filename, 'w'))
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_lrit'):
+                       self._side_config.add_section('usrp_rx_lrit')
+               self._side_config.set('usrp_rx_lrit', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+
+       def set_saved_decim(self, saved_decim):
+               self.saved_decim = saved_decim
+               self.set_decim(self.saved_decim)
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(64e6/self.decim)
+               self._saved_decim_config = ConfigParser.ConfigParser()
+               self._saved_decim_config.read(self.config_filename)
+               if not self._saved_decim_config.has_section('usrp_rx_lrit'):
+                       self._saved_decim_config.add_section('usrp_rx_lrit')
+               self._saved_decim_config.set('usrp_rx_lrit', 'decim', str(self.decim))
+               self._saved_decim_config.write(open(self.config_filename, 'w'))
+               self._decim_text_box.set_value(self.decim)
+               self.usrp_simple_source_x_0.set_decim_rate(self.decim)
+
+       def set_symbol_rate(self, symbol_rate):
+               self.symbol_rate = symbol_rate
+               self.set_sps(self.sample_rate/self.symbol_rate)
+               self.root_raised_cosine_filter_0.set_taps(firdes.root_raised_cosine(1, self.sample_rate, self.symbol_rate, 0.25, int(11*self.sample_rate/self.symbol_rate)))
+               self.mm_spectrum.set_sample_rate(self.symbol_rate)
+               self.mm_const.set_sample_rate(self.symbol_rate)
+
+       def set_saved_offset(self, saved_offset):
+               self.saved_offset = saved_offset
+               self.set_offset(self.saved_offset)
+
+       def set_saved_gain_mu(self, saved_gain_mu):
+               self.saved_gain_mu = saved_gain_mu
+               self.set_gain_mu(self.saved_gain_mu)
+
+       def set_saved_gain(self, saved_gain):
+               self.saved_gain = saved_gain
+               self.set_gain(self.saved_gain)
+
+       def set_saved_freq(self, saved_freq):
+               self.saved_freq = saved_freq
+               self.set_freq(self.saved_freq)
+
+       def set_saved_costas_alpha(self, saved_costas_alpha):
+               self.saved_costas_alpha = saved_costas_alpha
+               self.set_costas_alpha(self.saved_costas_alpha)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.set_sps(self.sample_rate/self.symbol_rate)
+               self.rx_waveform.set_sample_rate(self.sample_rate)
+               self.rx_spectrum.set_sample_rate(self.sample_rate)
+               self.root_raised_cosine_filter_0.set_taps(firdes.root_raised_cosine(1, self.sample_rate, self.symbol_rate, 0.25, int(11*self.sample_rate/self.symbol_rate)))
+               self.rrc_waveform.set_sample_rate(self.sample_rate)
+               self.rrc_spectrum.set_sample_rate(self.sample_rate)
+               self.costas_spectrum.set_sample_rate(self.sample_rate)
+               self.costas_waveform.set_sample_rate(self.sample_rate)
+
+       def set_sps(self, sps):
+               self.sps = sps
+               self.mm_sync.set_omega(self.sps)
+
+       def set_side(self, side):
+               self.side = side
+               self._side_config = ConfigParser.ConfigParser()
+               self._side_config.read(self.config_filename)
+               if not self._side_config.has_section('usrp_rx_lrit'):
+                       self._side_config.add_section('usrp_rx_lrit')
+               self._side_config.set('usrp_rx_lrit', 'side', str(self.side))
+               self._side_config.write(open(self.config_filename, 'w'))
+
+       def set_offset(self, offset):
+               self.offset = offset
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(self.config_filename)
+               if not self._saved_offset_config.has_section('usrp_rx_lrit'):
+                       self._saved_offset_config.add_section('usrp_rx_lrit')
+               self._saved_offset_config.set('usrp_rx_lrit', 'offset', str(self.offset))
+               self._saved_offset_config.write(open(self.config_filename, 'w'))
+               self._offset_slider.set_value(self.offset)
+               self._offset_text_box.set_value(self.offset)
+               self.rrc_spectrum.set_baseband_freq(self.freq+self.offset)
+               self.costas_spectrum.set_baseband_freq(self.freq+self.offset)
+               self.usrp_simple_source_x_0.set_frequency(self.freq+self.offset)
+
+       def set_gain_mu(self, gain_mu):
+               self.gain_mu = gain_mu
+               self._gain_mu_slider.set_value(self.gain_mu)
+               self._gain_mu_text_box.set_value(self.gain_mu)
+               self._saved_gain_mu_config = ConfigParser.ConfigParser()
+               self._saved_gain_mu_config.read(self.config_filename)
+               if not self._saved_gain_mu_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_mu_config.add_section('usrp_rx_lrit')
+               self._saved_gain_mu_config.set('usrp_rx_lrit', 'gain_mu', str(self.gain_mu))
+               self._saved_gain_mu_config.write(open(self.config_filename, 'w'))
+               self.mm_sync.set_gain_omega((self.gain_mu**2)/4.0)
+               self.mm_sync.set_gain_mu(self.gain_mu)
+
+       def set_gain(self, gain):
+               self.gain = gain
+               self._saved_gain_config = ConfigParser.ConfigParser()
+               self._saved_gain_config.read(self.config_filename)
+               if not self._saved_gain_config.has_section('usrp_rx_lrit'):
+                       self._saved_gain_config.add_section('usrp_rx_lrit')
+               self._saved_gain_config.set('usrp_rx_lrit', 'gain', str(self.gain))
+               self._saved_gain_config.write(open(self.config_filename, 'w'))
+               self._gain_slider.set_value(self.gain)
+               self._gain_text_box.set_value(self.gain)
+               self.usrp_simple_source_x_0.set_gain(self.gain)
+
+       def set_freq(self, freq):
+               self.freq = freq
+               self._freq_text_box.set_value(self.freq)
+               self._saved_freq_config = ConfigParser.ConfigParser()
+               self._saved_freq_config.read(self.config_filename)
+               if not self._saved_freq_config.has_section('usrp_rx_lrit'):
+                       self._saved_freq_config.add_section('usrp_rx_lrit')
+               self._saved_freq_config.set('usrp_rx_lrit', 'freq', str(self.freq))
+               self._saved_freq_config.write(open(self.config_filename, 'w'))
+               self.rx_spectrum.set_baseband_freq(self.freq)
+               self.rrc_spectrum.set_baseband_freq(self.freq+self.offset)
+               self.costas_spectrum.set_baseband_freq(self.freq+self.offset)
+               self.usrp_simple_source_x_0.set_frequency(self.freq+self.offset)
+
+       def set_costas_alpha(self, costas_alpha):
+               self.costas_alpha = costas_alpha
+               self._costas_alpha_slider.set_value(self.costas_alpha)
+               self._costas_alpha_text_box.set_value(self.costas_alpha)
+               self._saved_costas_alpha_config = ConfigParser.ConfigParser()
+               self._saved_costas_alpha_config.read(self.config_filename)
+               if not self._saved_costas_alpha_config.has_section('usrp_rx_lrit'):
+                       self._saved_costas_alpha_config.add_section('usrp_rx_lrit')
+               self._saved_costas_alpha_config.set('usrp_rx_lrit', 'costas_alpha', str(self.costas_alpha))
+               self._saved_costas_alpha_config.write(open(self.config_filename, 'w'))
+               self.costas.set_alpha(self.costas_alpha)
+               self.costas.set_beta((self.costas_alpha**2.0)/4.0)
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       (options, args) = parser.parse_args()
+       tb = usrp_rx_lrit()
+       tb.Run(True)
+
diff --git a/gr-noaa/grc/.gitignore b/gr-noaa/grc/.gitignore
new file mode 100644 (file)
index 0000000..70845e0
--- /dev/null
@@ -0,0 +1 @@
+Makefile.in
diff --git a/gr-noaa/grc/Makefile.am b/gr-noaa/grc/Makefile.am
new file mode 100644 (file)
index 0000000..73a0282
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+grcblocksdir = $(grc_blocksdir)
+
+dist_grcblocks_DATA = \
+       noaa_hrpt_decoder.xml \
+       noaa_hrpt_deframer.xml \
+       noaa_hrpt_pll_cf.xml
+
diff --git a/gr-noaa/grc/noaa_hrpt_decoder.xml b/gr-noaa/grc/noaa_hrpt_decoder.xml
new file mode 100644 (file)
index 0000000..2d6e98c
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<block>
+  <name>HRPT Decoder</name>
+  <key>noaa_hrpt_decoder</key>
+  <category>NOAA</category>
+  <import>from gnuradio import noaa</import>
+  <make>noaa.hrpt_decoder($verbose,$output)</make>
+
+  <param>
+    <name>Verbose</name>
+    <key>verbose</key>
+    <type>bool</type>
+  </param>
+
+  <param>
+    <name>Output Files</name>
+    <key>output</key>
+    <type>bool</type>
+  </param>
+
+  <sink>
+    <name>in</name>
+    <type>short</type>
+  </sink>
+</block>
diff --git a/gr-noaa/grc/noaa_hrpt_deframer.xml b/gr-noaa/grc/noaa_hrpt_deframer.xml
new file mode 100644 (file)
index 0000000..af36abf
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<block>
+  <name>HRPT Deframer</name>
+  <key>noaa_hrpt_deframer</key>
+  <category>NOAA</category>
+  <import>from gnuradio import noaa</import>
+  <make>noaa.hrpt_deframer()</make>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>short</type>
+  </source>
+</block>
diff --git a/gr-noaa/grc/noaa_hrpt_pll_cf.xml b/gr-noaa/grc/noaa_hrpt_pll_cf.xml
new file mode 100644 (file)
index 0000000..bbe15e8
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<block>
+  <name>HRPT PLL</name>
+  <key>noaa_hrpt_pll_cf</key>
+  <category>NOAA</category>
+  <import>from gnuradio import noaa</import>
+  <make>noaa.hrpt_pll_cf($alpha, $beta, $max_offset)</make>
+  <callback>set_alpha($alpha)</callback>
+  <callback>set_beta($beta)</callback>
+  <callback>set_max_offset($max_offset)</callback>
+  <param>
+    <name>Alpha</name>
+    <key>alpha</key>
+    <type>real</type>
+  </param>
+  <param>
+    <name>Beta</name>
+    <key>beta</key>
+    <type>real</type>
+  </param>
+  <param>
+    <name>Max Offset</name>
+    <key>max_offset</key>
+    <type>real</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>complex</type>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>float</type>
+  </source>
+</block>
diff --git a/gr-noaa/lib/.gitignore b/gr-noaa/lib/.gitignore
new file mode 100644 (file)
index 0000000..02b0523
--- /dev/null
@@ -0,0 +1,4 @@
+Makefile
+Makefile.in
+.deps
+.libs
diff --git a/gr-noaa/lib/Makefile.am b/gr-noaa/lib/Makefile.am
new file mode 100644 (file)
index 0000000..fdc1476
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = \
+       $(STD_DEFINES_AND_INCLUDES) \
+       $(WITH_INCLUDES)
+
+lib_LTLIBRARIES = \
+       libgnuradio-noaa.la
+
+libgnuradio_noaa_la_SOURCES = \
+       noaa_hrpt_decoder.cc \
+       noaa_hrpt_deframer.cc \
+       noaa_hrpt_pll_cf.cc
+
+noinst_HEADERS = \
+       noaa_hrpt.h
+
+libgnuradio_noaa_la_LIBADD = \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_noaa_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+grinclude_HEADERS = \
+       noaa_hrpt_decoder.h \
+       noaa_hrpt_deframer.h \
+       noaa_hrpt_pll_cf.h
\ No newline at end of file
diff --git a/gr-noaa/lib/noaa_hrpt.h b/gr-noaa/lib/noaa_hrpt.h
new file mode 100644 (file)
index 0000000..3812e93
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef INCLUDED_NOAA_HRPT_H
+#define INCLUDED_NOAA_HRPT_H
+
+#define HRPT_SYNC1 0x0284
+#define HRPT_SYNC2 0x016F
+#define HRPT_SYNC3 0x035C
+#define HRPT_SYNC4 0x019D
+#define HRPT_SYNC5 0x020F
+#define HRPT_SYNC6 0x0095
+
+#define HRPT_MINOR_FRAME_SYNC  0x0A116FD719D83C95LL
+
+#define HRPT_SYNC_WORDS        6
+#define HRPT_MINOR_FRAME_WORDS 11090
+#define HRPT_BITS_PER_WORD     10
+
+#endif /* INCLUDED_NOAA_HRPT_H */
diff --git a/gr-noaa/lib/noaa_hrpt_decoder.cc b/gr-noaa/lib/noaa_hrpt_decoder.cc
new file mode 100644 (file)
index 0000000..2433100
--- /dev/null
@@ -0,0 +1,200 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <noaa_hrpt_decoder.h>
+#include <noaa_hrpt.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+static const char *hrpt_ids[] = {
+  "000000",
+  "NOAA11",
+  "000002",
+  "NOAA16",
+  "000004",
+  "000005",
+  "000006",
+  "NOAA15",
+  "000008",
+  "NOAA12",
+  "000010",
+  "NOAA17",
+  "000012",
+  "NOAA18",
+  "000014",
+  "NOAA19"
+};
+
+noaa_hrpt_decoder_sptr
+noaa_make_hrpt_decoder(bool verbose, bool output_files)
+{
+  return gnuradio::get_initial_sptr(new noaa_hrpt_decoder(verbose, output_files));
+}
+
+noaa_hrpt_decoder::noaa_hrpt_decoder(bool verbose, bool output_files)
+  : gr_sync_block("noaa_hrpt_decoder",
+                 gr_make_io_signature(1, 1, sizeof(short)),
+                 gr_make_io_signature(0, 0, 0)),
+    d_verbose(verbose),
+    d_output_files(output_files),
+    d_word_num(0),
+    d_frames_seen(0),
+    d_current_mfnum(0),
+    d_expected_mfnum(0),
+    d_seq_errs(0),
+    d_address(0),
+    d_day_of_year(0),
+    d_milliseconds(0),
+    d_last_time(0)
+{
+  // Start of capture processing here
+}
+
+int
+noaa_hrpt_decoder::work(int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  const unsigned short *in = (const unsigned short*)input_items[0];
+
+  int i = 0;
+  while (i < noutput_items) {
+    d_current_word = in[i++] & 0x3FF;
+    d_word_num++;
+
+    // Per HRPT word processing here
+
+    switch (d_word_num) {
+    case 7:
+      process_mfnum();
+      process_address();
+      break;
+
+    case 9:
+      process_day_of_year();
+      break;
+
+    case 10:
+      process_milli1();
+      break;
+
+    case 11:
+      process_milli2();
+      break;
+
+    case 12:
+      process_milli3();
+      break;
+
+    default:
+      break;
+    }
+
+    if (d_word_num == HRPT_MINOR_FRAME_WORDS) {
+
+      // End of minor frame processing here
+      d_frames_seen++;
+      d_word_num = 0;
+      fprintf(stderr, "\n");
+    }
+  }
+
+  return i;
+}
+
+void
+noaa_hrpt_decoder::process_mfnum()
+{
+  d_current_mfnum = (d_current_word & 0x180) >> 7;
+
+  if (d_verbose)
+    fprintf(stderr, "MF:");
+
+  if (d_current_mfnum != d_expected_mfnum && d_frames_seen > 0) {
+    d_seq_errs++;
+
+    if (d_verbose)
+      fprintf(stderr, "*");
+  }
+  else
+    if (d_verbose)
+      fprintf(stderr, " ");
+  
+  if (d_verbose)
+    fprintf(stderr, "%i  ", d_current_mfnum);
+  d_expected_mfnum = (d_current_mfnum == 3) ? 1 : d_current_mfnum+1;
+}
+
+void
+noaa_hrpt_decoder::process_address()
+{
+  d_address = ((d_current_word & 0x078) >> 3) & 0x000F;
+
+  if (d_verbose)
+    fprintf(stderr, "SA: %s  ", hrpt_ids[d_address]);
+}
+
+void
+noaa_hrpt_decoder::process_day_of_year()
+{
+  d_day_of_year = d_current_word >> 1;
+
+  if (d_verbose)
+    fprintf(stderr, "DOY: %3i  ", d_day_of_year);
+}
+
+void
+noaa_hrpt_decoder::process_milli1()
+{
+  d_milliseconds = (d_current_word & 0x7F) << 20;
+}
+
+void
+noaa_hrpt_decoder::process_milli2()
+{
+  d_milliseconds |= (d_current_word << 10);
+}
+
+void
+noaa_hrpt_decoder::process_milli3()
+{
+  d_milliseconds |= d_current_word;
+  int delta = d_milliseconds - d_last_time;
+  d_last_time = d_milliseconds;
+
+  if (d_verbose)
+    fprintf(stderr, "MS: %8i  DT: %8i", d_milliseconds, delta);
+}
+
+noaa_hrpt_decoder::~noaa_hrpt_decoder()
+{
+  // End of capture processing here
+
+  if (d_verbose) {
+    fprintf(stderr, "Frames seen:     %10i\n", d_frames_seen);
+    fprintf(stderr, "Sequence errors: %10i\n", d_seq_errs);
+  }
+}
diff --git a/gr-noaa/lib/noaa_hrpt_decoder.h b/gr-noaa/lib/noaa_hrpt_decoder.h
new file mode 100644 (file)
index 0000000..9d67d71
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef INCLUDED_NOAA_HRPT_DECODER_H
+#define INCLUDED_NOAA_HRPT_DECODER_H
+
+#include <gr_sync_block.h>
+
+class noaa_hrpt_decoder;
+typedef boost::shared_ptr<noaa_hrpt_decoder> noaa_hrpt_decoder_sptr;
+
+noaa_hrpt_decoder_sptr
+noaa_make_hrpt_decoder(bool verbose, bool output_files);
+
+class noaa_hrpt_decoder : public gr_sync_block
+{
+  friend noaa_hrpt_decoder_sptr noaa_make_hrpt_decoder(bool verbose, bool output_files);
+  noaa_hrpt_decoder(bool verbose, bool output_files);
+
+  // Configuration
+  bool d_verbose;
+  bool d_output_files;
+
+  // Frame-level state
+  unsigned short d_current_word;
+  unsigned int   d_word_num;
+  int            d_frames_seen;
+
+  // Minor frame number
+  int d_current_mfnum;
+  int d_expected_mfnum;
+  int d_seq_errs;
+
+  // Spacecraft address
+  int d_address;
+
+  // Minor frame timestamp
+  int d_day_of_year;
+  int d_milliseconds;
+  int d_last_time;
+
+  void process_mfnum();
+  void process_address();
+  void process_day_of_year();
+  void process_milli1();
+  void process_milli2();
+  void process_milli3();
+
+public:
+  ~noaa_hrpt_decoder();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_NOAA_HRPT_DECODER_H */
diff --git a/gr-noaa/lib/noaa_hrpt_deframer.cc b/gr-noaa/lib/noaa_hrpt_deframer.cc
new file mode 100644 (file)
index 0000000..1a2af6c
--- /dev/null
@@ -0,0 +1,126 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <noaa_hrpt_deframer.h>
+#include <gr_io_signature.h>
+#include <noaa_hrpt.h>
+#include <cstring>
+#include <cstdio>
+
+#define ST_IDLE   0
+#define ST_SYNCED 1
+
+noaa_hrpt_deframer_sptr
+noaa_make_hrpt_deframer()
+{
+  return gnuradio::get_initial_sptr(new noaa_hrpt_deframer());
+}
+
+noaa_hrpt_deframer::noaa_hrpt_deframer()
+  : gr_block("noaa_hrpt_deframer",
+            gr_make_io_signature(1, 1, sizeof(char)),
+            gr_make_io_signature(1, 1, sizeof(short)))
+{
+  set_output_multiple(6); // room for writing full sync when received
+  d_mid_bit = true;
+  d_last_bit = 0;
+  enter_idle();
+}
+
+void
+noaa_hrpt_deframer::enter_idle()
+{
+  d_state = ST_IDLE;
+}
+
+void
+noaa_hrpt_deframer::enter_synced()
+{
+  d_state = ST_SYNCED;
+  d_bit_count = HRPT_BITS_PER_WORD;
+  d_word_count = HRPT_MINOR_FRAME_WORDS-HRPT_SYNC_WORDS;
+  d_word = 0;
+}
+
+int
+noaa_hrpt_deframer::general_work(int noutput_items,
+                                gr_vector_int &ninput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+{
+  int ninputs = ninput_items[0];
+  const char *in = (const char *)input_items[0];
+  unsigned short *out = (unsigned short *)output_items[0];
+
+  int i = 0, j = 0;
+  while (i < ninputs && j < noutput_items) {
+    char bit = in[i++];
+    char diff = bit^d_last_bit;
+    d_last_bit = bit;
+
+    // Wait for transition if not synced, otherwise, alternate bits
+    if (d_mid_bit && (diff | (d_state == ST_SYNCED))) {
+      switch (d_state) {
+      case ST_IDLE:
+       d_shifter = (d_shifter << 1) | bit; // MSB transmitted first
+       
+       if ((d_shifter & 0x0FFFFFFFFFFFFFFFLL) == HRPT_MINOR_FRAME_SYNC) {
+         out[j++] = HRPT_SYNC1;
+         out[j++] = HRPT_SYNC2;
+         out[j++] = HRPT_SYNC3;
+         out[j++] = HRPT_SYNC4;
+         out[j++] = HRPT_SYNC5;
+         out[j++] = HRPT_SYNC6;
+         enter_synced();
+       }
+       break;
+       
+      case ST_SYNCED:
+       d_word = (d_word << 1) | bit; // MSB transmitted first
+       if (--d_bit_count == 0) {
+         out[j++] = d_word;
+         d_word = 0;
+         d_bit_count = HRPT_BITS_PER_WORD;
+         if (--d_word_count == 0) {
+           enter_idle();
+         }
+       }
+       break;
+       
+      default:
+       throw std::runtime_error("noaa_hrpt_deframer: bad state\n");
+      }
+
+      d_mid_bit = false;
+    }
+    else {
+      d_mid_bit = true;
+    }
+  }
+
+  consume_each(i);
+  return j;
+}
diff --git a/gr-noaa/lib/noaa_hrpt_deframer.h b/gr-noaa/lib/noaa_hrpt_deframer.h
new file mode 100644 (file)
index 0000000..b11d0fa
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef INCLUDED_NOAA_HRPT_DEFRAMER_H
+#define INCLUDED_NOAA_HRPT_DEFRAMER_H
+
+#include <gr_block.h>
+
+class noaa_hrpt_deframer;
+typedef boost::shared_ptr<noaa_hrpt_deframer> noaa_hrpt_deframer_sptr;
+
+noaa_hrpt_deframer_sptr
+noaa_make_hrpt_deframer();
+
+class noaa_hrpt_deframer : public gr_block
+{
+  friend noaa_hrpt_deframer_sptr noaa_make_hrpt_deframer();
+  noaa_hrpt_deframer();
+
+  unsigned int       d_state;
+  bool               d_mid_bit;
+  unsigned char      d_last_bit;
+  unsigned int       d_bit_count;
+  unsigned int       d_word_count;
+  unsigned long long d_shifter;     // 60 bit sync word
+  unsigned short     d_word;        // 10 bit HRPT word
+
+  void enter_idle();
+  void enter_synced();
+public:
+  int general_work(int noutput_items,
+                  gr_vector_int &ninput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_NOAA_HRPT_DEFRAMER_H */
diff --git a/gr-noaa/lib/noaa_hrpt_pll_cf.cc b/gr-noaa/lib/noaa_hrpt_pll_cf.cc
new file mode 100644 (file)
index 0000000..08ab1d1
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <noaa_hrpt_pll_cf.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+#include <gr_sincos.h>
+
+#define M_TWOPI (2*M_PI)
+
+noaa_hrpt_pll_cf_sptr
+noaa_make_hrpt_pll_cf(float alpha, float beta, float max_offset)
+{
+  return gnuradio::get_initial_sptr(new noaa_hrpt_pll_cf(alpha, beta, max_offset));
+}
+
+noaa_hrpt_pll_cf::noaa_hrpt_pll_cf(float alpha, float beta, float max_offset)
+  : gr_sync_block("noaa_hrpt_pll_cf",
+                 gr_make_io_signature(1, 1, sizeof(gr_complex)),
+                 gr_make_io_signature(1, 1, sizeof(float))),
+    d_alpha(alpha), d_beta(beta), d_max_offset(max_offset),
+    d_phase(0.0), d_freq(0.0)
+{
+}
+
+float
+phase_wrap(float phase)
+{
+  while (phase < -M_PI)
+    phase += M_TWOPI;
+  while (phase > M_PI)
+    phase -= M_TWOPI;
+
+  return phase;
+}
+
+int
+noaa_hrpt_pll_cf::work(int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  const gr_complex *in = (const gr_complex *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++) {
+
+    // Adjust PLL phase/frequency
+    float error = phase_wrap(gr_fast_atan2f(in[i].imag(), in[i].real()) - d_phase);
+    d_freq  = gr_branchless_clip(d_freq + error*d_beta, d_max_offset);
+    d_phase = phase_wrap(d_phase + error*d_alpha + d_freq);
+
+    // Generate and mix out carrier
+    float re, im;
+    gr_sincosf(d_phase, &im, &re);
+    out[i] = (in[i]*gr_complex(re, -im)).imag();
+  }
+
+  return noutput_items;
+}
diff --git a/gr-noaa/lib/noaa_hrpt_pll_cf.h b/gr-noaa/lib/noaa_hrpt_pll_cf.h
new file mode 100644 (file)
index 0000000..507d47f
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef INCLUDED_NOAA_HRPT_PLL_CF_H
+#define INCLUDED_NOAA_HRPT_PLL_CF_H
+
+#include <gr_sync_block.h>
+
+class noaa_hrpt_pll_cf;
+typedef boost::shared_ptr<noaa_hrpt_pll_cf> noaa_hrpt_pll_cf_sptr;
+
+noaa_hrpt_pll_cf_sptr
+noaa_make_hrpt_pll_cf(float alpha, float beta, float max_offset);
+
+class noaa_hrpt_pll_cf : public gr_sync_block
+{
+  friend noaa_hrpt_pll_cf_sptr noaa_make_hrpt_pll_cf(float alpha, float beta, float max_offset);
+  noaa_hrpt_pll_cf(float alpha, float beta, float max_offset);
+
+  float d_alpha;               // 1st order loop constant
+  float d_beta;                        // 2nd order loop constant
+  float d_max_offset;          // Maximum frequency offset, radians/sample
+  float d_phase;               // Instantaneous carrier phase
+  float d_freq;                        // Instantaneous carrier frequency, radians/sample
+
+ public:
+  virtual int work(int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+
+  void set_alpha(float alpha) { d_alpha = alpha; }
+  void set_beta(float beta) { d_beta = beta; }
+  void set_max_offset(float max_offset) { d_max_offset = max_offset; }
+};
+
+#endif /* INCLUDED_NOAA_HRPT_PLL_CF_H */
diff --git a/gr-noaa/oct/.gitignore b/gr-noaa/oct/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-noaa/oct/Makefile.am b/gr-noaa/oct/Makefile.am
new file mode 100644 (file)
index 0000000..2f6e4e5
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+       frames_to_ppm.m \
+       frames-to-png.sh
diff --git a/gr-noaa/oct/frames-to-png.sh b/gr-noaa/oct/frames-to-png.sh
new file mode 100755 (executable)
index 0000000..cb3e3fb
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+octave --eval frames_to_ppm
+
+convert chan1.ppm chan1.png && rm chan1.ppm
+convert chan2.ppm chan2.png && rm chan2.ppm
+convert chan3.ppm chan3.png && rm chan3.ppm
+convert chan4.ppm chan4.png && rm chan4.ppm
+convert chan5.ppm chan5.png && rm chan5.ppm
diff --git a/gr-noaa/oct/frames_to_ppm.m b/gr-noaa/oct/frames_to_ppm.m
new file mode 100644 (file)
index 0000000..73842f0
--- /dev/null
@@ -0,0 +1,85 @@
+% -*- octave -*-
+%
+% Copyright 2009 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.
+% 
+
+% Extract AVHRR images from HRPT frames.dat
+clear
+
+fid = fopen('frames.hrpt');
+dat = fread(fid, 'uint16');
+
+frame_len = 11090;
+
+len = floor(length(dat) / frame_len);
+
+chan1 = zeros(len, 2048);
+
+start = 751;
+stop = 10986;
+
+for line = 1:len
+  chan1(line, 1:2048) = dat(start:5:stop)';
+  start = start + frame_len;
+  stop = stop + frame_len;
+end
+start = 752;
+stop = 10987;
+
+for line = 1:len
+  chan2(line, 1:2048) = dat(start:5:stop)';
+start = start + frame_len;
+stop = stop + frame_len;
+end
+start = 753;
+stop = 10988;
+
+for line = 1:len
+  chan3(line, 1:2048) = dat(start:5:stop)';
+  start = start + frame_len;
+  stop = stop + frame_len;
+end
+start = 754;
+stop = 10989;
+
+for line = 1:len
+  chan4(line, 1:2048) = dat(start:5:stop)';
+start = start + frame_len;
+stop = stop + frame_len;
+end
+start = 755;
+stop = 10990;
+
+for line = 1:len
+  chan5(line, 1:2048) = dat(start:5:stop)';
+  start = start + frame_len;
+  stop = stop + frame_len;
+end
+
+colormap(gray) 
+saveimage("chan1.ppm", chan1/4, 'ppm')
+saveimage("chan2.ppm", chan2/4, 'ppm')
+saveimage("chan3.ppm", chan3/4, 'ppm')
+saveimage("chan4.ppm", chan4/4, 'ppm')
+saveimage("chan5.ppm", chan5/4, 'ppm')
diff --git a/gr-noaa/python/Makefile.am b/gr-noaa/python/Makefile.am
new file mode 100644 (file)
index 0000000..869c5f3
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+if PYTHON
+
+endif
+
diff --git a/gr-noaa/swig/.gitignore b/gr-noaa/swig/.gitignore
new file mode 100644 (file)
index 0000000..d18a966
--- /dev/null
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+.deps
+.libs
+noaa_swig.cc
+noaa_swig.py
diff --git a/gr-noaa/swig/Makefile.am b/gr-noaa/swig/Makefile.am
new file mode 100644 (file)
index 0000000..73645e9
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = \
+       $(STD_DEFINES_AND_INCLUDES) \
+       $(PYTHON_CPPFLAGS) \
+       $(WITH_INCLUDES) \
+       -I$(top_srcdir)/gr-noaa/lib
+
+if PYTHON
+# ----------------------------------------------------------------
+# The SWIG library
+# TESTS = run_tests
+
+TOP_SWIG_IFILES = \
+       noaa_swig.i
+
+# Install so that they end up available as:
+#   import gnuradio.noaa
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio/noaa
+noaa_swig_pythondir_category = \
+       gnuradio/noaa
+
+# additional libraries for linking with the SWIG-generated library
+noaa_swig_la_swig_libadd = \
+       $(top_builddir)/gr-noaa/lib/libgnuradio-noaa.la
+
+# additional Python files to be installed along with the SWIG-generated one
+noaa_swig_python = \
+       __init__.py
+
+# additional SWIG files to be installed
+noaa_swig_swiginclude_headers =        \
+       noaa_hrpt_decoder.i \
+       noaa_hrpt_deframer.i \
+       noaa_hrpt_pll_cf.i
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-noaa/swig/Makefile.swig.gen b/gr-noaa/swig/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..3d7102f
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for noaa_swig.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/noaa_swig
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/noaa_swig
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+noaa_swig_pythondir_category ?= gnuradio/noaa_swig
+noaa_swig_pylibdir_category ?= $(noaa_swig_pythondir_category)
+noaa_swig_pythondir = $(pythondir)/$(noaa_swig_pythondir_category)
+noaa_swig_pylibdir = $(pyexecdir)/$(noaa_swig_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+noaa_swig_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/noaa_swig-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += noaa_swig.py noaa_swig.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+noaa_swig_swiginclude_HEADERS =                \
+       noaa_swig.i                     \
+       $(noaa_swig_swiginclude_headers)
+
+noaa_swig_pylib_LTLIBRARIES =          \
+       _noaa_swig.la
+
+_noaa_swig_la_SOURCES =                        \
+       noaa_swig.cc                    \
+       $(noaa_swig_la_swig_sources)
+
+_noaa_swig_la_LIBADD =                 \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(noaa_swig_la_swig_libadd)
+
+_noaa_swig_la_LDFLAGS =                        \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(noaa_swig_la_swig_ldflags)
+
+_noaa_swig_la_CXXFLAGS =                       \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(noaa_swig_la_swig_cxxflags)
+
+noaa_swig_python_PYTHON =                      \
+       noaa_swig.py                    \
+       $(noaa_swig_python)
+
+## Entry rule for running SWIG
+
+noaa_swig.h noaa_swig.py noaa_swig.cc: noaa_swig.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/noaa_swig-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/noaa_swig-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/noaa_swig-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/noaa_swig-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/noaa_swig-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/noaa_swig-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/noaa_swig-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/noaa_swig-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/noaa_swig-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(noaa_swig_swig_args) \
+               -MD -MF $(DEPDIR)/noaa_swig.Std \
+               -module noaa_swig -o noaa_swig.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/noaa_swig.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/noaa_swig.Std \
+                       > $(DEPDIR)/noaa_swig.Sd; \
+               $(RM) $(DEPDIR)/noaa_swig.Std; \
+               $(MV) $(DEPDIR)/noaa_swig.Sd $(DEPDIR)/noaa_swig.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/noaa_swig.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/noaa_swig.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/noaa_swig.Std $(DEPDIR)/noaa_swig.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/noaa_swig.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/noaa_swig.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/noaa_swig.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/noaa_swig.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/noaa_swig-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/noaa_swig.d@am__quote@
+
diff --git a/gr-noaa/swig/__init__.py b/gr-noaa/swig/__init__.py
new file mode 100644 (file)
index 0000000..d8d337e
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Copyright 2009 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.
+# 
+
+# The presence of this file turns this directory into a Python package
+
+# Add SWIG generated code to this namespace
+from noaa_swig import *
+
+# Add other content from pure-Python modules here
+
diff --git a/gr-noaa/swig/noaa_hrpt_decoder.i b/gr-noaa/swig/noaa_hrpt_decoder.i
new file mode 100644 (file)
index 0000000..220a571
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(noaa,hrpt_decoder)
+
+noaa_hrpt_decoder_sptr
+noaa_make_hrpt_decoder(bool verbose, bool output_files);
+
+class noaa_hrpt_decoder : public gr_sync_block
+{
+private:
+  noaa_hrpt_decoder();
+};
diff --git a/gr-noaa/swig/noaa_hrpt_deframer.i b/gr-noaa/swig/noaa_hrpt_deframer.i
new file mode 100644 (file)
index 0000000..6914b93
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(noaa,hrpt_deframer)
+
+noaa_hrpt_deframer_sptr
+noaa_make_hrpt_deframer();
+
+class noaa_hrpt_deframer : public gr_block
+{
+private:
+  noaa_hrpt_deframer();
+};
diff --git a/gr-noaa/swig/noaa_hrpt_pll_cf.i b/gr-noaa/swig/noaa_hrpt_pll_cf.i
new file mode 100644 (file)
index 0000000..859548a
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(noaa,hrpt_pll_cf)
+
+noaa_hrpt_pll_cf_sptr
+noaa_make_hrpt_pll_cf(float alpha, float beta, float max_offset);
+
+class noaa_hrpt_pll_cf : public gr_sync_block
+{
+private:
+  noaa_hrpt_pll_cf();
+
+public:
+  void set_alpha(float alpha);
+  void set_beta(float beta);
+  void set_max_offset(float min_freq);
+};
diff --git a/gr-noaa/swig/noaa_swig.i b/gr-noaa/swig/noaa_swig.i
new file mode 100644 (file)
index 0000000..8fe814a
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"
+
+%{
+#include <noaa_hrpt_decoder.h>
+#include <noaa_hrpt_deframer.h>
+#include <noaa_hrpt_pll_cf.h>
+%}
+
+%include "noaa_hrpt_decoder.i"
+%include "noaa_hrpt_deframer.i"
+%include "noaa_hrpt_pll_cf.i"
+
diff --git a/gr-pager/.gitignore b/gr-pager/.gitignore
new file mode 100644 (file)
index 0000000..27ff673
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/data
+/*.pc
index 7297661a1f524189b84999ae986ac7e035fcce48..002387c0c7340f17546e11bfc6e9d351ab17d4d6 100644 (file)
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = src
+SUBDIRS = lib
+
+if PYTHON
+SUBDIRS += swig python apps grc
+endif
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-pager.pc
diff --git a/gr-pager/apps/.gitignore b/gr-pager/apps/.gitignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/gr-pager/apps/Makefile.am b/gr-pager/apps/Makefile.am
new file mode 100644 (file)
index 0000000..7b495fd
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+if PYTHON
+
+dist_bin_SCRIPTS = \
+       usrp_flex.py \
+       usrp_flex_all.py \
+       usrp_flex_band.py
+
+noinst_PYTHON = \
+       usrp_rx_flex.py
+endif
+
+EXTRA_DIST = \
+       usrp_rx_flex.grc
diff --git a/gr-pager/apps/usrp_flex.py b/gr-pager/apps/usrp_flex.py
new file mode 100755 (executable)
index 0000000..f8d9d25
--- /dev/null
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2009 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, eng_notation, pager
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import time, os, sys
+
+"""
+This example application demonstrates receiving and demodulating the
+FLEX pager protocol.
+
+The following are required command line parameters:
+
+-f FREQ            USRP receive frequency
+
+The following are optional command line parameters:
+
+-R SUBDEV   Daughter board specification, defaults to first found
+-F FILE     Read samples from a file instead of USRP.
+-c FREQ     Calibration offset.  Gets added to receive frequency.
+            Defaults to 0.0 Hz.
+-g GAIN     Daughterboard gain setting. Defaults to mid-range.
+-l          Log flow graph to files (LOTS of data)
+-v          Verbose output
+
+Once the program is running, ctrl-break (Ctrl-C) stops operation.
+"""
+
+class app_top_block(gr.top_block):
+    def __init__(self, options, queue):
+        gr.top_block.__init__(self, "usrp_flex")
+        self.options = options
+       self.offset = 0.0
+       self.adj_time = time.time()
+       self.verbose = options.verbose
+                       
+       if options.from_file is None:
+            # Set up USRP source with specified RX daughterboard
+            self.src = usrp.source_c()
+            if options.rx_subdev_spec == None:
+                options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src)
+            self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
+            self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
+
+            # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex)
+            self.src.set_decim_rate(256)
+                   
+            # If no gain specified, set to midrange
+            if options.gain is None:
+                g = self.subdev.gain_range()
+                options.gain = (g[0]+g[1])/2.0
+            self.subdev.set_gain(options.gain)
+
+            # Tune daughterboard
+            actual_frequency = options.frequency+options.calibration
+            tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency)
+            if not tune_result:
+                sys.stderr.write("Failed to set center frequency to "+`actual_frequency`+"\n")
+                sys.exit(1)
+
+            if options.verbose:
+                print "Using RX daughterboard", self.subdev.side_and_name()
+                print "USRP gain is", options.gain
+                print "USRP tuned to", actual_frequency
+            
+        else:
+            # Use supplied file as source of samples
+            self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
+            if options.verbose:
+                print "Reading samples from", options.from_file
+           
+        if options.log and not options.from_file:
+            usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
+            self.connect(self.src, usrp_sink)
+
+        # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
+        # to get channel rate of 25Ksps
+        taps = optfir.low_pass(1.0,   # Filter gain
+                               250e3, # Sample rate
+                               11000, # One-sided modulation bandwidth
+                               12500, # One-sided channel bandwidth
+                               0.1,   # Passband ripple
+                               60)    # Stopband attenuation
+       
+       if options.verbose:
+           print "Channel filter has", len(taps), "taps."
+
+        self.chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
+                                                   taps,  # Filter taps
+                                                   0.0,   # Offset frequency
+                                                   250e3) # Sample rate
+
+       if options.log:
+           chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
+           self.connect(self.chan, chan_sink)
+
+        # FLEX protocol demodulator
+        self.flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
+
+        self.connect(self.src, self.chan, self.flex)
+
+    def freq_offset(self):
+       return self.flex.dc_offset()*1600
+
+    def adjust_freq(self):
+       if time.time() - self.adj_time > 1.6:   # Only do it once per FLEX frame
+           self.adj_time = time.time()
+           self.offset -= self.freq_offset()
+           self.chan.set_center_freq(self.offset)
+           if self.verbose:
+               print "Channel frequency offset (Hz):", int(self.offset)
+                       
+def main():
+    parser = OptionParser(option_class=eng_option)
+    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")
+    parser.add_option("-c",   "--calibration", type="eng_float", default=0.0,
+                      help="set frequency offset to Hz", metavar="Hz")
+    parser.add_option("-g", "--gain", type="int", default=None,
+                      help="set RF gain", metavar="dB")
+    parser.add_option("-l", "--log", action="store_true", default=False,
+                      help="log flowgraph to files (LOTS of data)")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="display debug output")
+    parser.add_option("-F", "--from-file", default=None,
+                      help="read samples from file instead of USRP")
+    (options, args) = parser.parse_args()
+
+    if len(args) > 0 or (options.frequency == None and options.from_file == None):
+       print "Run 'usrp_flex.py -h' for options."
+       sys.exit(1)
+
+    if options.frequency == None:
+       options.frequency = 0.0
+
+    # Flow graph emits pages into message queue
+    queue = gr.msg_queue()
+    tb = app_top_block(options, queue)
+    runner = pager.queue_runner(queue)
+    
+    try:
+        tb.run()
+    except KeyboardInterrupt:
+        pass
+
+    runner.end()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/gr-pager/apps/usrp_flex_all.py b/gr-pager/apps/usrp_flex_all.py
new file mode 100755 (executable)
index 0000000..14f9151
--- /dev/null
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2009 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, eng_notation, blks2, pager
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from string import split, join, printable
+import time
+
+class app_top_block(gr.top_block):
+    def __init__(self, options, queue):
+       gr.top_block.__init__(self, "usrp_flex_all")
+
+        if options.from_file is not None:
+            src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
+            if options.verbose:
+                print "Reading samples from file", options.from_file
+        else:
+            src = usrp.source_c()
+            if options.rx_subdev_spec is None:
+                options.rx_subdev_spec = usrp.pick_rx_subdevice(src)
+            subdev = usrp.selected_subdev(src, options.rx_subdev_spec)
+            src.set_mux(usrp.determine_rx_mux_value(src, options.rx_subdev_spec))
+            src.set_decim_rate(20)
+            result = usrp.tune(src, 0, subdev, 930.5125e6+options.calibration)
+            if options.verbose:
+                print "Using", subdev.name(), " for receiving."
+                print "Tuned USRP to", 930.5125e6+options.calibration
+                
+        taps = gr.firdes.low_pass(1.0,
+                                  1.0,
+                                  1.0/128.0*0.4,
+                                  1.0/128.0*0.1,
+                                  gr.firdes.WIN_HANN)
+
+        if options.verbose:
+            print "Channel filter has", len(taps), "taps"
+
+        bank = blks2.analysis_filterbank(128, taps)
+        self.connect(src, bank)
+
+        if options.log and options.from_file == None:
+            src_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
+            self.connect(src, src_sink)
+
+        for i in range(128):
+           if i < 64:
+               freq = 930.5e6+i*25e3
+           else:
+               freq = 928.9e6+(i-64)*25e3
+
+           if (freq < 929.0e6 or freq > 932.0e6):
+                self.connect((bank, i), gr.null_sink(gr.sizeof_gr_complex))
+           else:
+               self.connect((bank, i), pager.flex_demod(queue, freq, options.verbose, options.log))
+                if options.log:
+                    self.connect((bank, i), gr.file_sink(gr.sizeof_gr_complex, 'chan_'+'%3.3f'%(freq/1e6)+'.dat'))
+
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev",
+                      help="select USRP Rx side A or B (default=first daughterboard found)")
+    parser.add_option("-c", "--calibration", type="eng_float", default=0.0,
+                      help="set frequency offset to Hz", metavar="Hz")
+    parser.add_option("-g", "--gain", type="int",
+                      help="set RF gain", metavar="dB")
+    parser.add_option("-F", "--from-file", default=None,
+                      help="Read from file instead of USRP")
+    parser.add_option("-l", "--log", action="store_true", default=False,
+                      help="log flowgraph to files (LOTS of data)")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="display debug output")
+    (options, args) = parser.parse_args()
+
+    if options.verbose:
+        print options
+
+    queue = gr.msg_queue()
+    tb = app_top_block(options, queue)
+    runner = pager.queue_runner(queue)
+
+    try:
+        tb.run()
+    except KeyboardInterrupt:
+        pass
+
+    runner.end()
+    
+if __name__ == "__main__":
+    main()
diff --git a/gr-pager/apps/usrp_flex_band.py b/gr-pager/apps/usrp_flex_band.py
new file mode 100755 (executable)
index 0000000..06c2488
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2009 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, eng_notation, blks2, pager
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class app_top_block(gr.top_block):
+    def __init__(self, options, queue):
+       gr.top_block.__init__(self, "usrp_flex_all")
+        self.subdev = None
+
+        if options.from_file is not None:
+            self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
+            if options.verbose:
+                print "Reading samples from file", options.from_file
+        else:
+            self.src = usrp.source_c()
+            if options.rx_subdev_spec is None:
+                options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src)
+            self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
+            self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
+            self.src.set_decim_rate(64)
+           frequency = options.frequency+options.calibration
+            result = usrp.tune(self.src, 0, self.subdev, frequency)
+            if options.verbose:
+                print "Using", self.subdev.name(), " for receiving."
+                print "Tuned USRP to", frequency
+                
+        taps = gr.firdes.low_pass(1.0,
+                                  1.0,
+                                  1.0/40.0*0.4,
+                                  1.0/40.0*0.1,
+                                  gr.firdes.WIN_HANN)
+
+        if options.verbose:
+            print "Channel filter has", len(taps), "taps"
+
+        bank = blks2.analysis_filterbank(40, taps)
+        self.connect(self.src, bank)
+
+        if options.log and options.from_file == None:
+            src_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
+            self.connect(self.src, src_sink)
+
+        for i in range(40):
+           if i < 20:
+               freq = options.frequency+i*25e3
+           else:
+               freq = options.frequency-0.5e6+(i-20)*25e3
+
+           self.connect((bank, i), pager.flex_demod(queue, freq, options.verbose, options.log))
+           if options.log:
+               self.connect((bank, i), gr.file_sink(gr.sizeof_gr_complex, 'chan_'+'%3.3f'%(freq/1e6)+'.dat'))
+
+
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-f", "--frequency", type="eng_float", default=929.5e6,
+                      help="set receive center frequency to Hz", metavar="Hz")
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev",
+                      help="select USRP Rx side A or B (default=first daughterboard found)")
+    parser.add_option("-c", "--calibration", type="eng_float", default=0.0,
+                      help="set frequency offset to Hz", metavar="Hz")
+    parser.add_option("-g", "--gain", type="int",
+                      help="set RF gain", metavar="dB")
+    parser.add_option("-F", "--from-file", default=None,
+                      help="Read from file instead of USRP")
+    parser.add_option("-l", "--log", action="store_true", default=False,
+                      help="log flowgraph to files (LOTS of data)")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="display debug output")
+    (options, args) = parser.parse_args()
+
+    if options.verbose:
+        print options
+
+    queue = gr.msg_queue()
+    tb = app_top_block(options, queue)
+    runner = pager.queue_runner(queue)
+
+    try:
+        tb.run()
+    except KeyboardInterrupt:
+        pass
+
+    runner.end()
+
+    
+if __name__ == "__main__":
+    main()
diff --git a/gr-pager/apps/usrp_rx_flex.grc b/gr-pager/apps/usrp_rx_flex.grc
new file mode 100644 (file)
index 0000000..b9461a5
--- /dev/null
@@ -0,0 +1,1804 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+  <timestamp>Thu Oct 29 11:01:22 2009</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>usrp_rx_flex</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>USRP FLEX Pager Receiver (Single Channel)</value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>4095,4095</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>adc_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>64e6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(225, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>adc_rate/decim</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(382, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>band_freq+(channel-61)*25e3</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(480, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FLEX Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>band_freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>65536</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0,0,1,1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays,0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(34, 508)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>displays</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['RX Spectrum','Baseband']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 5</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(9, 209)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>import</key>
+    <param>
+      <key>id</key>
+      <value>import_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>import</key>
+      <value>import os, math</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 76)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>usrp_simple_source_x</key>
+    <param>
+      <key>id</key>
+      <value>usrp_source</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>format</key>
+      <value></value>
+    </param>
+    <param>
+      <key>which</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>decimation</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>frequency</key>
+      <value>band_freq</value>
+    </param>
+    <param>
+      <key>lo_offset</key>
+      <value>float('inf')</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>rx_gain</value>
+    </param>
+    <param>
+      <key>side</key>
+      <value>A</value>
+    </param>
+    <param>
+      <key>rx_ant</key>
+      <value>RXA</value>
+    </param>
+    <param>
+      <key>hb_filters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(32, 734)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_freq_xlating_fir_filter_xxx</key>
+    <param>
+      <key>id</key>
+      <value>gr_freq_xlating_fir_filter_xxx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ccc</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>channel_decim</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>channel_taps</value>
+    </param>
+    <param>
+      <key>center_freq</key>
+      <value>band_freq-freq+offset</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>sample_rate</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(321, 750)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Channel Spectrum</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>channel_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>65536</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>30</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(344, 511)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>20</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(310, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>symbol_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>3200</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(590, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>channel_decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(sample_rate/channel_rate)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(906, 12)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>deviation</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>4800</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(688, 14)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>demod_k</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>3*channel_rate/(2*math.pi*deviation)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(598, 857)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>channel_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>firdes.low_pass(10, sample_rate, passband/2.0, (channel_rate-passband)/2.0)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(325, 857)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>os.environ["HOME"]+"/.gnuradio/config.conf"</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(9, 133)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_band_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>930.5125e6</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>gr-pager</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>band_center</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>band_freq</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(228, 311)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_channel</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>25</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>gr-pager</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>channel</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>channel</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(387, 312)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>real</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>gr-pager</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>freq_offset</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(547, 312)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_config</key>
+    <param>
+      <key>id</key>
+      <value>saved_rx_gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>40</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>config_file</key>
+      <value>config_filename</value>
+    </param>
+    <param>
+      <key>section</key>
+      <value>gr-pager</value>
+    </param>
+    <param>
+      <key>option</key>
+      <value>rx_gain</value>
+    </param>
+    <param>
+      <key>writeback</key>
+      <value>rx_gain</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(706, 312)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_text_box</key>
+    <param>
+      <key>id</key>
+      <value>band_freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Band Freq.</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_band_freq</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(225, 121)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_static_text</key>
+    <param>
+      <key>id</key>
+      <value>freq_text</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Ch. Freq</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>formatter</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 2, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(801, 124)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>passband</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2*(deviation+symbol_rate)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(327, 930)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>channel_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>8*3200</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(792, 13)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>channel</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Channel</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_channel</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>120</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>119</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>int_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 1, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(376, 120)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>rx_gain</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Analog Gain</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_rx_gain</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>int_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 4, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(658, 122)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>offset</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Freq. Offset</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>saved_offset</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>-12.5e3</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>12.5e3</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 3, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(518, 118)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_quadrature_demod_cf</key>
+    <param>
+      <key>id</key>
+      <value>fm_demod</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>gain</key>
+      <value>demod_k</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(599, 774)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>baseband_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>16000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1019, 17)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>nchan_taps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>len(channel_taps)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(412, 931)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>ma_ntaps</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>int(channel_rate/symbol_rate)</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(850, 863)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>bb_interp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>5</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(938, 862)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_sink</key>
+    <param>
+      <key>id</key>
+      <value>virtual_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1100, 774)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blks2_rational_resampler_xxx</key>
+    <param>
+      <key>id</key>
+      <value>resampler</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>fff</value>
+    </param>
+    <param>
+      <key>decim</key>
+      <value>bb_decim</value>
+    </param>
+    <param>
+      <key>interp</key>
+      <value>bb_interp</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value>[1.0/ma_ntaps,]*ma_ntaps*bb_interp</value>
+    </param>
+    <param>
+      <key>fractional_bw</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(851, 750)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>bb_decim</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1027, 864)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Baseband</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>16e3</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>40.0/16e3</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>0, 0, 1, 1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(851, 586)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>virtual_source</key>
+    <param>
+      <key>id</key>
+      <value>virtual_source_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>stream_id</key>
+      <value>baseband</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(79, 1186)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_slicer_fb</key>
+    <param>
+      <key>id</key>
+      <value>pager_slicer_fb_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha</key>
+      <value>1e-6</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(304, 1186)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Slicer Output</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>baseband_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>40.0/baseband_rate</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value>1,0,1,1</value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>displays, 1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(75, 1044)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_char_to_float</key>
+    <param>
+      <key>id</key>
+      <value>gr_char_to_float_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(325, 1088)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>180</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_flex_sync</key>
+    <param>
+      <key>id</key>
+      <value>pager_flex_sync_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(529, 1139)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_flex_deinterleave</key>
+    <param>
+      <key>id</key>
+      <value>pager_flex_deinterleave_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(777, 1116)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_null_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_null_sink_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1042, 1116)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_flex_deinterleave</key>
+    <param>
+      <key>id</key>
+      <value>pager_flex_deinterleave_0_1_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(778, 1168)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_flex_deinterleave</key>
+    <param>
+      <key>id</key>
+      <value>pager_flex_deinterleave_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(776, 1225)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pager_flex_deinterleave</key>
+    <param>
+      <key>id</key>
+      <value>pager_flex_deinterleave_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(776, 1273)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_null_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_null_sink_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1042, 1168)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_null_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_null_sink_0_1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1041, 1225)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gr_null_sink</key>
+    <param>
+      <key>id</key>
+      <value>gr_null_sink_0_2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1040, 1273)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>gr_freq_xlating_fir_filter_xxx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_source</source_block_id>
+    <sink_block_id>gr_freq_xlating_fir_filter_xxx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>usrp_source</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_freq_xlating_fir_filter_xxx_0</source_block_id>
+    <sink_block_id>fm_demod</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>resampler</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>fm_demod</source_block_id>
+    <sink_block_id>resampler</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>resampler</source_block_id>
+    <sink_block_id>virtual_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_slicer_fb_0</source_block_id>
+    <sink_block_id>pager_flex_sync_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>virtual_source_0</source_block_id>
+    <sink_block_id>pager_slicer_fb_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_slicer_fb_0</source_block_id>
+    <sink_block_id>gr_char_to_float_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>gr_char_to_float_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_sync_0</source_block_id>
+    <sink_block_id>pager_flex_deinterleave_0_1_0</sink_block_id>
+    <source_key>1</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_sync_0</source_block_id>
+    <sink_block_id>pager_flex_deinterleave_0_1</sink_block_id>
+    <source_key>2</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_sync_0</source_block_id>
+    <sink_block_id>pager_flex_deinterleave_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_sync_0</source_block_id>
+    <sink_block_id>pager_flex_deinterleave_0_0</sink_block_id>
+    <source_key>3</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_deinterleave_0</source_block_id>
+    <sink_block_id>gr_null_sink_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_deinterleave_0_1_0</source_block_id>
+    <sink_block_id>gr_null_sink_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_deinterleave_0_1</source_block_id>
+    <sink_block_id>gr_null_sink_0_1</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>pager_flex_deinterleave_0_0</source_block_id>
+    <sink_block_id>gr_null_sink_0_2</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-pager/apps/usrp_rx_flex.py b/gr-pager/apps/usrp_rx_flex.py
new file mode 100755 (executable)
index 0000000..47bf5a3
--- /dev/null
@@ -0,0 +1,434 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: USRP FLEX Pager Receiver (Single Channel)
+# Generated: Thu Oct 29 11:03:16 2009
+##################################################
+
+from gnuradio import blks2
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import pager
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import fftsink2
+from gnuradio.wxgui import forms
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import usrp as grc_usrp
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import ConfigParser
+import os, math
+import wx
+
+class usrp_rx_flex(grc_wxgui.top_block_gui):
+
+       def __init__(self):
+               grc_wxgui.top_block_gui.__init__(self, title="USRP FLEX Pager Receiver (Single Channel)")
+
+               ##################################################
+               # Variables
+               ##################################################
+               self.config_filename = config_filename = os.environ["HOME"]+"/.gnuradio/config.conf"
+               self.symbol_rate = symbol_rate = 3200
+               self._saved_channel_config = ConfigParser.ConfigParser()
+               self._saved_channel_config.read(config_filename)
+               try: saved_channel = self._saved_channel_config.getint("gr-pager", "channel")
+               except: saved_channel = 25
+               self.saved_channel = saved_channel
+               self._saved_band_freq_config = ConfigParser.ConfigParser()
+               self._saved_band_freq_config.read(config_filename)
+               try: saved_band_freq = self._saved_band_freq_config.getfloat("gr-pager", "band_center")
+               except: saved_band_freq = 930.5125e6
+               self.saved_band_freq = saved_band_freq
+               self.deviation = deviation = 4800
+               self.decim = decim = 20
+               self.adc_rate = adc_rate = 64e6
+               self.sample_rate = sample_rate = adc_rate/decim
+               self.passband = passband = 2*(deviation+symbol_rate)
+               self.channel_rate = channel_rate = 8*3200
+               self.channel = channel = saved_channel
+               self.band_freq = band_freq = saved_band_freq
+               self._saved_rx_gain_config = ConfigParser.ConfigParser()
+               self._saved_rx_gain_config.read(config_filename)
+               try: saved_rx_gain = self._saved_rx_gain_config.getint("gr-pager", "rx_gain")
+               except: saved_rx_gain = 40
+               self.saved_rx_gain = saved_rx_gain
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(config_filename)
+               try: saved_offset = self._saved_offset_config.getfloat("gr-pager", "freq_offset")
+               except: saved_offset = 0
+               self.saved_offset = saved_offset
+               self.freq = freq = band_freq+(channel-61)*25e3
+               self.channel_taps = channel_taps = firdes.low_pass(10, sample_rate, passband/2.0, (channel_rate-passband)/2.0)
+               self.rx_gain = rx_gain = saved_rx_gain
+               self.offset = offset = saved_offset
+               self.nchan_taps = nchan_taps = len(channel_taps)
+               self.ma_ntaps = ma_ntaps = int(channel_rate/symbol_rate)
+               self.freq_text = freq_text = freq
+               self.demod_k = demod_k = 3*channel_rate/(2*math.pi*deviation)
+               self.channel_decim = channel_decim = int(sample_rate/channel_rate)
+               self.bb_interp = bb_interp = 5
+               self.bb_decim = bb_decim = 8
+               self.baseband_rate = baseband_rate = 16000
+
+               ##################################################
+               # Notebooks
+               ##################################################
+               self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "RX Spectrum")
+               self.displays.AddPage(grc_wxgui.Panel(self.displays), "Baseband")
+               self.GridAdd(self.displays, 1, 0, 1, 5)
+
+               ##################################################
+               # Controls
+               ##################################################
+               _channel_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._channel_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_channel_sizer,
+                       value=self.channel,
+                       callback=self.set_channel,
+                       label="Channel",
+                       converter=forms.int_converter(),
+                       proportion=0,
+               )
+               self._channel_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_channel_sizer,
+                       value=self.channel,
+                       callback=self.set_channel,
+                       minimum=1,
+                       maximum=120,
+                       num_steps=119,
+                       style=wx.SL_HORIZONTAL,
+                       cast=int,
+                       proportion=1,
+               )
+               self.GridAdd(_channel_sizer, 0, 1, 1, 1)
+               self._band_freq_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       value=self.band_freq,
+                       callback=self.set_band_freq,
+                       label="Band Freq.",
+                       converter=forms.float_converter(),
+               )
+               self.GridAdd(self._band_freq_text_box, 0, 0, 1, 1)
+               _rx_gain_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._rx_gain_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_rx_gain_sizer,
+                       value=self.rx_gain,
+                       callback=self.set_rx_gain,
+                       label="Analog Gain",
+                       converter=forms.int_converter(),
+                       proportion=0,
+               )
+               self._rx_gain_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_rx_gain_sizer,
+                       value=self.rx_gain,
+                       callback=self.set_rx_gain,
+                       minimum=0,
+                       maximum=100,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=int,
+                       proportion=1,
+               )
+               self.GridAdd(_rx_gain_sizer, 0, 4, 1, 1)
+               _offset_sizer = wx.BoxSizer(wx.VERTICAL)
+               self._offset_text_box = forms.text_box(
+                       parent=self.GetWin(),
+                       sizer=_offset_sizer,
+                       value=self.offset,
+                       callback=self.set_offset,
+                       label="Freq. Offset",
+                       converter=forms.float_converter(),
+                       proportion=0,
+               )
+               self._offset_slider = forms.slider(
+                       parent=self.GetWin(),
+                       sizer=_offset_sizer,
+                       value=self.offset,
+                       callback=self.set_offset,
+                       minimum=-12.5e3,
+                       maximum=12.5e3,
+                       num_steps=100,
+                       style=wx.SL_HORIZONTAL,
+                       cast=float,
+                       proportion=1,
+               )
+               self.GridAdd(_offset_sizer, 0, 3, 1, 1)
+               self._freq_text_static_text = forms.static_text(
+                       parent=self.GetWin(),
+                       value=self.freq_text,
+                       callback=self.set_freq_text,
+                       label="Ch. Freq",
+                       converter=forms.float_converter(),
+               )
+               self.GridAdd(self._freq_text_static_text, 0, 2, 1, 1)
+
+               ##################################################
+               # Blocks
+               ##################################################
+               self.fm_demod = gr.quadrature_demod_cf(demod_k)
+               self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc(channel_decim, (channel_taps), band_freq-freq+offset, sample_rate)
+               self.gr_null_sink_0 = gr.null_sink(gr.sizeof_int*1)
+               self.gr_null_sink_0_0 = gr.null_sink(gr.sizeof_int*1)
+               self.gr_null_sink_0_1 = gr.null_sink(gr.sizeof_int*1)
+               self.gr_null_sink_0_2 = gr.null_sink(gr.sizeof_int*1)
+               self.pager_flex_deinterleave_0 = pager.flex_deinterleave()
+               self.pager_flex_deinterleave_0_0 = pager.flex_deinterleave()
+               self.pager_flex_deinterleave_0_1 = pager.flex_deinterleave()
+               self.pager_flex_deinterleave_0_1_0 = pager.flex_deinterleave()
+               self.pager_flex_sync_0 = pager.flex_sync()
+               self.pager_slicer_fb_0 = pager.slicer_fb(1e-6)
+               self.resampler = blks2.rational_resampler_fff(
+                       interpolation=bb_interp,
+                       decimation=bb_decim,
+                       taps=([1.0/ma_ntaps,]*ma_ntaps*bb_interp),
+                       fractional_bw=None,
+               )
+               self.usrp_source = grc_usrp.simple_source_c(which=0, side="A", rx_ant="RXA")
+               self.usrp_source.set_decim_rate(decim)
+               self.usrp_source.set_frequency(band_freq, verbose=True)
+               self.usrp_source.set_gain(rx_gain)
+               self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=band_freq,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=0,
+                       ref_scale=65536,
+                       sample_rate=sample_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=False,
+                       avg_alpha=None,
+                       title="FLEX Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(0).GridAdd(self.wxgui_fftsink2_0.win, 0, 0, 1, 1)
+               self.wxgui_fftsink2_1 = fftsink2.fft_sink_c(
+                       self.displays.GetPage(0).GetWin(),
+                       baseband_freq=freq,
+                       y_per_div=10,
+                       y_divs=10,
+                       ref_level=0,
+                       ref_scale=65536,
+                       sample_rate=channel_rate,
+                       fft_size=1024,
+                       fft_rate=30,
+                       average=False,
+                       avg_alpha=None,
+                       title="Channel Spectrum",
+                       peak_hold=False,
+               )
+               self.displays.GetPage(0).GridAdd(self.wxgui_fftsink2_1.win, 1, 0, 1, 1)
+               self.wxgui_scopesink2_0_0 = scopesink2.scope_sink_f(
+                       self.displays.GetPage(1).GetWin(),
+                       title="Baseband",
+                       sample_rate=16e3,
+                       v_scale=1,
+                       v_offset=0,
+                       t_scale=40.0/16e3,
+                       ac_couple=False,
+                       xy_mode=False,
+                       num_inputs=1,
+               )
+               self.displays.GetPage(1).GridAdd(self.wxgui_scopesink2_0_0.win, 0, 0, 1, 1)
+
+               ##################################################
+               # Connections
+               ##################################################
+               self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_fftsink2_1, 0))
+               self.connect((self.usrp_source, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0))
+               self.connect((self.usrp_source, 0), (self.wxgui_fftsink2_0, 0))
+               self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.fm_demod, 0))
+               self.connect((self.resampler, 0), (self.wxgui_scopesink2_0_0, 0))
+               self.connect((self.fm_demod, 0), (self.resampler, 0))
+               self.connect((self.pager_slicer_fb_0, 0), (self.pager_flex_sync_0, 0))
+               self.connect((self.resampler, 0), (self.pager_slicer_fb_0, 0))
+               self.connect((self.pager_flex_sync_0, 1), (self.pager_flex_deinterleave_0_1_0, 0))
+               self.connect((self.pager_flex_sync_0, 2), (self.pager_flex_deinterleave_0_1, 0))
+               self.connect((self.pager_flex_sync_0, 0), (self.pager_flex_deinterleave_0, 0))
+               self.connect((self.pager_flex_sync_0, 3), (self.pager_flex_deinterleave_0_0, 0))
+               self.connect((self.pager_flex_deinterleave_0, 0), (self.gr_null_sink_0, 0))
+               self.connect((self.pager_flex_deinterleave_0_1_0, 0), (self.gr_null_sink_0_0, 0))
+               self.connect((self.pager_flex_deinterleave_0_1, 0), (self.gr_null_sink_0_1, 0))
+               self.connect((self.pager_flex_deinterleave_0_0, 0), (self.gr_null_sink_0_2, 0))
+
+       def set_config_filename(self, config_filename):
+               self.config_filename = config_filename
+               self._saved_band_freq_config = ConfigParser.ConfigParser()
+               self._saved_band_freq_config.read(self.config_filename)
+               if not self._saved_band_freq_config.has_section("gr-pager"):
+                       self._saved_band_freq_config.add_section("gr-pager")
+               self._saved_band_freq_config.set("gr-pager", "band_center", str(self.band_freq))
+               self._saved_band_freq_config.write(open(self.config_filename, 'w'))
+               self._saved_channel_config = ConfigParser.ConfigParser()
+               self._saved_channel_config.read(self.config_filename)
+               if not self._saved_channel_config.has_section("gr-pager"):
+                       self._saved_channel_config.add_section("gr-pager")
+               self._saved_channel_config.set("gr-pager", "channel", str(self.channel))
+               self._saved_channel_config.write(open(self.config_filename, 'w'))
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(self.config_filename)
+               if not self._saved_offset_config.has_section("gr-pager"):
+                       self._saved_offset_config.add_section("gr-pager")
+               self._saved_offset_config.set("gr-pager", "freq_offset", str(self.offset))
+               self._saved_offset_config.write(open(self.config_filename, 'w'))
+               self._saved_rx_gain_config = ConfigParser.ConfigParser()
+               self._saved_rx_gain_config.read(self.config_filename)
+               if not self._saved_rx_gain_config.has_section("gr-pager"):
+                       self._saved_rx_gain_config.add_section("gr-pager")
+               self._saved_rx_gain_config.set("gr-pager", "rx_gain", str(self.rx_gain))
+               self._saved_rx_gain_config.write(open(self.config_filename, 'w'))
+
+       def set_symbol_rate(self, symbol_rate):
+               self.symbol_rate = symbol_rate
+               self.set_passband(2*(self.deviation+self.symbol_rate))
+               self.set_ma_ntaps(int(self.channel_rate/self.symbol_rate))
+
+       def set_saved_channel(self, saved_channel):
+               self.saved_channel = saved_channel
+               self.set_channel(self.saved_channel)
+
+       def set_saved_band_freq(self, saved_band_freq):
+               self.saved_band_freq = saved_band_freq
+               self.set_band_freq(self.saved_band_freq)
+
+       def set_deviation(self, deviation):
+               self.deviation = deviation
+               self.set_demod_k(3*self.channel_rate/(2*math.pi*self.deviation))
+               self.set_passband(2*(self.deviation+self.symbol_rate))
+
+       def set_decim(self, decim):
+               self.decim = decim
+               self.set_sample_rate(self.adc_rate/self.decim)
+               self.usrp_source.set_decim_rate(self.decim)
+
+       def set_adc_rate(self, adc_rate):
+               self.adc_rate = adc_rate
+               self.set_sample_rate(self.adc_rate/self.decim)
+
+       def set_sample_rate(self, sample_rate):
+               self.sample_rate = sample_rate
+               self.wxgui_fftsink2_0.set_sample_rate(self.sample_rate)
+               self.set_channel_decim(int(self.sample_rate/self.channel_rate))
+               self.set_channel_taps(firdes.low_pass(10, self.sample_rate, self.passband/2.0, (self.channel_rate-self.passband)/2.0))
+
+       def set_passband(self, passband):
+               self.passband = passband
+               self.set_channel_taps(firdes.low_pass(10, self.sample_rate, self.passband/2.0, (self.channel_rate-self.passband)/2.0))
+
+       def set_channel_rate(self, channel_rate):
+               self.channel_rate = channel_rate
+               self.wxgui_fftsink2_1.set_sample_rate(self.channel_rate)
+               self.set_channel_decim(int(self.sample_rate/self.channel_rate))
+               self.set_demod_k(3*self.channel_rate/(2*math.pi*self.deviation))
+               self.set_channel_taps(firdes.low_pass(10, self.sample_rate, self.passband/2.0, (self.channel_rate-self.passband)/2.0))
+               self.set_ma_ntaps(int(self.channel_rate/self.symbol_rate))
+
+       def set_channel(self, channel):
+               self.channel = channel
+               self.set_freq(self.band_freq+(self.channel-61)*25e3)
+               self._saved_channel_config = ConfigParser.ConfigParser()
+               self._saved_channel_config.read(self.config_filename)
+               if not self._saved_channel_config.has_section("gr-pager"):
+                       self._saved_channel_config.add_section("gr-pager")
+               self._saved_channel_config.set("gr-pager", "channel", str(self.channel))
+               self._saved_channel_config.write(open(self.config_filename, 'w'))
+               self._channel_slider.set_value(self.channel)
+               self._channel_text_box.set_value(self.channel)
+
+       def set_band_freq(self, band_freq):
+               self.band_freq = band_freq
+               self.set_freq(self.band_freq+(self.channel-61)*25e3)
+               self.wxgui_fftsink2_0.set_baseband_freq(self.band_freq)
+               self.usrp_source.set_frequency(self.band_freq)
+               self.gr_freq_xlating_fir_filter_xxx_0.set_center_freq(self.band_freq-self.freq+self.offset)
+               self._saved_band_freq_config = ConfigParser.ConfigParser()
+               self._saved_band_freq_config.read(self.config_filename)
+               if not self._saved_band_freq_config.has_section("gr-pager"):
+                       self._saved_band_freq_config.add_section("gr-pager")
+               self._saved_band_freq_config.set("gr-pager", "band_center", str(self.band_freq))
+               self._saved_band_freq_config.write(open(self.config_filename, 'w'))
+               self._band_freq_text_box.set_value(self.band_freq)
+
+       def set_saved_rx_gain(self, saved_rx_gain):
+               self.saved_rx_gain = saved_rx_gain
+               self.set_rx_gain(self.saved_rx_gain)
+
+       def set_saved_offset(self, saved_offset):
+               self.saved_offset = saved_offset
+               self.set_offset(self.saved_offset)
+
+       def set_freq(self, freq):
+               self.freq = freq
+               self.gr_freq_xlating_fir_filter_xxx_0.set_center_freq(self.band_freq-self.freq+self.offset)
+               self.wxgui_fftsink2_1.set_baseband_freq(self.freq)
+               self.set_freq_text(self.freq)
+
+       def set_channel_taps(self, channel_taps):
+               self.channel_taps = channel_taps
+               self.gr_freq_xlating_fir_filter_xxx_0.set_taps((self.channel_taps))
+               self.set_nchan_taps(len(self.channel_taps))
+
+       def set_rx_gain(self, rx_gain):
+               self.rx_gain = rx_gain
+               self.usrp_source.set_gain(self.rx_gain)
+               self._saved_rx_gain_config = ConfigParser.ConfigParser()
+               self._saved_rx_gain_config.read(self.config_filename)
+               if not self._saved_rx_gain_config.has_section("gr-pager"):
+                       self._saved_rx_gain_config.add_section("gr-pager")
+               self._saved_rx_gain_config.set("gr-pager", "rx_gain", str(self.rx_gain))
+               self._saved_rx_gain_config.write(open(self.config_filename, 'w'))
+               self._rx_gain_slider.set_value(self.rx_gain)
+               self._rx_gain_text_box.set_value(self.rx_gain)
+
+       def set_offset(self, offset):
+               self.offset = offset
+               self.gr_freq_xlating_fir_filter_xxx_0.set_center_freq(self.band_freq-self.freq+self.offset)
+               self._saved_offset_config = ConfigParser.ConfigParser()
+               self._saved_offset_config.read(self.config_filename)
+               if not self._saved_offset_config.has_section("gr-pager"):
+                       self._saved_offset_config.add_section("gr-pager")
+               self._saved_offset_config.set("gr-pager", "freq_offset", str(self.offset))
+               self._saved_offset_config.write(open(self.config_filename, 'w'))
+               self._offset_slider.set_value(self.offset)
+               self._offset_text_box.set_value(self.offset)
+
+       def set_nchan_taps(self, nchan_taps):
+               self.nchan_taps = nchan_taps
+
+       def set_ma_ntaps(self, ma_ntaps):
+               self.ma_ntaps = ma_ntaps
+
+       def set_freq_text(self, freq_text):
+               self.freq_text = freq_text
+               self._freq_text_static_text.set_value(self.freq_text)
+
+       def set_demod_k(self, demod_k):
+               self.demod_k = demod_k
+
+       def set_channel_decim(self, channel_decim):
+               self.channel_decim = channel_decim
+
+       def set_bb_interp(self, bb_interp):
+               self.bb_interp = bb_interp
+
+       def set_bb_decim(self, bb_decim):
+               self.bb_decim = bb_decim
+
+       def set_baseband_rate(self, baseband_rate):
+               self.baseband_rate = baseband_rate
+
+if __name__ == '__main__':
+       parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+       (options, args) = parser.parse_args()
+       tb = usrp_rx_flex()
+       tb.Run(True)
+
diff --git a/gr-pager/gnuradio-pager.pc.in b/gr-pager/gnuradio-pager.pc.in
new file mode 100644 (file)
index 0000000..6fda2d2
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-comedi
+Description: GNU Radio blocks implementing a FLEX pager decoder
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-pager
+Cflags: -I${includedir}
diff --git a/gr-pager/grc/.gitignore b/gr-pager/grc/.gitignore
new file mode 100644 (file)
index 0000000..3dda729
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/gr-pager/grc/Makefile.am b/gr-pager/grc/Makefile.am
new file mode 100644 (file)
index 0000000..8c84f89
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+grcblocksdir = $(grc_blocksdir)
+
+dist_grcblocks_DATA = \
+       pager_slicer_fb.xml \
+       pager_flex_sync.xml \
+       pager_flex_deinterleave.xml
diff --git a/gr-pager/grc/pager_flex_deinterleave.xml b/gr-pager/grc/pager_flex_deinterleave.xml
new file mode 100644 (file)
index 0000000..14e5782
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## FLEX Pager Deinterleaver
+###################################################
+ -->
+<block>
+       <name>FLEX Deinterleave</name>
+       <key>pager_flex_deinterleave</key>
+       <category>Pager</category>
+       <import>from gnuradio import pager</import>
+       <make>pager.flex_deinterleave()</make>
+
+       <sink>
+               <name>bits</name>
+               <type>byte</type>
+       </sink>
+
+       <source>
+               <name>codes</name>
+               <type>int</type>
+       </source>
+</block>
diff --git a/gr-pager/grc/pager_flex_sync.xml b/gr-pager/grc/pager_flex_sync.xml
new file mode 100644 (file)
index 0000000..ec22321
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## FLEX Pager Synchronizer
+###################################################
+ -->
+<block>
+       <name>FLEX Synchronizer</name>
+       <key>pager_flex_sync</key>
+       <category>Pager</category>
+       <import>from gnuradio import pager</import>
+       <make>pager.flex_sync()</make>
+
+       <sink>
+               <name>dibits</name>
+               <type>byte</type>
+       </sink>
+
+       <source>
+               <name>A</name>
+               <type>byte</type>
+       </source>
+       <source>
+               <name>B</name>
+               <type>byte</type>
+       </source>
+       <source>
+               <name>C</name>
+               <type>byte</type>
+       </source>
+       <source>
+               <name>D</name>
+               <type>byte</type>
+       </source>
+
+</block>
diff --git a/gr-pager/grc/pager_slicer_fb.xml b/gr-pager/grc/pager_slicer_fb.xml
new file mode 100644 (file)
index 0000000..25642cb
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## FLEX Pager Slicer w/DC offset removal
+###################################################
+ -->
+<block>
+       <name>4-Level Slicer/DCR</name>
+       <key>pager_slicer_fb</key>
+       <category>Pager</category>
+       <import>from gnuradio import pager</import>
+       <make>pager.slicer_fb($alpha)</make>
+
+       <param>
+               <name>Alpha</name>
+               <key>alpha</key>
+               <value>1e-6</value>
+               <type>real</type>
+       </param>
+
+       <sink>
+               <name>bb</name>
+               <type>float</type>
+       </sink>
+
+       <source>
+               <name>dibits</name>
+               <type>byte</type>
+       </source>
+
+</block>
diff --git a/gr-pager/lib/.gitignore b/gr-pager/lib/.gitignore
new file mode 100644 (file)
index 0000000..1b6114c
--- /dev/null
@@ -0,0 +1,4 @@
+/.libs
+/.deps
+/Makefile
+/Makefile.in
diff --git a/gr-pager/lib/Makefile.am b/gr-pager/lib/Makefile.am
new file mode 100644 (file)
index 0000000..29c82eb
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS = \
+       pager_slicer_fb.h \
+       pager_flex_sync.h \
+       pager_flex_deinterleave.h \
+       pager_flex_parse.h \
+       pager_flex_frame.h \
+       pageri_bch3221.h \
+       pageri_flex_modes.h \
+       pageri_util.h
+
+lib_LTLIBRARIES = libgnuradio-pager.la
+
+libgnuradio_pager_la_SOURCES = \
+       pager_flex_frame.cc \
+       pager_slicer_fb.cc \
+       pager_flex_sync.cc \
+       pager_flex_deinterleave.cc \
+       pager_flex_parse.cc \
+       pageri_bch3221.cc \
+       pageri_flex_modes.cc \
+       pageri_util.cc
+
+libgnuradio_pager_la_LIBADD =  \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_pager_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
diff --git a/gr-pager/lib/Makefile.swig.gen b/gr-pager/lib/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..5cfbc66
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for pager_swig.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/pager_swig
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/pager_swig
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+pager_swig_pythondir_category ?= gnuradio/pager_swig
+pager_swig_pylibdir_category ?= $(pager_swig_pythondir_category)
+pager_swig_pythondir = $(pythondir)/$(pager_swig_pythondir_category)
+pager_swig_pylibdir = $(pyexecdir)/$(pager_swig_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+pager_swig_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/pager_swig-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += pager_swig.py pager_swig.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+pager_swig_swiginclude_HEADERS =               \
+       pager_swig.i                    \
+       $(pager_swig_swiginclude_headers)
+
+pager_swig_pylib_LTLIBRARIES =         \
+       _pager_swig.la
+
+_pager_swig_la_SOURCES =                       \
+       pager_swig.cc                   \
+       $(pager_swig_la_swig_sources)
+
+_pager_swig_la_LIBADD =                        \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(pager_swig_la_swig_libadd)
+
+_pager_swig_la_LDFLAGS =                       \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(pager_swig_la_swig_ldflags)
+
+_pager_swig_la_CXXFLAGS =                      \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(pager_swig_la_swig_cxxflags)
+
+pager_swig_python_PYTHON =                     \
+       pager_swig.py                   \
+       $(pager_swig_python)
+
+## Entry rule for running SWIG
+
+pager_swig.h pager_swig.py pager_swig.cc: pager_swig.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/pager_swig-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/pager_swig-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/pager_swig-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/pager_swig-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/pager_swig-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/pager_swig-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/pager_swig-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/pager_swig-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/pager_swig-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(pager_swig_swig_args) \
+               -MD -MF $(DEPDIR)/pager_swig.Std \
+               -module pager_swig -o pager_swig.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/pager_swig.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/pager_swig.Std \
+                       > $(DEPDIR)/pager_swig.Sd; \
+               $(RM) $(DEPDIR)/pager_swig.Std; \
+               $(MV) $(DEPDIR)/pager_swig.Sd $(DEPDIR)/pager_swig.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/pager_swig.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/pager_swig.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/pager_swig.Std $(DEPDIR)/pager_swig.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/pager_swig.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/pager_swig.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/pager_swig.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/pager_swig.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/pager_swig-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/pager_swig.d@am__quote@
+
diff --git a/gr-pager/lib/pager_flex_deinterleave.cc b/gr-pager/lib/pager_flex_deinterleave.cc
new file mode 100644 (file)
index 0000000..25ea22e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pager_flex_deinterleave.h>
+#include <pageri_bch3221.h>
+#include <pageri_util.h>
+#include <gr_io_signature.h>
+
+pager_flex_deinterleave_sptr pager_make_flex_deinterleave()
+{
+    return pager_flex_deinterleave_sptr(new pager_flex_deinterleave());
+}
+
+pager_flex_deinterleave::pager_flex_deinterleave() :
+    gr_sync_decimator("flex_deinterleave",
+    gr_make_io_signature(1, 1, sizeof(unsigned char)),
+    gr_make_io_signature(1, 1, sizeof(gr_int32)), 32)
+{
+    set_output_multiple(8); // One FLEX block at a time
+}
+
+int pager_flex_deinterleave::work(int noutput_items,
+    gr_vector_const_void_star &input_items,
+    gr_vector_void_star &output_items)
+{
+    const unsigned char *in = (const unsigned char *)input_items[0];
+    gr_int32 *out = (gr_int32 *)output_items[0];    
+
+    // FLEX codewords are interleaved in blocks of 256 bits or 8, 32 bit
+    // codes.  To deinterleave we parcel each incoming bit into the MSB
+    // of each codeword, then switch to MSB-1, etc.  This is done by shifting
+    // in the bits from the right on each codeword as the bits come in.
+    // When we are done we have a FLEX block of eight codewords, ready for
+    // conversion to data words.
+    //
+    // FLEX data words are recovered by reversing the bit order of the code
+    // word, masking off the (reversed) ECC, and inverting the remainder of 
+    // the bits (!).
+    //
+    // The data portion of a FLEX frame consists of 11 of these deinterleaved
+    // and converted blocks.
+    //
+    // set_output_multiple garauntees we have output space for at least
+    // eight data words, and 256 bits are supplied on input
+
+    int i, j;
+    for (i = 0; i < 32; i++) {
+       for (j = 0; j < 8; j++) {
+           d_codewords[j] <<= 1;
+           d_codewords[j]  |= *in++;
+       }
+    }
+
+    // Now convert code words into data words  
+    for (j = 0; j < 8; j++) {
+       gr_int32 codeword = d_codewords[j];
+       
+       // Apply BCH 32,21 error correction
+       // TODO: mark dataword when codeword fails ECC
+       pageri_bch3221(codeword);
+       
+       // Reverse bit order
+       codeword = pageri_reverse_bits32(codeword);
+
+       // Mask off ECC then invert lower 21 bits
+       codeword = (codeword & 0x001FFFFF)^0x001FFFFF;
+
+       *out++ = codeword;
+    }
+    
+    return j;
+}
diff --git a/gr-pager/lib/pager_flex_deinterleave.h b/gr-pager/lib/pager_flex_deinterleave.h
new file mode 100644 (file)
index 0000000..7211a71
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGER_FLEX_DEINTERLEAVE_H
+#define INCLUDED_PAGER_FLEX_DEINTERLEAVE_H
+
+#include <gr_sync_decimator.h>
+
+class pager_flex_deinterleave;
+typedef boost::shared_ptr<pager_flex_deinterleave> pager_flex_deinterleave_sptr;
+
+pager_flex_deinterleave_sptr pager_make_flex_deinterleave();
+
+/*!
+ * \brief flex deinterleave description
+ * \ingroup pager_blk
+ */
+
+class pager_flex_deinterleave : public gr_sync_decimator
+{
+private:
+    // Constructors
+    friend pager_flex_deinterleave_sptr pager_make_flex_deinterleave();
+    pager_flex_deinterleave();
+
+    // One FLEX block of deinterleaved data
+    gr_int32 d_codewords[8];
+   
+public:
+
+    int work(int noutput_items,
+             gr_vector_const_void_star &input_items, 
+             gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_PAGER_FLEX_DEINTERLEAVE_H */
diff --git a/gr-pager/lib/pager_flex_frame.cc b/gr-pager/lib/pager_flex_frame.cc
new file mode 100644 (file)
index 0000000..b707dbb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <pager_flex_frame.h>
+
+pager_flex_frame_sptr pager_make_flex_frame()
+{
+    return pager_flex_frame_sptr(new pager_flex_frame());
+}
+
+pager_flex_frame::pager_flex_frame()
+{
+}
+
+pager_flex_frame::~pager_flex_frame()
+{
+}
diff --git a/gr-pager/lib/pager_flex_frame.h b/gr-pager/lib/pager_flex_frame.h
new file mode 100644 (file)
index 0000000..1f4999e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+#ifndef INCLUDED_PAGER_FLEX_FRAME_H
+#define INCLUDED_PAGER_FLEX_FRAME_H
+
+#include <boost/shared_ptr.hpp>
+
+class pager_flex_frame;
+typedef boost::shared_ptr<pager_flex_frame> pager_flex_frame_sptr;
+
+/*!
+ * \brief public constructor for pager_flex_frame
+ */
+pager_flex_frame_sptr pager_make_flex_frame();
+
+/*!
+ * \brief flex_frame.
+ */
+class pager_flex_frame {
+    // Constructor is private to force use of shared_ptr
+    pager_flex_frame();
+    friend pager_flex_frame_sptr pager_make_flex_frame();
+
+public:
+    ~pager_flex_frame();
+};
+
+#endif /* INCLUDED_PAGER_FLEX_FRAME_H */
diff --git a/gr-pager/lib/pager_flex_parse.cc b/gr-pager/lib/pager_flex_parse.cc
new file mode 100644 (file)
index 0000000..0819294
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pager_flex_parse.h>
+#include <pageri_bch3221.h>
+#include <gr_io_signature.h>
+#include <ctype.h>
+#include <iostream>
+#include <iomanip>
+
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq)
+{
+    return pager_flex_parse_sptr(new pager_flex_parse(queue, freq));
+}
+
+pager_flex_parse::pager_flex_parse(gr_msg_queue_sptr queue, float freq) :
+    gr_sync_block("flex_parse",
+    gr_make_io_signature(1, 1, sizeof(gr_int32)),
+    gr_make_io_signature(0, 0, 0)),
+    d_queue(queue),
+    d_freq(freq)
+{
+    d_count = 0;
+}
+
+int pager_flex_parse::work(int noutput_items,
+    gr_vector_const_void_star &input_items,
+    gr_vector_void_star &output_items)
+{
+    const gr_int32 *in = (const gr_int32 *)input_items[0];
+    
+    int i = 0;
+    while (i < noutput_items) {
+       // Accumulate one whole frame's worth of data words (88 of them)
+       d_datawords[d_count] = *in++; i++;
+       if (++d_count == 88) {
+           parse_data();
+           d_count = 0;
+       }
+    }
+
+    return i;
+}
+
+/* FLEX data frames (that is, 88 data words per phase recovered after sync,
+   symbol decoding, dephasing, deinterleaving, error correction, and conversion
+   from codewords to data words) start with a block information word containing
+   indices of the page address field and page vector fields.
+*/
+
+void pager_flex_parse::parse_capcode(gr_int32 aw1, gr_int32 aw2)
+{
+    d_laddr = (aw1 < 0x008001L) ||
+              (aw1 > 0x1E0000L) ||
+             (aw1 > 0x1E7FFEL);        
+    
+    if (d_laddr)
+        d_capcode = aw1+((aw2^0x001FFFFF)<<15)+0x1F9000;  // Don't ask
+    else
+        d_capcode = aw1-0x8000;
+}
+
+void pager_flex_parse::parse_data()
+{
+    // Block information word is the first data word in frame
+    gr_int32 biw = d_datawords[0];
+
+    // Nothing to see here, please move along
+    if (biw == 0 || biw == 0x001FFFFF)
+       return;
+
+    // Vector start index is bits 15-10
+    // Address start address is bits 9-8, plus one for offset
+    int voffset = (biw >> 10) & 0x3f;
+    int aoffset = ((biw >> 8) & 0x03) + 1;
+    
+    //printf("BIW:%08X AW:%02i-%02i\n", biw, aoffset, voffset);
+
+    // Iterate through pages and dispatch to appropriate handler
+    for (int i = aoffset; i < voffset; i++) {
+       int j = voffset+i-aoffset;              // Start of vector field for address @ i
+
+       if (d_datawords[i] == 0x00000000 ||
+           d_datawords[i] == 0x001FFFFF)
+           continue;                           // Idle codewords, invalid address
+
+       parse_capcode(d_datawords[i], d_datawords[i+1]);
+        if (d_laddr)
+           i++;
+                           
+        if (d_capcode < 0)                     // Invalid address, skip
+          continue;        
+
+        // Parse vector information word for address @ offset 'i'
+       gr_int32 viw = d_datawords[j];
+       d_type = (page_type_t)((viw >> 4) & 0x00000007);
+       int mw1 = (viw >> 7) & 0x00000007F;
+       int len = (viw >> 14) & 0x0000007F;
+
+       if (is_numeric_page(d_type))
+            len &= 0x07;
+        int mw2 = mw1+len;
+           
+       if (mw1 == 0 && mw2 == 0)
+           continue;                           // Invalid VIW
+
+       if (is_tone_page(d_type))
+           mw1 = mw2 = 0;
+
+       if (mw1 > 87 || mw2 > 87)
+           continue;                           // Invalid offsets
+
+       d_payload.str("");
+       d_payload.setf(std::ios::showpoint);
+       d_payload << std::setprecision(6) << std::setw(7)
+                 << d_freq/1e6 << FIELD_DELIM 
+                 << std::setw(10) << d_capcode << FIELD_DELIM
+                 << flex_page_desc[d_type] << FIELD_DELIM;
+
+       if (is_alphanumeric_page(d_type))
+           parse_alphanumeric(mw1, mw2-1, j);
+       else if (is_numeric_page(d_type))
+           parse_numeric(mw1, mw2, j);
+       else if (is_tone_page(d_type))
+           parse_tone_only();
+       else
+           parse_unknown(mw1, mw2);
+
+       gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str()));
+       d_queue->handle(msg);
+    }
+}
+
+void pager_flex_parse::parse_alphanumeric(int mw1, int mw2, int j)
+{
+    int frag;
+    bool cont;
+
+    if (!d_laddr) {
+       frag = (d_datawords[mw1] >> 11) & 0x03;
+       cont = (d_datawords[mw1] >> 10) & 0x01;
+       mw1++;
+    }
+    else {
+       frag = (d_datawords[j+1] >> 11) & 0x03;
+       cont = (d_datawords[j+1] >> 10) & 0x01;
+       mw2--;
+    }    
+
+    //d_payload << frag << FIELD_DELIM;
+    //d_payload << cont << FIELD_DELIM;
+
+    for (int i = mw1; i <= mw2; i++) {
+       gr_int32 dw = d_datawords[i];
+       unsigned char ch;
+       
+       if (i > mw1 || frag != 0x03) {
+           ch = dw & 0x7F;
+           if (ch != 0x03)
+               d_payload << ch;
+       }
+       
+       ch = (dw >> 7) & 0x7F;
+       if (ch != 0x03) // Fill
+           d_payload << ch;
+               
+       ch = (dw >> 14) & 0x7F;
+       if (ch != 0x03) // Fill
+           d_payload << ch;
+    }
+}
+
+void pager_flex_parse::parse_numeric(int mw1, int mw2, int j)
+{
+    // Get first dataword from message field or from second
+    // vector word if long address
+    gr_int32 dw;
+    if (!d_laddr) {
+       dw = d_datawords[mw1];
+       mw1++;
+       mw2++;
+    }
+    else {
+       dw = d_datawords[j+1];
+    }
+
+    unsigned char digit = 0;
+    int count = 4;
+    if (d_type == FLEX_NUMBERED_NUMERIC)
+       count += 10;    // Skip 10 header bits for numbered numeric pages
+    else
+       count += 2;     // Otherwise skip 2
+    
+    for (int i = mw1; i <= mw2; i++) {
+       for (int k = 0; k < 21; k++) {
+           // Shift LSB from data word into digit
+           digit = (digit >> 1) & 0x0F;
+           if (dw & 0x01)
+               digit ^= 0x08;
+           dw >>= 1;
+           if (--count == 0) {
+               if (digit != 0x0C) // Fill
+                    d_payload << flex_bcd[digit];
+               count = 4;
+           }
+       }
+       
+       dw = d_datawords[i];
+    }
+}
+
+void pager_flex_parse::parse_tone_only()
+{
+}
+
+void pager_flex_parse::parse_unknown(int mw1, int mw2)
+{
+}
diff --git a/gr-pager/lib/pager_flex_parse.h b/gr-pager/lib/pager_flex_parse.h
new file mode 100644 (file)
index 0000000..0f7cfb3
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGER_FLEX_PARSE_H
+#define INCLUDED_PAGER_FLEX_PARSE_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+#include <pageri_flex_modes.h>
+#include <sstream>
+
+class pager_flex_parse;
+typedef boost::shared_ptr<pager_flex_parse> pager_flex_parse_sptr;
+
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
+
+#define FIELD_DELIM ((unsigned char)128)
+
+/*!
+ * \brief flex parse description
+ * \ingroup pager_blk
+ */
+class pager_flex_parse : public gr_sync_block
+{
+private:
+    // Constructors
+    friend pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
+    pager_flex_parse(gr_msg_queue_sptr queue, float freq);
+
+    std::ostringstream d_payload;
+    gr_msg_queue_sptr d_queue;           // Destination for decoded pages
+
+    int d_count;                         // Count of received codewords
+    gr_int32 d_datawords[88];             // 11 blocks of 8 32-bit words
+
+    page_type_t d_type;                          // Current page type
+    int d_capcode;                       // Current page destination address
+    bool d_laddr;                        // Current page has long address
+    float d_freq;                        // Channel frequency
+    
+    void parse_data();                   // Handle a frame's worth of data
+    void parse_capcode(gr_int32 aw1, gr_int32 aw2);     
+    void parse_alphanumeric(int mw1, int mw2, int j);
+    void parse_numeric(int mw1, int mw2, int j);
+    void parse_tone_only();
+    void parse_unknown(int mw1, int mw2);
+    
+public:
+    int work(int noutput_items,
+        gr_vector_const_void_star &input_items, 
+        gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_PAGER_FLEX_PARSE_H */
diff --git a/gr-pager/lib/pager_flex_sync.cc b/gr-pager/lib/pager_flex_sync.cc
new file mode 100644 (file)
index 0000000..6bcee8e
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pager_flex_sync.h>
+#include <pageri_flex_modes.h>
+#include <pageri_bch3221.h>
+#include <pageri_util.h>
+#include <gr_io_signature.h>
+#include <gr_count_bits.h>
+#include <cstdio>
+
+pager_flex_sync_sptr pager_make_flex_sync()
+{
+    return pager_flex_sync_sptr(new pager_flex_sync());
+}
+
+// FLEX sync block takes input from sliced baseband stream [0-3] at specified 
+// channel rate.  Symbol timing is established based on receiving one of the
+// defined FLEX protocol synchronization words.  The block outputs one FLEX frame
+// worth of bits on each output phase for the data portion of the frame. Unused phases
+// get all zeros, which are considered idle code words.
+
+pager_flex_sync::pager_flex_sync() :
+    gr_block ("flex_sync",
+    gr_make_io_signature (1, 1, sizeof(unsigned char)),
+    gr_make_io_signature (4, 4, sizeof(unsigned char))),
+    d_sync(10) // Fixed at 10 samples per baud (@ 1600 baud)
+{
+    enter_idle();
+}
+
+void pager_flex_sync::forecast(int noutput_items, gr_vector_int &inputs_required)
+{
+    // samples per bit X number of outputs needed
+    int items = noutput_items*d_spb;
+    for (unsigned int i = 0; i < inputs_required.size(); i++)
+        inputs_required[i] = items;
+}
+
+int pager_flex_sync::index_avg(int start, int end)
+{
+    // modulo average
+    if (start < end)
+        return (end + start)/2;
+    else
+        return ((end + start)/2 + d_spb/2) % d_spb;
+}
+
+bool pager_flex_sync::test_sync(unsigned char sym)
+{
+    // 64-bit FLEX sync code:
+    // AAAA:BBBBBBBB:CCCC
+    //
+    // Where BBBBBBBB is always 0xA6C6AAAA
+    // and AAAA^CCCC is 0xFFFF
+    // 
+    // Specific values of AAAA determine what bps and encoding the
+    // packet is beyond the frame information word
+    //
+    // First we match on the marker field with a hamming distance < 4
+    // Then we match on the outer code with a hamming distance < 4
+
+    d_sync[d_index] = (d_sync[d_index] << 1) | (sym < 2);
+    gr_int64 val = d_sync[d_index];
+    gr_int32 marker = ((val & 0x0000FFFFFFFF0000ULL)) >> 16;
+
+    if (gr_count_bits32(marker^FLEX_SYNC_MARKER) < 4) {
+        gr_int32 code = ((val & 0xFFFF000000000000ULL) >> 32) |
+                         (val & 0x000000000000FFFFULL);
+
+        for (int i = 0; i < num_flex_modes; i++) {
+            if (gr_count_bits32(code^flex_modes[i].sync) < 4) {
+                d_mode = i;
+                return true;
+            }
+        }
+
+        // Marker received but doesn't match known codes
+        // All codes have high word inverted to low word
+        unsigned short high = (code & 0xFFFF0000) >> 16;
+        unsigned short low = code & 0x0000FFFF;
+        unsigned short syn = high^low;
+        if (syn == 0xFFFF)
+            fprintf(stderr, "Unknown sync code detected: %08X\n", code);
+    }
+
+    return false;
+}
+
+void pager_flex_sync::enter_idle()
+{
+    d_state = ST_IDLE;
+    d_index = 0;
+    d_start = 0;
+    d_center = 0;
+    d_end = 0;
+    d_count = 0;
+    d_mode = 0;
+    d_baudrate = 1600;
+    d_levels = 2;
+    d_spb = 16000/d_baudrate;
+    d_bit_a = 0;
+    d_bit_b = 0;
+    d_bit_c = 0;
+    d_bit_d = 0;
+    d_hibit = false;
+    fflush(stdout);
+}
+
+void pager_flex_sync::enter_syncing()
+{
+    d_start = d_index;
+    d_state = ST_SYNCING;
+}
+
+void pager_flex_sync::enter_sync1()
+{
+    d_state = ST_SYNC1;
+    d_end = d_index;
+    d_center = index_avg(d_start, d_end); // Center of goodness
+    d_count = 0;
+}
+
+void pager_flex_sync::enter_sync2()
+{
+    d_state = ST_SYNC2;
+    d_count = 0;
+    d_baudrate = flex_modes[d_mode].baud;
+    d_levels = flex_modes[d_mode].levels;
+    d_spb = 16000/d_baudrate;
+
+    if (d_baudrate == 3200) {
+        // Oversampling buffer just got halved
+        d_center = d_center/2;
+
+       // We're here at the center of a 1600 baud bit
+       // So this hack puts the index and bit counter
+       // in the right place for 3200 bps.
+        d_index = d_index/2-d_spb/2;         
+       d_count = -1;                
+    }                               
+}
+
+void pager_flex_sync::enter_data()
+{
+    d_state = ST_DATA;
+    d_count = 0;
+}
+
+void pager_flex_sync::parse_fiw()
+{
+    // Nothing is done with these now, but these will end up getting
+    // passed as metadata when mblocks are available
+
+    // Bits 31-28 are frame number related, but unknown function
+    // This might be a checksum
+    d_unknown2 = pageri_reverse_bits8((d_fiw >> 24) & 0xF0);
+       
+    // Cycle is bits 27-24, reversed
+    d_cycle = pageri_reverse_bits8((d_fiw >> 20) & 0xF0);
+
+    // Frame is bits 23-17, reversed
+    d_frame = pageri_reverse_bits8((d_fiw >> 16) & 0xFE);
+
+    // Bits 16-11 are some sort of marker, usually identical across
+    // many frames but sometimes changes between frames or modes
+    d_unknown1 = (d_fiw >> 11) & 0x3F;
+
+    //printf("CYC:%02i FRM:%03i\n", d_cycle, d_frame);
+}
+
+int pager_flex_sync::output_symbol(unsigned char sym)
+{
+    // Here is where we output a 1 or 0 on each phase according
+    // to current FLEX mode and symbol value.  Unassigned phases
+    // are zero from the enter_idle() initialization.
+    //
+    // FLEX can transmit the data portion of the frame at either
+    // 1600 bps or 3200 bps, and can use either two- or four-level
+    // FSK encoding.
+    //
+    // At 1600 bps, 2-level, a single "phase" is transmitted with bit
+    // value '0' using level '3' and bit value '1' using level '0'.
+    //
+    // At 1600 bps, 4-level, a second "phase" is transmitted, and the 
+    // di-bits are encoded with a gray code:
+    //
+    // Symbol  Phase 1  Phase 2
+    // ------   -------  -------
+    //   0         1        1
+    //   1         1        0
+    //   2         0        0
+    //   3         0        1
+    //
+    // At 1600 bps, 4-level, these are called PHASE A and PHASE B.
+    //
+    // At 3200 bps, the same 1 or 2 bit encoding occurs, except that
+    // additionally two streams are interleaved on alternating symbols.
+    // Thus, PHASE A (and PHASE B if 4-level) are decoded on one symbol,
+    // then PHASE C (and PHASE D if 4-level) are decoded on the next.
+    
+    int bits = 0;
+    
+    if (d_baudrate == 1600) {
+       d_bit_a = (sym < 2);
+       if (d_levels == 4)
+           d_bit_b = (sym == 0) || (sym == 3);
+
+       *d_phase_a++ = d_bit_a;
+       *d_phase_b++ = d_bit_b;
+       *d_phase_c++ = d_bit_c;
+       *d_phase_d++ = d_bit_d;
+       bits++;
+    }
+    else {
+       if (!d_hibit) {
+           d_bit_a = (sym < 2);
+           if (d_levels == 4)
+               d_bit_b = (sym == 0) || (sym == 3);
+           d_hibit = true;
+       }
+       else {
+           d_bit_c = (sym < 2);
+           if (d_levels == 4)
+               d_bit_d = (sym == 0) || (sym == 3);
+           d_hibit = false;
+
+           *d_phase_a++ = d_bit_a;
+           *d_phase_b++ = d_bit_b;
+           *d_phase_c++ = d_bit_c;
+           *d_phase_d++ = d_bit_d;
+           bits++;
+       }
+    }
+
+    return bits;
+}
+
+int pager_flex_sync::general_work(int noutput_items,
+    gr_vector_int &ninput_items,
+    gr_vector_const_void_star &input_items,
+    gr_vector_void_star &output_items)
+{
+    const unsigned char *in = (const unsigned char *)input_items[0];
+    d_phase_a = (unsigned char *)output_items[0];
+    d_phase_b = (unsigned char *)output_items[1];
+    d_phase_c = (unsigned char *)output_items[2];
+    d_phase_d = (unsigned char *)output_items[3];
+
+    int i = 0, j = 0;
+    int ninputs = ninput_items[0];
+
+    while (i < ninputs && j < noutput_items) {
+        unsigned char sym = *in++; i++;
+        d_index = ++d_index % d_spb;
+    
+        switch (d_state) {
+            case ST_IDLE:
+               // Continually compare the received symbol stream
+               // against the known FLEX sync words.
+                if (test_sync(sym))
+                    enter_syncing();
+                break;
+    
+            case ST_SYNCING:
+               // Wait until we stop seeing sync, then calculate
+               // the center of the bit period (d_center)
+                if (!test_sync(sym))
+                    enter_sync1();
+                break;
+    
+            case ST_SYNC1:
+               // Skip 16 bits of dotting, then accumulate 32 bits
+               // of Frame Information Word.
+                if (d_index == d_center) {
+                   d_fiw = (d_fiw << 1) | (sym > 1);
+                    if (++d_count == 48) {
+                       // FIW is accumulated, call BCH to error correct it
+                       pageri_bch3221(d_fiw);
+                       parse_fiw();
+                        enter_sync2();  
+                   }
+                }
+                break;
+    
+            case ST_SYNC2:
+               // This part and the remainder of the frame are transmitted
+               // at either 1600 bps or 3200 bps based on the received
+               // FLEX sync word. The second SYNC header is 25ms of idle bits
+               // at either speed.
+                if (d_index == d_center) {
+                    // Skip 25 ms = 40 bits @ 1600 bps, 80 @ 3200 bps
+                    if (++d_count == d_baudrate/40)
+                        enter_data();
+                }
+                break;
+    
+            case ST_DATA:
+               // The data portion of the frame is 1760 ms long at either 
+               // baudrate.  This is 2816 bits @ 1600 bps and 5632 bits @ 3200 bps.
+               // The output_symbol() routine decodes and doles out the bits
+               // to each of the four transmitted phases of FLEX interleaved codes.
+                if (d_index == d_center) {
+                   j += output_symbol(sym);                
+                    if (++d_count == d_baudrate*1760/1000)
+                        enter_idle();
+               }
+                break;
+
+            default:
+                assert(0); // memory corruption of d_state if ever gets here
+                break;
+        }
+    }
+
+    consume_each(i);
+    return j;
+}
diff --git a/gr-pager/lib/pager_flex_sync.h b/gr-pager/lib/pager_flex_sync.h
new file mode 100644 (file)
index 0000000..b401bf5
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGER_FLEX_SYNC_H
+#define INCLUDED_PAGER_FLEX_SYNC_H
+
+#include <gr_block.h>
+
+class pager_flex_sync;
+typedef boost::shared_ptr<pager_flex_sync> pager_flex_sync_sptr;
+typedef std::vector<gr_int64> gr_int64_vector;
+
+pager_flex_sync_sptr pager_make_flex_sync();
+
+/*!
+ * \brief flex sync description
+ * \ingroup pager_blk
+ */
+
+class pager_flex_sync : public gr_block
+{
+private:
+    // Constructors
+    friend pager_flex_sync_sptr pager_make_flex_sync();
+    pager_flex_sync();
+   
+    // State machine transitions
+    void enter_idle();
+    void enter_syncing();
+    void enter_sync1();
+    void enter_sync2();
+    void enter_data();
+
+    int index_avg(int start, int end);
+    bool test_sync(unsigned char sym);
+    void parse_fiw();
+    int output_symbol(unsigned char sym);    
+    
+    // Simple state machine
+    enum state_t { ST_IDLE, ST_SYNCING, ST_SYNC1, ST_SYNC2, ST_DATA };
+    state_t d_state;     
+
+    int d_index;    // Index into current baud
+    int d_start;    // Start of good sync 
+    int d_center;   // Center of bit
+    int d_end;      // End of good sync
+    int d_count;    // Bit counter
+
+    int d_mode;     // Current packet mode
+    int d_baudrate; // Current decoding baud rate
+    int d_levels;   // Current decoding levels
+    int d_spb;      // Current samples per baud
+    bool d_hibit;   // Alternating bit indicator for 3200 bps
+    
+    gr_int32 d_fiw; // Frame information word
+    int d_frame;    // Current FLEX frame
+    int d_cycle;    // Current FLEX cycle
+    int d_unknown1;
+    int d_unknown2;
+
+    unsigned char d_bit_a;
+    unsigned char d_bit_b;
+    unsigned char d_bit_c;
+    unsigned char d_bit_d;
+    
+    unsigned char *d_phase_a;  
+    unsigned char *d_phase_b;
+    unsigned char *d_phase_c;
+    unsigned char *d_phase_d;
+    
+    gr_int64_vector d_sync; // Trial synchronizers
+
+public:
+    void forecast(int noutput_items, gr_vector_int &inputs_required);
+
+    int general_work(int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items, 
+                     gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_PAGER_FLEX_SYNC_H */
diff --git a/gr-pager/lib/pager_slicer_fb.cc b/gr-pager/lib/pager_slicer_fb.cc
new file mode 100644 (file)
index 0000000..d419db7
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pager_slicer_fb.h>
+#include <gr_io_signature.h>
+
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha)
+{
+    return pager_slicer_fb_sptr(new pager_slicer_fb(alpha));
+}
+
+pager_slicer_fb::pager_slicer_fb(float alpha) :
+    gr_sync_block ("slicer_fb",
+                   gr_make_io_signature (1, 1, sizeof(float)),
+                   gr_make_io_signature (1, 1, sizeof(unsigned char)))
+{
+    d_alpha = alpha;
+    d_beta = 1.0-alpha;
+    d_avg = 0.0;
+}
+
+// Tracks average, minimum, and peak, then converts input into one of:
+//
+// [0, 1, 2, 3]
+unsigned char pager_slicer_fb::slice(float sample)
+{
+    unsigned char decision;
+
+    // Update DC level and remove
+    d_avg = d_avg*d_beta+sample*d_alpha;
+    sample -= d_avg;
+
+    if (sample > 0) {
+        if (sample > 2.0)          
+            decision = 3;
+        else
+            decision = 2;
+    }
+    else {
+        if (sample < -2.0)
+            decision = 0;
+        else
+            decision = 1;
+    }
+
+    return decision;
+}
+
+int pager_slicer_fb::work(int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                                 gr_vector_void_star &output_items)
+{
+    float *iptr = (float *) input_items[0];
+    unsigned char *optr = (unsigned char *) output_items[0];
+
+    int size = noutput_items;
+
+    for (int i = 0; i < size; i++)
+        *optr++ = slice(*iptr++);
+
+    return noutput_items;
+}
diff --git a/gr-pager/lib/pager_slicer_fb.h b/gr-pager/lib/pager_slicer_fb.h
new file mode 100644 (file)
index 0000000..75eea3c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGER_SLICER_FB_H
+#define INCLUDED_PAGER_SLICER_FB_H
+
+#include <gr_sync_block.h>
+
+class pager_slicer_fb;
+typedef boost::shared_ptr<pager_slicer_fb> pager_slicer_fb_sptr;
+
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
+
+/*!
+ * \brief slicer description
+ * \ingroup pager_blk
+ */
+class pager_slicer_fb : public gr_sync_block
+{
+private:
+    friend pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
+    pager_slicer_fb(float alpha);
+
+    unsigned char slice(float sample);
+
+    float d_alpha;      // DC removal time constant
+    float d_beta;      // 1.0-d_alpha
+    float d_avg;        // Average value for DC offset subtraction
+
+public:
+    int work (int noutput_items,
+              gr_vector_const_void_star &input_items, 
+              gr_vector_void_star &output_items);
+
+    float dc_offset() const { return d_avg; }
+};
+
+#endif /* INCLUDED_PAGER_SLICER_FB_H */
diff --git a/gr-pager/lib/pageri_bch3221.cc b/gr-pager/lib/pageri_bch3221.cc
new file mode 100644 (file)
index 0000000..984ed4d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pageri_bch3221.h>
+
+// Corrects supplied data word according to BCH3221 encoding and
+// returns the number of errors detected/corrected.
+//
+// Not implemented yet
+
+int pageri_bch3221(gr_int32 &data)
+{
+    return 0;
+}
diff --git a/gr-pager/lib/pageri_bch3221.h b/gr-pager/lib/pageri_bch3221.h
new file mode 100644 (file)
index 0000000..9dd2be8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGERI_BCH3221_H
+#define INCLUDED_PAGERI_BCH3221_H
+
+#include <gr_types.h>
+
+// Perform BCH (32,21) error correction on supplied data
+// Return number of errors found/corrected (0, 1, or 2)
+int pageri_bch3221(gr_int32 &data);
+
+#endif /* INCLUDED_PAGERI_BCH3221_H */
diff --git a/gr-pager/lib/pageri_flex_modes.cc b/gr-pager/lib/pageri_flex_modes.cc
new file mode 100644 (file)
index 0000000..4553e0b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#include "pageri_flex_modes.h"
+
+const flex_mode_t flex_modes[] = 
+{
+    { 0x870C78F3, 1600, 2 },
+    { 0xB0684F97, 1600, 4 },
+//  { 0xUNKNOWN,  3200, 2 },
+    { 0xDEA0215F, 3200, 4 },
+    { 0x4C7CB383, 3200, 4 }
+};
+
+const int num_flex_modes = sizeof(flex_modes)/sizeof(flex_modes[0]);
+
+unsigned char flex_bcd[17] = "0123456789 U -][";
+
+const char *flex_page_desc[] =
+{
+    "ENC",
+    "UNK",
+    "TON",
+    "NUM",
+    "SPN",
+    "ALN",
+    "BIN",
+    "NNM"
+};
+
+int find_flex_mode(gr_int32 sync_code)
+{
+    for (int i = 0; i < num_flex_modes; i++)
+       if (flex_modes[i].sync == sync_code)
+           return i;
+       
+    // Not found
+    return -1;
+}
diff --git a/gr-pager/lib/pageri_flex_modes.h b/gr-pager/lib/pageri_flex_modes.h
new file mode 100644 (file)
index 0000000..bc53c12
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGERI_FLEX_MODES_H
+#define INCLUDED_PAGERI_FLEX_MODES_H
+
+#include <gr_types.h>
+
+#define FLEX_SYNC_MARKER 0xA6C6AAAA
+
+typedef struct flex_mode
+{
+    gr_int32     sync;          // Outer synchronization code
+    unsigned int baud;          // Baudrate of SYNC2 and DATA
+    unsigned int levels;        // FSK encoding of SYNC2 and DATA
+}
+flex_mode_t;
+
+extern const flex_mode_t flex_modes[];
+extern const char *flex_page_desc[];
+extern const int num_flex_modes;
+int find_flex_mode(gr_int32 sync_code);
+extern unsigned char flex_bcd[];
+
+typedef enum {
+    FLEX_SECURE,
+    FLEX_UNKNOWN,
+    FLEX_TONE,
+    FLEX_STANDARD_NUMERIC,
+    FLEX_SPECIAL_NUMERIC,
+    FLEX_ALPHANUMERIC,
+    FLEX_BINARY,
+    FLEX_NUMBERED_NUMERIC,
+    NUM_FLEX_PAGE_TYPES
+}
+page_type_t;
+
+inline bool is_alphanumeric_page(page_type_t type)
+{
+    return (type == FLEX_ALPHANUMERIC ||
+           type == FLEX_SECURE);
+}
+
+inline bool is_numeric_page(page_type_t type)
+{
+    return (type == FLEX_STANDARD_NUMERIC ||
+            type == FLEX_SPECIAL_NUMERIC  ||
+            type == FLEX_NUMBERED_NUMERIC);
+}
+
+inline bool is_tone_page(page_type_t type)
+{
+    return (type == FLEX_TONE);
+}
+
+#endif // INCLUDED_PAGERI_FLEX_MODES_H
diff --git a/gr-pager/lib/pageri_util.cc b/gr-pager/lib/pageri_util.cc
new file mode 100644 (file)
index 0000000..bdd0957
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pageri_util.h>
+
+unsigned char pageri_reverse_bits8(unsigned char val)
+{
+    // This method was attributed to Rich Schroeppel in the Programming 
+    // Hacks section of Beeler, M., Gosper, R. W., and Schroeppel, R. 
+    // HAKMEM. MIT AI Memo 239, Feb. 29, 1972.
+    //
+    // Reverses 8 bits in 5 machine operations with 64 bit arch
+    return (val * 0x0202020202ULL & 0x010884422010ULL) % 1023;
+}
+
+gr_int32 pageri_reverse_bits32(gr_int32 val)
+{
+    gr_int32 out = 0x00000000;
+    out |= (pageri_reverse_bits8((val >> 24) & 0x000000FF)      );
+    out |= (pageri_reverse_bits8((val >> 16) & 0x000000FF) <<  8);
+    out |= (pageri_reverse_bits8((val >>  8) & 0x000000FF) << 16);
+    out |= (pageri_reverse_bits8((val      ) & 0x000000FF) << 24);
+    return out;
+}
diff --git a/gr-pager/lib/pageri_util.h b/gr-pager/lib/pageri_util.h
new file mode 100644 (file)
index 0000000..78ae7aa
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_PAGERI_UTIL_H
+#define INCLUDED_PAGERI_UTIL_H
+
+#include <gr_types.h>
+
+unsigned char pageri_reverse_bits8(unsigned char val);
+gr_int32 pageri_reverse_bits32(gr_int32 val);
+
+#endif /* INCLUDED_PAGERI_UTIL_H */
diff --git a/gr-pager/python/.gitignore b/gr-pager/python/.gitignore
new file mode 100644 (file)
index 0000000..604b402
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/run_tests
diff --git a/gr-pager/python/Makefile.am b/gr-pager/python/Makefile.am
new file mode 100644 (file)
index 0000000..f80375c
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+if PYTHON
+pagerdir = $(grpythondir)/pager
+
+noinst_PYTHON = \
+       qa_pager.py
+
+pager_PYTHON = \
+       __init__.py \
+       pager_utils.py \
+       flex_demod.py
+
+TESTS = run_tests
+
+EXTRA_DIST = run_tests.in
+
+endif
diff --git a/gr-pager/python/__init__.py b/gr-pager/python/__init__.py
new file mode 100644 (file)
index 0000000..664b799
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# 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.
+# 
+
+# The presence of this file turns this directory into a Python package
+
+from pager_swig import *
+from flex_demod import flex_demod
+from pager_utils import *
diff --git a/gr-pager/python/flex_demod.py b/gr-pager/python/flex_demod.py
new file mode 100644 (file)
index 0000000..b79c1ad
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# 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, optfir, blks2
+from math import pi
+import pager_swig
+
+class flex_demod(gr.hier_block2):
+    """
+    FLEX pager protocol demodulation block.
+
+    This block demodulates a band-limited, complex down-converted baseband 
+    channel into FLEX protocol frames.
+
+    """
+
+    def __init__(self, queue, freq=0.0, verbose=False, log=False):
+       gr.hier_block2.__init__(self, "flex_demod",
+                               gr.io_signature(1, 1, gr.sizeof_gr_complex),
+                               gr.io_signature(0,0,0))
+
+        k = 25000/(2*pi*1600)        # 4800 Hz max deviation
+        quad = gr.quadrature_demod_cf(k)
+       self.connect(self, quad)
+       
+        rsamp = blks2.rational_resampler_fff(16, 25)
+        self.slicer = pager_swig.slicer_fb(5e-6) # DC removal averaging filter constant
+       self.sync = pager_swig.flex_sync()
+
+        self.connect(quad, rsamp, self.slicer, self.sync)
+
+       for i in range(4):
+           self.connect((self.sync, i), pager_swig.flex_deinterleave(), pager_swig.flex_parse(queue, freq))
+
+       if log:
+           suffix = '_'+ "%3.3f" % (freq/1e6,) + '.dat'
+           quad_sink = gr.file_sink(gr.sizeof_float, 'quad'+suffix)
+           rsamp_sink = gr.file_sink(gr.sizeof_float, 'rsamp'+suffix)
+           slicer_sink = gr.file_sink(gr.sizeof_char, 'slicer'+suffix)
+           self.connect(rsamp, rsamp_sink)
+           self.connect(quad, quad_sink)
+           self.connect(self.slicer, slicer_sink)
+
+    def dc_offset(self):
+       return self.slicer.dc_offset()
+                   
\ No newline at end of file
diff --git a/gr-pager/python/pager_utils.py b/gr-pager/python/pager_utils.py
new file mode 100644 (file)
index 0000000..72aac68
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr
+import gnuradio.gr.gr_threading as _threading
+from string import split, join, printable
+import time
+
+def make_trans_table():
+    table = 256 * ['.']
+    for i in range(256):
+        if (i < 32):
+            table[i] = '.'
+        else:
+            table[i] = chr(i)
+    return ''.join(table)
+
+_trans_table = make_trans_table()
+
+def make_printable(s):
+    return s.translate(_trans_table)
+
+
+class queue_runner(_threading.Thread):
+    def __init__(self, msgq):
+        _threading.Thread.__init__(self)
+        self.msgq = msgq
+        self.done = False
+        self.start()
+
+    def run(self):
+        while 1:
+            msg = self.msgq.delete_head() # Blocking read
+            if msg.type() != 0:
+                break
+            
+            page = join(split(msg.to_string(), chr(128)), '|')
+            s = make_printable(page)
+            print msg.type(), s
+                
+    def end(self):
+        self.msgq.insert_tail(gr.message(1))
+        self.done = True
diff --git a/gr-pager/python/qa_pager.py b/gr-pager/python/qa_pager.py
new file mode 100755 (executable)
index 0000000..5bf72b5
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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, gr_unittest
+import pager_swig
+
+class qa_pgr(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-pager/python/run_tests.in b/gr-pager/python/run_tests.in
new file mode 100644 (file)
index 0000000..6bb0c39
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# 1st parameter is absolute path to component source directory
+# 2nd parameter is absolute path to component build directory
+# 3rd parameter is path to Python QA directory
+
+@top_builddir@/run_tests.sh \
+    @abs_top_srcdir@/gr-pager \
+    @abs_top_builddir@/gr-pager \
+    @srcdir@
diff --git a/gr-pager/swig/.gitignore b/gr-pager/swig/.gitignore
new file mode 100644 (file)
index 0000000..6df28c3
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/pager_swig.py
+/pager_swig.cc
+/*.pyc
+/run_tests
diff --git a/gr-pager/swig/Makefile.am b/gr-pager/swig/Makefile.am
new file mode 100644 (file)
index 0000000..9e1a452
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = \
+       $(STD_DEFINES_AND_INCLUDES) \
+       $(PYTHON_CPPFLAGS) \
+       $(WITH_INCLUDES) \
+       -I$(top_srcdir)/gr-pager/lib
+
+##############################
+# SWIG interface and library
+TOP_SWIG_IFILES = \
+       pager_swig.i
+
+# Install so that they end up available as:
+#   import gnuradio.pager
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio/pager
+pager_swig_pythondir_category = \
+       gnuradio/pager
+
+# additional libraries for linking with the SWIG-generated library
+pager_swig_la_swig_libadd = \
+       $(abs_top_builddir)/gr-pager/lib/libgnuradio-pager.la
+
+# additional SWIG files to be installed
+pager_swig_swiginclude_headers = \
+       pager_flex_deinterleave.i \
+       pager_flex_frame.i \
+       pager_flex_parse.i \
+       pager_flex_sync.i \
+       pager_slicer_fb.i
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
diff --git a/gr-pager/swig/Makefile.swig.gen b/gr-pager/swig/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..5cfbc66
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 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.
+# 
+
+# Makefile.swig.gen for pager_swig.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/pager_swig
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/pager_swig
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+pager_swig_pythondir_category ?= gnuradio/pager_swig
+pager_swig_pylibdir_category ?= $(pager_swig_pythondir_category)
+pager_swig_pythondir = $(pythondir)/$(pager_swig_pythondir_category)
+pager_swig_pylibdir = $(pyexecdir)/$(pager_swig_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+pager_swig_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen").  By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies.  Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing.  For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/pager_swig-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += pager_swig.py pager_swig.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+pager_swig_swiginclude_HEADERS =               \
+       pager_swig.i                    \
+       $(pager_swig_swiginclude_headers)
+
+pager_swig_pylib_LTLIBRARIES =         \
+       _pager_swig.la
+
+_pager_swig_la_SOURCES =                       \
+       pager_swig.cc                   \
+       $(pager_swig_la_swig_sources)
+
+_pager_swig_la_LIBADD =                        \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(pager_swig_la_swig_libadd)
+
+_pager_swig_la_LDFLAGS =                       \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(pager_swig_la_swig_ldflags)
+
+_pager_swig_la_CXXFLAGS =                      \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(pager_swig_la_swig_cxxflags)
+
+pager_swig_python_PYTHON =                     \
+       pager_swig.py                   \
+       $(pager_swig_python)
+
+## Entry rule for running SWIG
+
+pager_swig.h pager_swig.py pager_swig.cc: pager_swig.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/pager_swig-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/pager_swig-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/pager_swig-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/pager_swig-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/pager_swig-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/pager_swig-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/pager_swig-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/pager_swig-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/pager_swig-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(pager_swig_swig_args) \
+               -MD -MF $(DEPDIR)/pager_swig.Std \
+               -module pager_swig -o pager_swig.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/pager_swig.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/pager_swig.Std \
+                       > $(DEPDIR)/pager_swig.Sd; \
+               $(RM) $(DEPDIR)/pager_swig.Std; \
+               $(MV) $(DEPDIR)/pager_swig.Sd $(DEPDIR)/pager_swig.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/pager_swig.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/pager_swig.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/pager_swig.Std $(DEPDIR)/pager_swig.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/pager_swig.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/pager_swig.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/pager_swig.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/pager_swig.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/pager_swig-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/pager_swig.d@am__quote@
+
diff --git a/gr-pager/swig/pager_flex_deinterleave.i b/gr-pager/swig/pager_flex_deinterleave.i
new file mode 100644 (file)
index 0000000..f34951a
--- /dev/null
@@ -0,0 +1,11 @@
+GR_SWIG_BLOCK_MAGIC(pager,flex_deinterleave);
+
+pager_flex_deinterleave_sptr pager_make_flex_deinterleave();
+
+class pager_flex_deinterleave : public gr_sync_decimator
+{
+private:
+    pager_flex_deinterleave();
+
+public:
+};
diff --git a/gr-pager/swig/pager_flex_frame.i b/gr-pager/swig/pager_flex_frame.i
new file mode 100644 (file)
index 0000000..d754f5f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+class pager_flex_frame;
+typedef boost::shared_ptr<pager_flex_frame> pager_flex_frame_sptr;
+%template(pager_flex_frame_sptr) boost::shared_ptr<pager_flex_frame>;
+
+%rename(flex_frame) pager_make_flex_frame;
+pager_flex_frame_sptr pager_make_flex_frame();
+
+/*!
+ * \brief flex_frame.
+ */
+class pager_flex_frame {
+    pager_flex_frame();
+
+public:
+};
+
diff --git a/gr-pager/swig/pager_flex_parse.i b/gr-pager/swig/pager_flex_parse.i
new file mode 100644 (file)
index 0000000..21e0245
--- /dev/null
@@ -0,0 +1,11 @@
+GR_SWIG_BLOCK_MAGIC(pager,flex_parse);
+
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue, float freq);
+
+class pager_flex_parse : public gr_block
+{
+private:
+    pager_flex_parse(gr_msg_queue_sptr queue, float freq);
+
+public:
+};
diff --git a/gr-pager/swig/pager_flex_sync.i b/gr-pager/swig/pager_flex_sync.i
new file mode 100644 (file)
index 0000000..49823db
--- /dev/null
@@ -0,0 +1,11 @@
+GR_SWIG_BLOCK_MAGIC(pager,flex_sync);
+
+pager_flex_sync_sptr pager_make_flex_sync();
+
+class pager_flex_sync : public gr_block
+{
+private:
+    pager_flex_sync();
+
+public:
+};
diff --git a/gr-pager/swig/pager_slicer_fb.i b/gr-pager/swig/pager_slicer_fb.i
new file mode 100644 (file)
index 0000000..4ffb5b7
--- /dev/null
@@ -0,0 +1,12 @@
+GR_SWIG_BLOCK_MAGIC(pager,slicer_fb);
+
+pager_slicer_fb_sptr pager_make_slicer_fb(float alpha);
+
+class pager_slicer_fb : public gr_sync_block
+{
+private:
+    pager_slicer_fb(float alpha);
+
+public:
+    float dc_offset() const { return d_avg; }
+};
diff --git a/gr-pager/swig/pager_swig.i b/gr-pager/swig/pager_swig.i
new file mode 100644 (file)
index 0000000..66d6de7
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005,2006,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"
+
+%{
+#include "pager_flex_frame.h"
+#include "pager_slicer_fb.h"
+#include "pager_flex_sync.h"
+#include "pager_flex_deinterleave.h"
+#include "pager_flex_parse.h"
+%}
+
+%include "pager_flex_frame.i"
+%include "pager_slicer_fb.i"
+%include "pager_flex_sync.i"
+%include "pager_flex_deinterleave.i"
+%include "pager_flex_parse.i"
diff --git a/gr-qtgui/.gitignore b/gr-qtgui/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-qtgui/src/.gitignore b/gr-qtgui/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 7230d6096df2d9d7cb473171f1db6ec6920afa11..52b06fbc454f0090d050a49faff1f553260a35bd 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-qtgui/src/lib/.gitignore b/gr-qtgui/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..58c8081
--- /dev/null
@@ -0,0 +1,13 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/qtgui.cc
+/qtgui.py
+/WaterfallDisplayPlot_moc.cc
+/Waterfall3DDisplayPlot_moc.cc
+/TimeDomainDisplayPlot_moc.cc
+/spectrumdisplayform_moc.cc
+/spectrumdisplayform_ui.h
+/FrequencyDisplayPlot_moc.cc
+/ConstellationDisplayPlot_moc.cc
index 10355f9f0bf4eccd12510ddb2e2f87d01e5d14b3..e8e6288f5bf7c6924296e1473ba59ccd624a4c2c 100644 (file)
@@ -26,20 +26,21 @@ public:
 protected:
   virtual QwtText trackerText( const QwtDoublePoint& p ) const 
   {
-    QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4));
-
+    QwtText t(QString("(%1, %2)").arg(p.x(), 0, 'f', 4).
+             arg(p.y(), 0, 'f', 4));
     return t;
   }
 };
 
-ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(parent){
+ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent)
+  : QwtPlot(parent)
+{
   timespec_reset(&_lastReplot);
 
   resize(parent->width(), parent->height());
 
-  _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
-
   _numPoints = 1024;
+  _penSize = 5;
   _realDataPoints = new double[_numPoints];
   _imagDataPoints = new double[_numPoints];
 
@@ -55,19 +56,17 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(pare
   canvas()->setPalette(palette);  
 
   setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
-  //setAxisScale(QwtPlot::xBottom, -1.0, 1.0);
   set_xaxis(-2.0, 2.0);
   setAxisTitle(QwtPlot::xBottom, "In-phase");
 
   setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
-  //setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
   set_yaxis(-2.0, 2.0);
   setAxisTitle(QwtPlot::yLeft, "Quadrature");
 
   // Automatically deleted when parent is deleted
   _plot_curve = new QwtPlotCurve("Constellation Points");
   _plot_curve->attach(this);
-  _plot_curve->setPen(QPen(Qt::blue, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+  _plot_curve->setPen(QPen(Qt::blue, _penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
   _plot_curve->setStyle(QwtPlotCurve::Dots);
   _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
 
@@ -106,7 +105,8 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(pare
          this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
 }
 
-ConstellationDisplayPlot::~ConstellationDisplayPlot(){
+ConstellationDisplayPlot::~ConstellationDisplayPlot()
+{
   delete[] _realDataPoints;
   delete[] _imagDataPoints;
 
@@ -114,6 +114,16 @@ ConstellationDisplayPlot::~ConstellationDisplayPlot(){
   // _zoomer and _panner deleted when parent deleted
 }
 
+void 
+ConstellationDisplayPlot::set_pen_size(int size)
+{
+  if(size > 0 && size < 30){
+    _penSize = size;
+    _plot_curve->setPen(QPen(Qt::blue, _penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+  }
+}
+
+
 void
 ConstellationDisplayPlot::set_xaxis(double min, double max)
 {
@@ -134,24 +144,25 @@ ConstellationDisplayPlot::set_axis(double xmin, double xmax,
   set_yaxis(ymin, ymax);
 }
 
-void ConstellationDisplayPlot::replot(){
-
-  const timespec startTime = get_highres_clock();
-  
+void ConstellationDisplayPlot::replot()
+{
   QwtPlot::replot();
-
-  double differenceTime = (diff_timespec(get_highres_clock(), startTime));
-
-  differenceTime *= 99.0;
-  // Require at least a 10% duty cycle
-  if(differenceTime > (1.0/10.0)){
-    _displayIntervalTime = differenceTime;
-  }
 }
 
-void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
-  if(numDataPoints > 0){
+void
+ConstellationDisplayPlot::resizeSlot( QSize *s )
+{
+  resize(s->width(), s->height());
+}
 
+void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints,
+                                          const double* imagDataPoints,
+                                          const int64_t numDataPoints,
+                                          const double timeInterval)
+{
+  if((numDataPoints > 0) && 
+     (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
+    
     if(numDataPoints != _numPoints){
       _numPoints = numDataPoints;
 
@@ -162,22 +173,19 @@ void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, const d
       
       _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
     }
+
     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
 
-  }
-
-  // Allow at least a 50% duty cycle
-  if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
-    // Only replot the screen if it is visible
-    if(isVisible()){
-      replot();
-    }
+    replot();
+    
     _lastReplot = get_highres_clock();
   }
 }
 
-void ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
+void
+ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on)
+{
   plotItem->setVisible(!on);
 }
 
index 612cd2b3933c4d463e7ca282a950115a04abd83d..a441a8bfe81168a2f1e60c6c9e52b7eebedb8f0a 100644 (file)
 #include <highResTimeFunctions.h>
 #include <qwt_symbol.h>
 
-class ConstellationDisplayPlot:public QwtPlot{
+class ConstellationDisplayPlot : public QwtPlot
+{
   Q_OBJECT
 
 public:
   ConstellationDisplayPlot(QWidget*);
   virtual ~ConstellationDisplayPlot();
 
-  void PlotNewData(const double* realDataPoints, const double* imagDataPoints, 
-                  const int64_t numDataPoints);
+  void PlotNewData(const double* realDataPoints, 
+                  const double* imagDataPoints, 
+                  const int64_t numDataPoints,
+                  const double timeInterval);
     
   virtual void replot();
 
@@ -30,6 +33,10 @@ public:
   void set_yaxis(double min, double max);
   void set_axis(double xmin, double xmax,
                double ymin, double ymax);
+  void set_pen_size(int size);
+
+public slots:
+  void resizeSlot( QSize *s );
 
 protected slots:
   void LegendEntryChecked(QwtPlotItem *plotItem, bool on);
@@ -48,8 +55,7 @@ private:
   timespec _lastReplot;
 
   int64_t _numPoints;
-
-  double _displayIntervalTime;
+  int64_t _penSize;
 };
 
 #endif /* CONSTELLATION_DISPLAY_PLOT_HPP */
index 154c8d2341a62fea73fae9e9ed6f7fc87e076b07..f2cde322efd1569f2ccaf8d1a5c46bee6fdebb5a 100644 (file)
@@ -73,13 +73,22 @@ public:
     updateDisplay();
   }
 
+  void SetUnitType(const std::string &type)
+  {
+    _unitType = type;
+  }
+
 protected:
   virtual QwtText trackerText( const QwtDoublePoint& p ) const 
   {
-    QwtText t(QString("%1 %2, %3 dB").arg(p.x(), 0, 'f', GetFrequencyPrecision()).arg( (GetFrequencyPrecision() == 0) ? "Hz" : "kHz").arg(p.y(), 0, 'f', 2));
-
+    QwtText t(QString("%1 %2, %3 dB").
+             arg(p.x(), 0, 'f', GetFrequencyPrecision()).
+             arg(_unitType.c_str()).arg(p.y(), 0, 'f', 2));
     return t;
   }
+
+private:
+  std::string _unitType;
 };
 
 FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
@@ -91,9 +100,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
   timespec_reset(&_lastReplot);
 
   resize(parent->width(), parent->height());
-
-  _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
-
+  
   _useCenterFrequencyFlag = false;
 
   _numPoints = 1024;
@@ -113,9 +120,8 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
   palette.setColor(canvas()->backgroundRole(), QColor("white"));
   canvas()->setPalette(palette);  
 
-  setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0));
-  setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
   setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
+  setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0));
 
   _minYAxis = -120;
   _maxYAxis = 10;
@@ -148,7 +154,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
 
   _upper_intensity_marker = new QwtPlotMarker();
   _upper_intensity_marker->setLineStyle(QwtPlotMarker::HLine);
-  _upper_intensity_marker->setLinePen(QPen(Qt::green));
+  _upper_intensity_marker->setLinePen(QPen(Qt::green, 0, Qt::DotLine));
   _upper_intensity_marker->attach(this);
 
   memset(_dataPoints, 0x0, _numPoints*sizeof(double));
@@ -159,9 +165,6 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
     _maxFFTPoints[number] = -280.0;
   }
 
-  _resetXAxisPoints();
-
-
   // set up peak marker
   QwtSymbol symbol;
 
@@ -211,6 +214,9 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
   const QColor c(Qt::darkRed);
   _zoomer->setRubberBandPen(c);
   _zoomer->setTrackerPen(c);
+
+  // Do this after the zoomer has been built
+  _resetXAxisPoints();
 }
 
 FrequencyDisplayPlot::~FrequencyDisplayPlot()
@@ -256,20 +262,26 @@ FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq,
     stopFreq = (stopFreq + centerFreq);
   }
 
-  _startFrequency = startFreq;
-  _stopFrequency = stopFreq;
-  _resetXAxisPoints();
-
-  setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
-  setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(2));
-  setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str()));
-  ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(2);
-
-  // Load up the new base zoom settings
-  _zoomer->setZoomBase();
-  
-  // Zooms back to the base and clears any other zoom levels
-  _zoomer->zoom(0);
+  bool reset = false;
+  if((startFreq != _startFrequency) || (stopFreq != _stopFrequency))
+    reset = true;
+
+  if(stopFreq > startFreq) {
+    _startFrequency = startFreq;
+    _stopFrequency = stopFreq;
+    
+    if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){
+      double display_units = ceil(log10(units)/2.0);
+      setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(display_units));
+      setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str()));
+
+      if(reset)
+       _resetXAxisPoints();
+      
+      ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(display_units);
+      ((FreqDisplayZoomer*)_zoomer)->SetUnitType(strunits);
+    }
+  }
 }
 
 
@@ -288,8 +300,6 @@ FrequencyDisplayPlot::GetStopFrequency() const
 void
 FrequencyDisplayPlot::replot()
 {
-  const timespec startTime = get_highres_clock();
-
   _markerNoiseFloorAmplitude->setYValue(_noiseFloorAmplitude);
   
   // Make sure to take into account the start frequency
@@ -302,26 +312,26 @@ FrequencyDisplayPlot::replot()
   _markerPeakAmplitude->setYValue(_peakAmplitude);
   
   QwtPlot::replot();
-
-  double differenceTime = (diff_timespec(get_highres_clock(), startTime));
-
-  differenceTime *= 99.0;
-  // Require at least a 10% duty cycle
-  if(differenceTime > (1.0/10.0)){
-    _displayIntervalTime = differenceTime;
-  }
+}
+void
+FrequencyDisplayPlot::resizeSlot( QSize *s )
+{
+  resize(s->width(), s->height());
 }
 
 void
 FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints,
                                  const double noiseFloorAmplitude, const double peakFrequency,
-                                 const double peakAmplitude)
+                                 const double peakAmplitude, const double timeInterval)
 {
-  if(numDataPoints > 0){
-
-    if(numDataPoints != _numPoints){
+  // Only update plot if there is data and if the time interval has elapsed
+  if((numDataPoints > 0) && 
+     (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
+    
+    if(numDataPoints != _numPoints) {
       _numPoints = numDataPoints;
-
+      
       delete[] _dataPoints;
       delete[] _minFFTPoints;
       delete[] _maxFFTPoints;
@@ -334,11 +344,12 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat
       _fft_plot_curve->setRawData(_xAxisPoints, _dataPoints, _numPoints);
       _min_fft_plot_curve->setRawData(_xAxisPoints, _minFFTPoints, _numPoints);
       _max_fft_plot_curve->setRawData(_xAxisPoints, _maxFFTPoints, _numPoints);
-
+      
       _resetXAxisPoints();
       ClearMaxData();
       ClearMinData();
     }
+    
     memcpy(_dataPoints, dataPoints, numDataPoints*sizeof(double));
     for(int64_t point = 0; point < numDataPoints; point++){
       if(dataPoints[point] < _minFFTPoints[point]){
@@ -353,14 +364,10 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat
     _peakFrequency = peakFrequency;
     _peakAmplitude = peakAmplitude;
 
-  }
+    SetUpperIntensityLevel(_peakAmplitude);
 
-  // Allow at least a 50% duty cycle
-  if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
-    // Only replot the screen if it is visible
-    if(isVisible()){
-      replot();
-    }
+    replot();
+    
     _lastReplot = get_highres_clock();
   }
 }
@@ -369,7 +376,7 @@ void
 FrequencyDisplayPlot::ClearMaxData()
 {
   for(int64_t number = 0; number < _numPoints; number++){
-    _maxFFTPoints[number] = _maxYAxis;
+    _maxFFTPoints[number] = _minYAxis;
   }
 }
 
@@ -377,7 +384,7 @@ void
 FrequencyDisplayPlot::ClearMinData()
 {
   for(int64_t number = 0; number < _numPoints; number++){
-    _minFFTPoints[number] = _minYAxis;
+    _minFFTPoints[number] = _maxYAxis;
   }
 }
 
@@ -402,6 +409,17 @@ FrequencyDisplayPlot::_resetXAxisPoints()
     _xAxisPoints[loc] = freqValue;
     freqValue += fft_bin_size;
   }
+
+  setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
+
+  // Set up zoomer base for maximum unzoom x-axis
+  // and reset to maximum unzoom level
+  QwtDoubleRect zbase = _zoomer->zoomBase();
+  zbase.setLeft(_startFrequency);
+  zbase.setRight(_stopFrequency);
+  _zoomer->zoom(zbase);
+  _zoomer->setZoomBase(zbase);
+  _zoomer->zoom(0);
 }
 
 void
index 5e828296211df72016aa3294285f988d7eb29075..c78e1667ea55ec99e929fedd8bd8af8d9cdc4a38 100644 (file)
@@ -30,7 +30,7 @@ public:
 
   void PlotNewData(const double* dataPoints, const int64_t numDataPoints,
                   const double noiseFloorAmplitude, const double peakFrequency,
-                  const double peakAmplitude);
+                  const double peakAmplitude, const double timeInterval);
   
   void ClearMaxData();
   void ClearMinData();
@@ -43,12 +43,14 @@ public:
   void set_yaxis(double min, double max);
 
 public slots:
+  void resizeSlot( QSize *e );
   void SetLowerIntensityLevel(const double);
   void SetUpperIntensityLevel(const double);
 
 protected:
 
 private:
+
   void _resetXAxisPoints();
   
   double _startFrequency;
@@ -84,8 +86,6 @@ private:
   timespec _lastReplot;
 
   bool _useCenterFrequencyFlag;
-
-  double _displayIntervalTime;
 };
 
 #endif /* FREQUENCY_DISPLAY_PLOT_HPP */
index 6543a71ce9400ecd7f21ad729d2ae673820d12ff..26b97d1d45f0f27426c6ed3bb74e6ec2ccff0a04 100644 (file)
@@ -26,7 +26,6 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \
 
 # Only include these files in the build if qtgui passes configure checks
 # This is mostly to help make distcheck pass
-if BUILD_QT
 QMAKE_SOURCES =                                \
        spectrumdisplayform_moc.cc              \
        FrequencyDisplayPlot_moc.cc             \
@@ -35,10 +34,11 @@ QMAKE_SOURCES =                             \
        Waterfall3DDisplayPlot_moc.cc           \
        ConstellationDisplayPlot_moc.cc         \
        spectrumdisplayform_ui.h
-endif
 
 EXTRA_DIST = spectrumdisplayform.ui
 
+BUILT_SOURCES = $(QMAKE_SOURCES)
+
 # Build the normal library for C++ apps to link against
 lib_LTLIBRARIES = libgnuradio-qtgui.la
 
@@ -75,28 +75,21 @@ grinclude_HEADERS =                 \
        qtgui_sink_c.h                  \
        qtgui_sink_f.h
 
-if BUILD_QT
 %_moc.cc : %.h
-       $(QT_MOC_EXEC) -DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB $< -o $@
+       $(QT_MOC_EXEC) -DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -p $(srcdir) $< -o $@
 
 %_ui.h : %.ui
        $(QT_UIC_EXEC) $< -o $@
-else
-%_moc.cc : %.h
-       touch $@
-
-%_ui.h : %.ui
-       touch $@
-endif
 
 # magic flags
-libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
 libgnuradio_qtgui_la_LIBADD =          \
        $(GNURADIO_CORE_LA)     \
        -lstdc++                \
        $(QT_LIBS)
 
+if PYTHON
 ##############################
 # SWIG interface and library
 
@@ -117,9 +110,10 @@ qtgui_la_swig_libadd =             \
 include $(top_srcdir)/Makefile.swig
 
 # add some of the variables generated inside the Makefile.swig.gen
-BUILT_SOURCES =                \
-       $(QMAKE_SOURCES)        \
+BUILT_SOURCES +=               \
        $(swig_built_sources)
+endif
 
-# Do not distribute the output of SWIG
-no_dist_files = $(swig_built_sources)
+# Do not distribute built sources, they may contain generated paths
+# which are invalid on other systems
+no_dist_files = $(BUILT_SOURCES)
index f196d7c5f28d03bdb7a951578f8eeec06172d653..8c1b3670300f16bc5ec230a11898c8482b07bcc2 100644 (file)
@@ -30,7 +30,6 @@ SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize,
   _startFrequency = newStartFrequency;
   _stopFrequency = newStopFrequency;
 
-#warning SPECIFY THIS LATER...
   _windowType = 5;
 
   timespec_reset(&_lastGUIUpdateTime);
@@ -112,7 +111,7 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent,
   timespec_reset(&_lastGUIUpdateTime);
 
   // Draw Blank Display
-  UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, 1.0, get_highres_clock(), true);
+  UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, get_highres_clock(), true);
 
   // Set up the initial frequency axis settings
   SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
@@ -221,7 +220,6 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
                               const uint64_t realTimeDomainDataSize,
                               const float* complexTimeDomainData,
                               const uint64_t complexTimeDomainDataSize,
-                              const double timePerFFT,
                               const timespec timestamp,
                               const bool lastOfMultipleFFTUpdateFlag)
 {
@@ -278,7 +276,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
   const timespec currentTime = get_highres_clock();
   const timespec lastUpdateGUITime = GetLastGUIUpdateTime();
 
-  if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) &&
+  if((diff_timespec(currentTime, lastUpdateGUITime) > (4*_updateTime)) &&
      (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)) {
     // Do not update the display if too much data is pending to be displayed
     _droppedEntriesCount++;
@@ -291,7 +289,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
                                            _realTimeDomainPoints,
                                            _imagTimeDomainPoints,
                                            timeDomainBufferSize,
-                                           timePerFFT, timestamp,
+                                           timestamp,
                                            repeatDataFlag,
                                            lastOfMultipleFFTUpdateFlag,
                                            currentTime,
@@ -449,10 +447,24 @@ SpectrumGUIClass::SetConstellationAxis(double xmin, double xmax,
 
 }
 
+void
+SpectrumGUIClass::SetConstellationPenSize(int size){
+  _spectrumDisplayForm->SetConstellationPenSize(size);
+}
+
+
 void
 SpectrumGUIClass::SetFrequencyAxis(double min, double max)
 {
   _spectrumDisplayForm->SetFrequencyAxis(min, max);
 }
 
+void
+SpectrumGUIClass::SetUpdateTime(double t)
+{
+  _updateTime = t;
+  _spectrumDisplayForm->SetUpdateTime(_updateTime);
+}
+
+
 #endif /* SPECTRUM_GUI_CLASS_CPP */
index 9a55271dfbe13dd7ef1460688aaf62b0f8f4205f..17d3a54c1af48601a368a72b6e03de89a03f5fa7 100644 (file)
@@ -47,7 +47,7 @@ public:
   void UpdateWindow(const bool, const std::complex<float>*,
                    const uint64_t, const float*,
                    const uint64_t, const float*,
-                   const uint64_t, const double,
+                   const uint64_t,
                    const timespec, const bool);
 
   float GetPowerValue()const;
@@ -76,8 +76,11 @@ public:
   void SetTimeDomainAxis(double min, double max);
   void SetConstellationAxis(double xmin, double xmax,
                            double ymin, double ymax);
+  void SetConstellationPenSize(int size);
   void SetFrequencyAxis(double min, double max);
 
+  void SetUpdateTime(double t);
+
 protected:
 
 private:
@@ -97,6 +100,7 @@ private:
   unsigned int _pendingGUIUpdateEventsCount;
   int _droppedEntriesCount;
   bool _fftBuffersCreatedFlag;
+  double _updateTime;
 
   SpectrumDisplayForm* _spectrumDisplayForm;
 
index 42f827d9ab920a414d5f3adb288713678bf37861..c299f83a4a09ea56f6b39df9d039cbfc1c96c794 100644 (file)
@@ -7,10 +7,37 @@
 #include <qwt_legend.h>
 
 
-class TimeDomainDisplayZoomer: public QwtPlotZoomer
+class TimePrecisionClass
 {
 public:
-  TimeDomainDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas)
+  TimePrecisionClass(const int timePrecision)
+  {
+    _timePrecision = timePrecision;
+  }
+
+  virtual ~TimePrecisionClass()
+  {
+  }
+
+  virtual unsigned int GetTimePrecision() const
+  {
+    return _timePrecision;
+  }
+
+  virtual void SetTimePrecision(const unsigned int newPrecision)
+  {
+    _timePrecision = newPrecision;
+  }
+protected:
+  unsigned int _timePrecision;
+};
+
+
+class TimeDomainDisplayZoomer: public QwtPlotZoomer, public TimePrecisionClass
+{
+public:
+  TimeDomainDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int timePrecision)
+    : QwtPlotZoomer(canvas),TimePrecisionClass(timePrecision)
   {
     setTrackerMode(QwtPicker::AlwaysOn);
   }
@@ -23,27 +50,38 @@ public:
     updateDisplay();
   }
 
+  void SetUnitType(const std::string &type)
+  {
+    _unitType = type;
+  }
+
 protected:
   virtual QwtText trackerText( const QwtDoublePoint& p ) const 
   {
-    QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4));
+    QwtText t(QString("%1 %2, %3 V").arg(p.x(), 0, 'f', GetTimePrecision()).
+             arg(_unitType.c_str()).
+             arg(p.y(), 0, 'f', 4));
 
     return t;
   }
+
+private:
+  std::string _unitType;
 };
 
-TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){
+TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
+{
   timespec_reset(&_lastReplot);
 
   resize(parent->width(), parent->height());
 
-  _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
-
   _numPoints = 1024;
   _realDataPoints = new double[_numPoints];
   _imagDataPoints = new double[_numPoints];
   _xAxisPoints = new double[_numPoints];
 
+  _zoomer = new TimeDomainDisplayZoomer(canvas(), 0);
+
   // Disable polygon clipping
   QwtPainter::setDeviceClipping(false);
   
@@ -56,8 +94,8 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){
   canvas()->setPalette(palette);  
 
   setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
-  setAxisScale(QwtPlot::xBottom, 0, _numPoints);
-  setAxisTitle(QwtPlot::xBottom, "Sample Number");
+  set_xaxis(0, _numPoints);
+  setAxisTitle(QwtPlot::xBottom, "Time (sec)");
 
   setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
   set_yaxis(-2.0, 2.0);
@@ -79,11 +117,11 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){
   memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
   memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
 
+  _sampleRate = 1;
   _resetXAxisPoints();
 
   replot();
 
-  _zoomer = new TimeDomainDisplayZoomer(canvas());
 #if QT_VERSION < 0x040000
   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
                          Qt::RightButton, Qt::ControlModifier);
@@ -113,7 +151,8 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){
   legendDisplay->setItemMode(QwtLegend::CheckableItem);
   insertLegend(legendDisplay);
 
-  connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
+  connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), 
+         this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
 }
 
 TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){
@@ -129,26 +168,36 @@ void
 TimeDomainDisplayPlot::set_yaxis(double min, double max)
 {
   setAxisScale(QwtPlot::yLeft, min, max);
+  _zoomer->setZoomBase();
 }
 
-void TimeDomainDisplayPlot::replot(){
-
-  const timespec startTime = get_highres_clock();
-  
-  QwtPlot::replot();
+void
+TimeDomainDisplayPlot::set_xaxis(double min, double max)
+{
+  setAxisScale(QwtPlot::xBottom, min, max);
+  _zoomer->setZoomBase();
+}
 
-  double differenceTime = (diff_timespec(get_highres_clock(), startTime));
 
-  differenceTime *= 99.0;
-  // Require at least a 10% duty cycle
-  if(differenceTime > (1.0/10.0)){
-    _displayIntervalTime = differenceTime;
-  }
+void TimeDomainDisplayPlot::replot()
+{
+  QwtPlot::replot();
 }
 
-void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
-  if(numDataPoints > 0){
+void
+TimeDomainDisplayPlot::resizeSlot( QSize *s )
+{
+  resize(s->width(), s->height());
+}
 
+void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints,
+                                       const double* imagDataPoints,
+                                       const int64_t numDataPoints,
+                                       const double timeInterval)
+{
+  if((numDataPoints > 0) && 
+     (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
+  
     if(numDataPoints != _numPoints){
       _numPoints = numDataPoints;
 
@@ -162,36 +211,65 @@ void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const doub
       _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
       _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
 
+      set_xaxis(0, numDataPoints);
+
       _resetXAxisPoints();
     }
+
     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
 
-  }
+    replot();
 
-  // Allow at least a 50% duty cycle
-  if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
-    // Only replot the screen if it is visible
-    if(isVisible()){
-      replot();
-    }
     _lastReplot = get_highres_clock();
   }
 }
 
-void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag){
+void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag)
+{
   _imag_plot_curve->setVisible(visibleFlag);
 }
 
-void TimeDomainDisplayPlot::_resetXAxisPoints(){
+void TimeDomainDisplayPlot::_resetXAxisPoints()
+{
+  double delt = 1.0/_sampleRate;
   for(long loc = 0; loc < _numPoints; loc++){
-    _xAxisPoints[loc] = loc;
+    _xAxisPoints[loc] = loc*delt;
   }
-  setAxisScale(QwtPlot::xBottom, 0, _numPoints);
+  setAxisScale(QwtPlot::xBottom, 0, _numPoints*delt);
+
+  // Set up zoomer base for maximum unzoom x-axis
+  // and reset to maximum unzoom level
+  QwtDoubleRect zbase = _zoomer->zoomBase();
+  zbase.setLeft(0);
+  zbase.setRight(_numPoints*delt);
+  _zoomer->zoom(zbase);
+  _zoomer->setZoomBase(zbase);
+  _zoomer->zoom(0);
 }
 
-void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
+void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on)
+{
   plotItem->setVisible(!on);
 }
 
+void
+TimeDomainDisplayPlot::SetSampleRate(double sr, double units,
+                                    const std::string &strunits)
+{
+  double newsr = sr/units;
+  if(newsr != _sampleRate) {
+    _sampleRate = sr/units;
+    _resetXAxisPoints();
+    
+    // While we could change the displayed sigfigs based on the unit being
+    // displayed, I think it looks better by just setting it to 4 regardless.
+    //double display_units = ceil(log10(units)/2.0);
+    double display_units = 4;
+    setAxisTitle(QwtPlot::xBottom, QString("Time (%1)").arg(strunits.c_str()));
+    ((TimeDomainDisplayZoomer*)_zoomer)->SetTimePrecision(display_units);
+    ((TimeDomainDisplayZoomer*)_zoomer)->SetUnitType(strunits);
+  }
+}
+
 #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */
index 9c6364af297d22c562aa003d9b625b16022b548e..5525bbabe956bc2379c33426f0f28449056aff92 100644 (file)
@@ -21,13 +21,20 @@ public:
   TimeDomainDisplayPlot(QWidget*);
   virtual ~TimeDomainDisplayPlot();
 
-  void PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints);
+  void PlotNewData(const double* realDataPoints, const double* imagDataPoints, 
+                  const int64_t numDataPoints, const double timeInterval);
     
   void SetImaginaryDataVisible(const bool);
                                   
   virtual void replot();
 
   void set_yaxis(double min, double max);
+  void set_xaxis(double min, double max);
+
+public slots:
+  void resizeSlot( QSize *s );
+  void SetSampleRate(double sr, double units, 
+                    const std::string &strunits);
 
 protected slots:
   void LegendEntryChecked(QwtPlotItem *plotItem, bool on);
@@ -47,11 +54,11 @@ private:
   double* _imagDataPoints;
   double* _xAxisPoints;
 
+  double _sampleRate;
+
   timespec _lastReplot;
 
   int64_t _numPoints;
-
-  double _displayIntervalTime;
 };
 
 #endif /* TIME_DOMAIN_DISPLAY_PLOT_HPP */
index 1b6650613190b827e1a9b38762d08fc98311fd8c..f676cb4af2ac529de9295b7bf428ebfd9b8972e7 100644 (file)
@@ -15,15 +15,21 @@ Waterfall3DColorMap::~Waterfall3DColorMap(){
 
 }
 
-Qwt3D::RGBA Waterfall3DColorMap::operator()(double, double, double z)const{
+Qwt3D::RGBA
+Waterfall3DColorMap::operator()(double, double, double z) const
+{
   return Qwt3D::RGBA(Qwt3D::Qt2GL(color(_interval, z)));
 }
 
-void Waterfall3DColorMap::SetInterval(const double minValue, const double maxValue){
+void
+Waterfall3DColorMap::SetInterval(const double minValue, const double maxValue)
+{
   _interval.setInterval(minValue, maxValue);
 }
 
-Qwt3D::ColorVector& Waterfall3DColorMap::createVector(Qwt3D::ColorVector& vec) { 
+Qwt3D::ColorVector&
+Waterfall3DColorMap::createVector(Qwt3D::ColorVector& vec)
+{
   // Generate 100 interval values and then return those
   Qwt3D::ColorVector colorVec;
   for(unsigned int number = 0; number < 100; number++){
@@ -41,7 +47,8 @@ const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_BLACK_HOT;
 const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_INCANDESCENT;
 const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED;
 
-Waterfall3DDisplayPlot::Waterfall3DDisplayPlot(QWidget* parent):Qwt3D::SurfacePlot(parent){
+Waterfall3DDisplayPlot::Waterfall3DDisplayPlot(QWidget* parent):Qwt3D::SurfacePlot(parent)
+{
   _startFrequency = 0;
   _stopFrequency = 4000;
 
@@ -76,11 +83,14 @@ Waterfall3DDisplayPlot::Waterfall3DDisplayPlot(QWidget* parent):Qwt3D::SurfacePl
   enableMouse(true);  
 }
 
-Waterfall3DDisplayPlot::~Waterfall3DDisplayPlot(){
+Waterfall3DDisplayPlot::~Waterfall3DDisplayPlot()
+{
   delete _waterfallData;
 }
 
-void Waterfall3DDisplayPlot::Init(){
+void
+Waterfall3DDisplayPlot::Init()
+{
   if(!_initialized && initializedGL()){
     resize(parentWidget()->width(), parentWidget()->height());
 
@@ -97,7 +107,9 @@ void Waterfall3DDisplayPlot::Init(){
   }
 }
 
-void Waterfall3DDisplayPlot::Reset(){
+void
+Waterfall3DDisplayPlot::Reset()
+{
   _waterfallData->ResizeData(_startFrequency, _stopFrequency, _numPoints);
   _waterfallData->Reset();
 
@@ -116,7 +128,8 @@ Waterfall3DDisplayPlot::SetFrequencyRange(const double constStartFreq,
                                          const double constStopFreq,
                                          const double constCenterFreq,
                                          const bool useCenterFrequencyFlag,
-                                         const double units, const std::string &strunits)
+                                         const double units,
+                                         const std::string &strunits)
 {
   double startFreq = constStartFreq / units;
   double stopFreq = constStopFreq / units;
@@ -138,8 +151,10 @@ Waterfall3DDisplayPlot::SetFrequencyRange(const double constStartFreq,
   }
 }
 
-bool Waterfall3DDisplayPlot::loadFromData(double** data, unsigned int columns, unsigned int rows
-                                         ,double minx, double maxx, double miny, double maxy){
+bool
+Waterfall3DDisplayPlot::loadFromData(double** data, unsigned int columns, unsigned int rows
+                                    ,double minx, double maxx, double miny, double maxy)
+{
 
   Qwt3D::GridData* gridPtr = (Qwt3D::GridData*)actualData_p;
   
@@ -196,15 +211,25 @@ bool Waterfall3DDisplayPlot::loadFromData(double** data, unsigned int columns, u
   return true;
 }
 
-double Waterfall3DDisplayPlot::GetStartFrequency()const{
+double
+Waterfall3DDisplayPlot::GetStartFrequency() const
+{
   return _startFrequency;
 }
 
-double Waterfall3DDisplayPlot::GetStopFrequency()const{
+double
+Waterfall3DDisplayPlot::GetStopFrequency() const
+{
   return _stopFrequency;
 }
 
-void Waterfall3DDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames){
+void
+Waterfall3DDisplayPlot::PlotNewData(const double* dataPoints,
+                                   const int64_t numDataPoints,
+                                   const double timePerFFT,
+                                   const timespec timestamp,
+                                   const int droppedFrames)
+{
   if(numDataPoints > 0){
     if(numDataPoints != _numPoints){
       _numPoints = numDataPoints;
@@ -238,7 +263,10 @@ void Waterfall3DDisplayPlot::PlotNewData(const double* dataPoints, const int64_t
   }
 }
 
-void Waterfall3DDisplayPlot::SetIntensityRange(const double minIntensity, const double maxIntensity){
+void
+Waterfall3DDisplayPlot::SetIntensityRange(const double minIntensity,
+                                         const double maxIntensity)
+{
   _waterfallData->SetFloorValue(minIntensity);
   _waterfallData->setMinZ(0);
   _waterfallData->setMaxZ(maxIntensity-minIntensity);
@@ -248,11 +276,14 @@ void Waterfall3DDisplayPlot::SetIntensityRange(const double minIntensity, const
   emit UpdatedLowerIntensityLevel(minIntensity);
   emit UpdatedUpperIntensityLevel(maxIntensity);
 
-  SetIntensityColorMapType(_intensityColorMapType, _userDefinedLowIntensityColor, _userDefinedLowIntensityColor, true);
+  SetIntensityColorMapType(_intensityColorMapType,
+                          _userDefinedLowIntensityColor,
+                          _userDefinedLowIntensityColor, true);
 }
 
-void Waterfall3DDisplayPlot::replot(){
-
+void
+Waterfall3DDisplayPlot::replot()
+{
   if(!_initialized){
     Init();
   }
@@ -283,11 +314,25 @@ void Waterfall3DDisplayPlot::replot(){
   }
 }
 
-int Waterfall3DDisplayPlot::GetIntensityColorMapType()const{
+void
+Waterfall3DDisplayPlot::resizeSlot( QSize *s )
+{
+  resize(s->width(), s->height());
+}
+
+int
+Waterfall3DDisplayPlot::GetIntensityColorMapType() const
+{
   return _intensityColorMapType;
 }
 
-void Waterfall3DDisplayPlot::SetIntensityColorMapType(const int newType, const QColor lowColor, const QColor highColor, const bool forceFlag, const bool noReplotFlag){
+void
+Waterfall3DDisplayPlot::SetIntensityColorMapType(const int newType,
+                                                const QColor lowColor,
+                                                const QColor highColor,
+                                                const bool forceFlag,
+                                                const bool noReplotFlag)
+{
   if(((_intensityColorMapType != newType) || forceFlag) || 
      ((newType == INTENSITY_COLOR_MAP_TYPE_USER_DEFINED) &&
       (lowColor.isValid() && highColor.isValid()))){
@@ -350,11 +395,15 @@ void Waterfall3DDisplayPlot::SetIntensityColorMapType(const int newType, const Q
   }
 }
 
-const QColor Waterfall3DDisplayPlot::GetUserDefinedLowIntensityColor()const{
+const QColor
+Waterfall3DDisplayPlot::GetUserDefinedLowIntensityColor() const
+{
   return _userDefinedLowIntensityColor;
 }
 
-const QColor Waterfall3DDisplayPlot::GetUserDefinedHighIntensityColor()const{
+const QColor
+Waterfall3DDisplayPlot::GetUserDefinedHighIntensityColor() const
+{
   return _userDefinedHighIntensityColor;
 }
 
index f46f260e37cd6cd0e2268f4d452a033dc9f55550..272bdf69706561d1b6af34df105363c3c5a902ad 100644 (file)
@@ -10,7 +10,8 @@
 #include <qwt3d_color.h>
 #include <qwt_color_map.h>
 
-class Waterfall3DColorMap:public Qwt3D::Color, public QwtLinearColorMap{
+class Waterfall3DColorMap: public Qwt3D::Color, public QwtLinearColorMap
+{
 public:
   Waterfall3DColorMap();
   virtual ~Waterfall3DColorMap();
@@ -75,12 +76,14 @@ class Waterfall3DDisplayPlot:public Qwt3D::SurfacePlot{
     virtual QString ticLabel(unsigned int idx) const{
       if (idx<majors_p.size())
        {
-         const timespec markerTime = timespec_add(_plot->_dataTimestamp, -(_plot->_timePerFFT) * majors_p[idx]);
+         const timespec markerTime = timespec_add(_plot->_dataTimestamp,
+                                                  -(_plot->_timePerFFT) * majors_p[idx]);
          struct tm timeTm;
          gmtime_r(&markerTime.tv_sec, &timeTm);
          
          char* timeBuffer = new char[128];
-         snprintf(timeBuffer, 128, "%02d:%02d:%02d.%03ld", timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, (markerTime.tv_nsec / 1000000));
+         snprintf(timeBuffer, 128, "%02d:%02d:%02d.%03ld", timeTm.tm_hour,
+                  timeTm.tm_min, timeTm.tm_sec, (markerTime.tv_nsec / 1000000));
          QString returnBuffer(timeBuffer);
          delete[] timeBuffer;
          return returnBuffer;
@@ -100,10 +103,14 @@ class Waterfall3DDisplayPlot:public Qwt3D::SurfacePlot{
     double _centerFrequency;
     bool _useCenterFrequencyFlag;
   public:
-    FrequencyScale(bool useCenterFrequencyFlag, double centerFrequency):_centerFrequency(centerFrequency),_useCenterFrequencyFlag(useCenterFrequencyFlag){}
+    FrequencyScale(bool useCenterFrequencyFlag, double centerFrequency)
+      : _centerFrequency(centerFrequency),_useCenterFrequencyFlag(useCenterFrequencyFlag)
+      {}
+
     virtual ~FrequencyScale(){}
 
-    virtual QString ticLabel(unsigned int idx) const{
+    virtual QString ticLabel(unsigned int idx) const
+    {
       if (idx<majors_p.size())
        {
          if(!_useCenterFrequencyFlag){
@@ -137,14 +144,18 @@ public:
   double GetStartFrequency()const;
   double GetStopFrequency()const;
 
-  void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames);
+  void PlotNewData(const double* dataPoints, const int64_t numDataPoints,
+                  const double timePerFFT, const timespec timestamp,
+                  const int droppedFrames);
 
   void SetIntensityRange(const double minIntensity, const double maxIntensity);
 
   virtual void replot(void);
 
   int GetIntensityColorMapType()const;
-  void SetIntensityColorMapType( const int, const QColor, const QColor, const bool forceFlag = false, const bool noReplotFlag = false );
+  void SetIntensityColorMapType( const int, const QColor,
+                                const QColor, const bool forceFlag = false,
+                                const bool noReplotFlag = false );
   const QColor GetUserDefinedLowIntensityColor()const;
   const QColor GetUserDefinedHighIntensityColor()const;
 
@@ -154,6 +165,10 @@ public:
   static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3;
   static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4;
 
+public slots:
+  void resizeSlot( QSize *s );
+
+
 signals:
   void UpdatedLowerIntensityLevel(const double);
   void UpdatedUpperIntensityLevel(const double);
index ad167f097aa3cc00643aec1f0a8ed7fe4f896a37..e0804fa64083bcbd379d81c1fa3fa8892d11a849 100644 (file)
 class FreqOffsetAndPrecisionClass
 {
 public:
-  FreqOffsetAndPrecisionClass(const int freqPrecision){
+  FreqOffsetAndPrecisionClass(const int freqPrecision)
+  {
     _frequencyPrecision = freqPrecision;
     _centerFrequency = 0;
   }
 
-  virtual ~FreqOffsetAndPrecisionClass(){
-
+  virtual ~FreqOffsetAndPrecisionClass()
+  {
   }
 
-  virtual unsigned int GetFrequencyPrecision()const{
+  virtual unsigned int GetFrequencyPrecision() const
+  {
     return _frequencyPrecision;
   }
 
-  virtual void SetFrequencyPrecision(const unsigned int newPrecision){
+  virtual void SetFrequencyPrecision(const unsigned int newPrecision)
+  {
     _frequencyPrecision = newPrecision;
   }
 
-  virtual double GetCenterFrequency()const{
+  virtual double GetCenterFrequency() const
+  {
     return _centerFrequency;
   }
 
-  virtual void SetCenterFrequency(const double newFreq){
+  virtual void SetCenterFrequency(const double newFreq)
+  {
     _centerFrequency = newFreq;
   }
 
@@ -50,19 +55,22 @@ private:
 
 class WaterfallFreqDisplayScaleDraw: public QwtScaleDraw, public FreqOffsetAndPrecisionClass{
 public:
-  WaterfallFreqDisplayScaleDraw(const unsigned int precision):QwtScaleDraw(), FreqOffsetAndPrecisionClass(precision){
-
+  WaterfallFreqDisplayScaleDraw(const unsigned int precision)
+    : QwtScaleDraw(), FreqOffsetAndPrecisionClass(precision)
+  {
   }
 
-  virtual ~WaterfallFreqDisplayScaleDraw(){
-
+  virtual ~WaterfallFreqDisplayScaleDraw()
+  {
   }
 
-  QwtText label(double value)const{
-    return QString("%1").arg((value + GetCenterFrequency()) / ((GetFrequencyPrecision() == 0) ? 1.0 : 1000.0), 0, 'f', GetFrequencyPrecision());
+  QwtText label(double value) const
+  {
+    return QString("%1").arg(value, 0, 'f', GetFrequencyPrecision());
   }
 
-  virtual void initiateUpdate(){
+  virtual void initiateUpdate()
+  {
     invalidateCache();
   }
 
@@ -75,29 +83,33 @@ private:
 class TimeScaleData
 {
 public:
-  TimeScaleData(){
+  TimeScaleData()
+  {
     timespec_reset(&_zeroTime);
     _secondsPerLine = 1.0;
-    
   }
   
-  virtual ~TimeScaleData(){
-    
+  virtual ~TimeScaleData()
+  {    
   }
 
-  virtual timespec GetZeroTime()const{
+  virtual timespec GetZeroTime() const
+  {
     return _zeroTime;
   }
   
-  virtual void SetZeroTime(const timespec newTime){
+  virtual void SetZeroTime(const timespec newTime)
+  {
     _zeroTime = newTime;
   }
 
-  virtual void SetSecondsPerLine(const double newTime){
+  virtual void SetSecondsPerLine(const double newTime)
+  {
     _secondsPerLine = newTime;
   }
 
-  virtual double GetSecondsPerLine()const{
+  virtual double GetSecondsPerLine() const
+  {
     return _secondsPerLine;
   }
 
@@ -113,27 +125,32 @@ private:
 class QwtTimeScaleDraw: public QwtScaleDraw, public TimeScaleData
 {
 public:
-  QwtTimeScaleDraw():QwtScaleDraw(),TimeScaleData(){
-    
+  QwtTimeScaleDraw():QwtScaleDraw(),TimeScaleData()
+  {    
   }
 
-  virtual ~QwtTimeScaleDraw(){
-    
+  virtual ~QwtTimeScaleDraw()
+  {    
   }
 
-  virtual QwtText label(double value)const{
+  virtual QwtText label(double value) const
+  {
     QwtText returnLabel("");
 
     timespec lineTime = timespec_add(GetZeroTime(), (-value) * GetSecondsPerLine());
     struct tm timeTm;
     gmtime_r(&lineTime.tv_sec, &timeTm);
-    returnLabel = (QString("").sprintf("%04d/%02d/%02d\n%02d:%02d:%02d.%03ld", timeTm.tm_year+1900, timeTm.tm_mon+1, timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, lineTime.tv_nsec/1000000));
-    
+    returnLabel = (QString("").sprintf("%04d/%02d/%02d\n%02d:%02d:%02d.%03ld",
+                                      timeTm.tm_year+1900, timeTm.tm_mon+1,
+                                      timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min,
+                                      timeTm.tm_sec, lineTime.tv_nsec/1000000));
     return returnLabel;
   }
 
-  virtual void initiateUpdate(){
-    // Do this in one call rather than when zeroTime and secondsPerLine updates is to prevent the display from being updated too often...
+  virtual void initiateUpdate()
+  {
+    // Do this in one call rather than when zeroTime and secondsPerLine
+    // updates is to prevent the display from being updated too often...
     invalidateCache();
   }
   
@@ -143,22 +160,31 @@ private:
 
 };
 
-class WaterfallZoomer: public QwtPlotZoomer, public TimeScaleData, public FreqOffsetAndPrecisionClass
+class WaterfallZoomer: public QwtPlotZoomer, public TimeScaleData, 
+                      public FreqOffsetAndPrecisionClass
 {
 public:
-  WaterfallZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision):QwtPlotZoomer(canvas), TimeScaleData(), FreqOffsetAndPrecisionClass(freqPrecision)
+  WaterfallZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision)
+    : QwtPlotZoomer(canvas), TimeScaleData(), 
+      FreqOffsetAndPrecisionClass(freqPrecision)
   {
     setTrackerMode(QwtPicker::AlwaysOn);
   }
 
-  virtual ~WaterfallZoomer(){
-
+  virtual ~WaterfallZoomer()
+  {
   }
   
-  virtual void updateTrackerText(){
+  virtual void updateTrackerText()
+  {
     updateDisplay();
   }
 
+  void SetUnitType(const std::string &type)
+  {
+    _unitType = type;
+  }
+
 protected:
   virtual QwtText trackerText( const QwtDoublePoint& p ) const 
   {
@@ -167,12 +193,19 @@ protected:
     timespec lineTime = timespec_add(GetZeroTime(), (-p.y()) * GetSecondsPerLine());
     struct tm timeTm;
     gmtime_r(&lineTime.tv_sec, &timeTm);
-    yLabel = (QString("").sprintf("%04d/%02d/%02d %02d:%02d:%02d.%03ld", timeTm.tm_year+1900, timeTm.tm_mon+1, timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, lineTime.tv_nsec/1000000));
-
-    QwtText t(QString("%1 %2, %3").arg((p.x() + GetCenterFrequency()) / ((GetFrequencyPrecision() == 0) ? 1.0 : 1000.0), 0, 'f', GetFrequencyPrecision()).arg( (GetFrequencyPrecision() == 0) ? "Hz" : "kHz").arg(yLabel));
-
+    yLabel = (QString("").sprintf("%04d/%02d/%02d %02d:%02d:%02d.%03ld",
+                                 timeTm.tm_year+1900, timeTm.tm_mon+1,
+                                 timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min,
+                                 timeTm.tm_sec, lineTime.tv_nsec/1000000));
+
+    QwtText t(QString("%1 %2, %3").
+             arg(p.x(), 0, 'f', GetFrequencyPrecision()).
+             arg(_unitType.c_str()).arg(yLabel));
     return t;
   }
+
+private:
+  std::string _unitType;
 };
 
 
@@ -192,8 +225,6 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent)
   resize(parent->width(), parent->height());
   _numPoints = 1024;
 
-  _displayIntervalTime = (1.0/5.0); // 1/5 of a second between updates
-
   _waterfallData = new WaterfallData(_startFrequency, _stopFrequency, _numPoints, 200);
 
   QPalette palette;
@@ -258,6 +289,7 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent)
 WaterfallDisplayPlot::~WaterfallDisplayPlot()
 {
   delete _waterfallData;
+  delete d_spectrogram;
 }
 
 void 
@@ -266,6 +298,8 @@ WaterfallDisplayPlot::Reset()
   _waterfallData->ResizeData(_startFrequency, _stopFrequency, _numPoints);
   _waterfallData->Reset();
 
+  setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
+
   // Load up the new base zoom settings
   QwtDoubleRect newSize = _zoomer->zoomBase();
   newSize.setLeft(_startFrequency);
@@ -286,84 +320,98 @@ WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq,
   double stopFreq = constStopFreq / units;
   double centerFreq = constCenterFreq / units;
 
-  if(stopFreq > startFreq) {
-    _startFrequency = 1000*startFreq;
-    _stopFrequency = 1000*stopFreq;
+  _useCenterFrequencyFlag = useCenterFrequencyFlag;
 
-    setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
+  if(_useCenterFrequencyFlag){
+    startFreq = (startFreq + centerFreq);
+    stopFreq = (stopFreq + centerFreq);
+  }
 
-    if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){
-      WaterfallFreqDisplayScaleDraw* freqScale = ((WaterfallFreqDisplayScaleDraw*)axisScaleDraw(QwtPlot::xBottom));
-      freqScale->SetCenterFrequency(centerFreq);
-      ((WaterfallZoomer*)_zoomer)->SetCenterFrequency(centerFreq);
+  bool reset = false;
+  if((startFreq != _startFrequency) || (stopFreq != _stopFrequency))
+    reset = true;
 
-      freqScale->SetFrequencyPrecision( 2 );
-      ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision( 2 );
+  if(stopFreq > startFreq) {
+    _startFrequency = startFreq;
+    _stopFrequency = stopFreq;
+    if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){
+      double display_units = ceil(log10(units)/2.0);
+      setAxisScaleDraw(QwtPlot::xBottom, new WaterfallFreqDisplayScaleDraw(display_units));
       setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str()));
-    }
 
-    Reset();
+      if(reset) {
+       Reset();
+      }
 
-    // Only replot if screen is visible
-    if(isVisible()){
-      replot();
+      ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision(display_units);
+      ((WaterfallZoomer*)_zoomer)->SetUnitType(strunits);
     }
   }
 }
 
 
-double WaterfallDisplayPlot::GetStartFrequency()const{
+double
+WaterfallDisplayPlot::GetStartFrequency() const
+{
   return _startFrequency;
 }
 
-double WaterfallDisplayPlot::GetStopFrequency()const{
+double
+WaterfallDisplayPlot::GetStopFrequency() const
+{
   return _stopFrequency;
 }
 
-void WaterfallDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames){
+void
+WaterfallDisplayPlot::PlotNewData(const double* dataPoints, 
+                                 const int64_t numDataPoints,
+                                 const double timePerFFT,
+                                 const timespec timestamp,
+                                 const int droppedFrames)
+{
   if(numDataPoints > 0){
     if(numDataPoints != _numPoints){
       _numPoints = numDataPoints;
-
+      
       Reset();
-
+      
       d_spectrogram->invalidateCache();
       d_spectrogram->itemChanged();
-
+      
       if(isVisible()){
        replot();
       }
-
+      
       _lastReplot = get_highres_clock();
     }
 
-    _waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames);
-    _waterfallData->IncrementNumLinesToUpdate();
-
-    QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft);
-    timeScale->SetSecondsPerLine(timePerFFT);
-    timeScale->SetZeroTime(timestamp);
-
-    ((WaterfallZoomer*)_zoomer)->SetSecondsPerLine(timePerFFT);
-    ((WaterfallZoomer*)_zoomer)->SetZeroTime(timestamp);
-  }
-
-  // Allow at least a 50% duty cycle
-  if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
-
-    d_spectrogram->invalidateCache();
-    d_spectrogram->itemChanged();
-
-    // Only update when window is visible
-    if(isVisible()){
+    if(diff_timespec(get_highres_clock(), _lastReplot) > timePerFFT) {
+      //FIXME: We may want to average the data between these updates to smooth display
+      _waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames);
+      _waterfallData->IncrementNumLinesToUpdate();
+      
+      QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft);
+      timeScale->SetSecondsPerLine(timePerFFT);
+      timeScale->SetZeroTime(timestamp);
+      
+      ((WaterfallZoomer*)_zoomer)->SetSecondsPerLine(timePerFFT);
+      ((WaterfallZoomer*)_zoomer)->SetZeroTime(timestamp);
+      
+      d_spectrogram->invalidateCache();
+      d_spectrogram->itemChanged();
+      
       replot();
-    }
 
-    _lastReplot = get_highres_clock();
+      _lastReplot = get_highres_clock();
+    }
   }
 }
 
-void WaterfallDisplayPlot::SetIntensityRange(const double minIntensity, const double maxIntensity){
+void
+WaterfallDisplayPlot::SetIntensityRange(const double minIntensity, 
+                                            const double maxIntensity)
+{
   _waterfallData->setRange(QwtDoubleInterval(minIntensity, maxIntensity));
 
   emit UpdatedLowerIntensityLevel(minIntensity);
@@ -372,9 +420,9 @@ void WaterfallDisplayPlot::SetIntensityRange(const double minIntensity, const do
   _UpdateIntensityRangeDisplay();
 }
 
-void WaterfallDisplayPlot::replot(){
-  const timespec startTime = get_highres_clock();
-
+void
+WaterfallDisplayPlot::replot()
+{
   QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft);
   timeScale->initiateUpdate();
 
@@ -396,21 +444,25 @@ void WaterfallDisplayPlot::replot(){
   }
 
   QwtPlot::replot();
+}
 
-  double differenceTime = (diff_timespec(get_highres_clock(), startTime));
-  
-  // Require at least a 5% duty cycle
-  differenceTime *= 19.0;
-  if(differenceTime > (1.0/5.0)){
-    _displayIntervalTime = differenceTime;
-  }
+void
+WaterfallDisplayPlot::resizeSlot( QSize *s )
+{
+  resize(s->width(), s->height());
 }
 
-int WaterfallDisplayPlot::GetIntensityColorMapType()const{
+int
+WaterfallDisplayPlot::GetIntensityColorMapType() const
+{
   return _intensityColorMapType;
 }
 
-void WaterfallDisplayPlot::SetIntensityColorMapType(const int newType, const QColor lowColor, const QColor highColor){
+void
+WaterfallDisplayPlot::SetIntensityColorMapType(const int newType, 
+                                              const QColor lowColor, 
+                                              const QColor highColor)
+{
   if((_intensityColorMapType != newType) || 
      ((newType == INTENSITY_COLOR_MAP_TYPE_USER_DEFINED) &&
       (lowColor.isValid() && highColor.isValid()))){
@@ -458,15 +510,21 @@ void WaterfallDisplayPlot::SetIntensityColorMapType(const int newType, const QCo
   }
 }
 
-const QColor WaterfallDisplayPlot::GetUserDefinedLowIntensityColor()const{
+const QColor
+WaterfallDisplayPlot::GetUserDefinedLowIntensityColor() const
+{
   return _userDefinedLowIntensityColor;
 }
 
-const QColor WaterfallDisplayPlot::GetUserDefinedHighIntensityColor()const{
+const QColor
+WaterfallDisplayPlot::GetUserDefinedHighIntensityColor() const
+{
   return _userDefinedHighIntensityColor;
 }
 
-void WaterfallDisplayPlot::_UpdateIntensityRangeDisplay(){
+void
+WaterfallDisplayPlot::_UpdateIntensityRangeDisplay()
+{
   QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
   rightAxis->setTitle("Intensity (dB)");
   rightAxis->setColorBarEnabled(true);
index fbbb69a5bd7ed77a142fd449b4eac579b6646821..a5ccaec401c1c961f880bfcd1193aef522800794 100644 (file)
@@ -45,6 +45,9 @@ public:
   static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3;
   static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4;
 
+public slots:
+  void resizeSlot( QSize *s );
+
 signals:
   void UpdatedLowerIntensityLevel(const double);
   void UpdatedUpperIntensityLevel(const double);
@@ -66,9 +69,9 @@ private:
 
   timespec _lastReplot;
 
-  int64_t _numPoints;
+  bool _useCenterFrequencyFlag;
 
-  double _displayIntervalTime;
+  int64_t _numPoints;
 
   int _intensityColorMapType;
   QColor _userDefinedLowIntensityColor;
index d2f734fdffd0774f6d8e5927edafbdbd709e34dc..1f50bf43c91db0cfccfd087ce02ff67d0e829602 100644 (file)
@@ -68,6 +68,7 @@ public:
   void set_constellation_axis(double xmin, double xmax,
                              double ymin, double ymax);
   void set_frequency_axis(double min, double max);
+  void set_constellation_pen_size(int size);
 };
 
 
@@ -116,5 +117,6 @@ public:
   void set_constellation_axis(double xmin, double xmax,
                              double ymin, double ymax);
   void set_frequency_axis(double min, double max);
+  void set_constellation_pen_size(int size);
 };
 
index b1fd60d349dd7e2e5ebd45f1680aa3419e67186a..a148cf50119343ad52b6ecbfa273890900cd01cc 100644 (file)
@@ -78,8 +78,6 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype,
 
   d_fft = new gri_fft_complex (d_fftsize, true);
 
-  d_fftdata = new gr_complex[d_fftsize];
-
   d_index = 0;
   d_residbuf = new gr_complex[d_fftsize];
 
@@ -90,12 +88,20 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype,
 
 qtgui_sink_c::~qtgui_sink_c()
 {
-  delete d_object;
-  delete [] d_fftdata;
+  delete d_main_gui;
   delete [] d_residbuf;
   delete d_fft;
 }
 
+void
+qtgui_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned int ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++) {
+    ninput_items_required[i] = std::min(d_fftsize, 8191);
+  }
+}
+
 void qtgui_sink_c::lock()
 {
   pthread_mutex_lock(&d_pmutex);
@@ -139,6 +145,9 @@ qtgui_sink_c::initialize(const bool opengl)
                                 d_plotconst,
                                 opengl);
 
+  // initialize update time to 10 times a second
+  set_update_time(0.1);
+
   d_object = new qtgui_obj(d_qApplication);
   qApp->postEvent(d_object, new qtgui_event(&d_pmutex));
 }
@@ -188,6 +197,13 @@ qtgui_sink_c::set_constellation_axis(double xmin, double xmax,
   d_main_gui->SetConstellationAxis(xmin, xmax, ymin, ymax);
 }
 
+void 
+qtgui_sink_c::set_constellation_pen_size(int size)
+{
+  d_main_gui->SetConstellationPenSize(size);
+}
+
+
 void
 qtgui_sink_c::set_frequency_axis(double min, double max)
 {
@@ -195,7 +211,14 @@ qtgui_sink_c::set_frequency_axis(double min, double max)
 }
 
 void
-qtgui_sink_c::fft(const gr_complex *data_in, int size, gr_complex *data_out)
+qtgui_sink_c::set_update_time(double t)
+{
+  d_update_time = t;
+  d_main_gui->SetUpdateTime(d_update_time);
+}
+
+void
+qtgui_sink_c::fft(const gr_complex *data_in, int size)
 {
   if (d_window.size()) {
     gr_complex *dst = d_fft->get_inbuf();
@@ -208,20 +231,6 @@ qtgui_sink_c::fft(const gr_complex *data_in, int size, gr_complex *data_out)
   }
 
   d_fft->execute ();     // compute the fft
-
-  for(int i=0; i < size; i++) {
-    d_fft->get_outbuf()[i] /= size;
-  }
-
-  // copy result to our output
-  if(d_shift) {  // apply a fft shift on the data
-    unsigned int len = (unsigned int)(ceil(size/2.0));
-    memcpy(&data_out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(size - len));
-    memcpy(&data_out[size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len);
-  }
-  else {
-    memcpy(data_out, d_fft->get_outbuf(), sizeof(gr_complex)*size);
-  }
 }
 
 void 
@@ -250,10 +259,6 @@ qtgui_sink_c::fftresize()
 
   if(newfftsize != d_fftsize) {
 
-    // Resize the fftdata buffer; no need to preserve old data
-    delete [] d_fftdata;
-    d_fftdata = new gr_complex[newfftsize];
-
     // Resize residbuf and replace data
     delete [] d_residbuf;
     d_residbuf = new gr_complex[newfftsize];
@@ -279,7 +284,7 @@ qtgui_sink_c::general_work (int noutput_items,
                            gr_vector_const_void_star &input_items,
                            gr_vector_void_star &output_items)
 {
-  int i=0, j=0;
+  int j=0;
   const gr_complex *in = (const gr_complex*)input_items[0];
 
   pthread_mutex_lock(&d_pmutex);
@@ -287,49 +292,36 @@ qtgui_sink_c::general_work (int noutput_items,
   // Update the FFT size from the application
   fftresize();
   windowreset();
-  const timespec currentTime = get_highres_clock();
-  const timespec lastUpdateGUITime = d_main_gui->GetLastGUIUpdateTime();
 
-  if(diff_timespec(currentTime, lastUpdateGUITime) > 0.05) {
+  for(int i=0; i < noutput_items; i+=d_fftsize) {
+    unsigned int datasize = noutput_items - i;
+    unsigned int resid = d_fftsize-d_index;
 
-    if(d_index) {
-      int filler = std::min(d_fftsize - d_index, noutput_items);
+    // If we have enough input for one full FFT, do it
+    if(datasize >= resid) {
+      const timespec currentTime = get_highres_clock();
       
-      memcpy(&d_residbuf[d_index], &in[0], sizeof(gr_complex)*filler);
-      d_index += filler;
-      i = filler;
-      j = filler;
-    }
-    
-    if(d_index == d_fftsize) {
+      // Fill up residbuf with d_fftsize number of items
+      memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*resid);
       d_index = 0;
-      fft(d_residbuf, d_fftsize, d_fftdata);
+
+      j += resid;
+      fft(d_residbuf, d_fftsize);
       
-      d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, 
-                              (float*)d_residbuf, d_fftsize,
-                              1.0/4.0, convert_to_timespec(0.0), true);
-    }
-    
-    for(; i < noutput_items; i+=d_fftsize) {
-      if(noutput_items - i > d_fftsize) {
-       j += d_fftsize;
-       fft(&in[i], d_fftsize, d_fftdata);
-       
-       d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, 
-                                (float*)&in[i], d_fftsize,
-                                1.0/4.0, convert_to_timespec(0.0), true);
-      }
-    }
-    
-    if(noutput_items > j) {
-      d_index = noutput_items - j;
-      memcpy(d_residbuf, &in[j], sizeof(gr_complex)*d_index);
+      d_main_gui->UpdateWindow(true, d_fft->get_outbuf(), d_fftsize,
+                              NULL, 0, (float*)d_residbuf, d_fftsize,
+                              currentTime, true);
     }
+    // Otherwise, copy what we received into the residbuf for next time
+    else {
+      memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*datasize);
+      d_index += datasize;
+      j += datasize;
+    }   
   }
 
   pthread_mutex_unlock(&d_pmutex);
 
-  consume_each(noutput_items);
-  return noutput_items;
+  consume_each(j);
+  return j;
 }
index 1c9d592009a73c4877528f3f89b3c8564b712ebf..1f6c284738981bf6abe8225d8c7984d6ecd28dcc 100644 (file)
@@ -63,6 +63,8 @@ private:
                bool use_openGL,
                QWidget *parent);
 
+  void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
   // use opengl to force OpenGL on or off
   // this might be necessary for sessions over SSH
   void initialize(const bool opengl=true);
@@ -78,20 +80,21 @@ private:
 
   bool d_shift;
   gri_fft_complex *d_fft;
-  gr_complex *d_fftdata;
 
   int d_index;
   gr_complex *d_residbuf;
 
   bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst;
   
+  double d_update_time;
+
   QWidget *d_parent;
   SpectrumGUIClass *d_main_gui;
 
   void windowreset();
   void buildwindow();
   void fftresize();
-  void fft(const gr_complex *data_in, int size, gr_complex *data_out);
+  void fft(const gr_complex *data_in, int size);
   
 public:
   ~qtgui_sink_c();
@@ -107,8 +110,11 @@ public:
   void set_time_domain_axis(double min, double max);
   void set_constellation_axis(double xmin, double xmax,
                              double ymin, double ymax);
+  void set_constellation_pen_size(int size);
   void set_frequency_axis(double min, double max);
 
+  void set_update_time(double t);
+
   QApplication *d_qApplication;
   qtgui_obj *d_object;
 
index 4c526f09f127d8436c9bce53f831936d9af2b781..8eb0a0347ff65f07552e9251df9e05257d138975 100644 (file)
@@ -78,8 +78,6 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype,
 
   d_fft = new gri_fft_complex (d_fftsize, true);
 
-  d_fftdata = new gr_complex[d_fftsize];
-
   d_index = 0;
   d_residbuf = new float[d_fftsize];
 
@@ -90,12 +88,20 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype,
 
 qtgui_sink_f::~qtgui_sink_f()
 {
-  delete d_object;
-  delete [] d_fftdata;
+  delete d_main_gui;
   delete [] d_residbuf;
   delete d_fft;
 }
 
+void
+qtgui_sink_f::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+  unsigned int ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++) {
+    ninput_items_required[i] = std::min(d_fftsize, 8191);
+  }
+}
+
 void qtgui_sink_f::lock()
 {
   pthread_mutex_lock(&d_pmutex);
@@ -134,6 +140,9 @@ qtgui_sink_f::initialize(const bool opengl)
                                 d_plotconst,
                                 opengl);
 
+  // initialize update time to 10 times a second
+  set_update_time(0.1);
+
   d_object = new qtgui_obj(d_qApplication);
   qApp->postEvent(d_object, new qtgui_event(&d_pmutex));
 }
@@ -182,6 +191,13 @@ qtgui_sink_f::set_constellation_axis(double xmin, double xmax,
   d_main_gui->SetConstellationAxis(xmin, xmax, ymin, ymax);
 }
 
+void 
+qtgui_sink_f::set_constellation_pen_size(int size)
+{
+  d_main_gui->SetConstellationPenSize(size);
+}
+
+
 void
 qtgui_sink_f::set_frequency_axis(double min, double max)
 {
@@ -189,7 +205,14 @@ qtgui_sink_f::set_frequency_axis(double min, double max)
 }
 
 void
-qtgui_sink_f::fft(const float *data_in, int size, gr_complex *data_out)
+qtgui_sink_f::set_update_time(double t)
+{
+  d_update_time = t;
+  d_main_gui->SetUpdateTime(d_update_time);
+}
+
+void
+qtgui_sink_f::fft(const float *data_in, int size)
 {
   if (d_window.size()) {
     gr_complex *dst = d_fft->get_inbuf();
@@ -203,20 +226,6 @@ qtgui_sink_f::fft(const float *data_in, int size, gr_complex *data_out)
   }
   
   d_fft->execute ();     // compute the fft
-
-  for(int i=0; i < size; i++) {
-    d_fft->get_outbuf()[i] /= size;
-  }
-
-  // copy result to our output
-  if(d_shift) {  // apply a fft shift on the data
-    unsigned int len = (unsigned int)(ceil(size/2.0));
-    memcpy(&data_out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(size - len));
-    memcpy(&data_out[size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len);
-  }
-  else {
-    memcpy(data_out, d_fft->get_outbuf(), sizeof(gr_complex)*size);
-  }
 }
 
 void 
@@ -245,10 +254,6 @@ qtgui_sink_f::fftresize()
 
   if(newfftsize != d_fftsize) {
 
-    // Resize the fftdata buffer; no need to preserve old data
-    delete [] d_fftdata;
-    d_fftdata = new gr_complex[newfftsize];
-
     // Resize residbuf and replace data
     delete [] d_residbuf;
     d_residbuf = new float[newfftsize];
@@ -274,46 +279,44 @@ qtgui_sink_f::general_work (int noutput_items,
                            gr_vector_const_void_star &input_items,
                            gr_vector_void_star &output_items)
 {
-  int i=0, j=0;
+  int j=0;
   const float *in = (const float*)input_items[0];
 
   pthread_mutex_lock(&d_pmutex);
 
-  if(d_index) {
-    int filler = std::min(d_fftsize - d_index, noutput_items);
-    memcpy(&d_residbuf[d_index], &in[0], sizeof(float)*filler);
-    d_index += filler;
-    i = filler;
-    j = filler;
-  }
+  // Update the FFT size from the application
+  fftresize();
+  windowreset();
 
-  if(d_index == d_fftsize) {
-    d_index = 0;
-    fft(d_residbuf, d_fftsize, d_fftdata);
-    
-    d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize,
-                            d_residbuf, d_fftsize, NULL, 0,
-                            1.0/4.0, convert_to_timespec(0.0), true);
-  }
-  
-  for(; i < noutput_items; i+=d_fftsize) {
-    if(noutput_items - i > d_fftsize) {
-      j += d_fftsize;
-      fft(&in[i], d_fftsize, d_fftdata);
+  for(int i=0; i < noutput_items; i+=d_fftsize) {
+    unsigned int datasize = noutput_items - i;
+    unsigned int resid = d_fftsize-d_index;
+
+    // If we have enough input for one full FFT, do it
+    if(datasize >= resid) {
+      const timespec currentTime = get_highres_clock();
       
-      d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, &in[i],
-                              d_fftsize, NULL, 0, 1.0/4.0,
-                              convert_to_timespec(0.0), true);
-    }
-  }
+      // Fill up residbuf with d_fftsize number of items
+      memcpy(d_residbuf+d_index, &in[j], sizeof(float)*resid);
+      d_index = 0;
 
-  if(noutput_items > j) {
-    d_index = noutput_items - j;
-    memcpy(d_residbuf, &in[j], sizeof(float)*d_index);
+      j += resid;
+      fft(d_residbuf, d_fftsize);
+      
+      d_main_gui->UpdateWindow(true, d_fft->get_outbuf(), d_fftsize,
+                              (float*)d_residbuf, d_fftsize, NULL, 0,
+                              currentTime, true);
+    }
+    // Otherwise, copy what we received into the residbuf for next time
+    else {
+      memcpy(d_residbuf+d_index, &in[j], sizeof(float)*datasize);
+      d_index += datasize;
+      j += datasize;
+    }   
   }
 
   pthread_mutex_unlock(&d_pmutex);
 
-  consume_each(noutput_items);
-  return noutput_items;
+  consume_each(j);
+  return j;
 }
index 4c24b4983faad33fe1c3a08fc50f169f6156827d..f603da7b6ac990f2e0b4756b9ca9d22653d3367f 100644 (file)
@@ -63,6 +63,8 @@ private:
                bool use_openGL,
                QWidget *parent);
 
+  void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
   void initialize(const bool opengl=true);
 
   int d_fftsize;
@@ -76,20 +78,21 @@ private:
 
   bool d_shift;
   gri_fft_complex *d_fft;
-  gr_complex *d_fftdata;
 
   int d_index;
   float *d_residbuf;
 
   bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst;
 
+  double d_update_time;
+
   QWidget *d_parent;
   SpectrumGUIClass *d_main_gui; 
 
   void windowreset();
   void buildwindow();
   void fftresize();
-  void fft(const float *data_in, int size, gr_complex *data_out);
+  void fft(const float *data_in, int size);
   
 public:
   ~qtgui_sink_f();
@@ -105,8 +108,11 @@ public:
   void set_time_domain_axis(double min, double max);
   void set_constellation_axis(double xmin, double xmax,
                              double ymin, double ymax);
+  void set_constellation_pen_size(int size);
   void set_frequency_axis(double min, double max);
 
+  void set_update_time(double t);
+
   QApplication *d_qApplication;
   qtgui_obj *d_object;
 
index 2da37d350e7db7ca8d475c8617ad5bbe3b2103ac..53a205fb78b1da79c8e865262b064ca5cc4f96c5 100644 (file)
@@ -8,7 +8,6 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints,
                                         const double* realTimeDomainPoints,
                                         const double* imagTimeDomainPoints,
                                         const uint64_t numTimeDomainDataPoints,
-                                        const double timePerFFT,
                                         const timespec dataTimestamp,
                                         const bool repeatDataFlag,
                                         const bool lastOfMultipleUpdateFlag,
@@ -16,15 +15,19 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints,
                                         const int droppedFFTFrames)
   : QEvent(QEvent::Type(10005))
 {
-  _numFFTDataPoints = numFFTDataPoints;
-  if(_numFFTDataPoints < 1){
+  if(numFFTDataPoints < 1) {
     _numFFTDataPoints = 1;
   }
+  else {
+    _numFFTDataPoints = numFFTDataPoints;
+  }
 
-  _numTimeDomainDataPoints = numTimeDomainDataPoints;
-  if(_numTimeDomainDataPoints < 1){
+  if(numTimeDomainDataPoints < 1) {
     _numTimeDomainDataPoints = 1;
   }
+  else {
+    _numTimeDomainDataPoints = numTimeDomainDataPoints;
+  }
 
   _fftPoints = new std::complex<float>[_numFFTDataPoints];
   _fftPoints[0] = std::complex<float>(0,0);
@@ -32,26 +35,26 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints,
 
   _realDataTimeDomainPoints = new double[_numTimeDomainDataPoints];
   memset(_realDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double));
-  if(numTimeDomainDataPoints > 0){
+  if(numTimeDomainDataPoints > 0) {
     memcpy(_realDataTimeDomainPoints, realTimeDomainPoints,
           numTimeDomainDataPoints*sizeof(double));
   }
 
   _imagDataTimeDomainPoints = new double[_numTimeDomainDataPoints];
   memset(_imagDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double));
-  if(numTimeDomainDataPoints > 0){
+  if(numTimeDomainDataPoints > 0) {
     memcpy(_imagDataTimeDomainPoints, imagTimeDomainPoints,
           numTimeDomainDataPoints*sizeof(double));
   }
   _dataTimestamp = dataTimestamp;
-  _timePerFFT = timePerFFT;
   _repeatDataFlag = repeatDataFlag;
   _lastOfMultipleUpdateFlag = lastOfMultipleUpdateFlag;
   _eventGeneratedTimestamp = generatedTimestamp;
   _droppedFFTFrames = droppedFFTFrames;
 }
 
-SpectrumUpdateEvent::~SpectrumUpdateEvent(){
+SpectrumUpdateEvent::~SpectrumUpdateEvent()
+{
   delete[] _fftPoints;
   delete[] _realDataTimeDomainPoints;
   delete[] _imagDataTimeDomainPoints;
@@ -87,12 +90,6 @@ SpectrumUpdateEvent::getNumTimeDomainDataPoints() const
   return _numTimeDomainDataPoints;
 }
 
-double
-SpectrumUpdateEvent::getTimePerFFT() const
-{
-  return _timePerFFT;
-}
-
 timespec
 SpectrumUpdateEvent::getDataTimestamp() const
 {
index 75fa273243a62fcde60f674011dbeda64d46cda7..ccc072c3e3387e43243d3066e08ac819d638be31 100644 (file)
 class SpectrumUpdateEvent:public QEvent{
 
 public:
-  SpectrumUpdateEvent(const std::complex<float>* fftPoints, const uint64_t numFFTDataPoints, const double* realTimeDomainPoints, const double* imagTimeDomainPoints, const uint64_t numTimeDomainDataPoints, const double timePerFFT, const timespec dataTimestamp, const bool repeatDataFlag, const bool lastOfMultipleUpdateFlag, const timespec generatedTimestamp, const int droppedFFTFrames);
+  SpectrumUpdateEvent(const std::complex<float>* fftPoints,
+                     const uint64_t numFFTDataPoints,
+                     const double* realTimeDomainPoints,
+                     const double* imagTimeDomainPoints,
+                     const uint64_t numTimeDomainDataPoints,
+                     const timespec dataTimestamp,
+                     const bool repeatDataFlag,
+                     const bool lastOfMultipleUpdateFlag,
+                     const timespec generatedTimestamp,
+                     const int droppedFFTFrames);
+
   ~SpectrumUpdateEvent();
-  const std::complex<float>* getFFTPoints()const;
-  const double* getRealTimeDomainPoints()const;
-  const double* getImagTimeDomainPoints()const;
-  uint64_t getNumFFTDataPoints()const;
-  uint64_t getNumTimeDomainDataPoints()const;
-  double getTimePerFFT()const;
-  timespec getDataTimestamp()const;
-  bool getRepeatDataFlag()const;
-  bool getLastOfMultipleUpdateFlag()const;
-  timespec getEventGeneratedTimestamp()const;
-  int getDroppedFFTFrames()const;
+
+  const std::complex<float>* getFFTPoints() const;
+  const double* getRealTimeDomainPoints() const;
+  const double* getImagTimeDomainPoints() const;
+  uint64_t getNumFFTDataPoints() const;
+  uint64_t getNumTimeDomainDataPoints() const;
+  timespec getDataTimestamp() const;
+  bool getRepeatDataFlag() const;
+  bool getLastOfMultipleUpdateFlag() const;
+  timespec getEventGeneratedTimestamp() const;
+  int getDroppedFFTFrames() const;
 
 protected:
 
@@ -32,7 +42,6 @@ private:
   double* _imagDataTimeDomainPoints;
   uint64_t _numFFTDataPoints;
   uint64_t _numTimeDomainDataPoints;
-  double _timePerFFT;
   timespec _dataTimestamp;
   bool _repeatDataFlag;
   bool _lastOfMultipleUpdateFlag;
index 427e70a271c21de76b87e5919b223c0e73c21f5f..f52a63d1f0a85c0ff555a8036b19fd0530e90567 100644 (file)
@@ -18,7 +18,7 @@ SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent)
   _waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame);
 
   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
-    _waterfall3DDisplayPlot = new Waterfall3DDisplayPlot(Waterfall3DPlotDisplayFrame);
+    //_waterfall3DDisplayPlot = new Waterfall3DDisplayPlot(Waterfall3DPlotDisplayFrame);
   }
 
   _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame);
@@ -28,8 +28,7 @@ SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent)
   _averagedValues = new double[_numRealDataPoints];
   _historyVector = new std::vector<double*>;
   
-  AvgLineEdit->setValidator(_intValidator);
-  PowerLineEdit->setValidator(_intValidator);
+  AvgLineEdit->setRange(0, 500);                 // Set range of Average box value from 0 to 500
   MinHoldCheckBox_toggled( false );
   MaxHoldCheckBox_toggled( false );
   
@@ -72,6 +71,10 @@ SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent)
   ToggleTabWaterfall3D(false);
   ToggleTabTime(false);
   ToggleTabConstellation(false);
+
+  // Create a timer to update plots at the specified rate
+  displayTimer = new QTimer(this);
+  connect(displayTimer, SIGNAL(timeout()), this, SLOT(UpdateGuiTimer()));
 }
 
 SpectrumDisplayForm::~SpectrumDisplayForm()
@@ -79,7 +82,7 @@ SpectrumDisplayForm::~SpectrumDisplayForm()
   // Qt deletes children when parent is deleted
 
   // Don't worry about deleting Display Plots - they are deleted when parents are deleted
-  /*   delete _intValidator; */
+  delete _intValidator;
 
   delete[] _realFFTDataPoints;
   delete[] _averagedValues;
@@ -89,6 +92,9 @@ SpectrumDisplayForm::~SpectrumDisplayForm()
   }
 
   delete _historyVector;
+
+  displayTimer->stop();
+  delete displayTimer;
 }
 
 void
@@ -110,13 +116,13 @@ SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem,
 void
 SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdateEvent)
 {
+  //_lastSpectrumEvent = (SpectrumUpdateEvent)(*spectrumUpdateEvent);
   const std::complex<float>* complexDataPoints = spectrumUpdateEvent->getFFTPoints();
   const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints();
   const double* realTimeDomainDataPoints = spectrumUpdateEvent->getRealTimeDomainPoints();
   const double* imagTimeDomainDataPoints = spectrumUpdateEvent->getImagTimeDomainPoints();
   const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints();
-  const double timePerFFT = spectrumUpdateEvent->getTimePerFFT();
-  const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp();;
+  const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp();
   const bool repeatDataFlag = spectrumUpdateEvent->getRepeatDataFlag();
   const bool lastOfMultipleUpdatesFlag = spectrumUpdateEvent->getLastOfMultipleUpdateFlag();
   const timespec generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp();
@@ -125,45 +131,55 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate
   ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
 
   // Calculate the Magnitude of the complex point
-  const std::complex<float>* complexDataPointsPtr = complexDataPoints;
+  const std::complex<float>* complexDataPointsPtr = complexDataPoints+numFFTDataPoints/2;
   double* realFFTDataPointsPtr = _realFFTDataPoints;
-  for(uint64_t point = 0; point < numFFTDataPoints; point++){
-    // Calculate dBm
-    // 50 ohm load assumption
-    // 10 * log10 (v^2 / (2 * 50.0 * .001)) = 10 * log10( v^2 * 10)
-    // 75 ohm load assumption
-    // 10 * log10 (v^2 / (2 * 75.0 * .001)) = 10 * log10( v^2 * 15)
+
+  double sumMean, localPeakAmplitude, localPeakFrequency;
+  const double fftBinSize = (_stopFrequency-_startFrequency) /
+    static_cast<double>(numFFTDataPoints);
+  localPeakAmplitude = -HUGE_VAL;
+  sumMean = 0.0;
+
+  // Run this twice to perform the fftshift operation on the data here as well
+  std::complex<float> scaleFactor = std::complex<float>((float)numFFTDataPoints);
+  for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
+    std::complex<float> pt = (*complexDataPointsPtr) / scaleFactor;
+    *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
+
+    if(*realFFTDataPointsPtr > localPeakAmplitude) {
+      localPeakFrequency = static_cast<float>(point) * fftBinSize;
+      localPeakAmplitude = *realFFTDataPointsPtr;
+    }
+    sumMean += *realFFTDataPointsPtr;
     
-    *realFFTDataPointsPtr = 10.0*log10((((*complexDataPointsPtr).real() * (*complexDataPointsPtr).real()) +
-                                       ((*complexDataPointsPtr).imag()*(*complexDataPointsPtr).imag())) + 1e-20);
+    complexDataPointsPtr++;
+    realFFTDataPointsPtr++;
+  }
+  
+  // This loop takes the first half of the input data and puts it in the 
+  // second half of the plotted data
+  complexDataPointsPtr = complexDataPoints;
+  for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
+    std::complex<float> pt = (*complexDataPointsPtr) / scaleFactor;
+    *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
+
+    if(*realFFTDataPointsPtr > localPeakAmplitude) {
+      localPeakFrequency = static_cast<float>(point) * fftBinSize;
+      localPeakAmplitude = *realFFTDataPointsPtr;
+    }
+    sumMean += *realFFTDataPointsPtr;
 
     complexDataPointsPtr++;
     realFFTDataPointsPtr++;
   }
-  int tabindex = SpectrumTypeTab->currentIndex();
 
   // Don't update the averaging history if this is repeated data
   if(!repeatDataFlag){
     _AverageHistory(_realFFTDataPoints);
 
-    double sumMean;
-    const double fft_bin_size = (_stopFrequency-_startFrequency) /
-      static_cast<double>(numFFTDataPoints);
-
-    // find the peak, sum (for mean), etc
-    _peakAmplitude = -HUGE_VAL;
-    sumMean = 0.0;
-    for(uint64_t number = 0; number < numFFTDataPoints; number++){
-      // find peak
-      if(_realFFTDataPoints[number] > _peakAmplitude){
-        _peakFrequency = (static_cast<float>(number) * fft_bin_size);  // Calculate the frequency relative to the local bw, adjust for _startFrequency later
-        _peakAmplitude = _realFFTDataPoints[number];
-        // _peakBin = number;
-      }
-      // sum (for mean)
-      sumMean += _realFFTDataPoints[number];
-    }
+    // Only use the local info if we are not repeating data
+    _peakAmplitude = localPeakAmplitude;
+    _peakFrequency = localPeakFrequency;
 
     // calculate the spectral mean
     // +20 because for the comparison below we only want to throw out bins
@@ -187,38 +203,44 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate
   }
 
   if(lastOfMultipleUpdatesFlag){
+    int tabindex = SpectrumTypeTab->currentIndex();
     if(tabindex == d_plot_fft) {
       _frequencyDisplayPlot->PlotNewData(_averagedValues, numFFTDataPoints, 
                                         _noiseFloorAmplitude, _peakFrequency, 
-                                        _peakAmplitude);
+                                        _peakAmplitude, d_update_time);
     }
     if(tabindex == d_plot_time) {
       _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
                                          imagTimeDomainDataPoints, 
-                                         numTimeDomainDataPoints);
+                                         numTimeDomainDataPoints,
+                                         d_update_time);
     }
     if(tabindex == d_plot_constellation) {
       _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
                                             imagTimeDomainDataPoints, 
-                                            numTimeDomainDataPoints);
+                                            numTimeDomainDataPoints,
+                                            d_update_time);
     }
 
     // Don't update the repeated data for the waterfall
     if(!repeatDataFlag){
       if(tabindex == d_plot_waterfall) {
        _waterfallDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
-                                          timePerFFT, dataTimestamp, 
+                                          d_update_time, dataTimestamp, 
                                           spectrumUpdateEvent->getDroppedFFTFrames());
       }
+      /*
       if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
        if( _openGLWaterfall3DFlag == 1 && (tabindex == d_plot_waterfall3d)) {
          _waterfall3DDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
-                                              timePerFFT, dataTimestamp, 
+                                              d_update_time, dataTimestamp, 
                                               spectrumUpdateEvent->getDroppedFFTFrames());
        }
       }
+      */
     }
 
+    
     // Tell the system the GUI has been updated
     if(_systemSpecifiedFlag){
       _system->SetLastGUIUpdateTime(generatedTimestamp);
@@ -230,112 +252,29 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate
 void
 SpectrumDisplayForm::resizeEvent( QResizeEvent *e )
 {
-  // Let the actual window resize its width, but not its height
-  QSize newSize(e->size().width(), e->oldSize().height());
-  QResizeEvent et(newSize, e->oldSize());
-  QWidget::resizeEvent(&et);
+  QSize s;
+  s.setWidth(FrequencyPlotDisplayFrame->width());
+  s.setHeight(FrequencyPlotDisplayFrame->height());
+  emit _frequencyDisplayPlot->resizeSlot(&s);
 
-  // Tell the Tab Window to Resize
-  SpectrumTypeTab->resize( e->size().width(), e->size().height()-60);
+  s.setWidth(TimeDomainDisplayFrame->width());
+  s.setHeight(TimeDomainDisplayFrame->height());
+  emit _timeDomainDisplayPlot->resizeSlot(&s);
+
+  s.setWidth(WaterfallPlotDisplayFrame->width());
+  s.setHeight(WaterfallPlotDisplayFrame->height());
+  emit _waterfallDisplayPlot->resizeSlot(&s);
 
-  // Tell the TabXFreqDisplay to resize
-  FrequencyPlotDisplayFrame->resize(e->size().width()-4,
-                                   e->size().height()-140);
-  _frequencyDisplayPlot->resize( FrequencyPlotDisplayFrame->width()-4,
-                                e->size().height()-140);
-  
-  // Move the Power Lbl and Line Edit
-  PowerLabel->move(e->size().width()-(415-324) - PowerLabel->width(),
-                  e->size().height()-135);
-  PowerLineEdit->move(e->size().width()-(415-318) - PowerLineEdit->width(),
-                     e->size().height()-115);
-  
-  // Move the Avg Lbl and Line Edit
-  AvgLabel->move(e->size().width()-(415-406) - AvgLabel->width(),
-                e->size().height()-135);
-  AvgLineEdit->move(e->size().width()-(415-400) - AvgLineEdit->width(),
-                   e->size().height()-115);
-  
-  // Move Max and Min check boxes
-  MaxHoldCheckBox->move(MaxHoldCheckBox->x(),
-                       e->size().height()-135);
-  MaxHoldResetBtn->move(MaxHoldResetBtn->x(),
-                       e->size().height()-135);
-  MinHoldCheckBox->move(MinHoldCheckBox->x(),
-                       e->size().height()-115);
-  MinHoldResetBtn->move(MinHoldResetBtn->x(),
-                       e->size().height()-115);
-
-  WaterfallPlotDisplayFrame->resize(e->size().width()-4,
-                                   e->size().height()-140);
-  _waterfallDisplayPlot->resize( WaterfallPlotDisplayFrame->width()-4,
-                                e->size().height()-140);
-  
-  // Move the IntensityWheels and Labels
-  WaterfallMaximumIntensityLabel->move(width() - 5 -
-                                      WaterfallMaximumIntensityLabel->width(),
-                                      WaterfallMaximumIntensityLabel->y());
-  WaterfallMaximumIntensityWheel->resize(WaterfallMaximumIntensityLabel->x() - 5 -
-                                        WaterfallMaximumIntensityWheel->x(),
-                                        WaterfallMaximumIntensityWheel->height());
-  
-  WaterfallMinimumIntensityLabel->move(width() - 5 -
-                                      WaterfallMinimumIntensityLabel->width(),
-                                      height() - 115);
-  WaterfallMinimumIntensityWheel->resize(WaterfallMinimumIntensityLabel->x() - 5 -
-                                        WaterfallMinimumIntensityWheel->x(),
-                                        WaterfallMaximumIntensityWheel->height());
-  WaterfallMinimumIntensityWheel->move(WaterfallMinimumIntensityWheel->x(),
-                                      height() - 115);
-  WaterfallAutoScaleBtn->move(WaterfallAutoScaleBtn->x(),
-                             e->size().height()-115);
-  
   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
-    Waterfall3DPlotDisplayFrame->resize(e->size().width()-4,
-                                       e->size().height()-140);
-    _waterfall3DDisplayPlot->resize( Waterfall3DPlotDisplayFrame->width()-4,
-                                    e->size().height()-140);
-
-    Waterfall3DMaximumIntensityLabel->move(width() - 5 -
-                                          Waterfall3DMaximumIntensityLabel->width(),
-                                          Waterfall3DMaximumIntensityLabel->y());
-    Waterfall3DMaximumIntensityWheel->resize(Waterfall3DMaximumIntensityLabel->x() - 5 -
-                                            Waterfall3DMaximumIntensityWheel->x(),
-                                            Waterfall3DMaximumIntensityWheel->height());
-    Waterfall3DMinimumIntensityLabel->move(width() - 5 -
-                                          Waterfall3DMinimumIntensityLabel->width(),
-                                          height() - 115);
-    Waterfall3DMinimumIntensityWheel->resize(Waterfall3DMinimumIntensityLabel->x() - 5 -
-                                            Waterfall3DMinimumIntensityWheel->x(),
-                                            Waterfall3DMaximumIntensityWheel->height());
-    Waterfall3DMinimumIntensityWheel->move(Waterfall3DMinimumIntensityWheel->x(),
-                                          height() - 115);
-    Waterfall3DAutoScaleBtn->move(WaterfallAutoScaleBtn->x(),
-                                 e->size().height()-115);
+    s.setWidth(Waterfall3DPlotDisplayFrame->width());
+    s.setHeight(Waterfall3DPlotDisplayFrame->height());
+    //emit _waterfall3DDisplayPlot->resizeSlot(&s);
   }
-  
-  TimeDomainDisplayFrame->resize(e->size().width()-4,
-                                e->size().height()-140);
-  _timeDomainDisplayPlot->resize( TimeDomainDisplayFrame->width()-4,
-                                 e->size().height()-140);
-  
-  ConstellationDisplayFrame->resize(e->size().width()-4,
-                                   e->size().height()-140);
-  _constellationDisplayPlot->resize( TimeDomainDisplayFrame->width()-4,
-                                    e->size().height()-140);
-  
-  // Move the FFT Size Combobox and label
-  FFTSizeComboBox->move(width() - 5 - FFTSizeComboBox->width(),
-                       height()-50);
-  FFTSizeLabel->move(width() - 10 - FFTSizeComboBox->width() - FFTSizeLabel->width(),
-                    height()-50);
-  
-  // Move the lower check and combo boxes
-  UseRFFrequenciesCheckBox->move(UseRFFrequenciesCheckBox->x(), height()-50);
-  WindowLbl->move(WindowLbl->x(), height()-25);
-  WindowComboBox->move(WindowComboBox->x(), height()-25);
-}
 
+  s.setWidth(ConstellationDisplayFrame->width());
+  s.setHeight(ConstellationDisplayFrame->height());
+  emit _constellationDisplayPlot->resizeSlot(&s);
+}
 
 void
 SpectrumDisplayForm::customEvent( QEvent * e)
@@ -345,7 +284,6 @@ SpectrumDisplayForm::customEvent( QEvent * e)
       WindowComboBox->setCurrentIndex(_system->GetWindowType());
       FFTSizeComboBox->setCurrentIndex(_system->GetFFTSizeIndex());
       //FFTSizeComboBox->setCurrentIndex(1);
-      PowerLineEdit_textChanged(PowerLineEdit->text());
     }
 
     waterfallMinimumIntensityChangedCB(WaterfallMinimumIntensityWheel->value());
@@ -357,6 +295,7 @@ SpectrumDisplayForm::customEvent( QEvent * e)
       waterfall3DMaximumIntensityChangedCB(Waterfall3DMaximumIntensityWheel->value());
       
       // Check for Hardware Acceleration of the OpenGL
+      /*
       if(!_waterfall3DDisplayPlot->format().directRendering()){
        // Only ask this once while the program is running...
        if(_openGLWaterfall3DFlag == -1){
@@ -369,6 +308,7 @@ SpectrumDisplayForm::customEvent( QEvent * e)
       else{
        _openGLWaterfall3DFlag = 1;
       }
+      */
     }
     
     if(_openGLWaterfall3DFlag != 1){
@@ -401,16 +341,23 @@ SpectrumDisplayForm::customEvent( QEvent * e)
 }
 
 void
-SpectrumDisplayForm::AvgLineEdit_textChanged( const QString &valueString )
+SpectrumDisplayForm::UpdateGuiTimer()
 {
-  if(!valueString.isEmpty()){
-    int value = valueString.toInt();
-    if(value > 500){
-      value = 500;
-      AvgLineEdit->setText("500");
-    }
-    SetAverageCount(value);
-  }
+  // This is called by the displayTimer and redraws the canvases of
+  // all of the plots.
+  _frequencyDisplayPlot->canvas()->update();
+  _waterfallDisplayPlot->canvas()->update();
+  //if((QGLFormat::hasOpenGL()) && (_useOpenGL))
+  //_waterfall3DDisplayPlot->canvas()->update();
+  _timeDomainDisplayPlot->canvas()->update();
+  _constellationDisplayPlot->canvas()->update();
+}
+
+
+void
+SpectrumDisplayForm::AvgLineEdit_valueChanged( int value )
+{
+  SetAverageCount(value);
 }
 
 
@@ -449,27 +396,10 @@ SpectrumDisplayForm::MaxHoldResetBtn_clicked()
 
 
 void
-SpectrumDisplayForm::PowerLineEdit_textChanged( const QString &valueString )
+SpectrumDisplayForm::TabChanged(int index)
 {
-  if(_systemSpecifiedFlag){
-    if(!valueString.isEmpty()){
-      double value = valueString.toDouble();
-      if(value < 1.0){
-       value = 1.0;
-       PowerLineEdit->setText("1");
-      }
-      _system->SetPowerValue(value);
-    }
-
-    if(_system->GetPowerValue() > 1){
-      UseRFFrequenciesCheckBox->setChecked(false);
-      UseRFFrequenciesCheckBox->setEnabled(false);
-      UseRFFrequenciesCB(false);
-    }
-    else{
-      UseRFFrequenciesCheckBox->setEnabled(true);
-    }
-  }
+  // This might be dangerous to call this with NULL
+  resizeEvent(NULL);  
 }
 
 void
@@ -487,6 +417,7 @@ SpectrumDisplayForm::SetFrequencyRange(const double newCenterFrequency,
 
   if(fdiff > 0) {
     std::string strunits[4] = {"Hz", "kHz", "MHz", "GHz"};
+    std::string strtime[4] = {"sec", "ms", "us", "ns"};
     double units10 = floor(log10(fdiff));
     double units3  = std::max(floor(units10 / 3.0), 0.0);
     double units = pow(10, (units10-fmod(units10, 3.0)));
@@ -496,23 +427,27 @@ SpectrumDisplayForm::SetFrequencyRange(const double newCenterFrequency,
     _stopFrequency = newStopFrequency;
     _centerFrequency = newCenterFrequency;
 
-    _frequencyDisplayPlot->SetFrequencyRange(newStartFrequency,
-                                            newStopFrequency,
-                                            newCenterFrequency,
+    _frequencyDisplayPlot->SetFrequencyRange(_startFrequency,
+                                            _stopFrequency,
+                                            _centerFrequency,
                                             UseRFFrequenciesCheckBox->isChecked(),
                                             units, strunits[iunit]);
-    _waterfallDisplayPlot->SetFrequencyRange(newStartFrequency,
-                                            newStopFrequency,
-                                            newCenterFrequency,
+    _waterfallDisplayPlot->SetFrequencyRange(_startFrequency,
+                                            _stopFrequency,
+                                            _centerFrequency,
                                             UseRFFrequenciesCheckBox->isChecked(),
                                             units, strunits[iunit]);
     if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
-      _waterfall3DDisplayPlot->SetFrequencyRange(newStartFrequency,
-                                                newStopFrequency,
-                                                newCenterFrequency,
+      /*
+      _waterfall3DDisplayPlot->SetFrequencyRange(_startFrequency,
+                                                _stopFrequency,
+                                                _centerFrequency,
                                                 UseRFFrequenciesCheckBox->isChecked(),
                                                 units, strunits[iunit]);
+      */
     }
+    _timeDomainDisplayPlot->SetSampleRate(_stopFrequency - _startFrequency,
+                                         units, strtime[iunit]);
   }
 }
 
@@ -602,7 +537,7 @@ SpectrumDisplayForm::Reset()
 
   _waterfallDisplayPlot->Reset();
   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
-    _waterfall3DDisplayPlot->Reset();
+    //_waterfall3DDisplayPlot->Reset();
   }
 }
 
@@ -688,9 +623,11 @@ SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue )
     else{
       Waterfall3DMaximumIntensityWheel->setValue(Waterfall3DMinimumIntensityWheel->value());
     }
-    
+
+    /*
     _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
                                               Waterfall3DMaximumIntensityWheel->value());
+    */
   }
 }
 
@@ -705,9 +642,11 @@ SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue )
     else{
       Waterfall3DMinimumIntensityWheel->setValue(Waterfall3DMaximumIntensityWheel->value());
     }
-    
+
+    /*
     _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
                                               Waterfall3DMaximumIntensityWheel->value());
+    */
   }
 }
 
@@ -804,8 +743,10 @@ SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType )
       QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display",  QMessageBox::Ok);
       highIntensityColor = QColorDialog::getColor(highIntensityColor, this);
     }
+    /*
     _waterfall3DDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor,
                                                      highIntensityColor);
+    */
   }
 }
 
@@ -844,12 +785,17 @@ void
 SpectrumDisplayForm::ToggleTabWaterfall3D(const bool state)
 {
   if(state == true) {
+    /*
     if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
       if(d_plot_waterfall3d == -1) {
        SpectrumTypeTab->addTab(Waterfall3DPage, "3D Waterfall Display");
        d_plot_waterfall3d = SpectrumTypeTab->count()-1;
       }
     }
+    */
+    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage));
+    d_plot_waterfall3d = -1;
+    fprintf(stderr, "\nWARNING: The Waterfall3D plot has been disabled until we get it working.\n\n");
   }
   else {
     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage));
@@ -901,8 +847,22 @@ SpectrumDisplayForm::SetConstellationAxis(double xmin, double xmax,
   _constellationDisplayPlot->set_axis(xmin, xmax, ymin, ymax);
 }
 
+void
+SpectrumDisplayForm::SetConstellationPenSize(int size)
+{
+  _constellationDisplayPlot->set_pen_size( size );
+}
+
 void
 SpectrumDisplayForm::SetFrequencyAxis(double min, double max)
 {
   _frequencyDisplayPlot->set_yaxis(min, max);
 }
+
+void
+SpectrumDisplayForm::SetUpdateTime(double t)
+{
+  d_update_time = t;
+  // QTimer class takes millisecond input
+  displayTimer->start(d_update_time*1000);
+}
index bf8023209139b45f57c80b960a520bfee4750aeb..bf2af703354439780aaa8f426b1eb22b6108a9cf 100644 (file)
@@ -13,6 +13,7 @@ class SpectrumGUIClass;
 #include <TimeDomainDisplayPlot.h>
 #include <ConstellationDisplayPlot.h>
 #include <QValidator>
+#include <QTimer>
 #include <vector>
 
 class SpectrumDisplayForm : public QWidget, public Ui::SpectrumDisplayForm
@@ -36,12 +37,13 @@ class SpectrumDisplayForm : public QWidget, public Ui::SpectrumDisplayForm
 public slots:
   void resizeEvent( QResizeEvent * e );
   void customEvent( QEvent * e );
-  void AvgLineEdit_textChanged( const QString & valueString );
+  void AvgLineEdit_valueChanged( int valueString );
   void MaxHoldCheckBox_toggled( bool newState );
   void MinHoldCheckBox_toggled( bool newState );
   void MinHoldResetBtn_clicked();
   void MaxHoldResetBtn_clicked();
-  void PowerLineEdit_textChanged( const QString& valueString );
+  void TabChanged(int index);
+
   void SetFrequencyRange( const double newCenterFrequency,
                          const double newStartFrequency,
                          const double newStopFrequency );
@@ -67,10 +69,13 @@ public slots:
   void SetTimeDomainAxis(double min, double max);
   void SetConstellationAxis(double xmin, double xmax,
                            double ymin, double ymax);
+  void SetConstellationPenSize(int size);
   void SetFrequencyAxis(double min, double max);
+  void SetUpdateTime(double t);
 
 private slots:
   void newFrequencyData( const SpectrumUpdateEvent* );
+  void UpdateGuiTimer();
 
 protected:
 
@@ -99,13 +104,18 @@ private:
   double _peakAmplitude;
   static int _openGLWaterfall3DFlag;
   double _stopFrequency;
-
+  
+  //SpectrumUpdateEvent _lastSpectrumEvent;
+  
   // whether or not to use a particular display
   int d_plot_fft;
   int d_plot_waterfall;
   int d_plot_waterfall3d;
   int d_plot_time;
   int d_plot_constellation;
+
+  QTimer *displayTimer;
+  double d_update_time;
 };
 
 #endif /* SPECTRUM_DISPLAY_FORM_H */
index 96096030d8a404a1fd8459d3fca65129e5b09e32..0e652d8337d78b90a31f95c1c777a63df9455367 100644 (file)
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>SpectrumDisplayForm</class>
- <widget class="QWidget" name="SpectrumDisplayForm" >
-  <property name="geometry" >
+ <widget class="QWidget" name="SpectrumDisplayForm">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>633</width>
-    <height>436</height>
+    <width>712</width>
+    <height>543</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Spectrum Display</string>
   </property>
-  <widget class="QCheckBox" name="UseRFFrequenciesCheckBox" >
-   <property name="geometry" >
-    <rect>
-     <x>10</x>
-     <y>385</y>
-     <width>180</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text" >
-    <string>Display RF Frequencies</string>
-   </property>
-  </widget>
-  <widget class="QComboBox" name="WindowComboBox" >
-   <property name="geometry" >
-    <rect>
-     <x>105</x>
-     <y>410</y>
-     <width>170</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="font" >
-    <font>
-     <pointsize>9</pointsize>
-    </font>
-   </property>
-   <item>
-    <property name="text" >
-     <string>Hamming</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>Hann</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>Blackman</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>Rectangular</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>Kaiser</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>Blackman-harris</string>
-    </property>
-   </item>
-  </widget>
-  <widget class="QLabel" name="WindowLbl" >
-   <property name="geometry" >
-    <rect>
-     <x>10</x>
-     <y>410</y>
-     <width>90</width>
-     <height>17</height>
-    </rect>
-   </property>
-   <property name="text" >
-    <string>Window:</string>
-   </property>
-   <property name="alignment" >
-    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-   </property>
-   <property name="wordWrap" >
-    <bool>false</bool>
-   </property>
-  </widget>
-  <widget class="QLabel" name="FFTSizeLabel" >
-   <property name="geometry" >
-    <rect>
-     <x>405</x>
-     <y>385</y>
-     <width>116</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text" >
-    <string>FFT Size:</string>
-   </property>
-   <property name="alignment" >
-    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-   </property>
-   <property name="wordWrap" >
-    <bool>false</bool>
-   </property>
-  </widget>
-  <widget class="QComboBox" name="FFTSizeComboBox" >
-   <property name="geometry" >
-    <rect>
-     <x>525</x>
-     <y>385</y>
-     <width>100</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <item>
-    <property name="text" >
-     <string>1024</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>2048</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>4096</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>8192</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>16384</string>
-    </property>
-   </item>
-   <item>
-    <property name="text" >
-     <string>32768</string>
-    </property>
-   </item>
-  </widget>
-  <widget class="QTabWidget" name="SpectrumTypeTab" >
-   <property name="geometry" >
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>630</width>
-     <height>380</height>
-    </rect>
-   </property>
-   <property name="currentIndex" >
-    <number>0</number>
-   </property>
-   <widget class="QWidget" name="FrequencyPage" >
-    <attribute name="title" >
-     <string>Frequency Display</string>
-    </attribute>
-    <widget class="QLineEdit" name="PowerLineEdit" >
-     <property name="geometry" >
-      <rect>
-       <x>480</x>
-       <y>320</y>
-       <width>60</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>1</string>
-     </property>
-    </widget>
-    <widget class="QCheckBox" name="MinHoldCheckBox" >
-     <property name="geometry" >
-      <rect>
-       <x>10</x>
-       <y>325</y>
-       <width>95</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Min Hold</string>
-     </property>
-     <property name="checked" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QLabel" name="AvgLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>545</x>
-       <y>300</y>
-       <width>72</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Average</string>
-     </property>
-     <property name="alignment" >
-      <set>Qt::AlignCenter</set>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QPushButton" name="MinHoldResetBtn" >
-     <property name="geometry" >
-      <rect>
-       <x>105</x>
-       <y>325</y>
-       <width>61</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Reset</string>
-     </property>
-    </widget>
-    <widget class="QLineEdit" name="AvgLineEdit" >
-     <property name="geometry" >
-      <rect>
-       <x>550</x>
-       <y>320</y>
-       <width>60</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>0</string>
-     </property>
-    </widget>
-    <widget class="QLabel" name="PowerLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>475</x>
-       <y>300</y>
-       <width>72</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Power</string>
-     </property>
-     <property name="alignment" >
-      <set>Qt::AlignCenter</set>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QPushButton" name="MaxHoldResetBtn" >
-     <property name="geometry" >
-      <rect>
-       <x>105</x>
-       <y>300</y>
-       <width>61</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Reset</string>
-     </property>
-    </widget>
-    <widget class="QCheckBox" name="MaxHoldCheckBox" >
-     <property name="geometry" >
-      <rect>
-       <x>10</x>
-       <y>300</y>
-       <width>95</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>Max Hold</string>
-     </property>
-     <property name="checked" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QFrame" name="FrequencyPlotDisplayFrame" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>5</y>
-       <width>620</width>
-       <height>290</height>
-      </rect>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Plain</enum>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QWidget" name="WaterfallPage" >
-    <attribute name="title" >
-     <string>Waterfall Display</string>
-    </attribute>
-    <widget class="QLabel" name="textLabel1" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>0</y>
-       <width>85</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>&lt;font size="-2">Intensity Display:&lt;/font></string>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QComboBox" name="WaterfallIntensityComboBox" >
-     <property name="geometry" >
-      <rect>
-       <x>90</x>
-       <y>0</y>
-       <width>121</width>
-       <height>25</height>
-      </rect>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="1" column="3">
+    <widget class="QComboBox" name="FFTSizeComboBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>120</width>
+       <height>16777215</height>
+      </size>
      </property>
      <item>
-      <property name="text" >
-       <string>Color</string>
+      <property name="text">
+       <string>1024</string>
       </property>
      </item>
      <item>
-      <property name="text" >
-       <string>White Hot</string>
+      <property name="text">
+       <string>2048</string>
       </property>
      </item>
      <item>
-      <property name="text" >
-       <string>Black Hot</string>
+      <property name="text">
+       <string>4096</string>
       </property>
      </item>
      <item>
-      <property name="text" >
-       <string>Incandescent</string>
+      <property name="text">
+       <string>8192</string>
       </property>
      </item>
      <item>
-      <property name="text" >
-       <string>User Defined</string>
+      <property name="text">
+       <string>16384</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>32768</string>
       </property>
      </item>
     </widget>
-    <widget class="QwtWheel" name="WaterfallMaximumIntensityWheel" >
-     <property name="geometry" >
-      <rect>
-       <x>215</x>
-       <y>0</y>
-       <width>335</width>
-       <height>24</height>
-      </rect>
-     </property>
-     <property name="mouseTracking" >
-      <bool>true</bool>
-     </property>
-     <property name="focusPolicy" >
-      <enum>Qt::WheelFocus</enum>
-     </property>
-     <property name="valid" >
-      <bool>true</bool>
-     </property>
-     <property name="totalAngle" >
-      <double>200.000000000000000</double>
-     </property>
-     <property name="viewAngle" >
-      <double>20.000000000000000</double>
-     </property>
-     <property name="mass" >
-      <double>0.000000000000000</double>
-     </property>
-    </widget>
-    <widget class="QLabel" name="WaterfallMaximumIntensityLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>563</x>
-       <y>3</y>
-       <width>55</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>100 dB</string>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QFrame" name="WaterfallPlotDisplayFrame" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>30</y>
-       <width>615</width>
-       <height>295</height>
-      </rect>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Plain</enum>
-     </property>
-    </widget>
-    <widget class="QwtWheel" name="WaterfallMinimumIntensityWheel" >
-     <property name="geometry" >
-      <rect>
-       <x>215</x>
-       <y>325</y>
-       <width>335</width>
-       <height>24</height>
-      </rect>
-     </property>
-     <property name="valid" >
-      <bool>true</bool>
-     </property>
-     <property name="totalAngle" >
-      <double>200.000000000000000</double>
-     </property>
-     <property name="viewAngle" >
-      <double>20.000000000000000</double>
-     </property>
-     <property name="mass" >
-      <double>0.000000000000000</double>
-     </property>
-    </widget>
-    <widget class="QLabel" name="WaterfallMinimumIntensityLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>565</x>
-       <y>325</y>
-       <width>55</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>-100 dB</string>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QPushButton" name="WaterfallAutoScaleBtn" >
-     <property name="geometry" >
-      <rect>
-       <x>0</x>
-       <y>325</y>
-       <width>135</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="toolTip" >
-      <string>Scales the Intensity to the current data extremes.</string>
-     </property>
-     <property name="text" >
-      <string>Auto Scale</string>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QWidget" name="Waterfall3DPage" >
-    <attribute name="title" >
-     <string>3D Waterfall Display</string>
-    </attribute>
-    <widget class="QLabel" name="textLabel1_2" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>0</y>
-       <width>85</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>&lt;font size="-2">Intensity Display:&lt;/font></string>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QLabel" name="Waterfall3DMaximumIntensityLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>563</x>
-       <y>3</y>
-       <width>55</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="text" >
-      <string>100 dB</string>
-     </property>
-     <property name="wordWrap" >
-      <bool>false</bool>
-     </property>
-    </widget>
-    <widget class="QPushButton" name="Waterfall3DAutoScaleBtn" >
-     <property name="geometry" >
-      <rect>
-       <x>0</x>
-       <y>325</y>
-       <width>135</width>
-       <height>21</height>
-      </rect>
-     </property>
-     <property name="toolTip" >
-      <string>Scales the Intensity to the current data extremes.</string>
-     </property>
-     <property name="text" >
-      <string>Auto Scale</string>
-     </property>
-    </widget>
-    <widget class="QwtWheel" name="Waterfall3DMinimumIntensityWheel" >
-     <property name="geometry" >
-      <rect>
-       <x>215</x>
-       <y>325</y>
-       <width>335</width>
-       <height>24</height>
-      </rect>
-     </property>
-     <property name="valid" >
-      <bool>true</bool>
-     </property>
-     <property name="totalAngle" >
-      <double>200.000000000000000</double>
-     </property>
-     <property name="viewAngle" >
-      <double>20.000000000000000</double>
-     </property>
-     <property name="mass" >
-      <double>0.000000000000000</double>
-     </property>
-    </widget>
-    <widget class="QLabel" name="Waterfall3DMinimumIntensityLabel" >
-     <property name="geometry" >
-      <rect>
-       <x>565</x>
-       <y>325</y>
-       <width>55</width>
-       <height>20</height>
-      </rect>
+   </item>
+   <item row="1" column="2">
+    <widget class="QLabel" name="FFTSizeLabel">
+     <property name="text">
+      <string>FFT Size:</string>
      </property>
-     <property name="text" >
-      <string>-100 dB</string>
+     <property name="alignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
      </property>
-     <property name="wordWrap" >
+     <property name="wordWrap">
       <bool>false</bool>
      </property>
     </widget>
-    <widget class="QFrame" name="Waterfall3DPlotDisplayFrame" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>30</y>
-       <width>615</width>
-       <height>295</height>
-      </rect>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Plain</enum>
+   </item>
+   <item row="1" column="0">
+    <widget class="QCheckBox" name="UseRFFrequenciesCheckBox">
+     <property name="text">
+      <string>Display RF Frequencies</string>
      </property>
     </widget>
-    <widget class="QComboBox" name="Waterfall3DIntensityComboBox" >
-     <property name="geometry" >
-      <rect>
-       <x>90</x>
-       <y>0</y>
-       <width>121</width>
-       <height>25</height>
-      </rect>
-     </property>
-     <item>
-      <property name="text" >
-       <string>Color</string>
-      </property>
-     </item>
-     <item>
-      <property name="text" >
-       <string>White Hot</string>
-      </property>
-     </item>
-     <item>
-      <property name="text" >
-       <string>Black Hot</string>
-      </property>
-     </item>
+   </item>
+   <item row="3" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <property name="text" >
-       <string>Incandescent</string>
-      </property>
+      <widget class="QLabel" name="WindowLbl">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Window:</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
      </item>
      <item>
-      <property name="text" >
-       <string>User Defined</string>
-      </property>
+      <widget class="QComboBox" name="WindowComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>120</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>120</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>9</pointsize>
+        </font>
+       </property>
+       <item>
+        <property name="text">
+         <string>Hamming</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Hann</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Blackman</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Rectangular</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Kaiser</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Blackman-harris</string>
+        </property>
+       </item>
+      </widget>
      </item>
+    </layout>
+   </item>
+   <item row="0" column="0" colspan="4">
+    <widget class="QTabWidget" name="SpectrumTypeTab">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="FrequencyPage">
+      <attribute name="title">
+       <string>Frequency Display</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_2">
+         <item>
+          <widget class="QFrame" name="FrequencyPlotDisplayFrame">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>400</width>
+             <height>350</height>
+            </size>
+           </property>
+           <property name="sizeIncrement">
+            <size>
+             <width>1</width>
+             <height>1</height>
+            </size>
+           </property>
+           <property name="frameShape">
+            <enum>QFrame::NoFrame</enum>
+           </property>
+           <property name="frameShadow">
+            <enum>QFrame::Plain</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <layout class="QGridLayout" name="gridLayout_2">
+           <item row="1" column="0">
+            <widget class="QCheckBox" name="MaxHoldCheckBox">
+             <property name="text">
+              <string>Max Hold</string>
+             </property>
+             <property name="checked">
+              <bool>false</bool>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0">
+            <widget class="QCheckBox" name="MinHoldCheckBox">
+             <property name="text">
+              <string>Min Hold</string>
+             </property>
+             <property name="checked">
+              <bool>false</bool>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1">
+            <widget class="QPushButton" name="MaxHoldResetBtn">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>25</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="text">
+              <string>Reset</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="3">
+            <widget class="QLabel" name="AvgLabel">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>62</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="text">
+              <string>Average</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignCenter</set>
+             </property>
+             <property name="wordWrap">
+              <bool>false</bool>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1">
+            <widget class="QPushButton" name="MinHoldResetBtn">
+             <property name="text">
+              <string>Reset</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="3">
+            <widget class="QSpinBox" name="AvgLineEdit"/>
+           </item>
+           <item row="1" column="2">
+            <spacer name="horizontalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>200</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="WaterfallPage">
+      <attribute name="title">
+       <string>Waterfall Display</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_3">
+       <item row="0" column="0">
+        <widget class="QLabel" name="textLabel1">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Intensity Display:</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="2">
+        <widget class="QwtWheel" name="WaterfallMaximumIntensityWheel">
+         <property name="minimumSize">
+          <size>
+           <width>200</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="mouseTracking">
+          <bool>true</bool>
+         </property>
+         <property name="focusPolicy">
+          <enum>Qt::WheelFocus</enum>
+         </property>
+         <property name="valid">
+          <bool>true</bool>
+         </property>
+         <property name="totalAngle">
+          <double>200.000000000000000</double>
+         </property>
+         <property name="viewAngle">
+          <double>20.000000000000000</double>
+         </property>
+         <property name="mass">
+          <double>0.000000000000000</double>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="3">
+        <widget class="QLabel" name="WaterfallMaximumIntensityLabel">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>100 dB</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0" colspan="4">
+        <widget class="QFrame" name="WaterfallPlotDisplayFrame">
+         <property name="minimumSize">
+          <size>
+           <width>617</width>
+           <height>338</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Plain</enum>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QwtWheel" name="WaterfallMinimumIntensityWheel">
+         <property name="minimumSize">
+          <size>
+           <width>200</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="valid">
+          <bool>true</bool>
+         </property>
+         <property name="totalAngle">
+          <double>200.000000000000000</double>
+         </property>
+         <property name="viewAngle">
+          <double>20.000000000000000</double>
+         </property>
+         <property name="mass">
+          <double>0.000000000000000</double>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="3">
+        <widget class="QLabel" name="WaterfallMinimumIntensityLabel">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>-100 dB</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0" colspan="2">
+        <widget class="QPushButton" name="WaterfallAutoScaleBtn">
+         <property name="maximumSize">
+          <size>
+           <width>80</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Scales the Intensity to the current data extremes.</string>
+         </property>
+         <property name="text">
+          <string>Auto Scale</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QComboBox" name="WaterfallIntensityComboBox">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <item>
+          <property name="text">
+           <string>Color</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>White Hot</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>Black Hot</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>Incandescent</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>User Defined</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="Waterfall3DPage">
+      <attribute name="title">
+       <string>3D Waterfall Display</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_6">
+       <item row="0" column="0">
+        <widget class="QLabel" name="textLabel1_2">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Intensity Display:</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QComboBox" name="Waterfall3DIntensityComboBox">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <item>
+          <property name="text">
+           <string>Color</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>White Hot</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>Black Hot</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>Incandescent</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>User Defined</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="0" column="2">
+        <widget class="QwtWheel" name="Waterfall3DMaximumIntensityWheel">
+         <property name="minimumSize">
+          <size>
+           <width>200</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="mouseTracking">
+          <bool>true</bool>
+         </property>
+         <property name="focusPolicy">
+          <enum>Qt::WheelFocus</enum>
+         </property>
+         <property name="valid">
+          <bool>true</bool>
+         </property>
+         <property name="totalAngle">
+          <double>200.000000000000000</double>
+         </property>
+         <property name="viewAngle">
+          <double>20.000000000000000</double>
+         </property>
+         <property name="mass">
+          <double>0.000000000000000</double>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="3">
+        <widget class="QLabel" name="Waterfall3DMaximumIntensityLabel">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>100 dB</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0" colspan="4">
+        <widget class="QFrame" name="Waterfall3DPlotDisplayFrame">
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Plain</enum>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0" colspan="2">
+        <widget class="QPushButton" name="Waterfall3DAutoScaleBtn">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>80</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="sizeIncrement">
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Scales the Intensity to the current data extremes.</string>
+         </property>
+         <property name="text">
+          <string>Auto Scale</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QwtWheel" name="Waterfall3DMinimumIntensityWheel">
+         <property name="minimumSize">
+          <size>
+           <width>200</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="valid">
+          <bool>true</bool>
+         </property>
+         <property name="totalAngle">
+          <double>200.000000000000000</double>
+         </property>
+         <property name="viewAngle">
+          <double>20.000000000000000</double>
+         </property>
+         <property name="mass">
+          <double>0.000000000000000</double>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="3">
+        <widget class="QLabel" name="Waterfall3DMinimumIntensityLabel">
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>-100 dB</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="TimeDomainPage">
+      <attribute name="title">
+       <string>Time Domain Display</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_4">
+       <item row="0" column="0">
+        <widget class="QFrame" name="TimeDomainDisplayFrame">
+         <property name="minimumSize">
+          <size>
+           <width>617</width>
+           <height>404</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Plain</enum>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="ConstellationPage">
+      <attribute name="title">
+       <string>Constellation Display</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_5">
+       <item row="0" column="0">
+        <widget class="QFrame" name="ConstellationDisplayFrame">
+         <property name="minimumSize">
+          <size>
+           <width>617</width>
+           <height>406</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::StyledPanel</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Raised</enum>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
     </widget>
-    <widget class="QwtWheel" name="Waterfall3DMaximumIntensityWheel" >
-     <property name="geometry" >
-      <rect>
-       <x>215</x>
-       <y>0</y>
-       <width>335</width>
-       <height>24</height>
-      </rect>
-     </property>
-     <property name="mouseTracking" >
-      <bool>true</bool>
-     </property>
-     <property name="focusPolicy" >
-      <enum>Qt::WheelFocus</enum>
-     </property>
-     <property name="valid" >
-      <bool>true</bool>
-     </property>
-     <property name="totalAngle" >
-      <double>200.000000000000000</double>
-     </property>
-     <property name="viewAngle" >
-      <double>20.000000000000000</double>
-     </property>
-     <property name="mass" >
-      <double>0.000000000000000</double>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QWidget" name="TimeDomainPage" >
-    <attribute name="title" >
-     <string>Time Domain Display</string>
-    </attribute>
-    <widget class="QFrame" name="TimeDomainDisplayFrame" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>5</y>
-       <width>620</width>
-       <height>340</height>
-      </rect>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Plain</enum>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QWidget" name="ConstellationPage" >
-    <attribute name="title" >
-     <string>Constellation Display</string>
-    </attribute>
-    <widget class="QFrame" name="ConstellationDisplayFrame" >
-     <property name="geometry" >
-      <rect>
-       <x>5</x>
-       <y>5</y>
-       <width>620</width>
-       <height>340</height>
-      </rect>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Raised</enum>
-     </property>
-    </widget>
-   </widget>
-  </widget>
+   </item>
+  </layout>
  </widget>
- <layoutdefault spacing="6" margin="11" />
+ <layoutdefault spacing="6" margin="11"/>
  <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
  <customwidgets>
   <customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>SpectrumTypeTab</tabstop>
-  <tabstop>MaxHoldCheckBox</tabstop>
-  <tabstop>MaxHoldResetBtn</tabstop>
-  <tabstop>MinHoldCheckBox</tabstop>
-  <tabstop>MinHoldResetBtn</tabstop>
-  <tabstop>PowerLineEdit</tabstop>
-  <tabstop>AvgLineEdit</tabstop>
   <tabstop>UseRFFrequenciesCheckBox</tabstop>
-  <tabstop>WindowComboBox</tabstop>
   <tabstop>FFTSizeComboBox</tabstop>
   <tabstop>WaterfallMaximumIntensityWheel</tabstop>
   <tabstop>WaterfallMinimumIntensityWheel</tabstop>
  </tabstops>
  <includes>
-  <include location="global" >SpectrumGUIClass.h</include>
-  <include location="global" >FrequencyDisplayPlot.h</include>
-  <include location="global" >WaterfallDisplayPlot.h</include>
-  <include location="global" >Waterfall3DDisplayPlot.h</include>
-  <include location="global" >TimeDomainDisplayPlot.h</include>
-  <include location="global" >qvalidator.h</include>
-  <include location="global" >vector</include>
-  <include location="local" >qwt_wheel.h</include>
+  <include location="global">SpectrumGUIClass.h</include>
+  <include location="global">FrequencyDisplayPlot.h</include>
+  <include location="global">WaterfallDisplayPlot.h</include>
+  <include location="global">Waterfall3DDisplayPlot.h</include>
+  <include location="global">TimeDomainDisplayPlot.h</include>
+  <include location="global">qvalidator.h</include>
+  <include location="global">vector</include>
+  <include location="local">qwt_wheel.h</include>
  </includes>
  <resources/>
  <connections>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>MaxHoldCheckBox_toggled(bool)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>22</x>
+     <y>324</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>MaxHoldResetBtn_clicked()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>107</x>
+     <y>324</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>MinHoldCheckBox_toggled(bool)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>22</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>MinHoldResetBtn_clicked()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>107</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>AvgLineEdit</sender>
-   <signal>textChanged(QString)</signal>
-   <receiver>SpectrumDisplayForm</receiver>
-   <slot>AvgLineEdit_textChanged(QString)</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>PowerLineEdit</sender>
-   <signal>textChanged(QString)</signal>
-   <receiver>SpectrumDisplayForm</receiver>
-   <slot>PowerLineEdit_textChanged(QString)</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>WindowTypeChanged(int)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>20</x>
      <y>20</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>UseRFFrequenciesCB(bool)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>20</x>
      <y>20</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>waterfallMaximumIntensityChangedCB(double)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>217</x>
+     <y>44</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>waterfallMinimumIntensityChangedCB(double)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>217</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>waterfall3DMaximumIntensityChangedCB(double)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>217</x>
+     <y>44</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>waterfall3DMinimumIntensityChangedCB(double)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>217</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>FFTComboBoxSelectedCB(QString)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>20</x>
      <y>20</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>WaterfallAutoScaleBtnCB()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>22</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>Waterfall3DAutoScaleBtnCB()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>22</x>
+     <y>349</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>WaterfallIntensityColorTypeChanged(int)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>92</x>
+     <y>44</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    <receiver>SpectrumDisplayForm</receiver>
    <slot>Waterfall3DIntensityColorTypeChanged(int)</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
+    <hint type="sourcelabel">
+     <x>92</x>
+     <y>44</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>20</x>
      <y>20</y>
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>SpectrumTypeTab</sender>
+   <signal>currentChanged(int)</signal>
+   <receiver>SpectrumDisplayForm</receiver>
+   <slot>TabChanged(int)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>314</x>
+     <y>189</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>316</x>
+     <y>217</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>AvgLineEdit</sender>
+   <signal>valueChanged(int)</signal>
+   <receiver>SpectrumDisplayForm</receiver>
+   <slot>AvgLineEdit_valueChanged(int)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>604</x>
+     <y>421</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>328</x>
+     <y>260</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
index 6e34ce5b1772d6c735eb79e9fa5c81b19d3a1945..247e0ae91a5b733157a3cdfd844c9c8bfee9365e 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <qwt_raster_data.h>
 #include <qwt3d_function.h>
+#include <inttypes.h>
 
 class Waterfall3DDisplayPlot;
 
diff --git a/gr-qtgui/src/python/.gitignore b/gr-qtgui/src/python/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 4fa8cdd92510cc9451136329bed9d914c4659ab6..7c0cfc6983d89f6ead8de1219a6a7bb70aef8d8e 100755 (executable)
@@ -131,9 +131,9 @@ class my_top_block(gr.top_block):
 
         # Wrap the pointer as a PyQt SIP object
         # This can now be manipulated as a PyQt4.QtGui.QWidget
-        pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+        self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
 
-        self.main_box = dialog_box(pyWin, self.ctrl_win)
+        self.main_box = dialog_box(self.pyWin, self.ctrl_win)
 
         self.main_box.show()
         
index 46fe07e0d89cf5f934a46f6587e648b32ace09fb..4e36ccca5ff19ed728f323da5f7c10dca6a1eb0e 100755 (executable)
@@ -130,9 +130,9 @@ class my_top_block(gr.top_block):
 
         # Wrap the pointer as a PyQt SIP object
         # This can now be manipulated as a PyQt4.QtGui.QWidget
-        pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+        self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
 
-        self.main_box = dialog_box(pyWin, self.ctrl_win)
+        self.main_box = dialog_box(self.pyWin, self.ctrl_win)
 
         self.main_box.show()
         
index ceb492c8d072a57db6264562d5621efbd4d1a26e..679f144eff7c6857e39efc475aaf999894e36a5c 100755 (executable)
@@ -139,7 +139,7 @@ class my_top_block(gr.top_block):
 
         self.qapp = QtGui.QApplication(sys.argv)
 
-        self._sample_rate = 200e3
+        self._sample_rate = 2000e3
 
         self.sps = 2
         self.excess_bw = 0.35
@@ -182,11 +182,13 @@ class my_top_block(gr.top_block):
         self.to = 1.0
         self.channel = gr.channel_model(noise, self.fo, self.to)
 
-        self.thr = gr.throttle(gr.sizeof_char, 10*fftsize)
-        self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, 1,
+        self.thr = gr.throttle(gr.sizeof_char, self._sample_rate)
+        self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 
+                                   0, self._sample_rate*self.sps,
                                    "Tx", True, True, False, True, True)
 
-        self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 0, 1,
+        self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                   0, self._sample_rate,
                                    "Rx", True, True, False, True, True)
 
         self.connect(self.src, self.thr, self.mod, self.channel, self.snk_tx)
index 9e4c57a8922aa8a87dd528426f07a6bc9d433d77..50dd53a923e3d46cd5ec8704d62eb2a52432d826 100644 (file)
@@ -2,8 +2,8 @@
 
 # Form implementation generated from reading ui file 'qt_digital_window.ui'
 #
-# Created: Thu Jun 18 07:57:58 2009
-#      by: PyQt4 UI code generator 4.4.3
+# Created: Sat May  1 20:14:02 2010
+#      by: PyQt4 UI code generator 4.6.1
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -12,73 +12,118 @@ from PyQt4 import QtCore, QtGui
 class Ui_DigitalWindow(object):
     def setupUi(self, DigitalWindow):
         DigitalWindow.setObjectName("DigitalWindow")
-        DigitalWindow.resize(1236, 739)
+        DigitalWindow.resize(1236, 741)
         self.centralwidget = QtGui.QWidget(DigitalWindow)
         self.centralwidget.setObjectName("centralwidget")
-        self.closeButton = QtGui.QPushButton(self.centralwidget)
-        self.closeButton.setGeometry(QtCore.QRect(1120, 650, 101, 31))
-        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
+        self.verticalLayout.setObjectName("verticalLayout")
         self.sinkFrame = QtGui.QFrame(self.centralwidget)
-        self.sinkFrame.setGeometry(QtCore.QRect(10, 10, 1221, 501))
+        self.sinkFrame.setMinimumSize(QtCore.QSize(0, 550))
         self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel)
         self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised)
         self.sinkFrame.setObjectName("sinkFrame")
-        self.horizontalLayoutWidget = QtGui.QWidget(self.sinkFrame)
-        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 1201, 481))
-        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
-        self.sinkLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget)
+        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.sinkFrame)
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.sinkLayout = QtGui.QHBoxLayout()
         self.sinkLayout.setObjectName("sinkLayout")
-        self.channelModeBox = QtGui.QGroupBox(self.centralwidget)
-        self.channelModeBox.setGeometry(QtCore.QRect(290, 520, 291, 161))
-        self.channelModeBox.setObjectName("channelModeBox")
-        self.timeLabel = QtGui.QLabel(self.channelModeBox)
-        self.timeLabel.setGeometry(QtCore.QRect(10, 90, 101, 17))
-        self.timeLabel.setObjectName("timeLabel")
-        self.timeEdit = QtGui.QLineEdit(self.channelModeBox)
-        self.timeEdit.setGeometry(QtCore.QRect(160, 90, 113, 23))
-        self.timeEdit.setObjectName("timeEdit")
-        self.snrEdit = QtGui.QLineEdit(self.channelModeBox)
-        self.snrEdit.setGeometry(QtCore.QRect(160, 30, 113, 23))
-        self.snrEdit.setObjectName("snrEdit")
-        self.snrLabel = QtGui.QLabel(self.channelModeBox)
-        self.snrLabel.setGeometry(QtCore.QRect(10, 30, 111, 20))
-        self.snrLabel.setObjectName("snrLabel")
-        self.freqEdit = QtGui.QLineEdit(self.channelModeBox)
-        self.freqEdit.setGeometry(QtCore.QRect(160, 60, 113, 23))
-        self.freqEdit.setObjectName("freqEdit")
-        self.freqLabel = QtGui.QLabel(self.channelModeBox)
-        self.freqLabel.setGeometry(QtCore.QRect(10, 60, 141, 17))
-        self.freqLabel.setObjectName("freqLabel")
-        self.rxBox = QtGui.QGroupBox(self.centralwidget)
-        self.rxBox.setGeometry(QtCore.QRect(590, 520, 251, 161))
-        self.rxBox.setObjectName("rxBox")
-        self.gainMuEdit = QtGui.QLineEdit(self.rxBox)
-        self.gainMuEdit.setGeometry(QtCore.QRect(120, 30, 113, 23))
-        self.gainMuEdit.setObjectName("gainMuEdit")
-        self.gainMuLabel = QtGui.QLabel(self.rxBox)
-        self.gainMuLabel.setGeometry(QtCore.QRect(10, 30, 111, 20))
-        self.gainMuLabel.setObjectName("gainMuLabel")
-        self.alphaEdit = QtGui.QLineEdit(self.rxBox)
-        self.alphaEdit.setGeometry(QtCore.QRect(120, 60, 113, 23))
-        self.alphaEdit.setObjectName("alphaEdit")
-        self.alphaLabel = QtGui.QLabel(self.rxBox)
-        self.alphaLabel.setGeometry(QtCore.QRect(10, 60, 111, 20))
-        self.alphaLabel.setObjectName("alphaLabel")
+        self.horizontalLayout_2.addLayout(self.sinkLayout)
+        self.verticalLayout.addWidget(self.sinkFrame)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
         self.sysBox = QtGui.QGroupBox(self.centralwidget)
-        self.sysBox.setGeometry(QtCore.QRect(20, 520, 261, 161))
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sysBox.sizePolicy().hasHeightForWidth())
+        self.sysBox.setSizePolicy(sizePolicy)
+        self.sysBox.setMinimumSize(QtCore.QSize(0, 0))
+        self.sysBox.setMaximumSize(QtCore.QSize(16777215, 120))
+        self.sysBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
         self.sysBox.setObjectName("sysBox")
+        self.gridLayout_2 = QtGui.QGridLayout(self.sysBox)
+        self.gridLayout_2.setObjectName("gridLayout_2")
         self.sampleRateEdit = QtGui.QLineEdit(self.sysBox)
-        self.sampleRateEdit.setGeometry(QtCore.QRect(140, 30, 113, 23))
+        self.sampleRateEdit.setMaximumSize(QtCore.QSize(100, 16777215))
         self.sampleRateEdit.setObjectName("sampleRateEdit")
+        self.gridLayout_2.addWidget(self.sampleRateEdit, 0, 3, 1, 1)
         self.sampleRateLabel = QtGui.QLabel(self.sysBox)
-        self.sampleRateLabel.setGeometry(QtCore.QRect(10, 30, 121, 20))
         self.sampleRateLabel.setObjectName("sampleRateLabel")
+        self.gridLayout_2.addWidget(self.sampleRateLabel, 0, 2, 1, 1)
+        self.horizontalLayout.addWidget(self.sysBox)
+        self.rxBox = QtGui.QGroupBox(self.centralwidget)
+        self.rxBox.setMaximumSize(QtCore.QSize(16777215, 120))
+        self.rxBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+        self.rxBox.setObjectName("rxBox")
+        self.gridLayout_3 = QtGui.QGridLayout(self.rxBox)
+        self.gridLayout_3.setObjectName("gridLayout_3")
+        self.alphaLabel = QtGui.QLabel(self.rxBox)
+        self.alphaLabel.setObjectName("alphaLabel")
+        self.gridLayout_3.addWidget(self.alphaLabel, 1, 0, 1, 1)
+        self.alphaEdit = QtGui.QLineEdit(self.rxBox)
+        self.alphaEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.alphaEdit.setObjectName("alphaEdit")
+        self.gridLayout_3.addWidget(self.alphaEdit, 1, 1, 1, 1)
+        self.gainMuLabel = QtGui.QLabel(self.rxBox)
+        self.gainMuLabel.setObjectName("gainMuLabel")
+        self.gridLayout_3.addWidget(self.gainMuLabel, 0, 0, 1, 1)
+        self.gainMuEdit = QtGui.QLineEdit(self.rxBox)
+        self.gainMuEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.gainMuEdit.setObjectName("gainMuEdit")
+        self.gridLayout_3.addWidget(self.gainMuEdit, 0, 1, 1, 1)
+        self.horizontalLayout.addWidget(self.rxBox)
+        self.channelModeBox = QtGui.QGroupBox(self.centralwidget)
+        self.channelModeBox.setMaximumSize(QtCore.QSize(16777215, 120))
+        self.channelModeBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+        self.channelModeBox.setObjectName("channelModeBox")
+        self.gridLayout = QtGui.QGridLayout(self.channelModeBox)
+        self.gridLayout.setSizeConstraint(QtGui.QLayout.SetMinimumSize)
+        self.gridLayout.setObjectName("gridLayout")
+        self.snrLabel = QtGui.QLabel(self.channelModeBox)
+        self.snrLabel.setObjectName("snrLabel")
+        self.gridLayout.addWidget(self.snrLabel, 0, 1, 1, 1)
+        self.snrEdit = QtGui.QLineEdit(self.channelModeBox)
+        self.snrEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.snrEdit.setObjectName("snrEdit")
+        self.gridLayout.addWidget(self.snrEdit, 0, 2, 1, 1)
+        self.freqLabel = QtGui.QLabel(self.channelModeBox)
+        self.freqLabel.setObjectName("freqLabel")
+        self.gridLayout.addWidget(self.freqLabel, 1, 1, 1, 1)
+        self.freqEdit = QtGui.QLineEdit(self.channelModeBox)
+        self.freqEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.freqEdit.setObjectName("freqEdit")
+        self.gridLayout.addWidget(self.freqEdit, 1, 2, 1, 1)
+        self.timeLabel = QtGui.QLabel(self.channelModeBox)
+        self.timeLabel.setObjectName("timeLabel")
+        self.gridLayout.addWidget(self.timeLabel, 2, 1, 1, 1)
+        self.timeEdit = QtGui.QLineEdit(self.channelModeBox)
+        self.timeEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.timeEdit.setObjectName("timeEdit")
+        self.gridLayout.addWidget(self.timeEdit, 2, 2, 1, 1)
+        self.horizontalLayout.addWidget(self.channelModeBox)
+        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout.addItem(spacerItem)
+        self.verticalLayout_2 = QtGui.QVBoxLayout()
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.verticalLayout_2.addItem(spacerItem1)
         self.pauseButton = QtGui.QPushButton(self.centralwidget)
-        self.pauseButton.setGeometry(QtCore.QRect(1120, 520, 101, 31))
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.pauseButton.sizePolicy().hasHeightForWidth())
+        self.pauseButton.setSizePolicy(sizePolicy)
+        self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215))
         self.pauseButton.setObjectName("pauseButton")
+        self.verticalLayout_2.addWidget(self.pauseButton)
+        self.closeButton = QtGui.QPushButton(self.centralwidget)
+        self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout_2.addWidget(self.closeButton)
+        self.horizontalLayout.addLayout(self.verticalLayout_2)
+        self.verticalLayout.addLayout(self.horizontalLayout)
         DigitalWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(DigitalWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 1236, 25))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1236, 23))
         self.menubar.setObjectName("menubar")
         self.menuFile = QtGui.QMenu(self.menubar)
         self.menuFile.setObjectName("menuFile")
@@ -95,23 +140,22 @@ class Ui_DigitalWindow(object):
         QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close)
         QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close)
         QtCore.QMetaObject.connectSlotsByName(DigitalWindow)
-        DigitalWindow.setTabOrder(self.closeButton, self.snrEdit)
         DigitalWindow.setTabOrder(self.snrEdit, self.freqEdit)
         DigitalWindow.setTabOrder(self.freqEdit, self.timeEdit)
 
     def retranslateUi(self, DigitalWindow):
         DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
-        self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.alphaLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainMuLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain mu", None, QtGui.QApplication.UnicodeUTF8))
         self.channelModeBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Channel Model Parameters", None, QtGui.QApplication.UnicodeUTF8))
-        self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8))
         self.snrLabel.setText(QtGui.QApplication.translate("DigitalWindow", "SNR (dB)", None, QtGui.QApplication.UnicodeUTF8))
         self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency Offset (Hz)", None, QtGui.QApplication.UnicodeUTF8))
-        self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
-        self.gainMuLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain mu", None, QtGui.QApplication.UnicodeUTF8))
-        self.alphaLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha", None, QtGui.QApplication.UnicodeUTF8))
-        self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8))
-        self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8))
         self.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8))
+        self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
         self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
         self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
 
index 79ba0128657dfee5da3338fc5b509d35fbf94118..96725218150e8834180626491d07a6a00491c49c 100644 (file)
     <x>0</x>
     <y>0</y>
     <width>1236</width>
-    <height>739</height>
+    <height>741</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
   <widget class="QWidget" name="centralwidget">
-   <widget class="QPushButton" name="closeButton">
-    <property name="geometry">
-     <rect>
-      <x>1120</x>
-      <y>650</y>
-      <width>101</width>
-      <height>31</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Close</string>
-    </property>
-   </widget>
-   <widget class="QFrame" name="sinkFrame">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>10</y>
-      <width>1221</width>
-      <height>501</height>
-     </rect>
-    </property>
-    <property name="frameShape">
-     <enum>QFrame::StyledPanel</enum>
-    </property>
-    <property name="frameShadow">
-     <enum>QFrame::Raised</enum>
-    </property>
-    <widget class="QWidget" name="horizontalLayoutWidget">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>10</y>
-       <width>1201</width>
-       <height>481</height>
-      </rect>
-     </property>
-     <layout class="QHBoxLayout" name="sinkLayout"/>
-    </widget>
-   </widget>
-   <widget class="QGroupBox" name="channelModeBox">
-    <property name="geometry">
-     <rect>
-      <x>290</x>
-      <y>520</y>
-      <width>291</width>
-      <height>161</height>
-     </rect>
-    </property>
-    <property name="title">
-     <string>Channel Model Parameters</string>
-    </property>
-    <widget class="QLabel" name="timeLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>90</y>
-       <width>101</width>
-       <height>17</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>Timing Offset</string>
-     </property>
-    </widget>
-    <widget class="QLineEdit" name="timeEdit">
-     <property name="geometry">
-      <rect>
-       <x>160</x>
-       <y>90</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLineEdit" name="snrEdit">
-     <property name="geometry">
-      <rect>
-       <x>160</x>
-       <y>30</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLabel" name="snrLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>30</y>
-       <width>111</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>SNR (dB)</string>
-     </property>
-    </widget>
-    <widget class="QLineEdit" name="freqEdit">
-     <property name="geometry">
-      <rect>
-       <x>160</x>
-       <y>60</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLabel" name="freqLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>60</y>
-       <width>141</width>
-       <height>17</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>Frequency Offset (Hz)</string>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QGroupBox" name="rxBox">
-    <property name="geometry">
-     <rect>
-      <x>590</x>
-      <y>520</y>
-      <width>251</width>
-      <height>161</height>
-     </rect>
-    </property>
-    <property name="title">
-     <string>Receiver Parameters</string>
-    </property>
-    <widget class="QLineEdit" name="gainMuEdit">
-     <property name="geometry">
-      <rect>
-       <x>120</x>
-       <y>30</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLabel" name="gainMuLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>30</y>
-       <width>111</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>Gain mu</string>
-     </property>
-    </widget>
-    <widget class="QLineEdit" name="alphaEdit">
-     <property name="geometry">
-      <rect>
-       <x>120</x>
-       <y>60</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLabel" name="alphaLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>60</y>
-       <width>111</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>Alpha</string>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QGroupBox" name="sysBox">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>520</y>
-      <width>261</width>
-      <height>161</height>
-     </rect>
-    </property>
-    <property name="title">
-     <string>System Parameters</string>
-    </property>
-    <widget class="QLineEdit" name="sampleRateEdit">
-     <property name="geometry">
-      <rect>
-       <x>140</x>
-       <y>30</y>
-       <width>113</width>
-       <height>23</height>
-      </rect>
-     </property>
-    </widget>
-    <widget class="QLabel" name="sampleRateLabel">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>30</y>
-       <width>121</width>
-       <height>20</height>
-      </rect>
-     </property>
-     <property name="text">
-      <string>Sample Rate (sps)</string>
-     </property>
-    </widget>
-   </widget>
-   <widget class="QPushButton" name="pauseButton">
-    <property name="geometry">
-     <rect>
-      <x>1120</x>
-      <y>520</y>
-      <width>101</width>
-      <height>31</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Pause</string>
-    </property>
-   </widget>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <widget class="QFrame" name="sinkFrame">
+      <property name="minimumSize">
+       <size>
+        <width>0</width>
+        <height>550</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Raised</enum>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <layout class="QHBoxLayout" name="sinkLayout"/>
+       </item>
+      </layout>
+     </widget>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QGroupBox" name="sysBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>120</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>System Parameters</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="0" column="3">
+          <widget class="QLineEdit" name="sampleRateEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLabel" name="sampleRateLabel">
+           <property name="text">
+            <string>Sample Rate (sps)</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="rxBox">
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>120</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Receiver Parameters</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_3">
+         <item row="1" column="0">
+          <widget class="QLabel" name="alphaLabel">
+           <property name="text">
+            <string>Alpha</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="alphaEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="0">
+          <widget class="QLabel" name="gainMuLabel">
+           <property name="text">
+            <string>Gain mu</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLineEdit" name="gainMuEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="channelModeBox">
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>120</height>
+         </size>
+        </property>
+        <property name="title">
+         <string>Channel Model Parameters</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <layout class="QGridLayout" name="gridLayout">
+         <property name="sizeConstraint">
+          <enum>QLayout::SetMinimumSize</enum>
+         </property>
+         <item row="0" column="1">
+          <widget class="QLabel" name="snrLabel">
+           <property name="text">
+            <string>SNR (dB)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLineEdit" name="snrEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLabel" name="freqLabel">
+           <property name="text">
+            <string>Frequency Offset (Hz)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QLineEdit" name="freqEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLabel" name="timeLabel">
+           <property name="text">
+            <string>Timing Offset</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="2">
+          <widget class="QLineEdit" name="timeEdit">
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pauseButton">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Pause</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="closeButton">
+          <property name="maximumSize">
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Close</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
   </widget>
   <widget class="QMenuBar" name="menubar">
    <property name="geometry">
      <x>0</x>
      <y>0</y>
      <width>1236</width>
-     <height>25</height>
+     <height>23</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
   </action>
  </widget>
  <tabstops>
-  <tabstop>closeButton</tabstop>
   <tabstop>snrEdit</tabstop>
   <tabstop>freqEdit</tabstop>
   <tabstop>timeEdit</tabstop>
index a145569d515ce4d2924e1609b78961a92a991bf5..75d374c2bd393ea970e7e7189da69279935a2498 100755 (executable)
@@ -61,6 +61,8 @@ class main_window(QtGui.QMainWindow):
         # Add the qtsnk widgets to the layout box
         self.gui.sinkLayout.addWidget(snk)
 
+        self.gui.dcGainEdit.setText(QtCore.QString("%1").arg(0.001))
+
         # Connect up some signals
         self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
                      self.pauseFg)
@@ -77,6 +79,11 @@ class main_window(QtGui.QMainWindow):
                      self.saveData)
         self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save)
 
+        self.connect(self.gui.dcGainEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.dcGainEditText)
+        self.connect(self.gui.dcCancelCheckBox, QtCore.SIGNAL("clicked(bool)"),
+                     self.dcCancelClicked)
+
     def pauseFg(self):
         if(self.gui.pauseButton.text() == "Pause"):
             self.fg.stop()
@@ -145,6 +152,14 @@ class main_window(QtGui.QMainWindow):
         if(len(fileName)):
             self.fg.save_to_file(str(fileName))
 
+    def dcGainEditText(self):
+        gain = float(self.gui.dcGainEdit.text())
+        self.fg.set_dc_gain(gain)
+        
+    def dcCancelClicked(self, state):
+        self.dcGainEditText()
+        self.fg.cancel_dc(state)
+        
 
         
 class my_top_block(gr.top_block):
@@ -156,9 +171,9 @@ class my_top_block(gr.top_block):
                           help="select Ethernet interface, default is eth0")
         parser.add_option("-m", "--mac-addr", type="string", default="",
                           help="select USRP by MAC address, default is auto-select")
-        parser.add_option("-W", "--bw", type="float", default=1e6,
+        parser.add_option("-W", "--bw", type="eng_float", default=1e6,
                           help="set bandwidth of receiver [default=%default]")
-        parser.add_option("-f", "--freq", type="eng_float", default=None,
+        parser.add_option("-f", "--freq", type="eng_float", default=2412e6,
                           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)")
@@ -201,6 +216,12 @@ class my_top_block(gr.top_block):
         self.amp = gr.multiply_const_cc(0.0)
         self.set_amplifier_gain(100)
 
+        # Create a single-pole IIR filter to remove DC
+        #   but don't connect it yet
+        self.dc_gain = 0.001
+        self.dc = gr.single_pole_iir_filter_cc(self.dc_gain)
+        self.dc_sub = gr.sub_cc()
+
         self.connect(self.u, self.amp, self.snk)
 
         if self.show_debug_info:
@@ -224,16 +245,13 @@ class my_top_block(gr.top_block):
 
 
     def save_to_file(self, name):
-        # Pause the flow graph
-        self.stop()
-        self.wait()
+        self.lock()
 
         # Add file sink to save data
         self.file_sink = gr.file_sink(gr.sizeof_gr_complex, name)
         self.connect(self.amp, self.file_sink)
 
-        # Restart flow graph
-        self.start()
+        self.unlock()
 
     def set_gain(self, gain):
         self._gain = gain
@@ -259,8 +277,28 @@ class my_top_block(gr.top_block):
             pass
 
     def set_amplifier_gain(self, amp):
-            self._amp_value = amp
-            self.amp.set_k(self._amp_value)
+        self._amp_value = amp
+        self.amp.set_k(self._amp_value)
+
+    def set_dc_gain(self, gain):
+        self.dc.set_taps(gain)
+        
+    def cancel_dc(self, state):
+        self.lock()
+
+        if(state):
+            self.disconnect(self.u, self.amp)
+            self.connect(self.u, (self.dc_sub,0))
+            self.connect(self.u, self.dc, (self.dc_sub,1))
+            self.connect(self.dc_sub, self.amp)
+        else:
+            self.disconnect(self.dc_sub, self.amp)
+            self.disconnect(self.dc, (self.dc_sub,1))
+            self.disconnect(self.u, self.dc)
+            self.disconnect(self.u, (self.dc_sub,0))
+            self.connect(self.u, self.amp)
+
+        self.unlock()
 
 def main ():
     tb = my_top_block()
diff --git a/gr-qtgui/src/python/usrp_display_qtgui.py b/gr-qtgui/src/python/usrp_display_qtgui.py
new file mode 100644 (file)
index 0000000..4c9de3a
--- /dev/null
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'usrp_display_qtgui.ui'
+#
+# Created: Thu Jul 16 22:06:24 2009
+#      by: PyQt4 UI code generator 4.4.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.resize(820, 774)
+        self.centralwidget = QtGui.QWidget(MainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
+        self.gridLayout_2.setObjectName("gridLayout_2")
+        self.horizontalLayout_2 = QtGui.QHBoxLayout()
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.groupBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
+        self.groupBox.setSizePolicy(sizePolicy)
+        self.groupBox.setMinimumSize(QtCore.QSize(240, 150))
+        self.groupBox.setMaximumSize(QtCore.QSize(240, 16777215))
+        self.groupBox.setObjectName("groupBox")
+        self.formLayoutWidget = QtGui.QWidget(self.groupBox)
+        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 221, 124))
+        self.formLayoutWidget.setObjectName("formLayoutWidget")
+        self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
+        self.formLayout.setObjectName("formLayout")
+        self.frequencyLabel = QtGui.QLabel(self.formLayoutWidget)
+        self.frequencyLabel.setObjectName("frequencyLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.frequencyLabel)
+        self.gainLabel = QtGui.QLabel(self.formLayoutWidget)
+        self.gainLabel.setObjectName("gainLabel")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.gainLabel)
+        self.bandwidthLabel = QtGui.QLabel(self.formLayoutWidget)
+        self.bandwidthLabel.setObjectName("bandwidthLabel")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.bandwidthLabel)
+        self.frequencyEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.frequencyEdit.sizePolicy().hasHeightForWidth())
+        self.frequencyEdit.setSizePolicy(sizePolicy)
+        self.frequencyEdit.setMinimumSize(QtCore.QSize(120, 26))
+        self.frequencyEdit.setObjectName("frequencyEdit")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.frequencyEdit)
+        self.gainEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.gainEdit.sizePolicy().hasHeightForWidth())
+        self.gainEdit.setSizePolicy(sizePolicy)
+        self.gainEdit.setMinimumSize(QtCore.QSize(120, 26))
+        self.gainEdit.setObjectName("gainEdit")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.gainEdit)
+        self.bandwidthEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.bandwidthEdit.sizePolicy().hasHeightForWidth())
+        self.bandwidthEdit.setSizePolicy(sizePolicy)
+        self.bandwidthEdit.setMinimumSize(QtCore.QSize(120, 26))
+        self.bandwidthEdit.setObjectName("bandwidthEdit")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.bandwidthEdit)
+        self.amplifierLabel = QtGui.QLabel(self.formLayoutWidget)
+        self.amplifierLabel.setObjectName("amplifierLabel")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.amplifierLabel)
+        self.amplifierEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.amplifierEdit.sizePolicy().hasHeightForWidth())
+        self.amplifierEdit.setSizePolicy(sizePolicy)
+        self.amplifierEdit.setMinimumSize(QtCore.QSize(120, 26))
+        self.amplifierEdit.setObjectName("amplifierEdit")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.amplifierEdit)
+        self.horizontalLayout_2.addWidget(self.groupBox)
+        self.frame_2 = QtGui.QFrame(self.centralwidget)
+        self.frame_2.setMinimumSize(QtCore.QSize(200, 0))
+        self.frame_2.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.frame_2.setFrameShadow(QtGui.QFrame.Raised)
+        self.frame_2.setObjectName("frame_2")
+        self.verticalLayoutWidget = QtGui.QWidget(self.frame_2)
+        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, -1, 191, 151))
+        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
+        self.verticalLayout_3 = QtGui.QVBoxLayout(self.verticalLayoutWidget)
+        self.verticalLayout_3.setObjectName("verticalLayout_3")
+        self.dcCancelCheckBox = QtGui.QCheckBox(self.verticalLayoutWidget)
+        self.dcCancelCheckBox.setObjectName("dcCancelCheckBox")
+        self.verticalLayout_3.addWidget(self.dcCancelCheckBox)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.dcGainLabel = QtGui.QLabel(self.verticalLayoutWidget)
+        self.dcGainLabel.setObjectName("dcGainLabel")
+        self.horizontalLayout.addWidget(self.dcGainLabel)
+        self.dcGainEdit = QtGui.QLineEdit(self.verticalLayoutWidget)
+        self.dcGainEdit.setObjectName("dcGainEdit")
+        self.horizontalLayout.addWidget(self.dcGainEdit)
+        self.verticalLayout_3.addLayout(self.horizontalLayout)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.verticalLayout_3.addItem(spacerItem)
+        self.horizontalLayout_2.addWidget(self.frame_2)
+        spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.horizontalLayout_2.addItem(spacerItem1)
+        self.verticalLayout = QtGui.QVBoxLayout()
+        self.verticalLayout.setObjectName("verticalLayout")
+        spacerItem2 = QtGui.QSpacerItem(20, 80, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout.addItem(spacerItem2)
+        self.pauseButton = QtGui.QPushButton(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.pauseButton.sizePolicy().hasHeightForWidth())
+        self.pauseButton.setSizePolicy(sizePolicy)
+        self.pauseButton.setObjectName("pauseButton")
+        self.verticalLayout.addWidget(self.pauseButton)
+        self.closeButton = QtGui.QPushButton(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.closeButton.sizePolicy().hasHeightForWidth())
+        self.closeButton.setSizePolicy(sizePolicy)
+        self.closeButton.setMinimumSize(QtCore.QSize(75, 0))
+        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout.addWidget(self.closeButton)
+        self.horizontalLayout_2.addLayout(self.verticalLayout)
+        self.gridLayout_2.addLayout(self.horizontalLayout_2, 1, 0, 1, 1)
+        self.verticalLayout_2 = QtGui.QVBoxLayout()
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        self.frame = QtGui.QFrame(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(1)
+        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+        self.frame.setSizePolicy(sizePolicy)
+        self.frame.setMinimumSize(QtCore.QSize(800, 550))
+        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.frame.setFrameShadow(QtGui.QFrame.Raised)
+        self.frame.setObjectName("frame")
+        self.gridLayout = QtGui.QGridLayout(self.frame)
+        self.gridLayout.setObjectName("gridLayout")
+        self.sinkLayout = QtGui.QHBoxLayout()
+        self.sinkLayout.setObjectName("sinkLayout")
+        self.gridLayout.addLayout(self.sinkLayout, 0, 0, 1, 1)
+        self.verticalLayout_2.addWidget(self.frame)
+        self.gridLayout_2.addLayout(self.verticalLayout_2, 0, 0, 1, 1)
+        MainWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 820, 24))
+        self.menubar.setObjectName("menubar")
+        self.menuFile = QtGui.QMenu(self.menubar)
+        self.menuFile.setObjectName("menuFile")
+        MainWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+        self.actionExit = QtGui.QAction(MainWindow)
+        self.actionExit.setObjectName("actionExit")
+        self.actionSaveData = QtGui.QAction(MainWindow)
+        self.actionSaveData.setObjectName("actionSaveData")
+        self.menuFile.addAction(self.actionSaveData)
+        self.menuFile.addAction(self.actionExit)
+        self.menubar.addAction(self.menuFile.menuAction())
+
+        self.retranslateUi(MainWindow)
+        QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), MainWindow.close)
+        QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), MainWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+    def retranslateUi(self, MainWindow):
+        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "USRP Display", None, QtGui.QApplication.UnicodeUTF8))
+        self.groupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.frequencyLabel.setText(QtGui.QApplication.translate("MainWindow", "Frequency (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.gainLabel.setText(QtGui.QApplication.translate("MainWindow", "RF Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.bandwidthLabel.setText(QtGui.QApplication.translate("MainWindow", "Bandwidth", None, QtGui.QApplication.UnicodeUTF8))
+        self.amplifierLabel.setText(QtGui.QApplication.translate("MainWindow", "Amplifier", None, QtGui.QApplication.UnicodeUTF8))
+        self.dcCancelCheckBox.setText(QtGui.QApplication.translate("MainWindow", "Cancel DC", None, QtGui.QApplication.UnicodeUTF8))
+        self.dcGainLabel.setText(QtGui.QApplication.translate("MainWindow", "DC Canceller Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.pauseButton.setText(QtGui.QApplication.translate("MainWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8))
+        self.closeButton.setText(QtGui.QApplication.translate("MainWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionExit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionSaveData.setText(QtGui.QApplication.translate("MainWindow", "&Save Data", None, QtGui.QApplication.UnicodeUTF8))
+
diff --git a/gr-qtgui/src/python/usrp_display_qtgui.ui b/gr-qtgui/src/python/usrp_display_qtgui.ui
new file mode 100644 (file)
index 0000000..e88ca9d
--- /dev/null
@@ -0,0 +1,375 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>820</width>
+    <height>774</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>USRP Display</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QGridLayout" name="gridLayout_2" >
+    <item row="1" column="0" >
+     <layout class="QHBoxLayout" name="horizontalLayout_2" >
+      <item>
+       <widget class="QGroupBox" name="groupBox" >
+        <property name="sizePolicy" >
+         <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize" >
+         <size>
+          <width>240</width>
+          <height>150</height>
+         </size>
+        </property>
+        <property name="maximumSize" >
+         <size>
+          <width>240</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="title" >
+         <string>Receiver Parameters</string>
+        </property>
+        <widget class="QWidget" name="formLayoutWidget" >
+         <property name="geometry" >
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>221</width>
+           <height>124</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout" >
+          <item row="0" column="0" >
+           <widget class="QLabel" name="frequencyLabel" >
+            <property name="text" >
+             <string>Frequency (Hz)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0" >
+           <widget class="QLabel" name="gainLabel" >
+            <property name="text" >
+             <string>RF Gain</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0" >
+           <widget class="QLabel" name="bandwidthLabel" >
+            <property name="text" >
+             <string>Bandwidth</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1" >
+           <widget class="QLineEdit" name="frequencyEdit" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>120</width>
+              <height>26</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1" >
+           <widget class="QLineEdit" name="gainEdit" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>120</width>
+              <height>26</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1" >
+           <widget class="QLineEdit" name="bandwidthEdit" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>120</width>
+              <height>26</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0" >
+           <widget class="QLabel" name="amplifierLabel" >
+            <property name="text" >
+             <string>Amplifier</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1" >
+           <widget class="QLineEdit" name="amplifierEdit" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>120</width>
+              <height>26</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="frame_2" >
+        <property name="minimumSize" >
+         <size>
+          <width>200</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="frameShape" >
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow" >
+         <enum>QFrame::Raised</enum>
+        </property>
+        <widget class="QWidget" name="verticalLayoutWidget" >
+         <property name="geometry" >
+          <rect>
+           <x>10</x>
+           <y>-1</y>
+           <width>191</width>
+           <height>151</height>
+          </rect>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_3" >
+          <item>
+           <widget class="QCheckBox" name="dcCancelCheckBox" >
+            <property name="text" >
+             <string>Cancel DC</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout" >
+            <item>
+             <widget class="QLabel" name="dcGainLabel" >
+              <property name="text" >
+               <string>DC Canceller Gain</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLineEdit" name="dcGainEdit" />
+            </item>
+           </layout>
+          </item>
+          <item>
+           <spacer name="verticalSpacer_2" >
+            <property name="orientation" >
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0" >
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer" >
+        <property name="orientation" >
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0" >
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout" >
+        <item>
+         <spacer name="verticalSpacer" >
+          <property name="orientation" >
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType" >
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0" >
+           <size>
+            <width>20</width>
+            <height>80</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pauseButton" >
+          <property name="sizePolicy" >
+           <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text" >
+           <string>Pause</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="closeButton" >
+          <property name="sizePolicy" >
+           <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize" >
+           <size>
+            <width>75</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="text" >
+           <string>Close</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+    <item row="0" column="0" >
+     <layout class="QVBoxLayout" name="verticalLayout_2" >
+      <item>
+       <widget class="QFrame" name="frame" >
+        <property name="sizePolicy" >
+         <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+          <horstretch>0</horstretch>
+          <verstretch>1</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize" >
+         <size>
+          <width>800</width>
+          <height>550</height>
+         </size>
+        </property>
+        <property name="frameShape" >
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow" >
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout" >
+         <item row="0" column="0" >
+          <layout class="QHBoxLayout" name="sinkLayout" />
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar" >
+   <property name="geometry" >
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>820</width>
+     <height>24</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile" >
+    <property name="title" >
+     <string>&amp;File</string>
+    </property>
+    <addaction name="actionSaveData" />
+    <addaction name="actionExit" />
+   </widget>
+   <addaction name="menuFile" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="actionExit" >
+   <property name="text" >
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+  <action name="actionSaveData" >
+   <property name="text" >
+    <string>&amp;Save Data</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>closeButton</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>808</x>
+     <y>739</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>66</x>
+     <y>561</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>actionExit</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>617</x>
+     <y>327</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/gr-radar-mono/.gitignore b/gr-radar-mono/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/doc/.gitignore b/gr-radar-mono/doc/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/.gitignore b/gr-radar-mono/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index c6fb49efa1e78f7270805a0fa79c10c289389525..d546da7f8656f5ceedbf0aec48b3c8cc57cff991 100644 (file)
@@ -21,4 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = fpga lib python
+SUBDIRS = fpga lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-radar-mono/src/fpga/.gitignore b/gr-radar-mono/src/fpga/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/fpga/lib/.gitignore b/gr-radar-mono/src/fpga/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/fpga/models/.gitignore b/gr-radar-mono/src/fpga/models/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/fpga/tb/.gitignore b/gr-radar-mono/src/fpga/tb/.gitignore
new file mode 100644 (file)
index 0000000..d709d8c
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/radar_tb
+/out
+/*.out*
+/*.vcd
diff --git a/gr-radar-mono/src/fpga/top/.gitignore b/gr-radar-mono/src/fpga/top/.gitignore
new file mode 100644 (file)
index 0000000..4049232
--- /dev/null
@@ -0,0 +1,21 @@
+/*.qmsg
+/*.qws
+/*.eqn
+/*.done
+/*.htm
+/*.rpt
+/*.ini
+/*.fsf
+/*.jam
+/*.jbc
+/*.pin
+/*.pof
+/*.rbf
+/*.smsg
+/*.sof
+/*.ttf
+/*.summary
+/undo_redo.txt
+/db
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/fpga/top/config.vh b/gr-radar-mono/src/fpga/top/config.vh
new file mode 100644 (file)
index 0000000..1769794
--- /dev/null
@@ -0,0 +1,24 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2007 Corgan Enterprises LLC
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
+//
+
+// Uncomment to enable 64 MHz Tx clock, otherwise 32 MHz
+//`define TX_RATE_MAX
+
diff --git a/gr-radar-mono/src/fpga/top/dacpll.v b/gr-radar-mono/src/fpga/top/dacpll.v
new file mode 100644 (file)
index 0000000..f3941bc
--- /dev/null
@@ -0,0 +1,291 @@
+// megafunction wizard: %ALTPLL%\r
+// GENERATION: STANDARD\r
+// VERSION: WM1.0\r
+// MODULE: altpll \r
+\r
+// ============================================================\r
+// File Name: dacpll.v\r
+// Megafunction Name(s):\r
+//                     altpll\r
+//\r
+// Simulation Library Files(s):\r
+//                     altera_mf\r
+// ============================================================\r
+// ************************************************************\r
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!\r
+//\r
+// 7.0 Build 33 02/05/2007 SJ Web Edition\r
+// ************************************************************\r
+\r
+\r
+//Copyright (C) 1991-2007 Altera Corporation\r
+//Your use of Altera Corporation's design tools, logic functions \r
+//and other software and tools, and its AMPP partner logic \r
+//functions, and any output files from any of the foregoing \r
+//(including device programming or simulation files), and any \r
+//associated documentation or information are expressly subject \r
+//to the terms and conditions of the Altera Program License \r
+//Subscription Agreement, Altera MegaCore Function License \r
+//Agreement, or other applicable license agreement, including, \r
+//without limitation, that your use is for the sole purpose of \r
+//programming logic devices manufactured by Altera and sold by \r
+//Altera or its authorized distributors.  Please refer to the \r
+//applicable agreement for further details.\r
+\r
+\r
+// synopsys translate_off\r
+`timescale 1 ps / 1 ps\r
+// synopsys translate_on\r
+module dacpll (\r
+       areset,\r
+       inclk0,\r
+       c0);\r
+\r
+       input     areset;\r
+       input     inclk0;\r
+       output    c0;\r
+\r
+       wire [5:0] sub_wire0;\r
+       wire [0:0] sub_wire4 = 1'h0;\r
+       wire [0:0] sub_wire1 = sub_wire0[0:0];\r
+       wire  c0 = sub_wire1;\r
+       wire  sub_wire2 = inclk0;\r
+       wire [1:0] sub_wire3 = {sub_wire4, sub_wire2};\r
+\r
+       altpll  altpll_component (\r
+                               .inclk (sub_wire3),\r
+                               .areset (areset),\r
+                               .clk (sub_wire0),\r
+                               .activeclock (),\r
+                               .clkbad (),\r
+                               .clkena ({6{1'b1}}),\r
+                               .clkloss (),\r
+                               .clkswitch (1'b0),\r
+                               .configupdate (1'b1),\r
+                               .enable0 (),\r
+                               .enable1 (),\r
+                               .extclk (),\r
+                               .extclkena ({4{1'b1}}),\r
+                               .fbin (1'b1),\r
+                               .fbout (),\r
+                               .locked (),\r
+                               .pfdena (1'b1),\r
+                               .phasecounterselect ({4{1'b1}}),\r
+                               .phasedone (),\r
+                               .phasestep (1'b1),\r
+                               .phaseupdown (1'b1),\r
+                               .pllena (1'b1),\r
+                               .scanaclr (1'b0),\r
+                               .scanclk (1'b0),\r
+                               .scanclkena (1'b1),\r
+                               .scandata (1'b0),\r
+                               .scandataout (),\r
+                               .scandone (),\r
+                               .scanread (1'b0),\r
+                               .scanwrite (1'b0),\r
+                               .sclkout0 (),\r
+                               .sclkout1 (),\r
+                               .vcooverrange (),\r
+                               .vcounderrange ());\r
+       defparam\r
+               altpll_component.clk0_divide_by = 1,\r
+               altpll_component.clk0_duty_cycle = 50,\r
+               altpll_component.clk0_multiply_by = 2,\r
+               altpll_component.clk0_phase_shift = "0000",\r
+               altpll_component.compensate_clock = "CLK0",\r
+               altpll_component.inclk0_input_frequency = 15625,\r
+               altpll_component.intended_device_family = "Cyclone",\r
+               altpll_component.lpm_type = "altpll",\r
+               altpll_component.operation_mode = "NORMAL",\r
+               altpll_component.pll_type = "AUTO",\r
+               altpll_component.port_activeclock = "PORT_UNUSED",\r
+               altpll_component.port_areset = "PORT_USED",\r
+               altpll_component.port_clkbad0 = "PORT_UNUSED",\r
+               altpll_component.port_clkbad1 = "PORT_UNUSED",\r
+               altpll_component.port_clkloss = "PORT_UNUSED",\r
+               altpll_component.port_clkswitch = "PORT_UNUSED",\r
+               altpll_component.port_configupdate = "PORT_UNUSED",\r
+               altpll_component.port_fbin = "PORT_UNUSED",\r
+               altpll_component.port_inclk0 = "PORT_USED",\r
+               altpll_component.port_inclk1 = "PORT_UNUSED",\r
+               altpll_component.port_locked = "PORT_UNUSED",\r
+               altpll_component.port_pfdena = "PORT_UNUSED",\r
+               altpll_component.port_phasecounterselect = "PORT_UNUSED",\r
+               altpll_component.port_phasedone = "PORT_UNUSED",\r
+               altpll_component.port_phasestep = "PORT_UNUSED",\r
+               altpll_component.port_phaseupdown = "PORT_UNUSED",\r
+               altpll_component.port_pllena = "PORT_UNUSED",\r
+               altpll_component.port_scanaclr = "PORT_UNUSED",\r
+               altpll_component.port_scanclk = "PORT_UNUSED",\r
+               altpll_component.port_scanclkena = "PORT_UNUSED",\r
+               altpll_component.port_scandata = "PORT_UNUSED",\r
+               altpll_component.port_scandataout = "PORT_UNUSED",\r
+               altpll_component.port_scandone = "PORT_UNUSED",\r
+               altpll_component.port_scanread = "PORT_UNUSED",\r
+               altpll_component.port_scanwrite = "PORT_UNUSED",\r
+               altpll_component.port_clk0 = "PORT_USED",\r
+               altpll_component.port_clk1 = "PORT_UNUSED",\r
+               altpll_component.port_clk3 = "PORT_UNUSED",\r
+               altpll_component.port_clk4 = "PORT_UNUSED",\r
+               altpll_component.port_clk5 = "PORT_UNUSED",\r
+               altpll_component.port_clkena0 = "PORT_UNUSED",\r
+               altpll_component.port_clkena1 = "PORT_UNUSED",\r
+               altpll_component.port_clkena3 = "PORT_UNUSED",\r
+               altpll_component.port_clkena4 = "PORT_UNUSED",\r
+               altpll_component.port_clkena5 = "PORT_UNUSED",\r
+               altpll_component.port_extclk0 = "PORT_UNUSED",\r
+               altpll_component.port_extclk1 = "PORT_UNUSED",\r
+               altpll_component.port_extclk2 = "PORT_UNUSED",\r
+               altpll_component.port_extclk3 = "PORT_UNUSED";\r
+\r
+\r
+endmodule\r
+\r
+// ============================================================\r
+// CNX file retrieval info\r
+// ============================================================\r
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"\r
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"\r
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"\r
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"\r
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"\r
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"\r
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"\r
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"\r
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"\r
+// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"\r
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"\r
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone"\r
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"\r
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"\r
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"\r
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"\r
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"\r
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"\r
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "64.000"\r
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"\r
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"\r
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"\r
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"\r
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"\r
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"\r
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"\r
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "512.000"\r
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"\r
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"\r
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"\r
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2"\r
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"\r
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"\r
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"\r
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"\r
+// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"\r
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "ns"\r
+// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"\r
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"\r
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"\r
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"\r
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"\r
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"\r
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"\r
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"\r
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"\r
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"\r
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"\r
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"\r
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"\r
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"\r
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"\r
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"\r
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"\r
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"\r
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"\r
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"\r
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"\r
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all\r
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"\r
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"\r
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"\r
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"\r
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"\r
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "15625"\r
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"\r
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"\r
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"\r
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"\r
+// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"\r
+// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"\r
+// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"\r
+// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"\r
+// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"\r
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"\r
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"\r
+// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"\r
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"\r
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"\r
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0\r
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0\r
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0\r
+// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll.v TRUE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll.ppf TRUE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll.inc FALSE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll.cmp FALSE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll.bsf TRUE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll_inst.v TRUE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll_bb.v TRUE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll_waveforms.html TRUE FALSE\r
+// Retrieval info: GEN_FILE: TYPE_NORMAL dacpll_wave*.jpg FALSE FALSE\r
+// Retrieval info: LIB_FILE: altera_mf\r
diff --git a/gr-radar-mono/src/fpga/top/usrp_radar_mono.srf b/gr-radar-mono/src/fpga/top/usrp_radar_mono.srf
new file mode 100644 (file)
index 0000000..e564532
--- /dev/null
@@ -0,0 +1,65 @@
+{ "Warning" "WSGN_SEARCH_FILE" "../../../../../trunk/usrp/fpga/megacells/bustri.v 1 1 " "Warning: Using design file ../../../../../trunk/usrp/fpga/megacells/bustri.v, which is not specified as a design file for the current project, but contains definitions for 1 design units and 1 entities in project" {  } {  } 0 0 "Using design file %1!s!, which is not specified as a design file for the current project, but contains definitions for %2!d! design units and %3!d! entities in project" 1 0 "" 0}\r
+{ "Warning" "WSGN_SEARCH_FILE" "../../../../../trunk/usrp/fpga/megacells/fifo_4k.v 10 10 " "Warning: Using design file ../../../../../trunk/usrp/fpga/megacells/fifo_4k.v, which is not specified as a design file for the current project, but contains definitions for 10 design units and 10 entities in project" {  } {  } 0 0 "Using design file %1!s!, which is not specified as a design file for the current project, but contains definitions for %2!d! design units and %3!d! entities in project" 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_rx_delay 12 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_rx_delay\" is connected to a signal of width 12. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_rx_delay" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 138 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_tx_delay 12 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_tx_delay\" is connected to a signal of width 12. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_tx_delay" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 137 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_rxval_3 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_rxval_3\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_rxval_3" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 134 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_txval_3 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_txval_3\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_txval_3" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 133 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_mask_3 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_mask_3\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_mask_3" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 132 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_rxval_2 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_rxval_2\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_rxval_2" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 130 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_txval_2 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_txval_2\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_txval_2" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 129 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_mask_2 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_mask_2\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_mask_2" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 128 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_rxval_1 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_rxval_1\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_rxval_1" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 126 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_txval_1 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_txval_1\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_txval_1" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 125 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_mask_1 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_mask_1\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_mask_1" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 124 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_rxval_0 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_rxval_0\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_rxval_0" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 122 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_txval_0 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_txval_0\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_txval_0" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 121 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_atr_mask_0 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_atr_mask_0\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_atr_mask_0" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 120 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_WIDE" "ratio clk_div_3 7 8 " "Warning: Port \"ratio\" on the entity instantiation of \"clk_div_3\" is connected to a signal of width 7. The formal width of the signal in the module is 8.  Extra bits will be driven by GND." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "clk_div_3" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 98 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be driven by GND." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_WIDE" "ratio clk_div_2 7 8 " "Warning: Port \"ratio\" on the entity instantiation of \"clk_div_2\" is connected to a signal of width 7. The formal width of the signal in the module is 8.  Extra bits will be driven by GND." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "clk_div_2" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 97 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be driven by GND." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_WIDE" "ratio clk_div_1 7 8 " "Warning: Port \"ratio\" on the entity instantiation of \"clk_div_1\" is connected to a signal of width 7. The formal width of the signal in the module is 8.  Extra bits will be driven by GND." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "clk_div_1" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 96 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be driven by GND." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_WIDE" "ratio clk_div_0 7 8 " "Warning: Port \"ratio\" on the entity instantiation of \"clk_div_0\" is connected to a signal of width 7. The formal width of the signal in the module is 8.  Extra bits will be driven by GND." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "clk_div_0" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 95 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be driven by GND." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_debugen 4 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_debugen\" is connected to a signal of width 4. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_debugen" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 93 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_rxbref 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_rxbref\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_rxbref" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 91 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_txbref 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_txbref\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_txbref" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 90 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_rxaref 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_rxaref\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_rxaref" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 89 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_txaref 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_txaref\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_txaref" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 88 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_decim 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_decim\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_decim" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 51 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_interp 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_interp\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_interp" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 50 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_mstr_ctrl 8 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_mstr_ctrl\" is connected to a signal of width 8. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/master_control.v" "sr_mstr_ctrl" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/master_control.v" 42 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage11 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage11\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage11" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 100 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage10 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage10\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage10" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 99 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage9 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage9\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage9" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 98 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage8 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage8\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage8" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 97 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage7 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage7\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage7" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 96 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage6 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage6\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage6" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 95 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage5 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage5\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage5" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 94 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage4 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage4\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage4" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 93 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage3 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage3\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage3" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 92 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage2 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage2\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage2" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 91 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage1 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage1\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage1" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 90 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_INPUT_PORT_TOO_NARROW" "ordered port 6 cordic_stage0 16 15 " "Warning: Port \"ordered port 6\" on the entity instantiation of \"cordic_stage0\" is connected to a signal of width 16. The formal width of the signal in the module is 15.  Extra bits will be ignored." {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "cordic_stage0" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 89 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be ignored." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_ampl 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_ampl\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_ampl" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 81 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_tlook 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_tlook\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_tlook" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 75 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_tsw 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_tsw\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_tsw" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 72 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_ton 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_ton\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_ton" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 69 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_rxformat 11 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_rxformat\" is connected to a signal of width 11. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/rx_buffer.v" "sr_rxformat" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/rx_buffer.v" 66 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_rxmux 20 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_rxmux\" is connected to a signal of width 20. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/adc_interface.v" "sr_rxmux" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/adc_interface.v" 54 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_dco_en 4 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_dco_en\" is connected to a signal of width 4. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../../../../usrp/fpga/sdr_lib/adc_interface.v" "sr_dco_en" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/adc_interface.v" 32 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WCDB_SGATE_CDB_WARN_TRIVIAL_REG" "radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[0\] data_in GND " "Warning: Reduced register \"radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[0\]\" with stuck data_in port to stuck value GND" {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 64 -1 0 } }  } 0 0 "Reduced register \"%1!s!\" with stuck %2!s! port to stuck value %3!s!" 1 0 "" 0}\r
+{ "Warning" "WCDB_SGATE_CDB_WARN_TRIVIAL_REG" "radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[1\] data_in GND " "Warning: Reduced register \"radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[1\]\" with stuck data_in port to stuck value GND" {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 64 -1 0 } }  } 0 0 "Reduced register \"%1!s!\" with stuck %2!s! port to stuck value %3!s!" 1 0 "" 0}\r
+{ "Warning" "WCDB_SGATE_CDB_WARN_TRIVIAL_REG" "master_control:master_control\|atr_delay:atr_delay\|state.0001 data_in GND " "Warning: Reduced register \"master_control:master_control\|atr_delay:atr_delay\|state.0001\" with stuck data_in port to stuck value GND" {  } { { "../../../../usrp/fpga/sdr_lib/atr_delay.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/atr_delay.v" 31 -1 0 } }  } 0 0 "Reduced register \"%1!s!\" with stuck %2!s! port to stuck value %3!s!" 1 0 "" 0}\r
+{ "Warning" "WOPT_MLS_STUCK_PIN_HDR" "" "Warning: Output pins are stuck at VCC or GND" { { "Warning" "WOPT_MLS_STUCK_PIN" "MYSTERY_SIGNAL GND " "Warning: Pin \"MYSTERY_SIGNAL\" stuck at GND" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 24 -1 0 } }  } 0 0 "Pin \"%1!s!\" stuck at %2!s!" 1 0 "" 0}  } {  } 0 0 "Output pins are stuck at VCC or GND" 0 0 "" 0}\r
+{ "Warning" "WOPT_MLS_STUCK_PIN_HDR" "" "Warning: Output pins are stuck at VCC or GND" { { "Warning" "WOPT_MLS_STUCK_PIN" "FX2_3 GND " "Warning: Pin \"FX2_3\" stuck at GND" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 33 -1 0 } }  } 0 0 "Pin \"%1!s!\" stuck at %2!s!" 1 0 "" 0}  } {  } 0 0 "Output pins are stuck at VCC or GND" 0 0 "" 0}\r
+{ "Warning" "WOPT_MLS_STUCK_PIN_HDR" "" "Warning: Output pins are stuck at VCC or GND" { { "Warning" "WOPT_MLS_STUCK_PIN" "usbrdy\[0\] GND " "Warning: Pin \"usbrdy\[0\]\" stuck at GND" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 49 -1 0 } }  } 0 0 "Pin \"%1!s!\" stuck at %2!s!" 1 0 "" 0}  } {  } 0 0 "Output pins are stuck at VCC or GND" 0 0 "" 0}\r
+{ "Warning" "WCUT_CUT_UNNECESSARY_INPUT_PIN_HDR" "1 " "Warning: Design contains * input pin(s) that do not drive logic" { { "Warning" "WCUT_CUT_UNNECESSARY_INPUT_PIN" "usbctl\[0\] " "Warning: No output dependent on input pin \"usbctl\[0\]\"" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 48 -1 0 } }  } 0 0 "No output dependent on input pin \"%1!s!\"" 1 0 "" 0}  } {  } 0 0 "Design contains %1!d! input pin(s) that do not drive logic" 0 0 "" 0}\r
+{ "Warning" "WFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN" "3 " "Warning: Following * pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" { { "Info" "IFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN_SUB" "MYSTERY_SIGNAL GND " "Info: Pin MYSTERY_SIGNAL has GND driving its datain port" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 24 -1 0 } } { "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" "" { Assignment "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" 1 { { 0 "MYSTERY_SIGNAL" } } } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { MYSTERY_SIGNAL } "NODE_NAME" } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { MYSTERY_SIGNAL } "NODE_NAME" } }  } 0 0 "Pin %1!s! has %2!s! driving its datain port" 1 0 "" 0}  } {  } 0 0 "Following %1!d! pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" 0 0 "" 0}\r
+{ "Warning" "WFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN" "3 " "Warning: Following * pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" { { "Info" "IFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN_SUB" "FX2_3 GND " "Info: Pin FX2_3 has GND driving its datain port" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 33 -1 0 } } { "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" "" { Assignment "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" 1 { { 0 "FX2_3" } } } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { FX2_3 } "NODE_NAME" } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { FX2_3 } "NODE_NAME" } }  } 0 0 "Pin %1!s! has %2!s! driving its datain port" 1 0 "" 0}  } {  } 0 0 "Following %1!d! pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" 0 0 "" 0}\r
+{ "Warning" "WFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN" "3 " "Warning: Following * pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" { { "Info" "IFIOMGR_BIDIR_OR_OUTPUT_WITH_TRIVIAL_DATAIN_SUB" "usbrdy\[0\] GND " "Info: Pin usbrdy\[0\] has GND driving its datain port" {  } { { "usrp_radar_mono.v" "" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/top/usrp_radar_mono.v" 49 -1 0 } } { "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" "" { Assignment "c:/altera/71sp1/quartus/bin/Assignment Editor.qase" 1 { { 0 "usbrdy\[0\]" } } } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { usbrdy[0] } "NODE_NAME" } } { "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" { Floorplan "c:/altera/71sp1/quartus/bin/TimingClosureFloorplan.fld" "" "" { usbrdy[0] } "NODE_NAME" } }  } 0 0 "Pin %1!s! has %2!s! driving its datain port" 1 0 "" 0}  } {  } 0 0 "Following %1!d! pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results" 0 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_ampl 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_ampl\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_ampl" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 79 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_tlook 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_tlook\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_tlook" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 73 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_tsw 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_tsw\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_tsw" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 70 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WSGN_WIDTH_MISMATCH_OUTPUT_PORT" "out sr_ton 16 32 " "Warning: Port \"out\" on the entity instantiation of \"sr_ton\" is connected to a signal of width 16. The formal width of the signal in the module is 32.  Extra bits will be left dangling without any fanout logic." {  } { { "../lib/radar_control.v" "sr_ton" { Text "H:/gnuradio/radar/gr-radar-mono/src/fpga/lib/radar_control.v" 67 0 0 } }  } 0 0 "Port \"%1!s!\" on the entity instantiation of \"%2!s!\" is connected to a signal of width %3!d!. The formal width of the signal in the module is %4!d!.  Extra bits will be left dangling without any fanout logic." 1 0 "" 0}\r
+{ "Warning" "WVRFX_L2_VERI_EXPRESSION_TRUNCATED_TO_FIT" "32 12 atr_delay.v(58) " "Warning (10230): Verilog HDL assignment warning at atr_delay.v(58): truncated value with size 32 to match size of target (12)" {  } { { "../../../../usrp/fpga/sdr_lib/atr_delay.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/atr_delay.v" 58 0 0 } }  } 0 10230 "Verilog HDL assignment warning at %3!s!: truncated value with size %1!d! to match size of target (%2!d!)" 1 0 "" 0}\r
+{ "Warning" "WVRFX_L2_VERI_EXPRESSION_TRUNCATED_TO_FIT" "32 12 atr_delay.v(71) " "Warning (10230): Verilog HDL assignment warning at atr_delay.v(71): truncated value with size 32 to match size of target (12)" {  } { { "../../../../usrp/fpga/sdr_lib/atr_delay.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/atr_delay.v" 71 0 0 } }  } 0 10230 "Verilog HDL assignment warning at %3!s!: truncated value with size %1!d! to match size of target (%2!d!)" 1 0 "" 0}\r
+{ "Warning" "WVRFX_L2_HDL_OBJECT_ASSIGNED_NOT_READ" "write_done serial_io.v(48) " "Warning (10036): Verilog HDL or VHDL warning at serial_io.v(48): object \"write_done\" assigned a value but never read" {  } { { "../../../../usrp/fpga/sdr_lib/serial_io.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/serial_io.v" 48 0 0 } }  } 0 10036 "Verilog HDL or VHDL warning at %2!s!: object \"%1!s!\" assigned a value but never read" 1 0 "" 0}\r
+{ "Warning" "WCDB_SGATE_CDB_WARN_TRIVIAL_REG" "radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[2\] data_in GND " "Warning: Reduced register \"radar:radar_mono\|radar_tx:transmitter\|cordic_nco:nco\|cordic:tx_cordic\|y0\[2\]\" with stuck data_in port to stuck value GND" {  } { { "../../../../usrp/fpga/sdr_lib/cordic.v" "" { Text "H:/gnuradio/radar/usrp/fpga/sdr_lib/cordic.v" 64 -1 0 } }  } 0 0 "Reduced register \"%1!s!\" with stuck %2!s! port to stuck value %3!s!" 1 0 "" 0}\r
diff --git a/gr-radar-mono/src/lib/.gitignore b/gr-radar-mono/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-radar-mono/src/python/.gitignore b/gr-radar-mono/src/python/.gitignore
new file mode 100644 (file)
index 0000000..f104c58
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/run_tests
+/*.pyc
diff --git a/gr-radar-mono/src/python/qa_nothing.py b/gr-radar-mono/src/python/qa_nothing.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-radar-mono/src/utils/calc_avg.m b/gr-radar-mono/src/utils/calc_avg.m
new file mode 100644 (file)
index 0000000..b240d24
--- /dev/null
@@ -0,0 +1,8 @@
+function avg = calc_avg(rlen, mintime)
+    avg = read_avg('echos.dat', rlen);
+    x = 1:rlen;
+    x = (x/64e6+mintime)*3e8/2;
+    plot(x, abs(avg), "^;Amplitude;");
+    xlabel("Range (meters)");
+    axis([max(x) 0])
+endfunction
diff --git a/gr-radar-mono/src/utils/czpad.m b/gr-radar-mono/src/utils/czpad.m
new file mode 100644 (file)
index 0000000..e213103
--- /dev/null
@@ -0,0 +1,8 @@
+# Center and zero pad v to length n
+function pad = czpad(v, n)
+    c = n/2;
+    l = length(v);
+    pad(c-l/2+1:c+l/2) = v;
+    pad(c+l/2+1:n) = 0;
+endfunction
\ No newline at end of file
diff --git a/gr-radar-mono/src/utils/echo_image.m b/gr-radar-mono/src/utils/echo_image.m
new file mode 100644 (file)
index 0000000..2e066ae
--- /dev/null
@@ -0,0 +1,6 @@
+function echo_image(filename, data)
+    d = abs(data);
+    d = d-min(min(d));
+    d = d/(max(max(d)))*255;
+    pngwrite(filename, d, d, d, ones(size(d)));
+endfunction
\ No newline at end of file
diff --git a/gr-radar-mono/src/utils/fftcorr.m b/gr-radar-mono/src/utils/fftcorr.m
new file mode 100644 (file)
index 0000000..5489889
--- /dev/null
@@ -0,0 +1,4 @@
+# Perform circular correlation via FFT
+function corr = fftcorr(v,ref)
+    corr = ifft(conj(fft(ref)).*fft(v));
+endfunction
diff --git a/gr-radar-mono/src/utils/pulse b/gr-radar-mono/src/utils/pulse
new file mode 100644 (file)
index 0000000..887558d
--- /dev/null
@@ -0,0 +1,396 @@
+# Created by Octave 2.1.73, Tue Sep 25 14:17:22 2007 EDT <jcorgan@mobile>
+# name: __nargin__
+# type: scalar
+0
+# name: pulse321
+# type: complex matrix
+# rows: 64
+# columns: 1
+ (-0.0003662109375,0.9998779296875)
+ (-0.0003662109375,0.9998779296875)
+ (0,-0.9996337890625)
+ (0,-0.9996337890625)
+ (-0.0010986328125,-0.961181640625)
+ (-0.0010986328125,-0.961181640625)
+ (0.0072021484375,0.882568359375)
+ (0.0072021484375,0.882568359375)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.0765380859375,0.616943359375)
+ (0.0765380859375,0.616943359375)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.1688232421875,-0.4447021484375)
+ (0.3212890625,0.26611328125)
+ (0.3212890625,0.26611328125)
+ (-0.54638671875,-0.1092529296875)
+ (-0.54638671875,-0.1092529296875)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (0.8046875,-0.019775390625)
+ (0.8046875,-0.019775390625)
+ (-0.444580078125,0.1688232421875)
+ (-0.444580078125,0.1688232421875)
+ (0.147705078125,-0.477294921875)
+ (0.147705078125,-0.477294921875)
+ (-0.0032958984375,0.921142578125)
+ (-0.0032958984375,0.921142578125)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.4447021484375,-0.1688232421875)
+ (-0.4447021484375,-0.1688232421875)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (0.4127197265625,-0.19140625)
+ (0.4127197265625,-0.19140625)
+ (-0.0379638671875,0.728759765625)
+ (-0.0379638671875,0.728759765625)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.617919921875,-0.0762939453125)
+ (-0.617919921875,-0.0762939453125)
+ (-0.6170654296875,0.0765380859375)
+ (-0.6170654296875,0.0765380859375)
+ (0.0621337890625,-0.654296875)
+ (0.0621337890625,-0.654296875)
+ (-0.127685546875,-0.511962890625)
+ (-0.127685546875,-0.511962890625)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (0.29296875,-0.293212890625)
+ (0.29296875,-0.293212890625)
+ (-0.01953125,-0.8046875)
+ (-0.01953125,-0.8046875)
+ (0.654296875,0.0618896484375)
+ (0.654296875,0.0618896484375)
+ (0.3505859375,-0.239990234375)
+ (0.3505859375,-0.239990234375)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.805419921875,0.01953125)
+ (0.805419921875,0.01953125)
+ (0.1688232421875,-0.444580078125)
+ (0.1688232421875,-0.444580078125)
+# name: pulse325
+# type: complex matrix
+# rows: 320
+# columns: 1
+ (-0.0003662109375,0.9998779296875)
+ (-0.0003662109375,0.9998779296875)
+ (0,-0.9996337890625)
+ (0,-0.9996337890625)
+ (-0.0010986328125,-0.961181640625)
+ (-0.0010986328125,-0.961181640625)
+ (0.0072021484375,0.882568359375)
+ (0.0072021484375,0.882568359375)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.0765380859375,0.616943359375)
+ (0.0765380859375,0.616943359375)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.1688232421875,-0.4447021484375)
+ (0.3212890625,0.26611328125)
+ (0.3212890625,0.26611328125)
+ (-0.54638671875,-0.1092529296875)
+ (-0.54638671875,-0.1092529296875)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (0.8046875,-0.019775390625)
+ (0.8046875,-0.019775390625)
+ (-0.444580078125,0.1688232421875)
+ (-0.444580078125,0.1688232421875)
+ (0.147705078125,-0.477294921875)
+ (0.147705078125,-0.477294921875)
+ (-0.0032958984375,0.921142578125)
+ (-0.0032958984375,0.921142578125)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.4447021484375,-0.1688232421875)
+ (-0.4447021484375,-0.1688232421875)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (0.4127197265625,-0.19140625)
+ (0.4127197265625,-0.19140625)
+ (-0.0379638671875,0.728759765625)
+ (-0.0379638671875,0.728759765625)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.617919921875,-0.0762939453125)
+ (-0.617919921875,-0.0762939453125)
+ (-0.6170654296875,0.0765380859375)
+ (-0.6170654296875,0.0765380859375)
+ (0.0621337890625,-0.654296875)
+ (0.0621337890625,-0.654296875)
+ (-0.127685546875,-0.511962890625)
+ (-0.127685546875,-0.511962890625)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (0.29296875,-0.293212890625)
+ (0.29296875,-0.293212890625)
+ (-0.01953125,-0.8046875)
+ (-0.01953125,-0.8046875)
+ (0.654296875,0.0618896484375)
+ (0.654296875,0.0618896484375)
+ (0.3505859375,-0.239990234375)
+ (0.3505859375,-0.239990234375)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.805419921875,0.01953125)
+ (0.805419921875,0.01953125)
+ (0.1688232421875,-0.444580078125)
+ (0.1688232421875,-0.444580078125)
+ (-0.1910400390625,-0.4127197265625)
+ (-0.1910400390625,-0.4127197265625)
+ (-0.6912841796875,0.049072265625)
+ (-0.6912841796875,0.049072265625)
+ (0.0009765625,0.9613037109375)
+ (0.0009765625,0.9613037109375)
+ (-0.8055419921875,-0.0194091796875)
+ (-0.8055419921875,-0.0194091796875)
+ (-0.076171875,0.6177978515625)
+ (-0.076171875,0.6177978515625)
+ (0.4771728515625,0.14794921875)
+ (0.4771728515625,0.14794921875)
+ (0.2144775390625,-0.3812255859375)
+ (0.2144775390625,-0.3812255859375)
+ (-0.3214111328125,-0.2659912109375)
+ (-0.3214111328125,-0.2659912109375)
+ (-0.29296875,0.293212890625)
+ (-0.29296875,0.293212890625)
+ (0.293212890625,0.29296875)
+ (0.293212890625,0.29296875)
+ (0.265869140625,-0.3212890625)
+ (0.265869140625,-0.3212890625)
+ (-0.3814697265625,-0.2144775390625)
+ (-0.3814697265625,-0.2144775390625)
+ (-0.1480712890625,0.4774169921875)
+ (-0.1480712890625,0.4774169921875)
+ (0.617919921875,0.0760498046875)
+ (0.617919921875,0.0760498046875)
+ (0.019287109375,-0.805419921875)
+ (0.019287109375,-0.805419921875)
+ (0.961181640625,-0.0009765625)
+ (0.961181640625,-0.0009765625)
+ (-0.049072265625,-0.6915283203125)
+ (-0.049072265625,-0.6915283203125)
+ (-0.412353515625,0.19091796875)
+ (-0.412353515625,0.19091796875)
+ (0.4444580078125,0.1689453125)
+ (0.4444580078125,0.1689453125)
+ (0.019287109375,-0.805419921875)
+ (0.019287109375,-0.805419921875)
+ (0.7664794921875,-0.02783203125)
+ (0.7664794921875,-0.02783203125)
+ (-0.2401123046875,-0.3507080078125)
+ (-0.2401123046875,-0.3507080078125)
+ (-0.06201171875,0.6541748046875)
+ (-0.06201171875,0.6541748046875)
+ (-0.804443359375,0.0194091796875)
+ (-0.804443359375,0.0194091796875)
+ (0.293212890625,0.29296875)
+ (0.293212890625,0.29296875)
+ (0.012451171875,-0.843994140625)
+ (0.012451171875,-0.843994140625)
+ (0.5118408203125,-0.127685546875)
+ (0.5118408203125,-0.127685546875)
+ (-0.6541748046875,-0.062255859375)
+ (-0.6541748046875,-0.062255859375)
+ (-0.07666015625,-0.6170654296875)
+ (-0.07666015625,-0.6170654296875)
+ (-0.076171875,0.6177978515625)
+ (-0.076171875,0.6177978515625)
+ (-0.581298828125,0.0921630859375)
+ (-0.581298828125,0.0921630859375)
+ (0.7286376953125,0.037841796875)
+ (0.7286376953125,0.037841796875)
+ (0.1912841796875,0.412353515625)
+ (0.1912841796875,0.412353515625)
+ (0,-0.9996337890625)
+ (0,-0.9996337890625)
+ (0.1688232421875,-0.444580078125)
+ (0.1688232421875,-0.444580078125)
+ (0.581298828125,-0.0924072265625)
+ (0.581298828125,-0.0924072265625)
+ (-0.9212646484375,-0.003662109375)
+ (-0.9212646484375,-0.003662109375)
+ (-0.4775390625,-0.1478271484375)
+ (-0.4775390625,-0.1478271484375)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.01953125,-0.8046875)
+ (-0.01953125,-0.8046875)
+ (-0.012451171875,0.8438720703125)
+ (-0.012451171875,0.8438720703125)
+ (-0.109375,0.5462646484375)
+ (-0.109375,0.5462646484375)
+ (-0.26611328125,0.321533203125)
+ (-0.26611328125,0.321533203125)
+ (-0.444580078125,0.1688232421875)
+ (-0.444580078125,0.1688232421875)
+ (-0.6170654296875,0.0765380859375)
+ (-0.6170654296875,0.0765380859375)
+ (-0.7666015625,0.02783203125)
+ (-0.7666015625,0.02783203125)
+ (-0.882568359375,0.00732421875)
+ (-0.882568359375,0.00732421875)
+ (-0.9613037109375,0.0010986328125)
+ (-0.9613037109375,0.0010986328125)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (-0.9613037109375,0.0010986328125)
+ (-0.9613037109375,0.0010986328125)
+ (-0.882568359375,0.00732421875)
+ (-0.882568359375,0.00732421875)
+ (-0.7666015625,0.02783203125)
+ (-0.7666015625,0.02783203125)
+ (-0.6170654296875,0.0765380859375)
+ (-0.6170654296875,0.0765380859375)
+ (-0.444580078125,0.1688232421875)
+ (-0.444580078125,0.1688232421875)
+ (-0.26611328125,0.321533203125)
+ (-0.26611328125,0.321533203125)
+ (-0.109375,0.5462646484375)
+ (-0.109375,0.5462646484375)
+ (-0.012451171875,0.8438720703125)
+ (-0.012451171875,0.8438720703125)
+ (-0.01953125,-0.8046875)
+ (-0.01953125,-0.8046875)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.4775390625,-0.1478271484375)
+ (-0.4775390625,-0.1478271484375)
+ (-0.9212646484375,-0.003662109375)
+ (-0.9212646484375,-0.003662109375)
+ (0.581298828125,-0.0924072265625)
+ (0.581298828125,-0.0924072265625)
+ (0.1688232421875,-0.444580078125)
+ (0.1688232421875,-0.444580078125)
+ (0,-0.9996337890625)
+ (0,-0.9996337890625)
+ (0.1912841796875,0.412353515625)
+ (0.1912841796875,0.412353515625)
+ (0.7286376953125,0.037841796875)
+ (0.7286376953125,0.037841796875)
+ (-0.581298828125,0.0921630859375)
+ (-0.581298828125,0.0921630859375)
+ (-0.076171875,0.6177978515625)
+ (-0.076171875,0.6177978515625)
+ (-0.07666015625,-0.6170654296875)
+ (-0.07666015625,-0.6170654296875)
+ (-0.6541748046875,-0.062255859375)
+ (-0.6541748046875,-0.062255859375)
+ (0.5118408203125,-0.127685546875)
+ (0.5118408203125,-0.127685546875)
+ (0.012451171875,-0.843994140625)
+ (0.012451171875,-0.843994140625)
+ (0.293212890625,0.29296875)
+ (0.293212890625,0.29296875)
+ (-0.804443359375,0.0194091796875)
+ (-0.804443359375,0.0194091796875)
+ (-0.06201171875,0.6541748046875)
+ (-0.06201171875,0.6541748046875)
+ (-0.2401123046875,-0.3507080078125)
+ (-0.2401123046875,-0.3507080078125)
+ (0.7664794921875,-0.02783203125)
+ (0.7664794921875,-0.02783203125)
+ (0.019287109375,-0.805419921875)
+ (0.019287109375,-0.805419921875)
+ (0.4444580078125,0.1689453125)
+ (0.4444580078125,0.1689453125)
+ (-0.412353515625,0.19091796875)
+ (-0.412353515625,0.19091796875)
+ (-0.049072265625,-0.6915283203125)
+ (-0.049072265625,-0.6915283203125)
+ (0.961181640625,-0.0009765625)
+ (0.961181640625,-0.0009765625)
+ (0.019287109375,-0.805419921875)
+ (0.019287109375,-0.805419921875)
+ (0.617919921875,0.0760498046875)
+ (0.617919921875,0.0760498046875)
+ (-0.1480712890625,0.4774169921875)
+ (-0.1480712890625,0.4774169921875)
+ (-0.3814697265625,-0.2144775390625)
+ (-0.3814697265625,-0.2144775390625)
+ (0.265869140625,-0.3212890625)
+ (0.265869140625,-0.3212890625)
+ (0.293212890625,0.29296875)
+ (0.293212890625,0.29296875)
+ (-0.29296875,0.293212890625)
+ (-0.29296875,0.293212890625)
+ (-0.3214111328125,-0.2659912109375)
+ (-0.3214111328125,-0.2659912109375)
+ (0.2144775390625,-0.3812255859375)
+ (0.2144775390625,-0.3812255859375)
+ (0.4771728515625,0.14794921875)
+ (0.4771728515625,0.14794921875)
+ (-0.076171875,0.6177978515625)
+ (-0.076171875,0.6177978515625)
+ (-0.8055419921875,-0.0194091796875)
+ (-0.8055419921875,-0.0194091796875)
+ (0.0009765625,0.9613037109375)
+ (0.0009765625,0.9613037109375)
+ (-0.6912841796875,0.049072265625)
+ (-0.6912841796875,0.049072265625)
+ (-0.1910400390625,-0.4127197265625)
+ (-0.1910400390625,-0.4127197265625)
+ (0.1688232421875,-0.444580078125)
+ (0.1688232421875,-0.444580078125)
+ (0.805419921875,0.01953125)
+ (0.805419921875,0.01953125)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.3505859375,-0.239990234375)
+ (0.3505859375,-0.239990234375)
+ (0.654296875,0.0618896484375)
+ (0.654296875,0.0618896484375)
+ (-0.01953125,-0.8046875)
+ (-0.01953125,-0.8046875)
+ (0.29296875,-0.293212890625)
+ (0.29296875,-0.293212890625)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (-0.127685546875,-0.511962890625)
+ (-0.127685546875,-0.511962890625)
+ (0.0621337890625,-0.654296875)
+ (0.0621337890625,-0.654296875)
+ (-0.6170654296875,0.0765380859375)
+ (-0.6170654296875,0.0765380859375)
+ (-0.617919921875,-0.0762939453125)
+ (-0.617919921875,-0.0762939453125)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.0379638671875,0.728759765625)
+ (-0.0379638671875,0.728759765625)
+ (0.4127197265625,-0.19140625)
+ (0.4127197265625,-0.19140625)
+ (0.9996337890625,0.000244140625)
+ (0.9996337890625,0.000244140625)
+ (-0.4447021484375,-0.1688232421875)
+ (-0.4447021484375,-0.1688232421875)
+ (0.09228515625,0.5811767578125)
+ (0.09228515625,0.5811767578125)
+ (-0.0032958984375,0.921142578125)
+ (-0.0032958984375,0.921142578125)
+ (0.147705078125,-0.477294921875)
+ (0.147705078125,-0.477294921875)
+ (-0.444580078125,0.1688232421875)
+ (-0.444580078125,0.1688232421875)
+ (0.8046875,-0.019775390625)
+ (0.8046875,-0.019775390625)
+ (0.843994140625,0.012451171875)
+ (0.843994140625,0.012451171875)
+ (-0.54638671875,-0.1092529296875)
+ (-0.54638671875,-0.1092529296875)
+ (0.3212890625,0.26611328125)
+ (0.3212890625,0.26611328125)
+ (-0.1688232421875,-0.4447021484375)
+ (-0.1688232421875,-0.4447021484375)
+ (0.0765380859375,0.616943359375)
+ (0.0765380859375,0.616943359375)
+ (-0.0279541015625,-0.7666015625)
+ (-0.0279541015625,-0.7666015625)
+ (0.0072021484375,0.882568359375)
+ (0.0072021484375,0.882568359375)
+ (-0.0010986328125,-0.961181640625)
+ (-0.0010986328125,-0.961181640625)
diff --git a/gr-radar-mono/src/utils/read_avg.m b/gr-radar-mono/src/utils/read_avg.m
new file mode 100644 (file)
index 0000000..7df3d4c
--- /dev/null
@@ -0,0 +1,22 @@
+function avg = read_avg(name, vlen)
+
+    f = fopen(name, "rb");
+    s = zeros(1, vlen);
+    n = 0;
+        
+    while (!feof(f))
+       t = fread(f, [2, vlen], "float");
+       if (size(t) == [2, vlen])
+          n = n+1;
+          c = t(1,:)+t(2,:)*j;
+         if (n > 10)
+             s = s+c;
+         endif
+       endif
+    endwhile
+
+    avg = s/(n-1);
+    
+    fclose(f);
+    
+endfunction
diff --git a/gr-radar-mono/src/utils/read_avg_sec.m b/gr-radar-mono/src/utils/read_avg_sec.m
new file mode 100644 (file)
index 0000000..7aa7767
--- /dev/null
@@ -0,0 +1,25 @@
+function avg = read_avg_sec(name, vlen)
+
+    f = fopen(name, "rb");
+    s = zeros(1, vlen);
+    n = 0;
+    m = 0;
+        
+    while (!feof(f))
+       t = fread(f, [2, vlen], "float");
+       if (size(t) == [2, vlen])
+          n = n+1;
+          c = t(1,:)+t(2,:)*j;
+          s = s+c;
+         m = m+1;        
+         if (m == 1000)
+            avg(n/1000,:) = s/1000;
+            s = zeros(1, vlen);
+            m = 0;
+         endif
+       endif
+    endwhile
+    
+    fclose(f);
+
+endfunction
diff --git a/gr-radar-mono/src/utils/read_echos.m b/gr-radar-mono/src/utils/read_echos.m
new file mode 100644 (file)
index 0000000..3fae47b
--- /dev/null
@@ -0,0 +1,7 @@
+# Read echos from file into array
+function echos = read_echos(filename, len, drop)
+    e = read_complex_binary(filename);
+    n = length(e)/len-drop;
+    start = drop*len+1;
+    echos = reshape(e(start:end), len, n).';
+endfunction
diff --git a/gr-radio-astronomy/.gitignore b/gr-radio-astronomy/.gitignore
new file mode 100644 (file)
index 0000000..8736aba
--- /dev/null
@@ -0,0 +1,22 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
diff --git a/gr-radio-astronomy/src/.gitignore b/gr-radio-astronomy/src/.gitignore
new file mode 100644 (file)
index 0000000..bb3f277
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
index e3f0399eb093e516a323ed1c5d4a6f7eb12c6cc9..be38b7c1ab43449ae85bcec13768c8afc0452f0b 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-radio-astronomy/src/lib/.gitignore b/gr-radio-astronomy/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..6fc7d94
--- /dev/null
@@ -0,0 +1,13 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
+/ra.cc
+/ra.py
+/*.pyc
index 33a8a859ab6e438a01f88d69713996dc16c639ef..d2dafdeacc7cf4324966d59075af100d6c737d4a 100644 (file)
@@ -23,6 +23,7 @@ include $(top_srcdir)/Makefile.common
 
 AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
 
+if PYTHON
 TOP_SWIG_IFILES =              \
        ra.i
 
@@ -40,3 +41,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-radio-astronomy/src/python/.gitignore b/gr-radio-astronomy/src/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-radio-astronomy/src/python/usrp_psr_receiver.help b/gr-radio-astronomy/src/python/usrp_psr_receiver.help
new file mode 100644 (file)
index 0000000..5801f3f
--- /dev/null
@@ -0,0 +1,111 @@
+This program is used to analyse pulsars of known parameters.  It contains
+  both a post-detector spectral display, and a "pulse profile" display.
+  It has a built-in de-dispersion filter that will work up to DM=100 for
+  21cm observing, and up to DM=5 for 327Mhz observing.
+
+The program takes the following options:
+
+  --rx-subdev-spec     which USRP Rx side?  A or B
+
+  --decim              USRP decimation rate use either 64 or 128
+
+  --freq               USRP daughtercard frequency
+
+  --observing          Actual observing frequency (default is to use the
+                       setting for --freq)
+
+  --avg                Averaging setting for spectral display--higher numbers
+                       equal more averaging.  25 to 40 is typical.
+
+  --favg               Pulse folding averaging.  2 to 5 is typical.
+
+  --gain               USRP daughtercard gain control
+
+  --reflevel           Reference level on pulse profile display
+
+  --lowest             Lowest spectral bin that is considered valid, in Hz
+
+  --longitude          Observer longitude: West is negative
+
+  --latitude           Observer latitude:  South is negative
+
+  --fft_size           Size of FFT for post-detector spectrum: default is 1024
+
+  --threshold          Threshold (dB) to be considered a spectral "peak"
+                       This is relative to the average spectral level
+
+  --lowpass            Low pass frequency for post-detector spectral display
+                       20-100 is typical
+
+  --prefix             Filename prefix to use for recording files
+                       Default is ./
+
+  --pulsefreq          The frequency of the expected pulses
+                       For sentimental reasons, this defaults to 0.748Hz
+
+  --dm                 The DM
+
+  --doppler            The doppler shift, as a ratio
+
+  --divbase            The base of the Y/Div menu in pulsar display
+
+  --division           The initial Y/Div in pulsar display
+
+DM, Doppler, Gain, Frequency, and the averaging parameters can all be
+  changed using the GUI at runtime.
+
+If latitude and longitude are set correctly, and the system time is
+  correct, then the current LMST is displayed below the frequency
+  input, updated once per second.
+
+Moving the mouse in the post-detector spectrum display shows you that
+  point in the post-detector spectrum, both frequency and signal level.
+
+The post-detector spectrum is analysed, with results shown below
+  "Best freq".  It shows the spectral peaks, and computes their relationship.
+  It shows the harmonic compliance among the peaks, as well as the average
+  peak-to-peak distance.
+
+
+Here's a complete example for observing a pulsar with a frequency of
+  1.35Hz, at 431.5Mhz, using an IF of 10.7Mhz, and a DM of 12.431, using
+  1Mhz observing bandwidth:
+
+./usrp_psr_receiver.py --freq 10.7e6 --decim 64 --dm 12.431 --avg 35 \
+  --pulsefreq 1.35 --fft_size 2048 --lowest 1.00 --gain 75 --threshold 11.5 \
+  --observing 431.5e6 --reflevel 200 --division 100 --divbase 10 --favg 3 \
+  --lowpass 20 --longitude -76.02 --latitude 44.95
+
+Since the observed pulsar is at 1.35Hz, a lowpass cutoff for the
+  post-detector spectral display of 20Hz will be adequate.  We
+  tell the spectral analyser to use a threshold of 11.5dB above
+  average when analysing spectral data, and set the epoch folder
+  averager (pulse profile display) to use an average from 3 samples.
+  Notice that our actual USRP/Daughtercard frequency is 10.7Mhz, while
+  our observing frequency is 431.5Mhz--this is important in order for
+  the DM de-dispersion calculations to be correct. We also set our
+  latitude and longitude, so that logfiles and the LMST display
+  will have the correct LMST in them.
+
+The entire complex baseband can be recorded, if the "Recording baseband"
+  button is pressed.  Filenames are generated dynamically, and a header
+  file is produced giving observation parameters.  The baseband data are
+  recorded as octet pairs: one for I and one for Q.  Pressing the button again
+  turns off baseband recording.  This baseband is "raw", so it will
+  not have been de-dispersed.  The data rate will be whatever the
+  USRP was programmed to at the time (based on --decim).
+
+  The files are:  YYYYMMDDHHMM.pdat  and YYYYMMDDHHMM.phdr
+
+  The .phdr file contains ASCII header information describing the
+  contents of the .pdat file.
+
+Similarly the raw, pre-folded, band-limited post-detector "audio" data can be
+  recorded using the "Record Pulses" button.  The data rate for these is
+  currently 20Khz, recorded as short integers.  Just like baseband recording,
+  pressing the button again turns off pulse recording.
+
+  The files are: YYYYMMDDHHMM.padat  and YYMMDDHHMM.pahdr
+
+  The .pahdr file is ascii text providing information about the contents
+  of the corresponding .padat file.
index c447cfec51d9f4953c20b7c700038cd0d2602db2..6ce4325a26426cc0df0f4ba144439cacc17be805 100755 (executable)
@@ -1089,7 +1089,7 @@ class app_flow_graph(stdgui2.std_top_block):
         return(int(ntaps))
 
 def main ():
-    app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY PULSAR RECEIVER: $Revision: 7241 $", nstatus=1)
+    app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY PULSAR RECEIVER: $Revision$", nstatus=1)
     app.MainLoop()
 
 if __name__ == '__main__':
diff --git a/gr-radio-astronomy/src/python/usrp_ra_receiver.help b/gr-radio-astronomy/src/python/usrp_ra_receiver.help
new file mode 100644 (file)
index 0000000..45a21e2
--- /dev/null
@@ -0,0 +1,90 @@
+This program is used to take spectra and total power measurements.
+  It records spectral and total-power data to external datalogging
+  files.
+
+The program takes the following options:
+
+  --rx-subdev-spec     which USRP Rx side?  A or B
+
+  --decim              USRP decimation rate: 8, 16, 32, and 64 are good
+                       (8Mhz, 4Mhz, 2Mhz, and 1Mhz bandwidth)
+
+  --freq               USRP daughtercard frequency
+
+  --observing          Actual observing frequency (default is to use the
+                       setting for --freq)
+
+  --avg                Averaging setting for spectral display--higher numbers
+                       equal more averaging.  25 to 40 is typical.
+
+  --integ              Total power integration time: seconds
+
+  --gain               USRP daughtercard gain control
+
+  --reflevel           Reference level on pulse profile display
+
+  --longitude          Observer longitude: West is negative
+
+  --latitude           Observer latitude:  South is negative
+
+  --fft_size           Size of FFT for post-detector spectrum: default is 1024
+
+  --prefix             Filename prefix to use for data logging files
+                       Default is ./
+
+  --divbase            The base of the Y/Div menu in pulsar display
+
+  --division           The initial Y/Div in pulsar display
+
+  --ylabel             Y axis label
+
+  --cfunc              The function name prefix for the spectral and
+                       calibrator functions
+
+  --waterfall          Use waterfall, rather than regular spectral display
+                       NOT TESTED IN THIS APPLICATION
+
+  --stripsize          Size of the total-power stripchart, in samples
+
+There are two windows--a spectral window, and the total-power window.
+  Moving the cursor around in the spectral window shows you the
+  corresponding frequency and doppler shift.  Left clicking in this
+  window sets an interference marker, which sets a "zero" in the
+  interference filter.  Use the "clear interference" button to clear this.
+
+The total power window is updated at a fixed 2Hz rate, and grows from
+  the left of the display.
+
+If latitude and longitude are set correctly, and system time is correct,
+  then the current LMST is displayed, updated once per second.
+
+Averaging parameters, gain, and frequency can all be set from the GUI using
+  the appropriate controls.  You can also enter the current declination, which
+  will appear in the datalogging files.  This is useful both for mapping,
+  and housekeeping purposes, particularly when you haven't looked at a datafile
+  for quite some time.
+
+There are two datalog files produced by this program:
+
+     YYYYMMDDHH.tpdat      Total power data
+
+     The date/time portion of the filename is referred to local time,
+     rather than UTC or sidereal.
+
+     First field is sidereal time when sample was taken
+     Second field is total power datum
+     Third field is declination in decimal degrees
+
+     Samples are written once per second
+
+     YYYYMMDDHH.sdat       Spectral data
+
+     The date/time portion of the filename is referred to local time,
+     rather than UTC or sidereal.
+
+     First field is sidereal time when spectrum was taken
+     Second field is declination in decimal degrees
+     Third field is complex spectral data--in the same order that FFTW3 library
+         places bins:  DC to bandwidth/2, followed by -bandwidth/2 to DC.
+
+     Spectral snapshots are written once every 5 seconds
index 60d5594423a9a077c0b9ae15cd3a38cf2f02c3f4..c37355d28a5eb87ac151580557bba87c9856ac24 100755 (executable)
@@ -1377,7 +1377,7 @@ class app_flow_graph(stdgui2.std_top_block):
                        self.cardtype = self.u.daughterboard_id()
 
 def main ():
-       app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY SPECTRAL/CONTINUUM RECEIVER: $Revision: 10631 $", nstatus=1)
+       app = stdgui2.stdapp(app_flow_graph, "RADIO ASTRONOMY SPECTRAL/CONTINUUM RECEIVER: $Revision$", nstatus=1)
        app.MainLoop()
 
 if __name__ == '__main__':
diff --git a/gr-sounder/.gitignore b/gr-sounder/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-sounder/doc/.gitignore b/gr-sounder/doc/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-sounder/src/.gitignore b/gr-sounder/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index c6fb49efa1e78f7270805a0fa79c10c289389525..d546da7f8656f5ceedbf0aec48b3c8cc57cff991 100644 (file)
@@ -21,4 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = fpga lib python
+SUBDIRS = fpga lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-sounder/src/fpga/.gitignore b/gr-sounder/src/fpga/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-sounder/src/fpga/lib/.gitignore b/gr-sounder/src/fpga/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-sounder/src/fpga/lib/lfsr.v b/gr-sounder/src/fpga/lib/lfsr.v
new file mode 100644 (file)
index 0000000..bd0743e
--- /dev/null
@@ -0,0 +1,46 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2007 Corgan Enterprises LLC
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
+//
+
+module lfsr(clk_i,rst_i,ena_i,strobe_i,mask_i,pn_o);
+   parameter width = 16;
+
+   input clk_i;
+   input rst_i;
+   input ena_i;
+   input strobe_i;
+   input [width-1:0] mask_i;
+   
+   output pn_o;
+
+   reg  [width-1:0] shifter;
+
+   wire parity = ^(shifter & mask_i);
+   
+   always @(posedge clk_i)
+     if (rst_i | ~ena_i)
+       shifter <= #5 1;
+     else
+       if (strobe_i)
+        shifter <= #5 {shifter[width-2:0],parity};
+
+   assign pn_o = shifter[0];
+   
+endmodule // lfsr
diff --git a/gr-sounder/src/fpga/lib/lfsr_constants.v b/gr-sounder/src/fpga/lib/lfsr_constants.v
new file mode 100644 (file)
index 0000000..e23ed66
--- /dev/null
@@ -0,0 +1,63 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2007 Corgan Enterprises LLC
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
+//
+
+module lfsr_constants(clk_i,rst_i,degree_i,mask_o,len_o);
+   input             clk_i;
+   input             rst_i;
+   input      [4:0]  degree_i;
+   output reg [15:0] mask_o;
+   output reg [16:0] len_o;
+
+   integer len;
+   
+   always @(posedge clk_i)
+     if (rst_i)
+       begin
+         len_o <= #5 17'b0;
+         mask_o <= #5 16'b0;
+       end
+     else
+       begin
+         len_o <= #5 ((1 << degree_i) << 1)-3;
+         
+         case (degree_i)
+           5'd00: mask_o <= #5 16'h0000;
+           5'd01: mask_o <= #5 16'h0001;
+           5'd02: mask_o <= #5 16'h0003;
+           5'd03: mask_o <= #5 16'h0005;
+           5'd04: mask_o <= #5 16'h0009;
+           5'd05: mask_o <= #5 16'h0012;
+           5'd06: mask_o <= #5 16'h0021;
+           5'd07: mask_o <= #5 16'h0041;
+           5'd08: mask_o <= #5 16'h008E;
+           5'd09: mask_o <= #5 16'h0108;
+           5'd10: mask_o <= #5 16'h0204;
+           5'd11: mask_o <= #5 16'h0402;
+           5'd12: mask_o <= #5 16'h0829;
+           5'd13: mask_o <= #5 16'h100D;
+           5'd14: mask_o <= #5 16'h2015;
+           5'd15: mask_o <= #5 16'h4001;
+           5'd16: mask_o <= #5 16'h8016;
+           default: mask_o <= #5 16'h0000;
+          endcase // case(degree_i)
+       end // else: !if(rst_i)
+
+endmodule // lfsr_constants
diff --git a/gr-sounder/src/fpga/tb/.gitignore b/gr-sounder/src/fpga/tb/.gitignore
new file mode 100644 (file)
index 0000000..b05ab62
--- /dev/null
@@ -0,0 +1,5 @@
+/Makefile
+/Makefile.in
+/*.vcd
+/sounder_tb
+/*.out*
diff --git a/gr-sounder/src/fpga/top/.gitignore b/gr-sounder/src/fpga/top/.gitignore
new file mode 100644 (file)
index 0000000..2c9458c
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/db
+/*.rpt
+/*.summary
+/*.rbf
+/*.qws
+/*.smsg
+/*.done
+/*.pin
+/*.sof
diff --git a/gr-sounder/src/lib/.gitignore b/gr-sounder/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-sounder/src/python/.gitignore b/gr-sounder/src/python/.gitignore
new file mode 100644 (file)
index 0000000..8ac573b
--- /dev/null
@@ -0,0 +1,5 @@
+/Makefile
+/Makefile.in
+/run_tests
+/*.pyc
+/loopback.dat
diff --git a/gr-trellis/.gitignore b/gr-trellis/.gitignore
new file mode 100644 (file)
index 0000000..f3462d0
--- /dev/null
@@ -0,0 +1,23 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/*.pc
index ecf56ee21543752c71eb92370c6ffc8a6dbfca41..d68fb59c9dbe25e3e9a3a37c0bedce30dcb72b07 100644 (file)
@@ -23,3 +23,5 @@ include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src doc
 
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-trellis.pc
diff --git a/gr-trellis/doc/.gitignore b/gr-trellis/doc/.gitignore
new file mode 100644 (file)
index 0000000..98c2518
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.html
diff --git a/gr-trellis/gnuradio-trellis.pc.in b/gr-trellis/gnuradio-trellis.pc.in
new file mode 100644 (file)
index 0000000..618667c
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-trellis
+Description: GNU Radio blocks for trellis coded modulation
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-trellis
+Cflags: -I${includedir}
diff --git a/gr-trellis/src/.gitignore b/gr-trellis/src/.gitignore
new file mode 100644 (file)
index 0000000..bb3f277
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/howto.cc
+/howto.py
index 41f525b0b8dbb477149a0e187001805396165f12..79e9d626ad5fffc23279cc1caece815da4dbaad9 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python examples
+SUBDIRS = lib 
+if PYTHON
+SUBDIRS += python examples
+endif
diff --git a/gr-trellis/src/examples/.gitignore b/gr-trellis/src/examples/.gitignore
new file mode 100644 (file)
index 0000000..c400497
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gr-trellis/src/examples/fsm_files/.gitignore b/gr-trellis/src/examples/fsm_files/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-trellis/src/examples/fsm_files/irregular.fsm b/gr-trellis/src/examples/fsm_files/irregular.fsm
new file mode 100644 (file)
index 0000000..80b82b8
--- /dev/null
@@ -0,0 +1,11 @@
+2 2 2
+
+0 0
+0 1
+
+0 1
+0 1
+
+
+useless irregular FSM for testing. state 0 has 3 incoming edges and state
+1 has 1 incoming edge.
diff --git a/gr-trellis/src/examples/fsm_files/joint_16_16.fsm b/gr-trellis/src/examples/fsm_files/joint_16_16.fsm
new file mode 100644 (file)
index 0000000..3dae314
--- /dev/null
@@ -0,0 +1,523 @@
+4 256 16
+
+0 8 128 136 
+0 8 128 136 
+1 9 129 137 
+1 9 129 137 
+2 10 130 138 
+2 10 130 138 
+3 11 131 139 
+3 11 131 139 
+4 12 132 140 
+4 12 132 140 
+5 13 133 141 
+5 13 133 141 
+6 14 134 142 
+6 14 134 142 
+7 15 135 143 
+7 15 135 143 
+0 8 128 136 
+0 8 128 136 
+1 9 129 137 
+1 9 129 137 
+2 10 130 138 
+2 10 130 138 
+3 11 131 139 
+3 11 131 139 
+4 12 132 140 
+4 12 132 140 
+5 13 133 141 
+5 13 133 141 
+6 14 134 142 
+6 14 134 142 
+7 15 135 143 
+7 15 135 143 
+16 24 144 152 
+16 24 144 152 
+17 25 145 153 
+17 25 145 153 
+18 26 146 154 
+18 26 146 154 
+19 27 147 155 
+19 27 147 155 
+20 28 148 156 
+20 28 148 156 
+21 29 149 157 
+21 29 149 157 
+22 30 150 158 
+22 30 150 158 
+23 31 151 159 
+23 31 151 159 
+16 24 144 152 
+16 24 144 152 
+17 25 145 153 
+17 25 145 153 
+18 26 146 154 
+18 26 146 154 
+19 27 147 155 
+19 27 147 155 
+20 28 148 156 
+20 28 148 156 
+21 29 149 157 
+21 29 149 157 
+22 30 150 158 
+22 30 150 158 
+23 31 151 159 
+23 31 151 159 
+32 40 160 168 
+32 40 160 168 
+33 41 161 169 
+33 41 161 169 
+34 42 162 170 
+34 42 162 170 
+35 43 163 171 
+35 43 163 171 
+36 44 164 172 
+36 44 164 172 
+37 45 165 173 
+37 45 165 173 
+38 46 166 174 
+38 46 166 174 
+39 47 167 175 
+39 47 167 175 
+32 40 160 168 
+32 40 160 168 
+33 41 161 169 
+33 41 161 169 
+34 42 162 170 
+34 42 162 170 
+35 43 163 171 
+35 43 163 171 
+36 44 164 172 
+36 44 164 172 
+37 45 165 173 
+37 45 165 173 
+38 46 166 174 
+38 46 166 174 
+39 47 167 175 
+39 47 167 175 
+48 56 176 184 
+48 56 176 184 
+49 57 177 185 
+49 57 177 185 
+50 58 178 186 
+50 58 178 186 
+51 59 179 187 
+51 59 179 187 
+52 60 180 188 
+52 60 180 188 
+53 61 181 189 
+53 61 181 189 
+54 62 182 190 
+54 62 182 190 
+55 63 183 191 
+55 63 183 191 
+48 56 176 184 
+48 56 176 184 
+49 57 177 185 
+49 57 177 185 
+50 58 178 186 
+50 58 178 186 
+51 59 179 187 
+51 59 179 187 
+52 60 180 188 
+52 60 180 188 
+53 61 181 189 
+53 61 181 189 
+54 62 182 190 
+54 62 182 190 
+55 63 183 191 
+55 63 183 191 
+64 72 192 200 
+64 72 192 200 
+65 73 193 201 
+65 73 193 201 
+66 74 194 202 
+66 74 194 202 
+67 75 195 203 
+67 75 195 203 
+68 76 196 204 
+68 76 196 204 
+69 77 197 205 
+69 77 197 205 
+70 78 198 206 
+70 78 198 206 
+71 79 199 207 
+71 79 199 207 
+64 72 192 200 
+64 72 192 200 
+65 73 193 201 
+65 73 193 201 
+66 74 194 202 
+66 74 194 202 
+67 75 195 203 
+67 75 195 203 
+68 76 196 204 
+68 76 196 204 
+69 77 197 205 
+69 77 197 205 
+70 78 198 206 
+70 78 198 206 
+71 79 199 207 
+71 79 199 207 
+80 88 208 216 
+80 88 208 216 
+81 89 209 217 
+81 89 209 217 
+82 90 210 218 
+82 90 210 218 
+83 91 211 219 
+83 91 211 219 
+84 92 212 220 
+84 92 212 220 
+85 93 213 221 
+85 93 213 221 
+86 94 214 222 
+86 94 214 222 
+87 95 215 223 
+87 95 215 223 
+80 88 208 216 
+80 88 208 216 
+81 89 209 217 
+81 89 209 217 
+82 90 210 218 
+82 90 210 218 
+83 91 211 219 
+83 91 211 219 
+84 92 212 220 
+84 92 212 220 
+85 93 213 221 
+85 93 213 221 
+86 94 214 222 
+86 94 214 222 
+87 95 215 223 
+87 95 215 223 
+96 104 224 232 
+96 104 224 232 
+97 105 225 233 
+97 105 225 233 
+98 106 226 234 
+98 106 226 234 
+99 107 227 235 
+99 107 227 235 
+100 108 228 236 
+100 108 228 236 
+101 109 229 237 
+101 109 229 237 
+102 110 230 238 
+102 110 230 238 
+103 111 231 239 
+103 111 231 239 
+96 104 224 232 
+96 104 224 232 
+97 105 225 233 
+97 105 225 233 
+98 106 226 234 
+98 106 226 234 
+99 107 227 235 
+99 107 227 235 
+100 108 228 236 
+100 108 228 236 
+101 109 229 237 
+101 109 229 237 
+102 110 230 238 
+102 110 230 238 
+103 111 231 239 
+103 111 231 239 
+112 120 240 248 
+112 120 240 248 
+113 121 241 249 
+113 121 241 249 
+114 122 242 250 
+114 122 242 250 
+115 123 243 251 
+115 123 243 251 
+116 124 244 252 
+116 124 244 252 
+117 125 245 253 
+117 125 245 253 
+118 126 246 254 
+118 126 246 254 
+119 127 247 255 
+119 127 247 255 
+112 120 240 248 
+112 120 240 248 
+113 121 241 249 
+113 121 241 249 
+114 122 242 250 
+114 122 242 250 
+115 123 243 251 
+115 123 243 251 
+116 124 244 252 
+116 124 244 252 
+117 125 245 253 
+117 125 245 253 
+118 126 246 254 
+118 126 246 254 
+119 127 247 255 
+119 127 247 255 
+
+0 3 12 15 
+3 0 15 12 
+1 2 13 14 
+2 1 14 13 
+1 2 13 14 
+2 1 14 13 
+0 3 12 15 
+3 0 15 12 
+2 1 14 13 
+1 2 13 14 
+3 0 15 12 
+0 3 12 15 
+3 0 15 12 
+0 3 12 15 
+2 1 14 13 
+1 2 13 14 
+12 15 0 3 
+15 12 3 0 
+13 14 1 2 
+14 13 2 1 
+13 14 1 2 
+14 13 2 1 
+12 15 0 3 
+15 12 3 0 
+14 13 2 1 
+13 14 1 2 
+15 12 3 0 
+12 15 0 3 
+15 12 3 0 
+12 15 0 3 
+14 13 2 1 
+13 14 1 2 
+4 7 8 11 
+7 4 11 8 
+5 6 9 10 
+6 5 10 9 
+5 6 9 10 
+6 5 10 9 
+4 7 8 11 
+7 4 11 8 
+6 5 10 9 
+5 6 9 10 
+7 4 11 8 
+4 7 8 11 
+7 4 11 8 
+4 7 8 11 
+6 5 10 9 
+5 6 9 10 
+8 11 4 7 
+11 8 7 4 
+9 10 5 6 
+10 9 6 5 
+9 10 5 6 
+10 9 6 5 
+8 11 4 7 
+11 8 7 4 
+10 9 6 5 
+9 10 5 6 
+11 8 7 4 
+8 11 4 7 
+11 8 7 4 
+8 11 4 7 
+10 9 6 5 
+9 10 5 6 
+4 7 8 11 
+7 4 11 8 
+5 6 9 10 
+6 5 10 9 
+5 6 9 10 
+6 5 10 9 
+4 7 8 11 
+7 4 11 8 
+6 5 10 9 
+5 6 9 10 
+7 4 11 8 
+4 7 8 11 
+7 4 11 8 
+4 7 8 11 
+6 5 10 9 
+5 6 9 10 
+8 11 4 7 
+11 8 7 4 
+9 10 5 6 
+10 9 6 5 
+9 10 5 6 
+10 9 6 5 
+8 11 4 7 
+11 8 7 4 
+10 9 6 5 
+9 10 5 6 
+11 8 7 4 
+8 11 4 7 
+11 8 7 4 
+8 11 4 7 
+10 9 6 5 
+9 10 5 6 
+0 3 12 15 
+3 0 15 12 
+1 2 13 14 
+2 1 14 13 
+1 2 13 14 
+2 1 14 13 
+0 3 12 15 
+3 0 15 12 
+2 1 14 13 
+1 2 13 14 
+3 0 15 12 
+0 3 12 15 
+3 0 15 12 
+0 3 12 15 
+2 1 14 13 
+1 2 13 14 
+12 15 0 3 
+15 12 3 0 
+13 14 1 2 
+14 13 2 1 
+13 14 1 2 
+14 13 2 1 
+12 15 0 3 
+15 12 3 0 
+14 13 2 1 
+13 14 1 2 
+15 12 3 0 
+12 15 0 3 
+15 12 3 0 
+12 15 0 3 
+14 13 2 1 
+13 14 1 2 
+8 11 4 7 
+11 8 7 4 
+9 10 5 6 
+10 9 6 5 
+9 10 5 6 
+10 9 6 5 
+8 11 4 7 
+11 8 7 4 
+10 9 6 5 
+9 10 5 6 
+11 8 7 4 
+8 11 4 7 
+11 8 7 4 
+8 11 4 7 
+10 9 6 5 
+9 10 5 6 
+4 7 8 11 
+7 4 11 8 
+5 6 9 10 
+6 5 10 9 
+5 6 9 10 
+6 5 10 9 
+4 7 8 11 
+7 4 11 8 
+6 5 10 9 
+5 6 9 10 
+7 4 11 8 
+4 7 8 11 
+7 4 11 8 
+4 7 8 11 
+6 5 10 9 
+5 6 9 10 
+12 15 0 3 
+15 12 3 0 
+13 14 1 2 
+14 13 2 1 
+13 14 1 2 
+14 13 2 1 
+12 15 0 3 
+15 12 3 0 
+14 13 2 1 
+13 14 1 2 
+15 12 3 0 
+12 15 0 3 
+15 12 3 0 
+12 15 0 3 
+14 13 2 1 
+13 14 1 2 
+0 3 12 15 
+3 0 15 12 
+1 2 13 14 
+2 1 14 13 
+1 2 13 14 
+2 1 14 13 
+0 3 12 15 
+3 0 15 12 
+2 1 14 13 
+1 2 13 14 
+3 0 15 12 
+0 3 12 15 
+3 0 15 12 
+0 3 12 15 
+2 1 14 13 
+1 2 13 14 
+12 15 0 3 
+15 12 3 0 
+13 14 1 2 
+14 13 2 1 
+13 14 1 2 
+14 13 2 1 
+12 15 0 3 
+15 12 3 0 
+14 13 2 1 
+13 14 1 2 
+15 12 3 0 
+12 15 0 3 
+15 12 3 0 
+12 15 0 3 
+14 13 2 1 
+13 14 1 2 
+0 3 12 15 
+3 0 15 12 
+1 2 13 14 
+2 1 14 13 
+1 2 13 14 
+2 1 14 13 
+0 3 12 15 
+3 0 15 12 
+2 1 14 13 
+1 2 13 14 
+3 0 15 12 
+0 3 12 15 
+3 0 15 12 
+0 3 12 15 
+2 1 14 13 
+1 2 13 14 
+8 11 4 7 
+11 8 7 4 
+9 10 5 6 
+10 9 6 5 
+9 10 5 6 
+10 9 6 5 
+8 11 4 7 
+11 8 7 4 
+10 9 6 5 
+9 10 5 6 
+11 8 7 4 
+8 11 4 7 
+11 8 7 4 
+8 11 4 7 
+10 9 6 5 
+9 10 5 6 
+4 7 8 11 
+7 4 11 8 
+5 6 9 10 
+6 5 10 9 
+5 6 9 10 
+6 5 10 9 
+4 7 8 11 
+7 4 11 8 
+6 5 10 9 
+5 6 9 10 
+7 4 11 8 
+4 7 8 11 
+7 4 11 8 
+4 7 8 11 
+6 5 10 9 
+5 6 9 10 
+
+This is the joint trellis of two trellises described in awgn1o2_16.fsm
+It is useful for application of joint decoding...
+It can be generated in python as follows:
+> import trellis
+> f1=trellis.fsm('awgn1o2_16.fsm')
+> f=trellis.fsm(f1,f1)
+> f.write_fsm_txt('joint_16_16.fsm')
diff --git a/gr-trellis/src/examples/fsm_files/joint_4_16.fsm b/gr-trellis/src/examples/fsm_files/joint_4_16.fsm
new file mode 100644 (file)
index 0000000..8f2cdab
--- /dev/null
@@ -0,0 +1,141 @@
+4 64 16
+
+0 8 32 40 
+0 8 32 40 
+1 9 33 41 
+1 9 33 41 
+2 10 34 42 
+2 10 34 42 
+3 11 35 43 
+3 11 35 43 
+4 12 36 44 
+4 12 36 44 
+5 13 37 45 
+5 13 37 45 
+6 14 38 46 
+6 14 38 46 
+7 15 39 47 
+7 15 39 47 
+0 8 32 40 
+0 8 32 40 
+1 9 33 41 
+1 9 33 41 
+2 10 34 42 
+2 10 34 42 
+3 11 35 43 
+3 11 35 43 
+4 12 36 44 
+4 12 36 44 
+5 13 37 45 
+5 13 37 45 
+6 14 38 46 
+6 14 38 46 
+7 15 39 47 
+7 15 39 47 
+16 24 48 56 
+16 24 48 56 
+17 25 49 57 
+17 25 49 57 
+18 26 50 58 
+18 26 50 58 
+19 27 51 59 
+19 27 51 59 
+20 28 52 60 
+20 28 52 60 
+21 29 53 61 
+21 29 53 61 
+22 30 54 62 
+22 30 54 62 
+23 31 55 63 
+23 31 55 63 
+16 24 48 56 
+16 24 48 56 
+17 25 49 57 
+17 25 49 57 
+18 26 50 58 
+18 26 50 58 
+19 27 51 59 
+19 27 51 59 
+20 28 52 60 
+20 28 52 60 
+21 29 53 61 
+21 29 53 61 
+22 30 54 62 
+22 30 54 62 
+23 31 55 63 
+23 31 55 63 
+
+0 3 12 15 
+3 0 15 12 
+1 2 13 14 
+2 1 14 13 
+1 2 13 14 
+2 1 14 13 
+0 3 12 15 
+3 0 15 12 
+2 1 14 13 
+1 2 13 14 
+3 0 15 12 
+0 3 12 15 
+3 0 15 12 
+0 3 12 15 
+2 1 14 13 
+1 2 13 14 
+12 15 0 3 
+15 12 3 0 
+13 14 1 2 
+14 13 2 1 
+13 14 1 2 
+14 13 2 1 
+12 15 0 3 
+15 12 3 0 
+14 13 2 1 
+13 14 1 2 
+15 12 3 0 
+12 15 0 3 
+15 12 3 0 
+12 15 0 3 
+14 13 2 1 
+13 14 1 2 
+4 7 8 11 
+7 4 11 8 
+5 6 9 10 
+6 5 10 9 
+5 6 9 10 
+6 5 10 9 
+4 7 8 11 
+7 4 11 8 
+6 5 10 9 
+5 6 9 10 
+7 4 11 8 
+4 7 8 11 
+7 4 11 8 
+4 7 8 11 
+6 5 10 9 
+5 6 9 10 
+8 11 4 7 
+11 8 7 4 
+9 10 5 6 
+10 9 6 5 
+9 10 5 6 
+10 9 6 5 
+8 11 4 7 
+11 8 7 4 
+10 9 6 5 
+9 10 5 6 
+11 8 7 4 
+8 11 4 7 
+11 8 7 4 
+8 11 4 7 
+10 9 6 5 
+9 10 5 6 
+
+This is the joint trellis of two trellises described in awgn1o2_4.fsm and awgn1o2_16.fsm
+It is useful for application of joint decoding...
+It can be generated in python as follows:
+> import trellis
+> f1=trellis.fsm('awgn1o2_4.fsm')
+> f2=trellis.fsm('awgn1o2_16.fsm')
+> f=trellis.fsm(f1,f2)
+> f.write_fsm_txt('joint_4_16.fsm')
+
diff --git a/gr-trellis/src/examples/test_cpm.py b/gr-trellis/src/examples/test_cpm.py
new file mode 100755 (executable)
index 0000000..ec432d4
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: CPM test
+# Author: Achilleas Anastasopoulos
+# Description: gnuradio flow graph
+# Generated: Thu Feb 19 23:16:23 2009
+##################################################
+
+from gnuradio import gr
+from gnuradio import trellis
+from gnuradio.gr import firdes
+from grc_gnuradio import blks2 as grc_blks2
+import math
+import numpy
+import scipy.stats
+import fsm_utils
+from gnuradio import trellis
+
+def run_test(seed,blocksize):
+        tb = gr.top_block()
+
+       ##################################################
+       # Variables
+       ##################################################
+       M = 2
+       K = 1
+       P = 2
+       h = (1.0*K)/P
+       L = 3
+       Q = 4
+        frac = 0.99
+        f = trellis.fsm(P,M,L)
+
+        # CPFSK signals
+        #p = numpy.ones(Q)/(2.0)
+        #q = numpy.cumsum(p)/(1.0*Q)
+
+        # GMSK signals
+        BT=0.3;
+        tt=numpy.arange(0,L*Q)/(1.0*Q)-L/2.0;
+        #print tt
+        p=(0.5*scipy.stats.erfc(2*math.pi*BT*(tt-0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0))-0.5*scipy.stats.erfc(2*math.pi*BT*(tt+0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0)))/2.0;
+        p=p/sum(p)*Q/2.0;
+        #print p
+        q=numpy.cumsum(p)/Q;
+        q=q/q[-1]/2.0;
+        #print q
+
+        (f0T,SS,S,F,Sf,Ff,N) = fsm_utils.make_cpm_signals(K,P,M,L,q,frac)
+        #print N
+        #print Ff
+        Ffa = numpy.insert(Ff,Q,numpy.zeros(N),axis=0)
+        #print Ffa
+        MF = numpy.fliplr(numpy.transpose(Ffa))
+        #print MF
+        E = numpy.sum(numpy.abs(Sf)**2,axis=0)
+        Es = numpy.sum(E)/f.O()
+        #print Es
+
+        constellation = numpy.reshape(numpy.transpose(Sf),N*f.O())
+        #print Ff
+        #print Sf
+        #print constellation
+        #print numpy.max(numpy.abs(SS - numpy.dot(Ff , Sf)))
+
+       EsN0_db = 10.0
+        N0 =  Es * 10.0**(-(1.0*EsN0_db)/10.0)
+        #N0 = 0.0
+        #print N0
+        head = 4
+        tail = 4
+        numpy.random.seed(seed*666)
+        data = numpy.random.randint(0, M, head+blocksize+tail+1)
+        #data = numpy.zeros(blocksize+1+head+tail,'int')
+        for i in range(head):
+            data[i]=0
+        for i in range(tail+1):
+            data[-i]=0
+      
+
+
+       ##################################################
+       # Blocks
+       ##################################################
+       random_source_x_0 = gr.vector_source_b(data, False)
+       gr_chunks_to_symbols_xx_0 = gr.chunks_to_symbols_bf((-1, 1), 1)
+       gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(Q, p)
+       gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*h*(1.0/Q))
+
+       gr_add_vxx_0 = gr.add_vcc(1)
+       gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, (N0/2.0)**0.5, -long(seed))
+
+       gr_multiply_vxx_0 = gr.multiply_vcc(1)
+       gr_sig_source_x_0 = gr.sig_source_c(Q, gr.GR_COS_WAVE, -f0T, 1, 0)
+        # only works for N=2, do it manually for N>2...
+       gr_fir_filter_xxx_0_0 = gr.fir_filter_ccc(Q, MF[0].conjugate())
+       gr_fir_filter_xxx_0_0_0 = gr.fir_filter_ccc(Q, MF[1].conjugate())
+       gr_streams_to_stream_0 = gr.streams_to_stream(gr.sizeof_gr_complex*1, N)
+       gr_skiphead_0 = gr.skiphead(gr.sizeof_gr_complex*1, N*(1+0))
+       viterbi = trellis.viterbi_combined_cb(f, head+blocksize+tail, 0, -1, N, constellation, trellis.TRELLIS_EUCLIDEAN)
+
+        gr_vector_sink_x_0 = gr.vector_sink_b()
+
+       ##################################################
+       # Connections
+       ##################################################
+       tb.connect((random_source_x_0, 0), (gr_chunks_to_symbols_xx_0, 0))
+       tb.connect((gr_chunks_to_symbols_xx_0, 0), (gr_interp_fir_filter_xxx_0, 0))
+       tb.connect((gr_interp_fir_filter_xxx_0, 0), (gr_frequency_modulator_fc_0, 0))
+       tb.connect((gr_frequency_modulator_fc_0, 0), (gr_add_vxx_0, 0))
+       tb.connect((gr_noise_source_x_0, 0), (gr_add_vxx_0, 1))
+       tb.connect((gr_add_vxx_0, 0), (gr_multiply_vxx_0, 0))
+       tb.connect((gr_sig_source_x_0, 0), (gr_multiply_vxx_0, 1))
+       tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0, 0))
+       tb.connect((gr_multiply_vxx_0, 0), (gr_fir_filter_xxx_0_0_0, 0))
+       tb.connect((gr_fir_filter_xxx_0_0, 0), (gr_streams_to_stream_0, 0))
+       tb.connect((gr_fir_filter_xxx_0_0_0, 0), (gr_streams_to_stream_0, 1))
+       tb.connect((gr_streams_to_stream_0, 0), (gr_skiphead_0, 0))
+       tb.connect((gr_skiphead_0, 0), (viterbi, 0))
+       tb.connect((viterbi, 0), (gr_vector_sink_x_0, 0))
+        
+
+        tb.run()
+        dataest = gr_vector_sink_x_0.data()
+        #print data
+        #print numpy.array(dataest)
+        perr = 0
+        err = 0
+        for i in range(blocksize):
+          if data[head+i] != dataest[head+i]:
+            #print i
+            err += 1
+        if err != 0 :
+          perr = 1
+        return (err,perr)
+
+if __name__ == '__main__':
+        blocksize = 1000
+        ss=0
+        ee=0
+        for i in range(10000):
+            (s,e) = run_test(i,blocksize)
+            ss += s
+            ee += e
+            if (i+1) % 100 == 0:
+                print i+1,ss,ee,(1.0*ss)/(i+1)/(1.0*blocksize),(1.0*ee)/(i+1)
+        print i+1,ss,ee,(1.0*ss)/(i+1)/(1.0*blocksize),(1.0*ee)/(i+1)
diff --git a/gr-trellis/src/lib/.gitignore b/gr-trellis/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..8932c36
--- /dev/null
@@ -0,0 +1,99 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/trellis.cc
+/trellis.py
+/wip
+/trellis_encoder_bs.cc
+/trellis_metrics_c.h
+/trellis_metrics_c.i
+/trellis_metrics_f.cc
+/trellis_viterbi_i.h
+/trellis_viterbi_combined_i.h
+/trellis_viterbi_i.i
+/trellis_viterbi_combined_i.i
+/trellis_metrics_i.h
+/trellis_metrics_i.i
+/trellis_encoder_bb.cc
+/trellis_encoder_ss.cc
+/trellis_viterbi_combined_s.h
+/trellis_viterbi_s.h
+/trellis_viterbi_combined_s.i
+/trellis_viterbi_s.i
+/trellis_metrics_s.h
+/trellis_metrics_s.i
+/trellis_encoder_si.h
+/trellis_encoder_si.i
+/trellis_metrics_i.cc
+/trellis_viterbi_s.cc
+/trellis_viterbi_combined_s.cc
+/trellis_encoder_ss.h
+/trellis_encoder_ss.i
+/trellis_encoder_bi.cc
+/trellis_encoder_bi.h
+/trellis_encoder_bi.i
+/trellis_encoder_ii.cc
+/trellis_viterbi_combined_b.cc
+/trellis_viterbi_b.cc
+/trellis_encoder_bs.h
+/trellis_encoder_bs.i
+/trellis_viterbi_combined_b.h
+/trellis_viterbi_b.h
+/trellis_viterbi_combined_b.i
+/trellis_viterbi_b.i
+/trellis_encoder_si.cc
+/trellis_metrics_f.h
+/trellis_metrics_f.i
+/trellis_encoder_ii.h
+/trellis_encoder_ii.i
+/trellis_metrics_c.cc
+/trellis_viterbi_combined_i.cc
+/trellis_viterbi_i.cc
+/trellis_encoder_bb.h
+/trellis_encoder_bb.i
+/trellis_metrics_s.cc
+/trellis_viterbi_combined_fs.h
+/trellis_viterbi_combined_fs.i
+/trellis_viterbi_combined_fi.cc
+/trellis_viterbi_combined_is.h
+/trellis_viterbi_combined_is.i
+/trellis_viterbi_combined_ci.h
+/trellis_viterbi_combined_ci.i
+/trellis_viterbi_combined_cs.cc
+/trellis_viterbi_combined_is.cc
+/trellis_viterbi_combined_si.h
+/trellis_viterbi_combined_si.i
+/trellis_viterbi_combined_ss.cc
+/trellis_viterbi_combined_fb.cc
+/trellis_viterbi_combined_fi.h
+/trellis_viterbi_combined_fi.i
+/trellis_viterbi_combined_cb.h
+/trellis_viterbi_combined_cb.i
+/trellis_viterbi_combined_ci.cc
+/trellis_viterbi_combined_ii.cc
+/trellis_viterbi_combined_ii.h
+/trellis_viterbi_combined_ii.i
+/trellis_viterbi_combined_sb.h
+/trellis_viterbi_combined_sb.i
+/trellis_viterbi_combined_si.cc
+/trellis_viterbi_combined_fb.h
+/trellis_viterbi_combined_fb.i
+/trellis_viterbi_combined_ib.h
+/trellis_viterbi_combined_ib.i
+/trellis_viterbi_combined_cs.h
+/trellis_viterbi_combined_cs.i
+/trellis_viterbi_combined_fs.cc
+/trellis_viterbi_combined_cb.cc
+/trellis_viterbi_combined_ss.h
+/trellis_viterbi_combined_ss.i
+/trellis_viterbi_combined_ib.cc
+/trellis_viterbi_combined_sb.cc
+/trellis_generated.i
+/generate-stamp
+/stamp-*
index 2e7591e4b9bc76e87136ea009e1d0033f81e3ffd..3e1803554b530edb1a806b7ff6daac3c0925d9f5 100644 (file)
@@ -66,6 +66,26 @@ grinclude_HEADERS =                  \
        trellis_siso_combined_f.h       \
        $(GENERATED_H)
 
+lib_LTLIBRARIES = libgnuradio-trellis.la
+
+libgnuradio_trellis_la_SOURCES =       \
+        fsm.cc                         \
+        quicksort_index.cc             \
+        base.cc                                \
+        interleaver.cc                 \
+        trellis_calc_metric.cc         \
+        trellis_permutation.cc         \
+       trellis_siso_f.cc               \
+       trellis_siso_combined_f.cc      \
+       $(GENERATED_CC)
+
+libgnuradio_trellis_la_LIBADD =        \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_trellis_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+
+if PYTHON
 #################################
 # SWIG interface and library
 
@@ -79,21 +99,9 @@ TOP_SWIG_IFILES =                    \
 trellis_pythondir_category =           \
        gnuradio
 
-# additional sources for the SWIG-generated library
-trellis_la_swig_sources =              \
-        fsm.cc                         \
-        quicksort_index.cc             \
-        base.cc                                \
-        interleaver.cc                 \
-        trellis_calc_metric.cc         \
-        trellis_permutation.cc         \
-       trellis_siso_f.cc               \
-       trellis_siso_combined_f.cc      \
-       $(GENERATED_CC)
-
 # additional libraries for linking with the SWIG-generated library
 trellis_la_swig_libadd =               \
-       $(GNURADIO_CORE_LA)
+       libgnuradio-trellis.la
 
 # additional SWIG files to be installed
 trellis_swiginclude_headers =          \
@@ -131,3 +139,4 @@ BUILT_SOURCES =                             \
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-trellis/src/python/.gitignore b/gr-trellis/src/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-usrp/.gitignore b/gr-usrp/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
diff --git a/gr-usrp/apps/.gitignore b/gr-usrp/apps/.gitignore
new file mode 100644 (file)
index 0000000..2d01df2
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/usrp_siggen
+/usrp_rx_cfile
index 824a48974779ef3f3f3cfabda9fb371b38c6886b..92938061f6e1062ecdd876431d6ef303c0a1ce01 100644 (file)
@@ -24,9 +24,7 @@ include $(top_srcdir)/Makefile.common
 # For compiling within the GNU Radio build tree
 AM_CPPFLAGS=$(STD_DEFINES_AND_INCLUDES) \
         -I$(top_srcdir)/gr-usrp/src \
-        -I$(top_srcdir)/usrp/host/lib/legacy \
-        -I\${abs_top_builddir}/usrp/host/lib/legacy \
-        -I$(top_srcdir)/usrp/firmware/include \
+        $(USRP_INCLUDES) \
         $(WITH_INCLUDES)
 
 GR_USRP_LA=$(top_builddir)/gr-usrp/src/libgnuradio-usrp.la
index 6c1d75d439cbbd9c5176d8f82b3d860eddb80e6d..b1f33f41beee9c3eb78162d19a7ed8bc78ee409d 100644 (file)
@@ -6,6 +6,6 @@ includedir=@includedir@/gnuradio
 Name: gnuradio-usrp
 Description: GNU Software Radio support for Universal Software Radio Peripheral
 Requires: gnuradio-core usrp
-Version: @VERSION@
+Version: @LIBVER@
 Libs: -L${libdir} -lgnuradio-usrp
 Cflags: -I${includedir}
diff --git a/gr-usrp/src/.gitignore b/gr-usrp/src/.gitignore
new file mode 100644 (file)
index 0000000..68abaf8
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/usrp_swig.cc
+/usrp_swig.py
+/run_tests
+/usrp_dbids.py
+/*.pyc
index 9b8737d715666b43b5487cee19c12e6673fb61f3..572a22485b89d7b8863bf215c8668f568c76b433 100644 (file)
@@ -26,8 +26,6 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
 DISTCLEANFILES = run_tests
 
 noinst_PYTHON =        qa_usrp.py
@@ -39,6 +37,7 @@ AM_CPPFLAGS = \
        $(STD_DEFINES_AND_INCLUDES) \
        $(PYTHON_CPPFLAGS) \
        $(USRP_INCLUDES) \
+       $(USB_INCLUDES) \
        $(WITH_INCLUDES)
 
 lib_LTLIBRARIES = \
@@ -57,7 +56,7 @@ libgnuradio_usrp_la_LIBADD = \
        $(GNURADIO_CORE_LA) \
        $(USRP_LA)                      
 
-libgnuradio_usrp_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libgnuradio_usrp_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
 
 grinclude_HEADERS = \
        usrp_base.h \
@@ -68,8 +67,10 @@ grinclude_HEADERS = \
        usrp_source_c.h \
        usrp_source_s.h
 
+if PYTHON
 # ----------------------------------------------------------------
 # The SWIG library
+TESTS = run_tests
 
 TOP_SWIG_IFILES =              \
        usrp_swig.i
@@ -111,3 +112,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-usrp/src/flexrf_debug_gui.py b/gr-usrp/src/flexrf_debug_gui.py
new file mode 100755 (executable)
index 0000000..ff32900
--- /dev/null
@@ -0,0 +1,176 @@
+#!/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.
+# 
+
+import sys
+import wx
+from gnuradio.wxgui import form
+
+class flexrf_debug_gui(wx.Frame):
+    def __init__(self, flexrf, title="Flexrf Debug"):
+        wx.Frame.__init__(self, None, -1, title)
+
+        self.flexrf = flexrf
+        
+        self.CreateStatusBar (1)
+
+        self.panel = wx.Panel(self, -1)
+        self.vbox = wx.BoxSizer(wx.VERTICAL)
+        self.panel.SetSizer(self.vbox)
+        self.panel.SetAutoLayout(True)
+
+        self._create_form()
+
+        self.vbox.Fit(self.panel)
+
+        self.frame_vbox = wx.BoxSizer(wx.VERTICAL)
+        self.frame_vbox.Add(self.panel, 1, wx.EXPAND)
+        self.SetSizer(self.frame_vbox)
+        self.SetAutoLayout(True)
+        self.frame_vbox.Fit(self)
+        
+    def _create_form(self):
+        self._create_set_freq()
+        self._create_write_fpga()
+        self._create_write_all()
+        self._create_write_it()
+        #self._create_set_gain()
+        
+    # ----------------------------------------------------------------
+
+    def _create_set_freq(self):
+
+        def _set_freq(kv):
+            return self.flexrf.set_freq(kv['freq'])[0]
+
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.HORIZONTAL)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        #sbs.Add(wx.StaticText(self.panel, -1, "set_freq "), 0, 0)
+        #sbs.Add((5,0), 0.1)       # stretchy space
+        myform = form.form()
+        myform['freq'] = form.float_field(self.panel, sbs, "Set Frequency")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(form.button_with_callback(self.panel, "Do It!",
+                                          self._generic_doit(_set_freq, myform)), 1, wx.EXPAND)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+
+    def _create_write_fpga(self):
+
+        def _write_fpga(kv):
+            return self.flexrf._u._write_fpga_reg(kv['regno'], kv['value'])
+
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.HORIZONTAL)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(wx.StaticText(self.panel, -1, "write_fpga_reg "), 0, 0)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform = form.form()
+        myform['regno'] = form.int_field(self.panel, sbs, "regno")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform['value'] = form.int_field(self.panel, sbs, "value")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(form.button_with_callback(self.panel, "Do It!",
+                                          self._generic_doit(_write_fpga, myform)), 1, wx.EXPAND)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+
+    def _create_write_all(self):
+
+        def _write_all(kv):
+            self.flexrf._write_all(kv['R'], kv['control'], kv['N'])   # void
+            return  True
+
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.HORIZONTAL)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(wx.StaticText(self.panel, -1, "write_all "), 0, 0)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform = form.form()
+        myform['R'] = form.int_field(self.panel, sbs, "R")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform['control'] = form.int_field(self.panel, sbs, "control")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform['N'] = form.int_field(self.panel, sbs, "N")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(form.button_with_callback(self.panel, "Do It!",
+                                          self._generic_doit(_write_all, myform)), 1, wx.EXPAND)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+
+    def _create_write_it(self):
+
+        def _write_it(kv):
+            self.flexrf._write_it(kv['v'])      # void
+            return True
+
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.HORIZONTAL)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(wx.StaticText(self.panel, -1, "write_it "), 0, 0)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        myform = form.form()
+        myform['v'] = form.int_field(self.panel, sbs, "24-bit value")
+        sbs.Add((5,0), 0.1)       # stretchy space
+        sbs.Add(form.button_with_callback(self.panel, "Do It!",
+                                          self._generic_doit(_write_it, myform)), 1, wx.EXPAND)
+        sbs.Add((5,0), 0.1)       # stretchy space
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+
+    # ----------------------------------------------------------------
+    
+    def _set_status_msg(self, msg):
+        self.GetStatusBar().SetStatusText(msg, 0)
+
+    def _generic_doit(self, callback, form):
+
+        def button_callback():
+            errors = form.check_input_for_errors()
+            if errors:
+                self._set_status_msg(errors[0])
+                print '\n'.join(tuple(errors))
+            else:
+                kv = form.get_key_vals()
+                if callback(kv):
+                    self._set_status_msg("OK")
+                else:
+                    self._set_status_msg("Failed")
+
+        return button_callback
+
+
+        
+if False and __name__ == '__main__':
+
+    class demo_app (wx.App):
+        def __init__ (self):
+            wx.App.__init__(self)
+
+        def OnInit (self):
+            frame = flexrf_debug_gui(None, "Debug FlexRF TX")
+            frame.Show(True)
+            self.SetTopWindow (frame)
+            return True
+
+    app = demo_app()
+    app.MainLoop()
+
index f9bdc78b6d844d6cb0fd84b0eb2a3ba3a90f4330..c03f96e0b63fc47e5dc9235cdb219948e8da14b0 100644 (file)
@@ -5,11 +5,11 @@
 # 3rd parameter is path to Python QA directory
 
 # For OS/X
-DYLD_LIBRARY_PATH=@abs_top_builddir@/usrp/host/lib/legacy:@abs_top_builddir@/usrp/host/lib/legacy/.libs:$DYLD_LIBRARY_PATH
+DYLD_LIBRARY_PATH=@abs_top_builddir@/usrp/host/lib:@abs_top_builddir@/usrp/host/lib/.libs:$DYLD_LIBRARY_PATH
 export DYLD_LIBRARY_PATH
 
 # For Win32
-PATH=@abs_top_builddir@/usrp/host/lib/legacy:@abs_top_builddir@/usrp/host/lib/legacy/.libs:$PATH
+PATH=@abs_top_builddir@/usrp/host/lib:@abs_top_builddir@/usrp/host/lib/.libs:$PATH
 
 @top_builddir@/run_tests.sh \
     @abs_top_srcdir@/gr-usrp \
diff --git a/gr-usrp/src/tx_debug_gui.py b/gr-usrp/src/tx_debug_gui.py
new file mode 100755 (executable)
index 0000000..6b2a0c2
--- /dev/null
@@ -0,0 +1,187 @@
+#!/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.
+# 
+
+import sys
+import wx
+from gnuradio.wxgui import form
+
+class tx_debug_gui(wx.Frame):
+    def __init__(self, tx_subdev, title="Tx Debug"):
+        wx.Frame.__init__(self, None, -1, title)
+
+        self.subdev = tx_subdev
+        self.subdev._u.set_verbose(True)
+        
+        self.CreateStatusBar (1)
+
+        self.panel = wx.Panel(self, -1)
+        self.vbox = wx.BoxSizer(wx.VERTICAL)
+        self.panel.SetSizer(self.vbox)
+        self.panel.SetAutoLayout(True)
+
+        self._create_form()
+
+        self.vbox.Fit(self.panel)
+
+        self.frame_vbox = wx.BoxSizer(wx.VERTICAL)
+        self.frame_vbox.Add(self.panel, 1, wx.EXPAND)
+        self.SetSizer(self.frame_vbox)
+        self.SetAutoLayout(True)
+        self.frame_vbox.Fit(self)
+        
+    # ----------------------------------------------------------------
+
+    def _write_9862(self, regno, v):
+        return self.subdev._u._write_9862(self.subdev._which, regno, v)
+
+    def _set_dac_offset(self, i_or_q, offset, offset_pin):
+        return self.subdev._u.set_dac_offset(self.subdev._which * 2 + i_or_q, offset, offset_pin)
+
+    def _set_dac_fine_gain(self, i_or_q, gain, coarse):
+        return self._write_9862(14 + i_or_q, (coarse & 0xC0) | (gain & 0x3f))
+
+    def _create_form(self):
+        self._create_dac_offset()
+        self._create_dac_fine_gain()
+        self._create_pga()
+        
+    # ----------------------------------------------------------------
+
+    def _create_dac_offset(self):
+
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add(wx.StaticText(self.panel, -1, "DAC Offset"), 5, 0)
+        sbs.Add(hbox, 0, 1)
+
+
+        self._create_dac_offset_helper(sbs, 0)
+        self._create_dac_offset_helper(sbs, 1)
+
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+    def _create_dac_offset_helper(self, vbox, i_or_q):
+
+        def doit(kv):
+            drive_positive = kv['drive_positive']
+            dac_offset = kv['dac_offset']
+            print "drive_positive =", drive_positive
+            print "dac_offset[%d] = %4d" % (i_or_q, dac_offset)
+            
+            # FIXME signed magnitude??
+            # dac_offset = signed_mag10(dac_offset)
+            return self._set_dac_offset(i_or_q, dac_offset, int(drive_positive))
+        
+        def signed_mag10(x):
+            # not clear from doc if this is really 2's comp or 10-bit signed magnitude
+            # we'll guess it's 10-bit signed mag
+            if x < 0:
+                return (1 << 9) | min(511, max(0, abs(x)))
+            else:
+                return (0 << 9) | min(511, max(0, abs(x)))
+
+        myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        vbox.Add(hbox, 0, wx.EXPAND)
+        myform['drive_positive'] = form.checkbox_field(parent=self.panel, sizer=hbox,
+                                                       callback=myform.check_input_and_call(doit),
+                                                       weight=0,
+                                                       label="drive +ve")
+        myform['dac_offset'] = form.slider_field(parent=self.panel, sizer=hbox,
+                                                 callback=myform.check_input_and_call(doit),
+                                                 min=-512, max=511, value=0,
+                                                 weight=5)
+        
+    # ----------------------------------------------------------------
+
+    def _create_dac_fine_gain(self):
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add(wx.StaticText(self.panel, -1, "DAC Gain"), 5, 0)
+        sbs.Add(hbox, 0, 1)
+
+        self._create_dac_gain_helper(sbs, 0)
+        self._create_dac_gain_helper(sbs, 1)
+
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+    def _create_dac_gain_helper(self, vbox, i_or_q):
+
+        d = { "1/1"  : 0xC0,
+              "1/2"  : 0x40,
+              "1/11" : 0x00 }
+
+        def doit(kv):
+            dac_gain = kv['dac_gain']
+            coarse_s = kv['coarse']
+            print "dac_gain[%d] = %4d" % (i_or_q, dac_gain)
+            print "coarse = ", coarse_s
+            return self._set_dac_fine_gain(i_or_q, dac_gain, d[coarse_s])
+        
+        myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        vbox.Add(hbox, 0, wx.EXPAND)
+        myform['coarse'] = form.radiobox_field(parent=self.panel, sizer=hbox,
+                                               callback=myform.check_input_and_call(doit),
+                                               choices=['1/11', '1/2', '1/1'],
+                                               weight=1, value='1/1')
+        myform['dac_gain'] = form.slider_field(parent=self.panel, sizer=hbox,
+                                               callback=myform.check_input_and_call(doit),
+                                               min=-32, max=31, value=0,
+                                               weight=4)
+
+
+    # ----------------------------------------------------------------
+
+    def _create_pga(self):
+        sbs = wx.StaticBoxSizer(wx.StaticBox(self.panel), wx.VERTICAL)
+
+        form.quantized_slider_field(parent=self.panel, sizer=sbs, label="PGA",
+                                    weight=3, range=self.subdev.gain_range(),
+                                    callback=self.subdev.set_gain)
+
+        self.vbox.Add(sbs, 0, wx.EXPAND)
+
+
+    # ----------------------------------------------------------------
+
+    
+    def _set_status_msg(self, msg):
+        self.GetStatusBar().SetStatusText(msg, 0)
+
+        
+if False and __name__ == '__main__':
+
+    class demo_app (wx.App):
+        def __init__ (self):
+            wx.App.__init__(self)
+
+        def OnInit (self):
+            frame = tx_debug_gui(None, "Debug TX")
+            frame.Show(True)
+            self.SetTopWindow (frame)
+            return True
+
+    app = demo_app()
+    app.MainLoop()
index a4cf64ed736797c3261c32787646527f0b66dbdd..1d632a5673c406cfb3bcca160bf503b0c64ece39 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 #include <usrp_base.h>
-#include <usrp_basic.h>
+#include <usrp/usrp_basic.h>
 
 class truth_table_element_t 
 {
index a914159e61e9c5cbe87b88b4fb68d0c8b75f7624..7947723fba27dfe65085e01005f5857b408265a3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -24,8 +24,8 @@
 #include <gr_sync_block.h>
 #include <stdexcept>
 #include <boost/shared_ptr.hpp>
-#include <db_base.h>
-#include <usrp_subdev_spec.h>
+#include <usrp/db_base.h>
+#include <usrp/usrp_subdev_spec.h>
 
 class usrp_basic;
 
diff --git a/gr-usrp/src/usrp_multi.py b/gr-usrp/src/usrp_multi.py
new file mode 100644 (file)
index 0000000..c04d731
--- /dev/null
@@ -0,0 +1,233 @@
+#
+# Copyright 2005,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from gnuradio import gr, gru
+from gnuradio.gr import hier_block2
+from gnuradio import usrp
+from usrpm import usrp_prims
+import sys
+
+
+class multi_source_align(object):
+    def __init__(self, fg, master_serialno, decim, nchan=2, pga_gain=0.0,
+                 cordic_freq=0.0, mux=None, align_interval=-1,
+                 fpga_filename="multi_2rxhb_2tx.rbf"):
+        """
+        Align multiple sources (usrps) using samplenumbers in the first channel.
+
+        Takes two ore more sources producing interleaved shorts.
+                               produces nchan * nsources gr_complex output streams.
+
+        @param nchan: number of interleaved channels in source
+        @param align_interval: number of samples to minimally skip between alignments
+                                                      default = -1 which means align only once per work call.
+        @param master_serial_no: serial number of the source which must be the master.
+
+
+        Exported sub-blocks (attributes):
+          master_source
+          slave_source
+          usrp_master
+          usrp_slave
+        """
+        mode=usrp.FPGA_MODE_NORMAL
+        mode = mode | usrp_prims.bmFR_MODE_RX_COUNTING_32BIT #(1 << 2) #usrp1.FPGA_MODE_COUNTING_32BIT
+        align=gr.align_on_samplenumbers_ss (nchan,align_interval) 
+        self.usrp_master = None
+        self.usrp_slave = None
+        # um is master usrp
+        # us is slave usrp
+        if mux is None:
+          mux=self.get_default_mux()  #Note that all channels have shifted left because of the added 32 bit counter channel
+        
+        u1 = usrp.source_s (1, decim, nchan, gru.hexint(mux), mode,fpga_filename=fpga_filename )
+        u0 = usrp.source_s (0, decim, nchan, gru.hexint(mux), mode,fpga_filename=fpga_filename )
+        print 'usrp[0] serial',u0.serial_number()
+        print 'usrp[1] serial',u1.serial_number()
+        #default, choose the second found usrp as master (which is usually the usrp which was first plugged in)
+        um_index=1
+        um=u1
+        us_index=0
+        us=u0
+        if (not (master_serialno is None)): #((master_serialno>0) | (master_serialno <-2)):
+          if (u0.serial_number() == master_serialno):
+            um_index=0
+            um=u0
+            us_index=1
+            us=u1
+          elif (u1.serial_number() != master_serialno):              
+              errorstring = 'Error. requested master_serialno ' + master_serialno +' not found\n'
+              errorstring = errorstring + 'Available are:\n'
+              errorstring = errorstring + 'usrp[1] serial_no = ' + u1.serial_number() +'\n' 
+              errorstring = errorstring + 'usrp[0] serial_no = ' + u0.serial_number() +'\n'
+              print errorstring
+              raise ValueError, errorstring
+          else: #default, just choose the first found usrp as master
+            um_index=1
+            um=u1
+            us_index=0
+            us=u0
+
+        self.usrp_master=um
+        self.usrp_slave=us
+        print 'usrp_master=usrp[%i] serial_no = %s' % (um_index,self.usrp_master.serial_number() ,)
+        print 'usrp_slave=usrp[%i] serial_no = %s' % (us_index,self.usrp_slave.serial_number() ,)
+        self.subdev_mAr = usrp.selected_subdev(self.usrp_master, (0,0))
+        self.subdev_mBr = usrp.selected_subdev(self.usrp_master, (1,0))
+        self.subdev_sAr = usrp.selected_subdev(self.usrp_slave, (0,0))
+        self.subdev_sBr = usrp.selected_subdev(self.usrp_slave, (1,0))
+        #throttle = gr.throttle(gr.sizeof_gr_complex, input_rate)
+        if not (pga_gain is None):
+          um.set_pga (0, pga_gain)
+          um.set_pga (1, pga_gain)
+
+          us.set_pga (0, pga_gain)
+          us.set_pga (1, pga_gain)
+
+        self.input_rate = um.adc_freq () / um.decim_rate ()
+        deintm=gr.deinterleave(gr.sizeof_gr_complex) 
+        deints=gr.deinterleave(gr.sizeof_gr_complex)
+        nullsinkm=gr.null_sink(gr.sizeof_gr_complex)
+        nullsinks=gr.null_sink(gr.sizeof_gr_complex)
+
+        tocomplexm=gr.interleaved_short_to_complex()
+        tocomplexs=gr.interleaved_short_to_complex()
+
+        fg.connect(um,(align,0))
+        fg.connect(us,(align,1))
+        fg.connect((align,0),tocomplexm)
+        fg.connect((align,1),tocomplexs)
+        fg.connect(tocomplexm,deintm)
+        fg.connect(tocomplexs,deints)
+        fg.connect((deintm,0),nullsinkm) #The counters are not usefull for the user but must be connected to something
+        fg.connect((deints,0),nullsinks) #The counters are not usefull for the user but must be connected to something
+        if 4==nchan:
+          nullsinkm3=gr.null_sink(gr.sizeof_gr_complex)
+          nullsinks3=gr.null_sink(gr.sizeof_gr_complex)
+          fg.connect((deintm,3), nullsinkm3) #channel 4 is not used but must be connected
+          fg.connect((deints,3), nullsinks3) #channel 4 is not used but must be connected
+
+        self.fg=fg
+        self.master_source=deintm
+        self.slave_source=deints
+
+        if not (cordic_freq is None):
+          um.set_rx_freq (1, cordic_freq)
+          um.set_rx_freq (0, cordic_freq)
+          us.set_rx_freq (1, cordic_freq)
+          us.set_rx_freq (0, cordic_freq)
+
+        self.enable_master_and_slave()
+        # add an idle handler
+        self.unsynced=True
+
+        # wire the block together
+        #hier_block_multi_tail.__init__(self, fg, nchan,deintm,deints)
+    def get_default_mux(self):
+        return 0x10321032     # Note that all channels have shifted left because of the added 32 bit counter channel  
+
+    def get_master_source_c(self):
+        return self.master_source
+
+    def get_slave_source_c(self):
+        return self.slave_source
+
+    def get_master_usrp(self):
+        return self.usrp_master
+
+    def get_slave_usrp(self):
+        return self.usrp_slave
+
+    def enable_master_and_slave(self):
+        # Warning, allways FIRST enable the slave before you enable the master
+        # This is to be sure you don't have two masters connecting to each other
+        # Otherwise you could ruin your hardware because the two sync outputs would be connected together
+
+        #SLAVE
+        #disable master, enable slave and set sync pulse to zero
+        reg_mask = usrp_prims.bmFR_RX_SYNC_SLAVE | usrp_prims.bmFR_RX_SYNC_MASTER | usrp_prims.bmFR_RX_SYNC
+        self.usrp_slave._u._write_fpga_reg_masked(usrp_prims.FR_RX_MASTER_SLAVE, usrp_prims.bmFR_RX_SYNC_SLAVE,reg_mask)
+        #set SYNC slave iopin on daughterboards RXA as input
+        oe = 0 # set rx_a_io[bitnoFR_RX_SYNC_INPUT_IOPIN] as input
+        oe_mask = usrp_prims.bmFR_RX_SYNC_INPUT_IOPIN 
+        self.usrp_slave._u._write_oe(0,oe,oe_mask)
+        #Now it is save to enable the master
+
+        #MASTER
+        #enable master, disable slave and set sync pulse to zero
+        reg_mask = usrp_prims.bmFR_RX_SYNC_SLAVE | usrp_prims.bmFR_RX_SYNC_MASTER | usrp_prims.bmFR_RX_SYNC
+        self.usrp_master._u._write_fpga_reg_masked(usrp_prims.FR_RX_MASTER_SLAVE,usrp_prims.bmFR_RX_SYNC_MASTER,reg_mask)
+        #set SYNC master iopin on daughterboards RXA as output
+        oe = usrp_prims.bmFR_RX_SYNC_OUTPUT_IOPIN # set rx_a_io[bitnoFR_RX_SYNC_OUTPUT_IOPIN] as output
+        oe_mask = usrp_prims.bmFR_RX_SYNC_OUTPUT_IOPIN 
+        self.usrp_master._u._write_oe(0,oe,oe_mask)
+
+    def sync_usrps(self, evt):
+        self.sync()
+
+    def sync(self):
+        result=False
+        result = self.usrp_master._u._write_fpga_reg_masked (usrp_prims.FR_RX_MASTER_SLAVE, usrp_prims.bmFR_RX_SYNC, usrp_prims.bmFR_RX_SYNC )
+        #There should be a small delay here, but the time it takes to get the sync to the usrp is long enough
+        #turn sync pulse off
+        result  = result & self.usrp_master._u._write_fpga_reg_masked (usrp_prims.FR_RX_MASTER_SLAVE,0 ,usrp_prims.bmFR_RX_SYNC);
+        return result;
+
+    def nullsink_counters(self):
+        nullsinkm=gr.null_sink(gr.sizeof_gr_complex)
+        nullsinks=gr.null_sink(gr.sizeof_gr_complex)
+        self.fg.connect((self.master_source,0),nullsinkm)
+        self.fg.connect((self.slave_source,0),nullsinks)
+
+
+    def print_db_info(self):
+        print "MASTER RX d'board %s" % (self.subdev_mAr.side_and_name(),)
+        print "MASTER RX d'board %s" % (self.subdev_mBr.side_and_name(),)
+        #print "TX d'board %s" % (self.subdev_At.side_and_name(),)
+        #print "TX d'board %s" % (self.subdev_Bt.side_and_name(),)
+        print "SLAVE RX d'board %s" % (self.subdev_sAr.side_and_name(),)
+        print "SLAVE RX d'board %s" % (self.subdev_sBr.side_and_name(),)
+        #print "TX d'board %s" % (self.subdev_At.side_and_name(),)
+        #print "TX d'board %s" % (self.subdev_Bt.side_and_name(),)
+
+    def tune_all_rx(self,target_freq):
+        result = True
+        r1 =  usrp.tune(self.usrp_master, 0, self.subdev_mAr, target_freq)
+        if r1 is None:
+          result=False
+        r2 = usrp.tune(self.usrp_master, 1, self.subdev_mBr, target_freq)
+        if r2 is None:
+          result=False
+        r3 = usrp.tune(self.usrp_slave, 0, self.subdev_sAr, target_freq)
+        if r3 is None:
+          result=False
+        r4 = usrp.tune(self.usrp_slave, 1, self.subdev_sBr, target_freq)
+        if r4 is None:
+          result=False
+        return result,r1,r2,r3,r4
+
+    def set_gain_all_rx(self, gain):
+        self.subdev_mAr.set_gain(gain)
+        self.subdev_mBr.set_gain(gain)
+        self.subdev_sAr.set_gain(gain)
+        self.subdev_sBr.set_gain(gain)
index cb65e02cd9f3c62020017f4c8128355540f06571..635d9345f019a30c330b1c90c5afef0406712cf5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,7 +26,7 @@
 
 #include <usrp_sink_base.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <assert.h>
 #include <cstdio>
 
index b27813a42ad89fb1ac2fbc1a9904a374f03a7714..8d573af1b05214aad97fd27c2d6c31a5187197f9 100644 (file)
@@ -1,7 +1,7 @@
 
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_base.h>
 #include <stdexcept>
-#include <usrp_tune_result.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_tune_result.h>
+#include <usrp/usrp_dbid.h>
 
 class usrp_standard_tx;
 
index 363a113fc8afab4e3e8414a3e969f739e38675ab..40750b477d23360dd26b56138b36c649d30a7bad 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_sink_c.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 usrp_sink_c_sptr
 usrp_make_sink_c (int which_board,
index adbf3acbd9330dc2434f6909907c5f3830160456..1f51da24db293c9918489938159e3e096c658bd6 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_sink_s.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 usrp_sink_s_sptr
 usrp_make_sink_s (int which_board,
index 99efbcdda9f8e00cae7ababd8eccb745df091216..5a5e20f3e3decb142c4c940c0d112712aa3532c4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,7 +26,7 @@
 
 #include <usrp_source_base.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <assert.h>
 #include <cstdio>
 
@@ -292,6 +292,10 @@ usrp_source_base::pick_rx_subdevice()
     USRP_DBID_FLEX_2400_RX,
     USRP_DBID_TV_RX,
     USRP_DBID_TV_RX_REV_2,
+    USRP_DBID_TV_RX_REV_3,
+    USRP_DBID_TV_RX_MIMO,
+    USRP_DBID_TV_RX_REV_2_MIMO,
+    USRP_DBID_TV_RX_REV_3_MIMO,
     USRP_DBID_DBS_RX,
     USRP_DBID_BASIC_RX
   };
index e1d091d893b006b47eec85de3cc08c8a4566d2db..4def48e24c058f0c9ad560b56c18bc7ccff69ec1 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -25,8 +25,8 @@
 
 #include <usrp_base.h>
 #include <stdexcept>
-#include <usrp_tune_result.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_tune_result.h>
+#include <usrp/usrp_dbid.h>
 
 class usrp_standard_rx;
 
index 71ca1e0d7c8fa65e86b133d82d5f499bcfd53590..26d95dc1b36c1a5a9611bc9158b0ac9854b1d6bb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_source_c.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 static const int NBASIC_SAMPLES_PER_ITEM = 2;  // I & Q
 
index f20384599fe1f286fe072d5e1bee28f54d5bb2e5..88b8495d3679512f165491146c6b5055850ec10d 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,8 +26,8 @@
 
 #include <usrp_source_s.h>
 #include <gr_io_signature.h>
-#include <usrp_standard.h>
-#include <usrp_bytesex.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 static const int NBASIC_SAMPLES_PER_ITEM = 1;
 
index 7d32cdf8137018b73f056832803b9b17070ff37a..61053bb3b20dab549752a08999830a8f9773218b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 // FIXME: move to usrp/usrpm component
 
 %{
-#include <usrp_standard.h>
+#include <usrp/usrp_standard.h>
 #include <usrp_spi_defs.h>
-#include <usrp_dbid.h>
+#include <usrp/usrp_dbid.h>
 %}
 
 %include <usrp_spi_defs.h>
-%include <usrp_dbid.h>
+%include <usrp/usrp_dbid.h>
 
 %constant int FPGA_MODE_NORMAL   = usrp_standard_rx::FPGA_MODE_NORMAL;
 %constant int FPGA_MODE_LOOPBACK = usrp_standard_rx::FPGA_MODE_LOOPBACK;
index f5841985dda59543b78f68621f8de8aa75f61bec..2a47877c3ceef3027218e1edba1c9390162f6e25 100644 (file)
@@ -26,8 +26,8 @@
 #include <vector>
 %}
 
-%include <usrp_subdev_spec.h>
-%include <db_base.i>
+%include <usrp/usrp_subdev_spec.h>
+%include <usrp/db_base.i>
 %include <fpga_regs_common.h>
 %include <fpga_regs_standard.h>
 %include "usrp_standard.i"
diff --git a/gr-usrp2/.gitignore b/gr-usrp2/.gitignore
new file mode 100644 (file)
index 0000000..a43ae9c
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/gnuradio-usrp2.pc
index 403e5f1c912eda8b8ed83782256a1a82660ef06a..2222badd7ddc1c2321c0fc24df83b4bb1fbdc0ad 100644 (file)
@@ -6,6 +6,6 @@ includedir=@includedir@/gnuradio
 Name: gnuradio-usrp2
 Description: GNU Software Radio support for Universal Software Radio Peripheral 2
 Requires: gnuradio-core usrp2
-Version: @VERSION@
+Version: @LIBVER@
 Libs: -L${libdir} -lgnuradio-usrp2
 Cflags: -I${includedir}
diff --git a/gr-usrp2/src/.gitignore b/gr-usrp2/src/.gitignore
new file mode 100644 (file)
index 0000000..6f241fe
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/usrp2.py
+/usrp2.cc
+/run_tests
+/test_gr_usrp2
+/*.pyc
index 77da2bd4918931287516cddbb87a4db6221f2657..03b6d0dd9d15c0747c1ef32201efe66aca95031a 100644 (file)
@@ -34,7 +34,6 @@ noinst_PYTHON = qa_usrp2.py
 # ----------------------------------------------------------------------
 
 EXTRA_DIST = run_tests.in
-TESTS = run_tests
 DISTCLEANFILES = run_tests
 
 # ----------------------------------------------------------------------
@@ -51,6 +50,8 @@ AM_CPPFLAGS = \
 
 lib_LTLIBRARIES = libgnuradio-usrp2.la
 
+libgnuradio_usrp2_la_LDFLAGS = $(LTVERSIONFLAGS)
+
 libgnuradio_usrp2_la_SOURCES = \
        rx_16sc_handler.cc \
        rx_32fc_handler.cc \
@@ -79,12 +80,14 @@ noinst_HEADERS = \
        rx_16sc_handler.h \
        rx_32fc_handler.h
 
+if PYTHON
 # ----------------------------------------------------------------------
 # Python SWIG wrapper around C++ library
 #
 # usrp2.py
 # _usrp2.so
 # ----------------------------------------------------------------------
+TESTS = run_tests
 
 TOP_SWIG_IFILES =              \
        usrp2.i
@@ -111,3 +114,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
index 99190b81b3ddd33c199e1c65056263a5e578c252..3f068256eefe6425416759d3386409bacd0a3ea0 100644 (file)
@@ -5,11 +5,11 @@
 # 3rd parameter is path to Python QA directory
 
 # For OS/X
-DYLD_LIBRARY_PATH=@abs_top_builddir@/usrp2/host/lib/legacy:@abs_top_builddir@/usrp2/host/lib/legacy/.libs:$DYLD_LIBRARY_PATH
+DYLD_LIBRARY_PATH=@abs_top_builddir@/usrp2/host/lib:@abs_top_builddir@/usrp2/host/lib/.libs:$DYLD_LIBRARY_PATH
 export DYLD_LIBRARY_PATH
 
 # For Win32
-PATH=@abs_top_builddir@/usrp2/host/lib/legacy:@abs_top_builddir@/usrp2/host/lib/legacy/.libs:$PATH
+PATH=@abs_top_builddir@/usrp2/host/lib:@abs_top_builddir@/usrp2/host/lib/.libs:$PATH
 
 @top_builddir@/run_tests.sh \
     @abs_top_srcdir@/gr-usrp2 \
index 319740283f86de341b0ea99628f0a4c85bb18fe7..d1fa091f73f6d8c69e5409dfe688899be207683e 100644 (file)
@@ -66,6 +66,7 @@ protected:
 public:
   ~usrp2_source_base();
 
+  bool set_antenna(int ant);
   bool set_gain(double gain);
   %rename(_real_set_center_freq) set_center_freq;
   bool set_lo_offset(double frequency);
@@ -138,6 +139,7 @@ protected:
 public:
   ~usrp2_sink_base();
 
+  bool set_antenna(int ant);
   bool set_gain(double gain);
   %rename(_real_set_center_freq) set_center_freq;
   bool set_lo_offset(double frequency);
index 96e6b174c7aa2c9468a6d4b0a41aaa81ba5caa33..1e7c54dcdb16d8c0cb62f0281c39af9303b0c3bf 100644 (file)
@@ -29,6 +29,9 @@
 #include <gr_io_signature.h>
 #include <iostream>
 
+// FIXME hack until VRT replaces libusrp2
+#define U2_MIN_SAMPLES 9
+
 usrp2_sink_16sc_sptr
 usrp2_make_sink_16sc(const std::string &ifc, const std::string &mac_addr) 
   throw (std::runtime_error)
@@ -57,6 +60,12 @@ usrp2_sink_16sc::work(int noutput_items,
 {
   std::complex<int16_t> *in = (std::complex<int16_t> *)input_items[0];
 
+  // FIXME: Current libusrp2 can't handle short packets.
+  // Returning 0 assumes there will be more samples
+  // the next round...
+  if (noutput_items < U2_MIN_SAMPLES)
+    return 0;
+
   usrp2::tx_metadata metadata;
   metadata.timestamp = -1;
   metadata.send_now = 1;
index 6cfff0d758d289fded02b08b46b88d8e3da8677d..b1e28a8297ee83468801a8ebd57a43e916d86938 100644 (file)
@@ -29,6 +29,9 @@
 #include <gr_io_signature.h>
 #include <iostream>
 
+// FIXME hack until VRT replaces libusrp2
+#define U2_MIN_SAMPLES 9
+
 usrp2_sink_32fc_sptr
 usrp2_make_sink_32fc(const std::string &ifc, const std::string &mac_addr) 
   throw (std::runtime_error)
@@ -57,6 +60,12 @@ usrp2_sink_32fc::work(int noutput_items,
 {
   gr_complex *in = (gr_complex *)input_items[0];
 
+  // FIXME: Current libusrp2 can't handle short packets.
+  // Returning 0 assumes there will be more samples
+  // the next round...
+  if (noutput_items < U2_MIN_SAMPLES)
+    return 0;
+
   usrp2::tx_metadata metadata;
   metadata.timestamp = -1;
   metadata.send_now = 1;
index 4579d1651fffe301b67fa106ea0b6afce293484b..ce473f2365e08b132237f219921d6d4b52c6d142 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -46,6 +46,12 @@ usrp2_sink_base::~usrp2_sink_base ()
   // NOP
 }
 
+bool
+usrp2_sink_base::set_antenna(int ant)
+{
+  return d_u2->set_tx_antenna(ant);
+}
+
 bool
 usrp2_sink_base::set_gain(double gain)
 {
index f973e805c4dee84a581d24b3d81c3277867b7bda..38dc4f2364a60fef6cbadc39c8394afcca9ed06a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -40,6 +40,11 @@ protected:
 public:
   ~usrp2_sink_base();
 
+  /*!
+   * \brief Set antenna
+   */
+  bool set_antenna(int ant);
+
   /*!
    * \brief Set transmitter gain
    */
index 0ad7008a6fc037d774d3027d7d53d95e15973e3c..d946991dec00673e417b30ad7bed41d6a71da57e 100644 (file)
@@ -46,6 +46,12 @@ usrp2_source_base::~usrp2_source_base ()
   // NOP
 }
 
+bool
+usrp2_source_base::set_antenna(int ant)
+{
+  return d_u2->set_rx_antenna(ant);
+}
+
 bool
 usrp2_source_base::set_gain(double gain)
 {
index 2e2d51fc391f66b516a4177f2722b703b53b6aef..9e35e2e9360e245f6a5971e2ea182c0ab773970b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -40,6 +40,11 @@ protected:
 public:
   ~usrp2_source_base();
 
+  /*!
+   * \brief Set antenna
+   */
+  bool set_antenna(int ant);
+
   /*!
    * \brief Set receiver gain
    */
diff --git a/gr-utils/.gitignore b/gr-utils/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-utils/src/.gitignore b/gr-utils/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 7a941211384b6d536ef7ca05e5d17f032f8c66cc..b2847dce98e99f4d3f5d7703cf405d1ae4481674 100644 (file)
@@ -19,4 +19,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = lib python
+SUBDIRS = lib
+if PYTHON
+SUBDIRS += python
+endif
diff --git a/gr-utils/src/lib/.gitignore b/gr-utils/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-utils/src/python/.gitignore b/gr-utils/src/python/.gitignore
new file mode 100644 (file)
index 0000000..b695091
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pyc
index b58faa9bf9a0d113ae6c8dbf60083f0c3adc9473..9c4e222c810d52ac44c7ec4512b3685dd1f39e98 100644 (file)
@@ -23,14 +23,19 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = \
     $(bin_SCRIPTS) \
-    README.plot
+    README.plot \
+    pyqt_plot.ui \
+    pyqt_filter.ui
 
 ourpythondir = $(grpythondir)
 
 ourpython_PYTHON = \
-    plot_data.py
+    plot_data.py   \
+    pyqt_plot.py   \
+    pyqt_filter.py
 
 bin_SCRIPTS = \
+    create-gnuradio-out-of-tree-project \
     gr_plot_char.py \
     gr_plot_const.py \
     gr_plot_fft.py \
@@ -43,6 +48,8 @@ bin_SCRIPTS = \
     gr_plot_int.py \
     gr_plot_iq.py \
     gr_plot_short.py \
+    gr_plot_qt.py \
+    gr_filter_design.py \
     lsusrp \
     usrp_fft.py \
     usrp_oscope.py \
@@ -50,9 +57,9 @@ bin_SCRIPTS = \
     usrp_rx_cfile.py \
     usrp_rx_nogui.py \
     usrp_siggen.py \
+    usrp_siggen_gui.py \
     usrp_test_counting.py \
     usrp_test_loopback.py \
     usrp2_fft.py \
-    usrp2_rx_cfile.py \
-    usrp2_siggen.py \
-    usrp2_siggen_gui.py
+    usrp2_rx_cfile.py
+
diff --git a/gr-utils/src/python/create-gnuradio-out-of-tree-project b/gr-utils/src/python/create-gnuradio-out-of-tree-project
new file mode 100755 (executable)
index 0000000..1f512b2
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+import os
+import re
+import sys
+import subprocess
+
+tarball_url="http://gnuradio.org/releases/gnuradio/gr-howto-write-a-block-3.3git-651-g642252d8.tar.gz"
+
+def open_tarball(tarball_name=None):
+    """Return a readable fileobject that references the tarball.
+    If tarball_name is None, download from the net
+    """
+    if tarball_name:
+        return open(tarball_name, 'r')
+    p = subprocess.Popen(["wget", "-O", "-", tarball_url],
+                         close_fds=True, stdout=subprocess.PIPE)
+    return p.stdout
+
+def extract_and_rename_files(tarball, module_name):
+    #  Requires GNU tar.
+    tar_cmd = 'tar xz --strip-components=1 --transform="s/howto/%s/g"' % (module_name,)
+    p = subprocess.Popen(tar_cmd, shell=True, stdin=tarball, close_fds=True)
+    sts = os.waitpid(p.pid, 0)
+    return sts == 0
+
+def main():
+    usage = "%prog: [options] new_module_name"
+    description="Create a prototype 'out of tree' GNU Radio project"
+    parser = OptionParser(usage=usage, description=description)
+    parser.add_option("-T", "--tarball", type="string", default=None,
+                      help="path to gr-howto-build-a-block gzipped tarball [default=<get from web>]")
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        raise SystemExit,2
+    module_name = args[0]
+    if not re.match(r'[_a-z][_a-z0-9]*$', module_name):
+        sys.stderr.write("module_name '%s' may only contain [a-z0-9_]\n" % (module_name))
+        raise SystemExit, 1
+
+    # Ensure there's no file or directory called <module_name>
+    if os.path.exists(module_name):
+        sys.stderr.write("A file or directory named '%s' already exists\n" % (module_name,))
+        raise SystemExit, 1
+
+    os.mkdir(module_name)
+    os.chdir(module_name)
+
+    ok = extract_and_rename_files(open_tarball(options.tarball), module_name)
+
+    # rename file contents
+    upper_module_name = module_name.upper()
+    sed_cmd = 'sed -i -e "s/howto/%s/g" -e "s/HOWTO/%s/g"' % (module_name,
+                                                                 upper_module_name)
+    os.system('find . -type f -print0 | xargs -0 ' + sed_cmd)
+
+    sys.stdout.write("""
+Project '%s' is now ready to build.
+
+  $ ./bootstrap
+  $ ./configure --prefix=/home/[user]/install
+  $ (make && make check && make install) 2>&1 | tee make.log
+
+""" % (module_name,))
+
+if __name__ == '__main__':
+    main()
diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py
new file mode 100755 (executable)
index 0000000..bf83cf6
--- /dev/null
@@ -0,0 +1,673 @@
+#!/usr/bin/env python
+
+import sys, os
+from optparse import OptionParser
+from gnuradio import gr, blks2, eng_notation
+
+try:
+    import scipy
+    from scipy import fftpack
+except ImportError:
+    print "Please install SciPy to run this script (http://www.scipy.org/)"
+    raise SystemExit, 1
+
+try:
+    from PyQt4 import Qt, QtCore, QtGui
+except ImportError:
+    print "Please install PyQt4 to run this script (http://www.riverbankcomputing.co.uk/software/pyqt/download)"
+    raise SystemExit, 1
+
+try:
+    import PyQt4.Qwt5 as Qwt
+except ImportError:
+    print "Please install PyQwt5 to run this script (http://pyqwt.sourceforge.net/)"
+    raise SystemExit, 1
+
+try:
+    from pyqt_filter import Ui_MainWindow
+except ImportError:
+    print "Could not import from pyqt_filter. Please build with \"pyuic4 pyqt_filter.ui -o pyqt_filter.py\""
+    raise SystemExit, 1
+
+
+class gr_plot_filter(QtGui.QMainWindow):
+    def __init__(self, qapp, options):
+        QtGui.QWidget.__init__(self, None)
+        self.gui = Ui_MainWindow()
+        self.gui.setupUi(self)
+
+        self.connect(self.gui.filterTypeComboBox,
+                     Qt.SIGNAL("currentIndexChanged(const QString&)"),
+                     self.changed_filter_type)
+        self.connect(self.gui.filterDesignTypeComboBox,
+                     Qt.SIGNAL("currentIndexChanged(const QString&)"),
+                     self.changed_filter_design_type)
+
+        self.connect(self.gui.designButton,
+                     Qt.SIGNAL("released()"),
+                     self.design)
+
+        self.connect(self.gui.tabGroup,
+                     Qt.SIGNAL("currentChanged(int)"),
+                     self.tab_changed)
+
+        self.connect(self.gui.nfftEdit,
+                     Qt.SIGNAL("textEdited(QString)"),
+                     self.nfft_edit_changed)
+
+        self.gui.designButton.setShortcut(QtCore.Qt.Key_Return)
+
+        self.taps = []
+        self.fftdB = []
+        self.fftDeg = []
+        self.groupDelay = []
+        self.nfftpts = int(10000)
+        self.gui.nfftEdit.setText(Qt.QString("%1").arg(self.nfftpts))
+
+        self.firFilters = ("Low Pass", "Band Pass", "Complex Band Pass", "Band Notch",
+                           "High Pass", "Root Raised Cosine", "Gaussian")
+        self.optFilters = ("Low Pass", "Band Pass", "Complex Band Pass",
+                           "Band Notch", "High Pass")
+        
+        self.set_windowed()
+                
+        # Initialize to LPF
+        self.gui.filterTypeWidget.setCurrentWidget(self.gui.firlpfPage)
+
+        # Set Axis labels
+        self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.xBottom,
+                                       "Frequency (Hz)")
+        self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.yLeft,
+                                       "Magnitude (dB)")
+        self.gui.timePlot.setAxisTitle(self.gui.timePlot.xBottom,
+                                       "Tap number")
+        self.gui.timePlot.setAxisTitle(self.gui.timePlot.yLeft,
+                                       "Amplitude")
+        self.gui.phasePlot.setAxisTitle(self.gui.phasePlot.xBottom,
+                                        "Frequency (Hz)")
+        self.gui.phasePlot.setAxisTitle(self.gui.phasePlot.yLeft,
+                                        "Phase (Radians)")
+        self.gui.groupPlot.setAxisTitle(self.gui.groupPlot.xBottom,
+                                        "Frequency (Hz)")
+        self.gui.groupPlot.setAxisTitle(self.gui.groupPlot.yLeft,
+                                        "Delay (sec)")
+
+        # Set up plot curves
+        self.rcurve = Qwt.QwtPlotCurve("Real")
+        self.rcurve.attach(self.gui.timePlot)
+        self.icurve = Qwt.QwtPlotCurve("Imag")
+        self.icurve.attach(self.gui.timePlot)
+
+        self.freqcurve = Qwt.QwtPlotCurve("PSD")
+        self.freqcurve.attach(self.gui.freqPlot)
+
+        self.phasecurve = Qwt.QwtPlotCurve("Phase")
+        self.phasecurve.attach(self.gui.phasePlot)
+
+        self.groupcurve = Qwt.QwtPlotCurve("Group Delay")
+        self.groupcurve.attach(self.gui.groupPlot)
+
+        # Create zoom functionality for the plots
+        self.timeZoomer = Qwt.QwtPlotZoomer(self.gui.timePlot.xBottom,
+                                            self.gui.timePlot.yLeft,
+                                            Qwt.QwtPicker.PointSelection,
+                                            Qwt.QwtPicker.AlwaysOn,
+                                            self.gui.timePlot.canvas())
+
+        self.freqZoomer = Qwt.QwtPlotZoomer(self.gui.freqPlot.xBottom,
+                                            self.gui.freqPlot.yLeft,
+                                            Qwt.QwtPicker.PointSelection,
+                                            Qwt.QwtPicker.AlwaysOn,
+                                            self.gui.freqPlot.canvas())
+
+        self.phaseZoomer = Qwt.QwtPlotZoomer(self.gui.phasePlot.xBottom,
+                                             self.gui.phasePlot.yLeft,
+                                             Qwt.QwtPicker.PointSelection,
+                                             Qwt.QwtPicker.AlwaysOn,
+                                             self.gui.phasePlot.canvas())
+
+        self.groupZoomer = Qwt.QwtPlotZoomer(self.gui.groupPlot.xBottom,
+                                             self.gui.groupPlot.yLeft,
+                                             Qwt.QwtPicker.PointSelection,
+                                             Qwt.QwtPicker.AlwaysOn,
+                                             self.gui.groupPlot.canvas())
+
+        # Set up pen for colors and line width
+        blue = QtGui.qRgb(0x00, 0x00, 0xFF)
+        blueBrush = Qt.QBrush(Qt.QColor(blue))
+        red = QtGui.qRgb(0xFF, 0x00, 0x00)
+        redBrush = Qt.QBrush(Qt.QColor(red))
+        self.freqcurve.setPen(Qt.QPen(blueBrush, 2))
+        self.rcurve.setPen(Qt.QPen(blueBrush, 2))
+        self.icurve.setPen(Qt.QPen(redBrush, 2))
+        self.phasecurve.setPen(Qt.QPen(blueBrush, 2))
+        self.groupcurve.setPen(Qt.QPen(blueBrush, 2))
+
+        # Set up validators for edit boxes
+        self.intVal = Qt.QIntValidator(None)
+        self.dblVal = Qt.QDoubleValidator(None)
+        self.gui.nfftEdit.setValidator(self.intVal)
+        self.gui.sampleRateEdit.setValidator(self.dblVal)
+        self.gui.filterGainEdit.setValidator(self.dblVal)
+        self.gui.endofLpfPassBandEdit.setValidator(self.dblVal)
+        self.gui.startofLpfStopBandEdit.setValidator(self.dblVal)
+        self.gui.lpfStopBandAttenEdit.setValidator(self.dblVal)
+        self.gui.lpfPassBandRippleEdit.setValidator(self.dblVal)
+        self.gui.startofBpfPassBandEdit.setValidator(self.dblVal)
+        self.gui.endofBpfPassBandEdit.setValidator(self.dblVal)
+        self.gui.bpfTransitionEdit.setValidator(self.dblVal)
+        self.gui.bpfStopBandAttenEdit.setValidator(self.dblVal)
+        self.gui.bpfPassBandRippleEdit.setValidator(self.dblVal)
+        self.gui.startofBnfStopBandEdit.setValidator(self.dblVal)
+        self.gui.endofBnfStopBandEdit.setValidator(self.dblVal)
+        self.gui.bnfTransitionEdit.setValidator(self.dblVal)
+        self.gui.bnfStopBandAttenEdit.setValidator(self.dblVal)
+        self.gui.bnfPassBandRippleEdit.setValidator(self.dblVal)
+        self.gui.endofHpfStopBandEdit.setValidator(self.dblVal)
+        self.gui.startofHpfPassBandEdit.setValidator(self.dblVal)
+        self.gui.hpfStopBandAttenEdit.setValidator(self.dblVal)
+        self.gui.hpfPassBandRippleEdit.setValidator(self.dblVal)
+        self.gui.rrcSymbolRateEdit.setValidator(self.dblVal)
+        self.gui.rrcAlphaEdit.setValidator(self.dblVal)
+        self.gui.rrcNumTapsEdit.setValidator(self.dblVal)
+        self.gui.gausSymbolRateEdit.setValidator(self.dblVal)
+        self.gui.gausBTEdit.setValidator(self.dblVal)
+        self.gui.gausNumTapsEdit.setValidator(self.dblVal)
+
+        self.gui.nTapsEdit.setText("0")
+
+        self.filterWindows = {"Hamming Window" : gr.firdes.WIN_HAMMING,
+                              "Hann Window" : gr.firdes.WIN_HANN,
+                              "Blackman Window" : gr.firdes.WIN_BLACKMAN,
+                              "Rectangular Window" : gr.firdes.WIN_RECTANGULAR,
+                              "Kaiser Window" : gr.firdes.WIN_KAISER,
+                              "Blackman-harris Window" : gr.firdes.WIN_BLACKMAN_hARRIS}
+
+        self.show()
+
+    def changed_filter_type(self, ftype):
+        strftype = str(ftype.toAscii())
+        if(ftype == "Low Pass"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.firlpfPage)
+        elif(ftype == "Band Pass"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.firbpfPage)
+        elif(ftype == "Complex Band Pass"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.firbpfPage)
+        elif(ftype == "Band Notch"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.firbnfPage)
+        elif(ftype == "High Pass"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.firhpfPage)
+        elif(ftype == "Root Raised Cosine"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.rrcPage)
+        elif(ftype == "Gaussian"):
+            self.gui.filterTypeWidget.setCurrentWidget(self.gui.gausPage)
+
+        self.design()
+        
+    def changed_filter_design_type(self, design):
+        if(design == "Equiripple"):
+            self.set_equiripple()
+        else:
+            self.set_windowed()
+            
+        self.design()
+
+    def set_equiripple(self):
+        # Stop sending the signal for this function
+        self.gui.filterTypeComboBox.blockSignals(True)
+        
+        self.equiripple = True
+        self.gui.lpfPassBandRippleLabel.setVisible(True)
+        self.gui.lpfPassBandRippleEdit.setVisible(True)
+        self.gui.bpfPassBandRippleLabel.setVisible(True)
+        self.gui.bpfPassBandRippleEdit.setVisible(True)
+        self.gui.bnfPassBandRippleLabel.setVisible(True)
+        self.gui.bnfPassBandRippleEdit.setVisible(True)
+        self.gui.hpfPassBandRippleLabel.setVisible(True)
+        self.gui.hpfPassBandRippleEdit.setVisible(True)
+
+        # Save current type and repopulate the combo box for
+        # filters this window type can handle
+        currenttype = self.gui.filterTypeComboBox.currentText()
+        items = self.gui.filterTypeComboBox.count()
+        for i in xrange(items):
+            self.gui.filterTypeComboBox.removeItem(0)
+        self.gui.filterTypeComboBox.addItems(self.optFilters)
+
+        # If the last filter type was valid for this window type,
+        # go back to it; otherwise, reset
+        try:
+            index = self.optFilters.index(currenttype)
+            self.gui.filterTypeComboBox.setCurrentIndex(index)
+        except ValueError:
+            pass
+
+        # Tell gui its ok to start sending this signal again
+        self.gui.filterTypeComboBox.blockSignals(False)
+        
+    def set_windowed(self):
+        # Stop sending the signal for this function
+        self.gui.filterTypeComboBox.blockSignals(True)
+        
+        self.equiripple = False
+        self.gui.lpfPassBandRippleLabel.setVisible(False)
+        self.gui.lpfPassBandRippleEdit.setVisible(False)
+        self.gui.bpfPassBandRippleLabel.setVisible(False)
+        self.gui.bpfPassBandRippleEdit.setVisible(False)
+        self.gui.bnfPassBandRippleLabel.setVisible(False)
+        self.gui.bnfPassBandRippleEdit.setVisible(False)
+        self.gui.hpfPassBandRippleLabel.setVisible(False)
+        self.gui.hpfPassBandRippleEdit.setVisible(False)
+
+        # Save current type and repopulate the combo box for
+        # filters this window type can handle
+        currenttype = self.gui.filterTypeComboBox.currentText()
+        items = self.gui.filterTypeComboBox.count()
+        for i in xrange(items):
+            self.gui.filterTypeComboBox.removeItem(0)
+        self.gui.filterTypeComboBox.addItems(self.firFilters)
+
+        # If the last filter type was valid for this window type,
+        # go back to it; otherwise, reset
+        try:
+            index = self.optFilters.index(currenttype)
+            self.gui.filterTypeComboBox.setCurrentIndex(index)
+        except ValueError:
+            pass
+
+        # Tell gui its ok to start sending this signal again
+        self.gui.filterTypeComboBox.blockSignals(False)
+
+    def design(self):
+        ret = True
+        fs,r = self.gui.sampleRateEdit.text().toDouble()
+        ret = r and ret
+        gain,r = self.gui.filterGainEdit.text().toDouble()
+        ret = r and ret
+
+        if(ret):
+            winstr = str(self.gui.filterDesignTypeComboBox.currentText().toAscii())
+            ftype = str(self.gui.filterTypeComboBox.currentText().toAscii())
+
+            if(winstr == "Equiripple"):
+                designer = {"Low Pass" : self.design_opt_lpf,
+                            "Band Pass" : self.design_opt_bpf,
+                            "Complex Band Pass" : self.design_opt_cbpf,
+                            "Band Notch" : self.design_opt_bnf,
+                            "High Pass" :  self.design_opt_hpf}
+                taps,r = designer[ftype](fs, gain)
+
+            else:
+                designer = {"Low Pass" : self.design_win_lpf,
+                            "Band Pass" : self.design_win_bpf,
+                            "Complex Band Pass" : self.design_win_cbpf,
+                            "Band Notch" : self.design_win_bnf,
+                            "High Pass" :  self.design_win_hpf,
+                            "Root Raised Cosine" :  self.design_win_rrc,
+                            "Gaussian" :  self.design_win_gaus}
+                wintype = self.filterWindows[winstr]
+                taps,r = designer[ftype](fs, gain, wintype)
+
+            if(r):
+                self.taps = scipy.array(taps)
+                self.get_fft(fs, self.taps, self.nfftpts)
+                self.update_time_curves()
+                self.update_freq_curves()
+                self.update_phase_curves()
+                self.update_group_curves()
+
+                self.gui.nTapsEdit.setText(Qt.QString("%1").arg(self.taps.size))
+
+
+    # Filter design functions using a window
+    def design_win_lpf(self, fs, gain, wintype):
+        ret = True
+        pb,r = self.gui.endofLpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        sb,r = self.gui.startofLpfStopBandEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.lpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+
+        if(ret):
+            tb = sb - pb
+            
+            taps = gr.firdes.low_pass_2(gain, fs, pb, tb,
+                                        atten, wintype)
+            return (taps, ret)
+        else:
+            return ([], ret)
+    
+    def design_win_bpf(self, fs, gain, wintype):
+        ret = True
+        pb1,r = self.gui.startofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        pb2,r = self.gui.endofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bpfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            taps = gr.firdes.band_pass_2(gain, fs, pb1, pb2, tb,
+                                         atten, wintype)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_win_cbpf(self, fs, gain, wintype):
+        ret = True
+        pb1,r = self.gui.startofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        pb2,r = self.gui.endofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bpfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            taps = gr.firdes.complex_band_pass_2(gain, fs, pb1, pb2, tb,
+                                                 atten, wintype)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_win_bnf(self, fs, gain, wintype):
+        ret = True
+        pb1,r = self.gui.startofBnfStopBandEdit.text().toDouble()
+        ret = r and ret
+        pb2,r = self.gui.endofBnfStopBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bnfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bnfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            taps = gr.firdes.band_reject_2(gain, fs, pb1, pb2, tb,
+                                           atten, wintype)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_win_hpf(self, fs, gain, wintype):
+        ret = True
+        sb,r = self.gui.endofHpfStopBandEdit.text().toDouble()
+        ret = r and ret
+        pb,r = self.gui.startofHpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.hpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            tb = pb - sb
+            taps = gr.firdes.high_pass_2(gain, fs, pb, tb,
+                                         atten, wintype)            
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_win_rrc(self, fs, gain, wintype):
+        ret = True
+        sr,r = self.gui.rrcSymbolRateEdit.text().toDouble()
+        ret = r and ret
+        alpha,r = self.gui.rrcAlphaEdit.text().toDouble()
+        ret = r and ret
+        ntaps,r = self.gui.rrcNumTapsEdit.text().toInt()
+        ret = r and ret
+
+        if(r):
+            taps = gr.firdes.root_raised_cosine(gain, fs, sr,
+                                                alpha, ntaps)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_win_gaus(self, fs, gain, wintype):
+        ret = True
+        sr,r = self.gui.gausSymbolRateEdit.text().toDouble()
+        ret = r and ret
+        bt,r = self.gui.gausBTEdit.text().toDouble()
+        ret = r and ret
+        ntaps,r = self.gui.gausNumTapsEdit.text().toInt()
+        ret = r and ret
+
+        if(r):
+            spb = fs / sr
+            taps = gr.firdes.gaussian(gain, spb, bt, ntaps)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    # Design Functions for Equiripple Filters
+    def design_opt_lpf(self, fs, gain):
+        ret = True
+        pb,r = self.gui.endofLpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        sb,r = self.gui.startofLpfStopBandEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.lpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+        ripple,r = self.gui.lpfPassBandRippleEdit.text().toDouble()
+        ret = r and ret
+
+        if(ret):
+            taps = blks2.optfir.low_pass(gain, fs, pb, sb,
+                                         ripple, atten)
+            return (taps, ret)
+        else:
+            return ([], ret)
+    
+    def design_opt_bpf(self, fs, gain):
+        ret = True
+        pb1,r = self.gui.startofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        pb2,r = self.gui.endofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bpfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+        ripple,r = self.gui.bpfPassBandRippleEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            sb1 = pb1 - tb
+            sb2 = pb2 + tb
+            taps = blks2.optfir.band_pass(gain, fs, sb1, pb1, pb2, sb2,
+                                          ripple, atten)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_opt_cbpf(self, fs, gain):
+        ret = True
+        pb1,r = self.gui.startofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        pb2,r = self.gui.endofBpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bpfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+        ripple,r = self.gui.bpfPassBandRippleEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            sb1 = pb1 - tb
+            sb2 = pb2 + tb
+            taps = blks2.optfir.complex_band_pass(gain, fs, sb1, pb1, pb2, sb2,
+                                                  ripple, atten)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_opt_bnf(self, fs, gain):
+        ret = True
+        sb1,r = self.gui.startofBnfStopBandEdit.text().toDouble()
+        ret = r and ret
+        sb2,r = self.gui.endofBnfStopBandEdit.text().toDouble()
+        ret = r and ret
+        tb,r  = self.gui.bnfTransitionEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.bnfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+        ripple,r = self.gui.bnfPassBandRippleEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            pb1 = sb1 - tb
+            pb2 = sb2 + tb
+            taps = blks2.optfir.band_reject(gain, fs, pb1, sb1, sb2, pb2,
+                                            ripple, atten)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def design_opt_hpf(self, fs, gain):
+        ret = True
+        sb,r = self.gui.endofHpfStopBandEdit.text().toDouble()
+        ret = r and ret
+        pb,r = self.gui.startofHpfPassBandEdit.text().toDouble()
+        ret = r and ret
+        atten,r = self.gui.hpfStopBandAttenEdit.text().toDouble()
+        ret = r and ret
+        ripple,r = self.gui.hpfPassBandRippleEdit.text().toDouble()
+        ret = r and ret
+
+        if(r):
+            taps = blks2.optfir.high_pass(gain, fs, sb, pb,
+                                          atten, ripple)
+            return (taps,r)
+        else:
+            return ([],r)
+
+    def nfft_edit_changed(self, nfft):
+        infft,r = nfft.toInt()
+        if(r and (infft != self.nfftpts)):
+            self.nfftpts = infft
+            self.update_freq_curves()
+
+    def tab_changed(self, tab):
+        if(tab == 0):
+            self.update_freq_curves()
+        if(tab == 1):
+            self.update_time_curves()
+        if(tab == 2):
+            self.update_phase_curves()
+        if(tab == 3):
+            self.update_group_curves()
+        
+    def get_fft(self, fs, taps, Npts):
+        Ts = 1.0/fs
+        fftpts = fftpack.fft(taps, Npts)
+        self.freq = scipy.arange(0, fs, 1.0/(Npts*Ts))        
+        self.fftdB = 20.0*scipy.log10(abs(fftpts))
+        self.fftDeg = scipy.unwrap(scipy.angle(fftpts))
+        self.groupDelay = -scipy.diff(self.fftDeg)
+        
+    def update_time_curves(self):
+        ntaps = len(self.taps)
+        if(ntaps > 0):
+            if(type(self.taps[0]) == scipy.complex128):
+                self.rcurve.setData(scipy.arange(ntaps), self.taps.real)
+                self.icurve.setData(scipy.arange(ntaps), self.taps.imag)
+            else:
+                self.rcurve.setData(scipy.arange(ntaps), self.taps)
+
+            # Reset the x-axis to the new time scale
+            ymax = 1.5 * max(self.taps)
+            ymin = 1.5 * min(self.taps)
+            self.gui.timePlot.setAxisScale(self.gui.timePlot.xBottom,
+                                           0, ntaps)
+            self.gui.timePlot.setAxisScale(self.gui.timePlot.yLeft,
+                                           ymin, ymax)
+            
+            # Set the zoomer base to unzoom to the new axis
+            self.timeZoomer.setZoomBase()
+            
+            self.gui.timePlot.replot()
+        
+    def update_freq_curves(self):
+        npts = len(self.fftdB)
+        if(npts > 0):
+            self.freqcurve.setData(self.freq, self.fftdB)
+            
+            # Reset the x-axis to the new time scale
+            ymax = 1.5 * max(self.fftdB[0:npts/2])
+            ymin = 1.1 * min(self.fftdB[0:npts/2])
+            xmax = self.freq[npts/2]
+            xmin = self.freq[0]
+            self.gui.freqPlot.setAxisScale(self.gui.freqPlot.xBottom,
+                                           xmin, xmax)
+            self.gui.freqPlot.setAxisScale(self.gui.freqPlot.yLeft,
+                                           ymin, ymax)
+            
+            # Set the zoomer base to unzoom to the new axis
+            self.freqZoomer.setZoomBase()
+            
+            self.gui.freqPlot.replot()
+
+
+    def update_phase_curves(self):
+        npts = len(self.fftDeg)
+        if(npts > 0):
+            self.phasecurve.setData(self.freq, self.fftDeg)
+            
+            # Reset the x-axis to the new time scale
+            ymax = 1.5 * max(self.fftDeg[0:npts/2])
+            ymin = 1.1 * min(self.fftDeg[0:npts/2])
+            xmax = self.freq[npts/2]
+            xmin = self.freq[0]
+            self.gui.phasePlot.setAxisScale(self.gui.phasePlot.xBottom,
+                                            xmin, xmax)
+            self.gui.phasePlot.setAxisScale(self.gui.phasePlot.yLeft,
+                                            ymin, ymax)
+            
+            # Set the zoomer base to unzoom to the new axis
+            self.phaseZoomer.setZoomBase()
+            
+            self.gui.phasePlot.replot()
+
+    def update_group_curves(self):
+        npts = len(self.groupDelay)
+        if(npts > 0):
+            self.groupcurve.setData(self.freq, self.groupDelay)
+            
+            # Reset the x-axis to the new time scale
+            ymax = 1.5 * max(self.groupDelay[0:npts/2])
+            ymin = 1.1 * min(self.groupDelay[0:npts/2])
+            xmax = self.freq[npts/2]
+            xmin = self.freq[0]
+            self.gui.groupPlot.setAxisScale(self.gui.groupPlot.xBottom,
+                                            xmin, xmax)
+            self.gui.groupPlot.setAxisScale(self.gui.groupPlot.yLeft,
+                                            ymin, ymax)
+            
+            # Set the zoomer base to unzoom to the new axis
+            self.groupZoomer.setZoomBase()
+            
+            self.gui.groupPlot.replot()
+
+
+def setup_options():
+    usage="%prog: [options] (input_filename)"
+    description = ""
+
+    parser = OptionParser(conflict_handler="resolve",
+                          usage=usage, description=description)
+    return parser
+
+def main(args):
+    parser = setup_options()
+    (options, args) = parser.parse_args ()
+
+    app = Qt.QApplication(args)
+    gplt = gr_plot_filter(app, options)
+    app.exec_()
+
+if __name__ == '__main__':
+    main(sys.argv)
+
index 3553099552b75281c2140a9452acf094abd34d03..ec2272c744f3b2dd712b8819dcf0b76e8feac475 100755 (executable)
@@ -35,9 +35,6 @@ except ImportError:
 
 from optparse import OptionParser
 
-matplotlib.interactive(True)
-matplotlib.use('TkAgg')
-
 class draw_constellation:
     def __init__(self, filename, options):
         self.hfile = open(filename, "r")
@@ -139,8 +136,9 @@ class draw_constellation:
         draw()
         
     def zoom(self, event):
-        newxlim = self.sp_iq.get_xlim()
-        if(newxlim.all() != self.xlim.all()):
+        newxlim = scipy.array(self.sp_iq.get_xlim())
+        curxlim = scipy.array(self.xlim)
+        if(newxlim.all() != curxlim.all()):
             self.xlim = newxlim
             r = self.reals[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
             i = self.imags[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
index 59a3f286b65fc3a7ae4189fe5200092355722d6b..a9c1417f9b308993cfaa09ebc0a78c3461ef4118 100755 (executable)
 # Boston, MA 02110-1301, USA.
 # 
 
-try:
-    import matplotlib
-    matplotlib.use('TkAgg')
-    matplotlib.interactive(True)
-except ImportError:
-    print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)"
-    raise SystemExit, 1
-
 try:
     import scipy
     from scipy import fftpack
@@ -164,8 +156,9 @@ class gr_plot_fft:
         draw()
         
     def zoom(self, event):
-        newxlim = self.sp_iq.get_xlim()
-        if(newxlim.all() != self.xlim.all()):
+        newxlim = scipy.array(self.sp_iq.get_xlim())
+        curxlim = scipy.array(self.xlim)
+        if(newxlim.all() != curxlim.all()):
             self.xlim = newxlim
             xmin = max(0, int(ceil(self.sample_rate*(self.xlim[0] - self.position))))
             xmax = min(int(ceil(self.sample_rate*(self.xlim[1] - self.position))), len(self.iq))
index 2a4142a815863c71c5d14f63079313f51b6b875b..371ce3b7991b55137c7cb177180a23494d608a3e 100755 (executable)
@@ -34,10 +34,7 @@ except ImportError:
 
 from optparse import OptionParser
 
-matplotlib.interactive(True)
-matplotlib.use('TkAgg')
-
-class draw_fft:
+class draw_iq:
     def __init__(self, filename, options):
         self.hfile = open(filename, "r")
         self.block_length = options.block
@@ -168,7 +165,7 @@ def main():
         raise SystemExit, 1
     filename = args[0]
 
-    dc = draw_fft(filename, options)
+    dc = draw_iq(filename, options)
 
 if __name__ == "__main__":
     try:
index 669d7b573a4e0b6cfe5e0b0a8c98dadf41c26171..0e3dbecd944f583d126364d76f215f244063d57d 100755 (executable)
 # Boston, MA 02110-1301, USA.
 # 
 
-try:
-    import matplotlib
-    matplotlib.use('TkAgg')
-    matplotlib.interactive(True)
-except ImportError:
-    print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)"
-    raise SystemExit, 1
-
 try:
     import scipy
     from scipy import fftpack
@@ -187,8 +179,9 @@ class gr_plot_psd:
         draw()
         
     def zoom(self, event):
-        newxlim = self.sp_iq.get_xlim()
-        if(newxlim.all() != self.xlim.all()):
+        newxlim = scipy.array(self.sp_iq.get_xlim())
+        curxlim = scipy.array(self.xlim)
+        if(newxlim.all() != curxlim.all()):
             self.xlim = newxlim
             xmin = max(0, int(ceil(self.sample_rate*(self.xlim[0] - self.position))))
             xmax = min(int(ceil(self.sample_rate*(self.xlim[1] - self.position))), len(self.iq))
diff --git a/gr-utils/src/python/gr_plot_qt.py b/gr-utils/src/python/gr_plot_qt.py
new file mode 100755 (executable)
index 0000000..f3dc472
--- /dev/null
@@ -0,0 +1,729 @@
+#!/usr/bin/env python
+
+try:
+    import scipy
+    from scipy import fftpack
+except ImportError:
+    print "Please install SciPy to run this script (http://www.scipy.org/)"
+    raise SystemExit, 1
+
+try:
+    from matplotlib import mlab
+except ImportError:
+    print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net)"
+    raise SystemExit, 1
+
+try:
+    from PyQt4 import Qt, QtCore, QtGui
+except ImportError:
+    print "Please install PyQt4 to run this script (http://www.riverbankcomputing.co.uk/software/pyqt/download)"
+    raise SystemExit, 1
+
+try:
+    import PyQt4.Qwt5 as Qwt
+except ImportError:
+    print "Please install PyQwt5 to run this script (http://pyqwt.sourceforge.net/)"
+    raise SystemExit, 1
+
+try:
+    # FIXME: reenable this before committing
+    #from gnuradio.pyqt_plot import Ui_MainWindow
+    from pyqt_plot import Ui_MainWindow
+except ImportError:
+    print "Could not import from pyqt_plot. Please build with \"pyuic4 pyqt_plot.ui -o pyqt_plot.py\""
+    raise SystemExit, 1
+
+import sys, os
+from optparse import OptionParser
+from gnuradio import eng_notation
+
+
+class SpectrogramData(Qwt.QwtRasterData):
+
+    def __init__(self, f, t):
+        Qwt.QwtArrayData.__init__(self, Qt.QRectF(0, 0, 0, 0))
+        self.sp = scipy.array([[0], [0]])
+
+    def set_data(self, xfreq, ytime, data):
+        self.sp = data
+        self.freq = xfreq
+        self.time = ytime
+        boundingBox = Qt.QRectF(self.freq.min(), self.time.min(),
+                                self.freq.max() - self.freq.min(),
+                                self.time.max() - self.time.min())
+        self.setBoundingRect(boundingBox)
+
+    def rasterHint(self, rect):
+        return Qt.QSize(self.sp.shape[0], self.sp.shape[1])
+        
+    def copy(self):
+        return self
+
+    def range(self):
+        
+        return Qwt.QwtDoubleInterval(self.sp.min(), self.sp.max())
+
+    def value(self, x, y):
+        try:
+            f = int(self.freq.searchsorted(x))
+            t = int(self.time.searchsorted(y))
+            return self.sp[f][t-1]
+        except AttributeError: # if no file loaded yet
+            return 0
+
+
+class gr_plot_qt(QtGui.QMainWindow):
+    def __init__(self, qapp, filename, options, parent=None):
+        QtGui.QWidget.__init__(self, parent)
+        self.gui = Ui_MainWindow()
+        self.gui.setupUi(self)
+                       
+        self.filename = None
+        self.block_length = options.block_length
+        self.start = options.start
+        self.sample_rate = options.sample_rate
+        self.psdfftsize = options.psd_size
+        self.specfftsize = options.spec_size
+        self.winfunc = scipy.blackman
+        self.sizeof_data = 8
+        self.datatype = scipy.complex64
+        self.pen_width = 1
+        self.iq = list()
+        self.time = list()
+
+        # Set up basic plot attributes
+        self.gui.timePlot.setAxisTitle(self.gui.timePlot.xBottom, "Time (sec)")
+        self.gui.timePlot.setAxisTitle(self.gui.timePlot.yLeft, "Amplitude (V)")
+        self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.xBottom, "Frequency (Hz)")
+        self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.yLeft, "Magnitude (dB)")
+        self.gui.specPlot.setAxisTitle(self.gui.specPlot.xBottom, "Frequency (Hz)")
+        self.gui.specPlot.setAxisTitle(self.gui.specPlot.yLeft, "Time (sec)")
+
+        # Set up FFT size combo box
+        self.fftsizes = ["128", "256", "512", "1024", "2048",
+                         "4096", "8192", "16384", "32768"]
+        self.gui.psdFFTComboBox.addItems(self.fftsizes)
+        self.gui.specFFTComboBox.addItems(self.fftsizes)
+        pos = self.gui.psdFFTComboBox.findText(Qt.QString("%1").arg(self.psdfftsize))
+        self.gui.psdFFTComboBox.setCurrentIndex(pos)
+        pos = self.gui.specFFTComboBox.findText(Qt.QString("%1").arg(self.specfftsize))
+        self.gui.specFFTComboBox.setCurrentIndex(pos)
+
+        self.connect(self.gui.psdFFTComboBox,
+                     Qt.SIGNAL("activated (const QString&)"),
+                     self.psdFFTComboBoxEdit)
+        self.connect(self.gui.specFFTComboBox,
+                     Qt.SIGNAL("activated (const QString&)"),
+                     self.specFFTComboBoxEdit)
+
+        # Set up color scheme box
+        self.color_modes = {"Black on White" : self.color_black_on_white,
+                            "White on Black" : self.color_white_on_black,
+                            "Blue on Black"  : self.color_blue_on_black,
+                            "Green on Black" : self.color_green_on_black}
+        self.gui.colorComboBox.addItems(self.color_modes.keys())
+        pos = self.gui.colorComboBox.findText("Blue on Black")
+        self.gui.colorComboBox.setCurrentIndex(pos)
+        self.connect(self.gui.colorComboBox,
+                     Qt.SIGNAL("activated (const QString&)"),
+                     self.colorComboBoxEdit)
+        
+        
+        # Set up line style combo box
+        self.line_styles = {"None" : Qwt.QwtSymbol.NoSymbol,
+                            "Circle" : Qwt.QwtSymbol.Ellipse,
+                            "Diamond"  : Qwt.QwtSymbol.Rect,
+                            "Triangle" : Qwt.QwtSymbol.Triangle}
+        self.gui.lineStyleComboBox.addItems(self.line_styles.keys())
+        pos = self.gui.lineStyleComboBox.findText("None")
+        self.gui.lineStyleComboBox.setCurrentIndex(pos)
+        self.connect(self.gui.lineStyleComboBox,
+                     Qt.SIGNAL("activated (const QString&)"),
+                     self.lineStyleComboBoxEdit)
+
+        # Create zoom functionality for the plots
+        self.timeZoomer = Qwt.QwtPlotZoomer(self.gui.timePlot.xBottom,
+                                            self.gui.timePlot.yLeft,
+                                            Qwt.QwtPicker.PointSelection,
+                                            Qwt.QwtPicker.AlwaysOn,
+                                            self.gui.timePlot.canvas())
+
+        self.freqZoomer = Qwt.QwtPlotZoomer(self.gui.freqPlot.xBottom,
+                                            self.gui.freqPlot.yLeft,
+                                            Qwt.QwtPicker.PointSelection,
+                                            Qwt.QwtPicker.AlwaysOn,
+                                            self.gui.freqPlot.canvas())
+
+        self.specZoomer = Qwt.QwtPlotZoomer(self.gui.specPlot.xBottom,
+                                            self.gui.specPlot.yLeft,
+                                            Qwt.QwtPicker.PointSelection,
+                                            Qwt.QwtPicker.AlwaysOn,
+                                            self.gui.specPlot.canvas())
+
+        # Set up action when tab is changed
+        self.connect(self.gui.tabGroup,
+                     Qt.SIGNAL("currentChanged (int)"),
+                     self.tabChanged)
+
+        # Add a legend to the Time plot
+        legend_real = Qwt.QwtLegend()
+        self.gui.timePlot.insertLegend(legend_real)
+
+        # Set up slider
+        self.gui.plotHBar.setSingleStep(1)
+        self.gui.plotHBar.setPageStep(self.block_length)
+        self.gui.plotHBar.setMinimum(0)
+        self.gui.plotHBar.setMaximum(self.block_length)
+        self.connect(self.gui.plotHBar,
+                     Qt.SIGNAL("valueChanged(int)"),
+                     self.sliderMoved)
+
+        # Connect Open action to Open Dialog box
+        self.connect(self.gui.action_open,
+                     Qt.SIGNAL("activated()"),
+                     self.open_file)
+
+        # Connect Reload action to reload the file
+        self.connect(self.gui.action_reload,
+                     Qt.SIGNAL("activated()"),
+                     self.reload_file)
+        self.gui.action_reload.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+R",
+                                                                        None, QtGui.QApplication.UnicodeUTF8))
+
+        # Set up file position boxes to update current figure
+        self.connect(self.gui.filePosStartLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_position_changed)
+        self.connect(self.gui.filePosStopLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_position_changed)
+        self.connect(self.gui.filePosLengthLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_length_changed)
+
+        self.connect(self.gui.fileTimeStartLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_time_changed)
+        self.connect(self.gui.fileTimeStopLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_time_changed)
+        self.connect(self.gui.fileTimeLengthLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.file_time_length_changed)
+
+        stylestr = str(self.gui.lineStyleComboBox.currentText().toAscii())
+        style = self.line_styles[stylestr]
+
+        self.rcurve = Qwt.QwtPlotCurve("Real")
+        self.icurve = Qwt.QwtPlotCurve("Imaginary")
+        self.rsym = Qwt.QwtSymbol()
+        self.rsym.setStyle(style)
+        self.rsym.setSize(10)
+        self.isym = Qwt.QwtSymbol()
+        self.isym.setStyle(style)
+        self.isym.setSize(10)
+        self.rcurve.setSymbol(self.rsym)
+        self.icurve.setSymbol(self.isym)
+
+
+        self.icurve.attach(self.gui.timePlot)
+        self.rcurve.attach(self.gui.timePlot)
+
+        self.psdcurve = Qwt.QwtPlotCurve("PSD")
+        self.psdcurve.attach(self.gui.freqPlot)
+
+        # Set up specTab plot as a spectrogram
+        self.specdata = SpectrogramData(range(0, 10), range(0, 10))
+
+        colorMap = Qwt.QwtLinearColorMap(Qt.Qt.darkCyan, Qt.Qt.red)
+        colorMap.addColorStop(0.1, Qt.Qt.cyan)
+        colorMap.addColorStop(0.6, Qt.Qt.green)
+        colorMap.addColorStop(0.95, Qt.Qt.yellow)
+
+        self.spec = Qwt.QwtPlotSpectrogram()
+        self.spec.setColorMap(colorMap)
+        self.spec.attach(self.gui.specPlot)
+        self.spec.setDisplayMode(Qwt.QwtPlotSpectrogram.ImageMode, True)
+        self.spec.setData(self.specdata)
+
+        self.rightAxis = self.gui.specPlot.axisWidget(Qwt.QwtPlot.yRight)
+        self.rightAxis.setTitle("Magnitude (dBm)")
+        self.rightAxis.setColorBarEnabled(True)
+        self.rightAxis.setColorMap(self.spec.data().range(),
+                                   self.spec.colorMap())
+        self.gui.specPlot.enableAxis(Qwt.QwtPlot.yRight)
+
+        # Set up initial color scheme
+        self.color_modes["Blue on Black"]()
+
+        # When line width spin box changes, update the pen size
+        self.connect(self.gui.lineWidthSpinBox,
+                     Qt.SIGNAL("valueChanged(int)"),
+                     self.change_pen_width)
+        self.gui.lineWidthSpinBox.setRange(1, 10)
+
+        # When style size spin box changes, update the pen size
+        self.connect(self.gui.styleSizeSpinBox,
+                     Qt.SIGNAL("valueChanged(int)"),
+                     self.change_style_size)
+        self.gui.styleSizeSpinBox.setRange(1, 20)
+        self.gui.styleSizeSpinBox.setValue(5)
+
+
+        # Connect a signal for when the sample rate changes
+        self.set_sample_rate(self.sample_rate)
+        self.connect(self.gui.sampleRateLineEdit,
+                     Qt.SIGNAL("editingFinished()"),
+                     self.sample_rate_changed)
+
+        if(filename is not None):
+            self.initialize(filename)
+
+        self.show()
+
+    def open_file(self):
+        filename = Qt.QFileDialog.getOpenFileName(self, "Open", ".")
+        if(filename != ""):
+            #print filename
+            self.initialize(filename)
+
+    def reload_file(self):
+        if(self.filename):
+            self.initialize(self.filename)
+        
+    def initialize(self, filename):
+        self.filename = filename
+        self.hfile = open(filename, "r")
+
+        self.setWindowTitle(("GNU Radio File Plot Utility: %s" % filename))
+
+        self.gui.filePosStartLineEdit.setText("0")
+        self.gui.filePosStopLineEdit.setText("0")
+        self.gui.fileTimeStartLineEdit.setText("0")
+        self.gui.fileTimeStopLineEdit.setText("0")
+
+        self.cur_start = 0
+        self.cur_stop = self.block_length
+
+        self.init_data_input()
+        self.get_data(self.cur_start, self.cur_stop)
+        self.get_psd()
+        self.get_specgram() 
+        self.gui.plotHBar.setSliderPosition(0)
+        self.gui.plotHBar.setMaximum(self.signal_size-self.block_length)
+
+
+        self.update_time_curves()
+        self.update_psd_curves()
+        self.update_specgram_curves()
+
+    def init_data_input(self):
+        self.hfile.seek(0, os.SEEK_END)
+        self.signal_size = self.hfile.tell()/self.sizeof_data
+        #print "Sizeof File: ", self.signal_size
+        self.hfile.seek(0, os.SEEK_SET)
+        
+    def get_data(self, start, end):
+        if(end > start):
+            self.hfile.seek(start*self.sizeof_data, os.SEEK_SET)
+            self.position = start
+            try:
+                iq = scipy.fromfile(self.hfile, dtype=self.datatype,
+                                    count=end-start)
+
+                if(len(iq) < (end-start)):
+                    end = start + len(iq)
+                    self.gui.filePosLengthLineEdit.setText(Qt.QString("%1").arg(len(iq)))
+                    self.file_length_changed()
+
+                tstep = 1.0 / self.sample_rate
+                self.iq = iq
+                self.time = [tstep*(self.position + i) for i in xrange(len(self.iq))]
+
+                self.set_file_pos_box(start, end)
+            except MemoryError:
+                pass
+        else:
+            # Do we want to do anything about this?
+            pass
+
+    def get_psd(self):
+        winpoints = self.winfunc(self.psdfftsize)
+        iq_psd, freq = mlab.psd(self.iq, Fs=self.sample_rate,
+                                NFFT=self.psdfftsize,
+                                noverlap=self.psdfftsize/4.0,
+                                window=winpoints,
+                                scale_by_freq=False)
+
+        self.iq_psd = 10.0*scipy.log10(abs(fftpack.fftshift(iq_psd)))
+        self.freq = freq - self.sample_rate/2.0
+
+    def get_specgram(self):
+        winpoints = self.winfunc(self.specfftsize)
+        iq_spec, f, t = mlab.specgram(self.iq, Fs=self.sample_rate,
+                                      NFFT=self.specfftsize,
+                                      noverlap=self.specfftsize/4.0,
+                                      window=winpoints,
+                                      scale_by_freq=False)
+        
+        self.iq_spec = 10.0*scipy.log10(abs(iq_spec))
+        self.spec_f = f
+        self.spec_t = t
+
+    def psdFFTComboBoxEdit(self, fftSize):
+        self.psdfftsize = fftSize.toInt()[0]
+        self.get_psd()
+        self.update_psd_curves()
+
+    def specFFTComboBoxEdit(self, fftSize):
+        self.specfftsize = fftSize.toInt()[0]
+        self.get_specgram()
+        self.update_specgram_curves()
+        
+    def colorComboBoxEdit(self, colorSelection):
+        colorstr = str(colorSelection.toAscii())
+        color_func = self.color_modes[colorstr]
+        color_func()
+
+    def lineStyleComboBoxEdit(self, styleSelection):
+        stylestr = str(styleSelection.toAscii())
+        self.rsym.setStyle(self.line_styles[stylestr])
+        self.isym.setStyle(self.line_styles[stylestr])
+        self.rcurve.setSymbol(self.rsym)
+        self.icurve.setSymbol(self.isym)
+        self.gui.timePlot.replot()
+
+    def sliderMoved(self, value):
+        pos_start = value
+        pos_end = value + self.gui.plotHBar.pageStep()
+
+        self.get_data(pos_start, pos_end)
+        self.get_psd()
+        self.get_specgram()
+        self.update_time_curves()
+        self.update_psd_curves()
+        self.update_specgram_curves()
+
+    def set_sample_rate(self, sr):
+        self.sample_rate = sr
+        srstr = eng_notation.num_to_str(self.sample_rate)
+        self.gui.sampleRateLineEdit.setText(Qt.QString("%1").arg(srstr))
+
+    def sample_rate_changed(self):
+        srstr = self.gui.sampleRateLineEdit.text().toAscii()
+        self.sample_rate = eng_notation.str_to_num(srstr)
+        self.set_file_pos_box(self.cur_start, self.cur_stop)
+        self.get_data(self.cur_start, self.cur_stop)
+        self.get_psd()
+        self.get_specgram()
+        self.update_time_curves()
+        self.update_psd_curves()
+        self.update_specgram_curves()
+
+    def set_file_pos_box(self, start, end):
+        tstart = start / self.sample_rate
+        tend = end / self.sample_rate
+
+        self.gui.filePosStartLineEdit.setText(Qt.QString("%1").arg(start))
+        self.gui.filePosStopLineEdit.setText(Qt.QString("%1").arg(end))
+        self.gui.filePosLengthLineEdit.setText(Qt.QString("%1").arg(end-start))
+
+        self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
+        self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
+        self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tend-tstart))
+
+    def file_position_changed(self):
+        start  = self.gui.filePosStartLineEdit.text().toInt()
+        end    = self.gui.filePosStopLineEdit.text().toInt()
+        if((start[1] == True) and (end[1] == True)):
+            self.cur_start = start[0]
+            self.cur_stop = end[0]
+
+            tstart = self.cur_start / self.sample_rate
+            tend = self.cur_stop / self.sample_rate
+            self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
+            self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
+            
+            self.get_data(self.cur_start, self.cur_stop)
+
+            self.update_time_curves()
+            self.update_psd_curves()
+            self.update_specgram_curves()
+
+        # If there's a non-digit character, reset box
+        else:
+            try:
+                self.set_file_pos_box(self.cur_start, self.cur_stop)
+            except AttributeError:
+                pass
+            
+
+    def file_time_changed(self):
+        tstart = self.gui.fileTimeStartLineEdit.text().toDouble()
+        tstop  = self.gui.fileTimeStopLineEdit.text().toDouble()
+        if((tstart[1] == True) and (tstop[1] == True)):
+            self.cur_start = int(tstart[0] * self.sample_rate)
+            self.cur_stop = int(tstop[0] * self.sample_rate)
+            self.get_data(self.cur_start, self.cur_stop)
+
+            self.gui.filePosStartLineEdit.setText(Qt.QString("%1").arg(self.cur_start))
+            self.gui.filePosStopLineEdit.setText(Qt.QString("%1").arg(self.cur_stop))
+
+            self.update_time_curves()
+            self.update_psd_curves()
+            self.update_specgram_curves()
+        # If there's a non-digit character, reset box
+        else:
+            self.set_file_pos_box(self.cur_start, self.cur_stop)
+
+    def file_length_changed(self):
+        start = self.gui.filePosStartLineEdit.text().toInt()
+        length = self.gui.filePosLengthLineEdit.text().toInt()
+
+        if((start[1] == True) and (length[1] == True)):
+            self.cur_start = start[0]
+            self.block_length = length[0]
+            self.cur_stop = self.cur_start + self.block_length
+
+            tstart = self.cur_start / self.sample_rate
+            tend = self.cur_stop / self.sample_rate
+            tlen = self.block_length / self.sample_rate
+            self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
+            self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
+            self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tlen))
+
+            self.gui.plotHBar.setPageStep(self.block_length)
+
+            self.get_data(self.cur_start, self.cur_stop)
+            self.get_psd()
+            self.get_specgram()
+
+            self.update_time_curves()
+            self.update_psd_curves()
+            self.update_specgram_curves()
+        # If there's a non-digit character, reset box
+        else:
+            self.set_file_pos_box(self.cur_start, self.cur_stop)
+
+    def file_time_length_changed(self):
+        tstart = self.gui.fileTimeStartLineEdit.text().toDouble()
+        tlength = self.gui.fileTimeLengthLineEdit.text().toDouble()
+        if((tstart[1] == True) and (tlength[1] == True)):
+            self.cur_start = int(tstart[0] * self.sample_rate)
+            self.block_length = int(tlength[0] * self.sample_rate)
+            self.cur_stop = self.cur_start + self.block_length
+
+            tstart = self.cur_start / self.sample_rate
+            tend = self.cur_stop / self.sample_rate
+            tlen = self.block_length / self.sample_rate
+            self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
+            self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
+            self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tlen))
+
+            self.get_data(self.cur_start, self.cur_stop)
+            self.get_psd()
+            self.get_specgram()
+
+            self.update_time_curves()
+            self.update_psd_curves()
+            self.update_specgram_curves()
+        # If there's a non-digit character, reset box
+        else:
+            self.set_file_pos_box(self.cur_start, self.cur_stop)
+
+
+    def update_time_curves(self):
+        self.icurve.setData(self.time, self.iq.imag)
+        self.rcurve.setData(self.time, self.iq.real)
+
+        # Reset the x-axis to the new time scale
+        iqmax = 1.5 * max(max(self.iq.real), max(self.iq.imag))
+        iqmin = 1.5 * min(min(self.iq.real), min(self.iq.imag))
+        self.gui.timePlot.setAxisScale(self.gui.timePlot.xBottom,
+                                       min(self.time),
+                                       max(self.time))
+        self.gui.timePlot.setAxisScale(self.gui.timePlot.yLeft,
+                                       iqmin,
+                                       iqmax)
+
+        # Set the zoomer base to unzoom to the new axis
+        self.timeZoomer.setZoomBase()
+    
+        self.gui.timePlot.replot()
+        
+    def update_psd_curves(self):
+        self.psdcurve.setData(self.freq, self.iq_psd)
+
+        self.gui.freqPlot.setAxisScale(self.gui.freqPlot.xBottom,
+                                       min(self.freq),
+                                       max(self.freq))
+                                       
+        # Set the zoomer base to unzoom to the new axis
+        self.freqZoomer.setZoomBase()
+
+        self.gui.freqPlot.replot()
+
+    def update_specgram_curves(self):
+        # We don't have to reset the data for the speccurve here
+        # since this is taken care of in the SpectrogramData class
+        self.specdata.set_data(self.spec_f, self.spec_t, self.iq_spec)
+
+        # Set the color map based on the new data
+        self.rightAxis.setColorMap(self.spec.data().range(),
+                                   self.spec.colorMap())
+
+        # Set the new axis base; include right axis for the intenisty color bar
+        self.gui.specPlot.setAxisScale(self.gui.specPlot.xBottom,
+                                       min(self.spec_f),
+                                       max(self.spec_f))
+        self.gui.specPlot.setAxisScale(self.gui.specPlot.yLeft,
+                                       min(self.spec_t),
+                                       max(self.spec_t))
+        self.gui.specPlot.setAxisScale(self.gui.specPlot.yRight, 
+                                       self.iq_spec.min(),
+                                       self.iq_spec.max())
+        # Set the zoomer base to unzoom to the new axis
+        self.specZoomer.setZoomBase()
+
+        self.gui.specPlot.replot()
+
+    def tabChanged(self, index):
+        self.gui.timePlot.replot()
+        self.gui.freqPlot.replot()
+        self.gui.specPlot.replot()
+
+    def change_pen_width(self, width):
+        self.pen_width = width
+        colormode = str(self.gui.colorComboBox.currentText().toAscii())
+        color_func = self.color_modes[colormode]()
+
+    def change_style_size(self, size):
+        self.rsym.setSize(size)
+        self.isym.setSize(size)
+        self.rcurve.setSymbol(self.rsym)
+        self.icurve.setSymbol(self.isym)
+        self.gui.timePlot.replot()
+    
+    def color_black_on_white(self):
+        blue = QtGui.qRgb(0x00, 0x00, 0xFF)
+        red = QtGui.qRgb(0xFF, 0x00, 0x00)
+
+        blackPen = Qt.QPen(Qt.QBrush(Qt.QColor("black")), self.pen_width)
+        bluePen = Qt.QPen(Qt.QBrush(Qt.QColor(blue)), self.pen_width)
+        redPen = Qt.QPen(Qt.QBrush(Qt.QColor(red)), self.pen_width)
+
+        self.gui.timePlot.setCanvasBackground(Qt.QColor("white"))
+        self.gui.freqPlot.setCanvasBackground(Qt.QColor("white"))
+        self.timeZoomer.setTrackerPen(blackPen)
+        self.timeZoomer.setRubberBandPen(blackPen)
+        self.freqZoomer.setTrackerPen(blackPen)
+        self.freqZoomer.setRubberBandPen(blackPen)
+        self.psdcurve.setPen(bluePen)
+        self.rcurve.setPen(bluePen)
+        self.icurve.setPen(redPen)
+
+        self.rsym.setPen(bluePen)
+        self.isym.setPen(redPen)
+
+        self.gui.timePlot.replot()
+        self.gui.freqPlot.replot()
+
+    def color_white_on_black(self):
+        white = QtGui.qRgb(0xFF, 0xFF, 0xFF)
+        red = QtGui.qRgb(0xFF, 0x00, 0x00)
+
+        whiteBrush = Qt.QBrush(Qt.QColor("white"))
+        whiteBrush = Qt.QBrush(Qt.QColor(white))
+        redBrush = Qt.QBrush(Qt.QColor(red))
+        
+        self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
+        self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
+        self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.psdcurve.setPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.rcurve.setPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.icurve.setPen(Qt.QPen(redBrush, self.pen_width))
+
+        self.gui.timePlot.replot()
+        self.gui.freqPlot.replot()
+
+
+    def color_green_on_black(self):
+        green = QtGui.qRgb(0x00, 0xFF, 0x00)
+        red = QtGui.qRgb(0xFF, 0x00, 0x50)
+
+        whiteBrush = Qt.QBrush(Qt.QColor("white"))
+        greenBrush = Qt.QBrush(Qt.QColor(green))
+        redBrush = Qt.QBrush(Qt.QColor(red))
+        
+        self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
+        self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
+        self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.psdcurve.setPen(Qt.QPen(greenBrush, self.pen_width))
+        self.rcurve.setPen(Qt.QPen(greenBrush, self.pen_width))
+        self.icurve.setPen(Qt.QPen(redBrush, self.pen_width))
+
+        self.gui.timePlot.replot()
+        self.gui.freqPlot.replot()
+
+    def color_blue_on_black(self):
+        blue = QtGui.qRgb(0x00, 0x00, 0xFF)
+        red = QtGui.qRgb(0xFF, 0x00, 0x00)
+
+        whiteBrush = Qt.QBrush(Qt.QColor("white"))
+        blueBrush = Qt.QBrush(Qt.QColor(blue))
+        redBrush = Qt.QBrush(Qt.QColor(red))
+        
+        self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
+        self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
+        self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, self.pen_width))
+        self.psdcurve.setPen(Qt.QPen(blueBrush, self.pen_width))
+        self.rcurve.setPen(Qt.QPen(blueBrush, self.pen_width))
+        self.icurve.setPen(Qt.QPen(redBrush, self.pen_width))
+
+        self.gui.timePlot.replot()
+        self.gui.freqPlot.replot()
+
+def setup_options():
+    usage="%prog: [options] (input_filename)"
+    description = ""
+
+    parser = OptionParser(conflict_handler="resolve", usage=usage, description=description)
+    parser.add_option("-B", "--block-length", type="int", default=8192,
+                      help="Specify the block size [default=%default]")
+    parser.add_option("-s", "--start", type="int", default=0,
+                      help="Specify where to start in the file [default=%default]")
+    parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+                      help="Set the sampler rate of the data [default=%default]")
+    parser.add_option("", "--psd-size", type="int", default=2048,
+                      help="Set the size of the PSD FFT [default=%default]")
+    parser.add_option("", "--spec-size", type="int", default=2048,
+                      help="Set the size of the spectrogram FFT [default=%default]")
+
+    return parser
+
+def main(args):
+    parser = setup_options()
+    (options, args) = parser.parse_args ()
+
+    if(len(args) == 1):
+        filename = args[0]
+    else:
+        filename = None
+
+    app = Qt.QApplication(args)
+    gplt = gr_plot_qt(app, filename, options)
+    app.exec_()
+
+if __name__ == '__main__':
+    main(sys.argv)
+
index 7c79e17143d6d2b5be8bbbf81d37499ca2c1bc1f..08cdd60306bfb0b20e69d24431fc1b9659212850 100644 (file)
@@ -33,9 +33,6 @@ except ImportError:
 
 from optparse import OptionParser
 
-matplotlib.interactive(True)
-matplotlib.use('TkAgg')
-
 class plot_data:
     def __init__(self, datatype, filenames, options):
         self.hfile = list()
diff --git a/gr-utils/src/python/pyqt_filter.py b/gr-utils/src/python/pyqt_filter.py
new file mode 100644 (file)
index 0000000..12ad183
--- /dev/null
@@ -0,0 +1,426 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'pyqt_filter.ui'
+#
+# Created: Tue Aug 25 11:13:57 2009
+#      by: PyQt4 UI code generator 4.4.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.resize(1124, 696)
+        self.centralwidget = QtGui.QWidget(MainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
+        self.gridLayout.setObjectName("gridLayout")
+        self.filterFrame = QtGui.QFrame(self.centralwidget)
+        self.filterFrame.setMinimumSize(QtCore.QSize(300, 0))
+        self.filterFrame.setMaximumSize(QtCore.QSize(300, 16777215))
+        self.filterFrame.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.filterFrame.setFrameShadow(QtGui.QFrame.Raised)
+        self.filterFrame.setObjectName("filterFrame")
+        self.verticalLayout = QtGui.QVBoxLayout(self.filterFrame)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.filterTypeComboBox = QtGui.QComboBox(self.filterFrame)
+        self.filterTypeComboBox.setObjectName("filterTypeComboBox")
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.filterTypeComboBox.addItem(QtCore.QString())
+        self.verticalLayout.addWidget(self.filterTypeComboBox)
+        self.filterDesignTypeComboBox = QtGui.QComboBox(self.filterFrame)
+        self.filterDesignTypeComboBox.setObjectName("filterDesignTypeComboBox")
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.filterDesignTypeComboBox.addItem(QtCore.QString())
+        self.verticalLayout.addWidget(self.filterDesignTypeComboBox)
+        self.globalParamsLayout = QtGui.QFormLayout()
+        self.globalParamsLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.globalParamsLayout.setObjectName("globalParamsLayout")
+        self.sampleRateLabel = QtGui.QLabel(self.filterFrame)
+        self.sampleRateLabel.setMaximumSize(QtCore.QSize(16777215, 30))
+        self.sampleRateLabel.setObjectName("sampleRateLabel")
+        self.globalParamsLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel)
+        self.sampleRateEdit = QtGui.QLineEdit(self.filterFrame)
+        self.sampleRateEdit.setMaximumSize(QtCore.QSize(16777215, 30))
+        self.sampleRateEdit.setObjectName("sampleRateEdit")
+        self.globalParamsLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit)
+        self.filterGainLabel = QtGui.QLabel(self.filterFrame)
+        self.filterGainLabel.setObjectName("filterGainLabel")
+        self.globalParamsLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.filterGainLabel)
+        self.filterGainEdit = QtGui.QLineEdit(self.filterFrame)
+        self.filterGainEdit.setObjectName("filterGainEdit")
+        self.globalParamsLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.filterGainEdit)
+        self.verticalLayout.addLayout(self.globalParamsLayout)
+        self.filterTypeWidget = QtGui.QStackedWidget(self.filterFrame)
+        self.filterTypeWidget.setObjectName("filterTypeWidget")
+        self.firlpfPage = QtGui.QWidget()
+        self.firlpfPage.setObjectName("firlpfPage")
+        self.formLayout = QtGui.QFormLayout(self.firlpfPage)
+        self.formLayout.setObjectName("formLayout")
+        self.endofLpfPassBandLabel = QtGui.QLabel(self.firlpfPage)
+        self.endofLpfPassBandLabel.setObjectName("endofLpfPassBandLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.endofLpfPassBandLabel)
+        self.endofLpfPassBandEdit = QtGui.QLineEdit(self.firlpfPage)
+        self.endofLpfPassBandEdit.setObjectName("endofLpfPassBandEdit")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.endofLpfPassBandEdit)
+        self.startofLpfStopBandLabel = QtGui.QLabel(self.firlpfPage)
+        self.startofLpfStopBandLabel.setObjectName("startofLpfStopBandLabel")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.startofLpfStopBandLabel)
+        self.startofLpfStopBandEdit = QtGui.QLineEdit(self.firlpfPage)
+        self.startofLpfStopBandEdit.setObjectName("startofLpfStopBandEdit")
+        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.startofLpfStopBandEdit)
+        self.lpfStopBandAttenLabel = QtGui.QLabel(self.firlpfPage)
+        self.lpfStopBandAttenLabel.setObjectName("lpfStopBandAttenLabel")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.lpfStopBandAttenLabel)
+        self.lpfStopBandAttenEdit = QtGui.QLineEdit(self.firlpfPage)
+        self.lpfStopBandAttenEdit.setObjectName("lpfStopBandAttenEdit")
+        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.lpfStopBandAttenEdit)
+        self.lpfPassBandRippleEdit = QtGui.QLineEdit(self.firlpfPage)
+        self.lpfPassBandRippleEdit.setObjectName("lpfPassBandRippleEdit")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.lpfPassBandRippleEdit)
+        self.lpfPassBandRippleLabel = QtGui.QLabel(self.firlpfPage)
+        self.lpfPassBandRippleLabel.setObjectName("lpfPassBandRippleLabel")
+        self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.lpfPassBandRippleLabel)
+        self.filterTypeWidget.addWidget(self.firlpfPage)
+        self.firbpfPage = QtGui.QWidget()
+        self.firbpfPage.setObjectName("firbpfPage")
+        self.formLayout_2 = QtGui.QFormLayout(self.firbpfPage)
+        self.formLayout_2.setObjectName("formLayout_2")
+        self.startofBpfPassBandLabel = QtGui.QLabel(self.firbpfPage)
+        self.startofBpfPassBandLabel.setObjectName("startofBpfPassBandLabel")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.startofBpfPassBandLabel)
+        self.startofBpfPassBandEdit = QtGui.QLineEdit(self.firbpfPage)
+        self.startofBpfPassBandEdit.setObjectName("startofBpfPassBandEdit")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.startofBpfPassBandEdit)
+        self.endofBpfPassBandLabel = QtGui.QLabel(self.firbpfPage)
+        self.endofBpfPassBandLabel.setObjectName("endofBpfPassBandLabel")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.endofBpfPassBandLabel)
+        self.endofBpfPassBandEdit = QtGui.QLineEdit(self.firbpfPage)
+        self.endofBpfPassBandEdit.setObjectName("endofBpfPassBandEdit")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.endofBpfPassBandEdit)
+        self.bpfStopBandAttenEdit = QtGui.QLineEdit(self.firbpfPage)
+        self.bpfStopBandAttenEdit.setObjectName("bpfStopBandAttenEdit")
+        self.formLayout_2.setWidget(3, QtGui.QFormLayout.FieldRole, self.bpfStopBandAttenEdit)
+        self.bpfStopBandAttenLabel = QtGui.QLabel(self.firbpfPage)
+        self.bpfStopBandAttenLabel.setObjectName("bpfStopBandAttenLabel")
+        self.formLayout_2.setWidget(3, QtGui.QFormLayout.LabelRole, self.bpfStopBandAttenLabel)
+        self.bpfTransitionLabel = QtGui.QLabel(self.firbpfPage)
+        self.bpfTransitionLabel.setObjectName("bpfTransitionLabel")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.bpfTransitionLabel)
+        self.bpfTransitionEdit = QtGui.QLineEdit(self.firbpfPage)
+        self.bpfTransitionEdit.setObjectName("bpfTransitionEdit")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.bpfTransitionEdit)
+        self.bpfPassBandRippleEdit = QtGui.QLineEdit(self.firbpfPage)
+        self.bpfPassBandRippleEdit.setObjectName("bpfPassBandRippleEdit")
+        self.formLayout_2.setWidget(4, QtGui.QFormLayout.FieldRole, self.bpfPassBandRippleEdit)
+        self.bpfPassBandRippleLabel = QtGui.QLabel(self.firbpfPage)
+        self.bpfPassBandRippleLabel.setObjectName("bpfPassBandRippleLabel")
+        self.formLayout_2.setWidget(4, QtGui.QFormLayout.LabelRole, self.bpfPassBandRippleLabel)
+        self.filterTypeWidget.addWidget(self.firbpfPage)
+        self.firbnfPage = QtGui.QWidget()
+        self.firbnfPage.setObjectName("firbnfPage")
+        self.formLayout_5 = QtGui.QFormLayout(self.firbnfPage)
+        self.formLayout_5.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_5.setObjectName("formLayout_5")
+        self.startofBnfStopBandLabel = QtGui.QLabel(self.firbnfPage)
+        self.startofBnfStopBandLabel.setObjectName("startofBnfStopBandLabel")
+        self.formLayout_5.setWidget(0, QtGui.QFormLayout.LabelRole, self.startofBnfStopBandLabel)
+        self.startofBnfStopBandEdit = QtGui.QLineEdit(self.firbnfPage)
+        self.startofBnfStopBandEdit.setObjectName("startofBnfStopBandEdit")
+        self.formLayout_5.setWidget(0, QtGui.QFormLayout.FieldRole, self.startofBnfStopBandEdit)
+        self.endofBnfStopBandLabel = QtGui.QLabel(self.firbnfPage)
+        self.endofBnfStopBandLabel.setObjectName("endofBnfStopBandLabel")
+        self.formLayout_5.setWidget(1, QtGui.QFormLayout.LabelRole, self.endofBnfStopBandLabel)
+        self.endofBnfStopBandEdit = QtGui.QLineEdit(self.firbnfPage)
+        self.endofBnfStopBandEdit.setObjectName("endofBnfStopBandEdit")
+        self.formLayout_5.setWidget(1, QtGui.QFormLayout.FieldRole, self.endofBnfStopBandEdit)
+        self.bnfTransitionLabel = QtGui.QLabel(self.firbnfPage)
+        self.bnfTransitionLabel.setObjectName("bnfTransitionLabel")
+        self.formLayout_5.setWidget(2, QtGui.QFormLayout.LabelRole, self.bnfTransitionLabel)
+        self.bnfTransitionEdit = QtGui.QLineEdit(self.firbnfPage)
+        self.bnfTransitionEdit.setObjectName("bnfTransitionEdit")
+        self.formLayout_5.setWidget(2, QtGui.QFormLayout.FieldRole, self.bnfTransitionEdit)
+        self.bnfStopBandAttenLabel = QtGui.QLabel(self.firbnfPage)
+        self.bnfStopBandAttenLabel.setObjectName("bnfStopBandAttenLabel")
+        self.formLayout_5.setWidget(3, QtGui.QFormLayout.LabelRole, self.bnfStopBandAttenLabel)
+        self.bnfStopBandAttenEdit = QtGui.QLineEdit(self.firbnfPage)
+        self.bnfStopBandAttenEdit.setObjectName("bnfStopBandAttenEdit")
+        self.formLayout_5.setWidget(3, QtGui.QFormLayout.FieldRole, self.bnfStopBandAttenEdit)
+        self.bnfPassBandRippleLabel = QtGui.QLabel(self.firbnfPage)
+        self.bnfPassBandRippleLabel.setObjectName("bnfPassBandRippleLabel")
+        self.formLayout_5.setWidget(4, QtGui.QFormLayout.LabelRole, self.bnfPassBandRippleLabel)
+        self.bnfPassBandRippleEdit = QtGui.QLineEdit(self.firbnfPage)
+        self.bnfPassBandRippleEdit.setObjectName("bnfPassBandRippleEdit")
+        self.formLayout_5.setWidget(4, QtGui.QFormLayout.FieldRole, self.bnfPassBandRippleEdit)
+        self.filterTypeWidget.addWidget(self.firbnfPage)
+        self.firhpfPage = QtGui.QWidget()
+        self.firhpfPage.setObjectName("firhpfPage")
+        self.formLayout_3 = QtGui.QFormLayout(self.firhpfPage)
+        self.formLayout_3.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_3.setObjectName("formLayout_3")
+        self.endofHpfStopBandLabel = QtGui.QLabel(self.firhpfPage)
+        self.endofHpfStopBandLabel.setObjectName("endofHpfStopBandLabel")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.endofHpfStopBandLabel)
+        self.endofHpfStopBandEdit = QtGui.QLineEdit(self.firhpfPage)
+        self.endofHpfStopBandEdit.setObjectName("endofHpfStopBandEdit")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.endofHpfStopBandEdit)
+        self.startofHpfPassBandLabel = QtGui.QLabel(self.firhpfPage)
+        self.startofHpfPassBandLabel.setObjectName("startofHpfPassBandLabel")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.startofHpfPassBandLabel)
+        self.startofHpfPassBandEdit = QtGui.QLineEdit(self.firhpfPage)
+        self.startofHpfPassBandEdit.setObjectName("startofHpfPassBandEdit")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.startofHpfPassBandEdit)
+        self.hpfStopBandAttenLabel = QtGui.QLabel(self.firhpfPage)
+        self.hpfStopBandAttenLabel.setObjectName("hpfStopBandAttenLabel")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.hpfStopBandAttenLabel)
+        self.hpfStopBandAttenEdit = QtGui.QLineEdit(self.firhpfPage)
+        self.hpfStopBandAttenEdit.setObjectName("hpfStopBandAttenEdit")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.hpfStopBandAttenEdit)
+        self.hpfPassBandRippleLabel = QtGui.QLabel(self.firhpfPage)
+        self.hpfPassBandRippleLabel.setObjectName("hpfPassBandRippleLabel")
+        self.formLayout_3.setWidget(3, QtGui.QFormLayout.LabelRole, self.hpfPassBandRippleLabel)
+        self.hpfPassBandRippleEdit = QtGui.QLineEdit(self.firhpfPage)
+        self.hpfPassBandRippleEdit.setObjectName("hpfPassBandRippleEdit")
+        self.formLayout_3.setWidget(3, QtGui.QFormLayout.FieldRole, self.hpfPassBandRippleEdit)
+        self.filterTypeWidget.addWidget(self.firhpfPage)
+        self.rrcPage = QtGui.QWidget()
+        self.rrcPage.setObjectName("rrcPage")
+        self.formLayout_6 = QtGui.QFormLayout(self.rrcPage)
+        self.formLayout_6.setObjectName("formLayout_6")
+        self.rrcSymbolRateLabel = QtGui.QLabel(self.rrcPage)
+        self.rrcSymbolRateLabel.setObjectName("rrcSymbolRateLabel")
+        self.formLayout_6.setWidget(0, QtGui.QFormLayout.LabelRole, self.rrcSymbolRateLabel)
+        self.rrcAlphaLabel = QtGui.QLabel(self.rrcPage)
+        self.rrcAlphaLabel.setObjectName("rrcAlphaLabel")
+        self.formLayout_6.setWidget(1, QtGui.QFormLayout.LabelRole, self.rrcAlphaLabel)
+        self.rrcNumTapsLabel = QtGui.QLabel(self.rrcPage)
+        self.rrcNumTapsLabel.setObjectName("rrcNumTapsLabel")
+        self.formLayout_6.setWidget(2, QtGui.QFormLayout.LabelRole, self.rrcNumTapsLabel)
+        self.rrcSymbolRateEdit = QtGui.QLineEdit(self.rrcPage)
+        self.rrcSymbolRateEdit.setObjectName("rrcSymbolRateEdit")
+        self.formLayout_6.setWidget(0, QtGui.QFormLayout.FieldRole, self.rrcSymbolRateEdit)
+        self.rrcAlphaEdit = QtGui.QLineEdit(self.rrcPage)
+        self.rrcAlphaEdit.setObjectName("rrcAlphaEdit")
+        self.formLayout_6.setWidget(1, QtGui.QFormLayout.FieldRole, self.rrcAlphaEdit)
+        self.rrcNumTapsEdit = QtGui.QLineEdit(self.rrcPage)
+        self.rrcNumTapsEdit.setObjectName("rrcNumTapsEdit")
+        self.formLayout_6.setWidget(2, QtGui.QFormLayout.FieldRole, self.rrcNumTapsEdit)
+        self.filterTypeWidget.addWidget(self.rrcPage)
+        self.gausPage = QtGui.QWidget()
+        self.gausPage.setObjectName("gausPage")
+        self.formLayout_7 = QtGui.QFormLayout(self.gausPage)
+        self.formLayout_7.setObjectName("formLayout_7")
+        self.gausSymbolRateLabel = QtGui.QLabel(self.gausPage)
+        self.gausSymbolRateLabel.setObjectName("gausSymbolRateLabel")
+        self.formLayout_7.setWidget(0, QtGui.QFormLayout.LabelRole, self.gausSymbolRateLabel)
+        self.gausSymbolRateEdit = QtGui.QLineEdit(self.gausPage)
+        self.gausSymbolRateEdit.setObjectName("gausSymbolRateEdit")
+        self.formLayout_7.setWidget(0, QtGui.QFormLayout.FieldRole, self.gausSymbolRateEdit)
+        self.gausBTLabel = QtGui.QLabel(self.gausPage)
+        self.gausBTLabel.setObjectName("gausBTLabel")
+        self.formLayout_7.setWidget(1, QtGui.QFormLayout.LabelRole, self.gausBTLabel)
+        self.gausBTEdit = QtGui.QLineEdit(self.gausPage)
+        self.gausBTEdit.setObjectName("gausBTEdit")
+        self.formLayout_7.setWidget(1, QtGui.QFormLayout.FieldRole, self.gausBTEdit)
+        self.gausNumTapsLabel = QtGui.QLabel(self.gausPage)
+        self.gausNumTapsLabel.setObjectName("gausNumTapsLabel")
+        self.formLayout_7.setWidget(2, QtGui.QFormLayout.LabelRole, self.gausNumTapsLabel)
+        self.gausNumTapsEdit = QtGui.QLineEdit(self.gausPage)
+        self.gausNumTapsEdit.setObjectName("gausNumTapsEdit")
+        self.formLayout_7.setWidget(2, QtGui.QFormLayout.FieldRole, self.gausNumTapsEdit)
+        self.filterTypeWidget.addWidget(self.gausPage)
+        self.verticalLayout.addWidget(self.filterTypeWidget)
+        self.filterPropsBox = QtGui.QGroupBox(self.filterFrame)
+        self.filterPropsBox.setObjectName("filterPropsBox")
+        self.formLayout_8 = QtGui.QFormLayout(self.filterPropsBox)
+        self.formLayout_8.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_8.setObjectName("formLayout_8")
+        self.nTapsLabel = QtGui.QLabel(self.filterPropsBox)
+        self.nTapsLabel.setMinimumSize(QtCore.QSize(150, 0))
+        self.nTapsLabel.setObjectName("nTapsLabel")
+        self.formLayout_8.setWidget(1, QtGui.QFormLayout.LabelRole, self.nTapsLabel)
+        self.nTapsEdit = QtGui.QLabel(self.filterPropsBox)
+        self.nTapsEdit.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.nTapsEdit.setFrameShape(QtGui.QFrame.Box)
+        self.nTapsEdit.setFrameShadow(QtGui.QFrame.Raised)
+        self.nTapsEdit.setObjectName("nTapsEdit")
+        self.formLayout_8.setWidget(1, QtGui.QFormLayout.FieldRole, self.nTapsEdit)
+        self.verticalLayout.addWidget(self.filterPropsBox)
+        self.sysParamsBox = QtGui.QGroupBox(self.filterFrame)
+        self.sysParamsBox.setObjectName("sysParamsBox")
+        self.formLayout_4 = QtGui.QFormLayout(self.sysParamsBox)
+        self.formLayout_4.setObjectName("formLayout_4")
+        self.nfftEdit = QtGui.QLineEdit(self.sysParamsBox)
+        self.nfftEdit.setObjectName("nfftEdit")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.nfftEdit)
+        self.nfftLabel = QtGui.QLabel(self.sysParamsBox)
+        self.nfftLabel.setMinimumSize(QtCore.QSize(150, 0))
+        self.nfftLabel.setObjectName("nfftLabel")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.LabelRole, self.nfftLabel)
+        self.verticalLayout.addWidget(self.sysParamsBox)
+        self.designButton = QtGui.QPushButton(self.filterFrame)
+        self.designButton.setMinimumSize(QtCore.QSize(0, 0))
+        self.designButton.setMaximumSize(QtCore.QSize(200, 16777215))
+        self.designButton.setAutoDefault(True)
+        self.designButton.setDefault(True)
+        self.designButton.setObjectName("designButton")
+        self.verticalLayout.addWidget(self.designButton)
+        self.gridLayout.addWidget(self.filterFrame, 1, 0, 1, 1)
+        self.tabGroup = QtGui.QTabWidget(self.centralwidget)
+        self.tabGroup.setMinimumSize(QtCore.QSize(800, 0))
+        self.tabGroup.setObjectName("tabGroup")
+        self.freqTab = QtGui.QWidget()
+        self.freqTab.setObjectName("freqTab")
+        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.freqTab)
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.freqPlot = Qwt5.QwtPlot(self.freqTab)
+        self.freqPlot.setObjectName("freqPlot")
+        self.horizontalLayout_2.addWidget(self.freqPlot)
+        self.tabGroup.addTab(self.freqTab, "")
+        self.timeTab = QtGui.QWidget()
+        self.timeTab.setObjectName("timeTab")
+        self.horizontalLayout = QtGui.QHBoxLayout(self.timeTab)
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.timePlot = Qwt5.QwtPlot(self.timeTab)
+        self.timePlot.setObjectName("timePlot")
+        self.horizontalLayout.addWidget(self.timePlot)
+        self.tabGroup.addTab(self.timeTab, "")
+        self.phaseTab = QtGui.QWidget()
+        self.phaseTab.setObjectName("phaseTab")
+        self.horizontalLayout_3 = QtGui.QHBoxLayout(self.phaseTab)
+        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+        self.phasePlot = Qwt5.QwtPlot(self.phaseTab)
+        self.phasePlot.setObjectName("phasePlot")
+        self.horizontalLayout_3.addWidget(self.phasePlot)
+        self.tabGroup.addTab(self.phaseTab, "")
+        self.groupTab = QtGui.QWidget()
+        self.groupTab.setObjectName("groupTab")
+        self.horizontalLayout_4 = QtGui.QHBoxLayout(self.groupTab)
+        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+        self.groupPlot = Qwt5.QwtPlot(self.groupTab)
+        self.groupPlot.setObjectName("groupPlot")
+        self.horizontalLayout_4.addWidget(self.groupPlot)
+        self.tabGroup.addTab(self.groupTab, "")
+        self.gridLayout.addWidget(self.tabGroup, 1, 1, 1, 1)
+        MainWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1124, 24))
+        self.menubar.setObjectName("menubar")
+        self.menu_File = QtGui.QMenu(self.menubar)
+        self.menu_File.setObjectName("menu_File")
+        MainWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+        self.action_open = QtGui.QAction(MainWindow)
+        self.action_open.setObjectName("action_open")
+        self.action_exit = QtGui.QAction(MainWindow)
+        self.action_exit.setObjectName("action_exit")
+        self.menu_File.addAction(self.action_exit)
+        self.menubar.addAction(self.menu_File.menuAction())
+
+        self.retranslateUi(MainWindow)
+        self.filterTypeWidget.setCurrentIndex(0)
+        self.tabGroup.setCurrentIndex(0)
+        QtCore.QObject.connect(self.action_exit, QtCore.SIGNAL("activated()"), MainWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+        MainWindow.setTabOrder(self.filterTypeComboBox, self.filterDesignTypeComboBox)
+        MainWindow.setTabOrder(self.filterDesignTypeComboBox, self.sampleRateEdit)
+        MainWindow.setTabOrder(self.sampleRateEdit, self.filterGainEdit)
+        MainWindow.setTabOrder(self.filterGainEdit, self.endofLpfPassBandEdit)
+        MainWindow.setTabOrder(self.endofLpfPassBandEdit, self.startofLpfStopBandEdit)
+        MainWindow.setTabOrder(self.startofLpfStopBandEdit, self.lpfStopBandAttenEdit)
+        MainWindow.setTabOrder(self.lpfStopBandAttenEdit, self.lpfPassBandRippleEdit)
+        MainWindow.setTabOrder(self.lpfPassBandRippleEdit, self.startofBpfPassBandEdit)
+        MainWindow.setTabOrder(self.startofBpfPassBandEdit, self.endofBpfPassBandEdit)
+        MainWindow.setTabOrder(self.endofBpfPassBandEdit, self.bpfTransitionEdit)
+        MainWindow.setTabOrder(self.bpfTransitionEdit, self.bpfStopBandAttenEdit)
+        MainWindow.setTabOrder(self.bpfStopBandAttenEdit, self.bpfPassBandRippleEdit)
+        MainWindow.setTabOrder(self.bpfPassBandRippleEdit, self.startofBnfStopBandEdit)
+        MainWindow.setTabOrder(self.startofBnfStopBandEdit, self.endofBnfStopBandEdit)
+        MainWindow.setTabOrder(self.endofBnfStopBandEdit, self.bnfTransitionEdit)
+        MainWindow.setTabOrder(self.bnfTransitionEdit, self.bnfStopBandAttenEdit)
+        MainWindow.setTabOrder(self.bnfStopBandAttenEdit, self.bnfPassBandRippleEdit)
+        MainWindow.setTabOrder(self.bnfPassBandRippleEdit, self.endofHpfStopBandEdit)
+        MainWindow.setTabOrder(self.endofHpfStopBandEdit, self.startofHpfPassBandEdit)
+        MainWindow.setTabOrder(self.startofHpfPassBandEdit, self.hpfStopBandAttenEdit)
+        MainWindow.setTabOrder(self.hpfStopBandAttenEdit, self.hpfPassBandRippleEdit)
+        MainWindow.setTabOrder(self.hpfPassBandRippleEdit, self.rrcSymbolRateEdit)
+        MainWindow.setTabOrder(self.rrcSymbolRateEdit, self.rrcAlphaEdit)
+        MainWindow.setTabOrder(self.rrcAlphaEdit, self.rrcNumTapsEdit)
+        MainWindow.setTabOrder(self.rrcNumTapsEdit, self.gausSymbolRateEdit)
+        MainWindow.setTabOrder(self.gausSymbolRateEdit, self.gausBTEdit)
+        MainWindow.setTabOrder(self.gausBTEdit, self.gausNumTapsEdit)
+        MainWindow.setTabOrder(self.gausNumTapsEdit, self.nfftEdit)
+        MainWindow.setTabOrder(self.nfftEdit, self.designButton)
+        MainWindow.setTabOrder(self.designButton, self.tabGroup)
+
+    def retranslateUi(self, MainWindow):
+        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "GNU Radio Filter Design Tool", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(0, QtGui.QApplication.translate("MainWindow", "Low Pass", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(1, QtGui.QApplication.translate("MainWindow", "Band Pass", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(2, QtGui.QApplication.translate("MainWindow", "Complex Band Pass", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(3, QtGui.QApplication.translate("MainWindow", "Band Notch", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(4, QtGui.QApplication.translate("MainWindow", "High Pass", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(5, QtGui.QApplication.translate("MainWindow", "Root Raised Cosine", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterTypeComboBox.setItemText(6, QtGui.QApplication.translate("MainWindow", "Gaussian", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(0, QtGui.QApplication.translate("MainWindow", "Hamming Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(1, QtGui.QApplication.translate("MainWindow", "Hann Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(2, QtGui.QApplication.translate("MainWindow", "Blackman Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(3, QtGui.QApplication.translate("MainWindow", "Rectangular Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(4, QtGui.QApplication.translate("MainWindow", "Kaiser Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(5, QtGui.QApplication.translate("MainWindow", "Blackman-harris Window", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterDesignTypeComboBox.setItemText(6, QtGui.QApplication.translate("MainWindow", "Equiripple", None, QtGui.QApplication.UnicodeUTF8))
+        self.sampleRateLabel.setText(QtGui.QApplication.translate("MainWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterGainLabel.setText(QtGui.QApplication.translate("MainWindow", "Filter Gain", None, QtGui.QApplication.UnicodeUTF8))
+        self.endofLpfPassBandLabel.setText(QtGui.QApplication.translate("MainWindow", "End of Pass Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.startofLpfStopBandLabel.setText(QtGui.QApplication.translate("MainWindow", "Start of Stop Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.lpfStopBandAttenLabel.setText(QtGui.QApplication.translate("MainWindow", "Stop Band Attenuation (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.lpfPassBandRippleLabel.setText(QtGui.QApplication.translate("MainWindow", "Pass Band Ripple (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.startofBpfPassBandLabel.setText(QtGui.QApplication.translate("MainWindow", "Start of Pass Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.endofBpfPassBandLabel.setText(QtGui.QApplication.translate("MainWindow", "End of Pass Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bpfStopBandAttenLabel.setText(QtGui.QApplication.translate("MainWindow", "Stop Band Attenuation (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bpfTransitionLabel.setText(QtGui.QApplication.translate("MainWindow", "Transition Width (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bpfPassBandRippleLabel.setText(QtGui.QApplication.translate("MainWindow", "Pass Band Ripple (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.startofBnfStopBandLabel.setText(QtGui.QApplication.translate("MainWindow", "Start of Stop Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.endofBnfStopBandLabel.setText(QtGui.QApplication.translate("MainWindow", "End of Stop Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bnfTransitionLabel.setText(QtGui.QApplication.translate("MainWindow", "Transition Width (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bnfStopBandAttenLabel.setText(QtGui.QApplication.translate("MainWindow", "Stop Band Attenuation (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.bnfPassBandRippleLabel.setText(QtGui.QApplication.translate("MainWindow", "Pass Band Ripple (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.endofHpfStopBandLabel.setText(QtGui.QApplication.translate("MainWindow", "End of Stop Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.startofHpfPassBandLabel.setText(QtGui.QApplication.translate("MainWindow", "Start of Pass Band (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.hpfStopBandAttenLabel.setText(QtGui.QApplication.translate("MainWindow", "Stop Band Attenuation (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.hpfPassBandRippleLabel.setText(QtGui.QApplication.translate("MainWindow", "Pass Band Ripple (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.rrcSymbolRateLabel.setText(QtGui.QApplication.translate("MainWindow", "Symbol Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.rrcAlphaLabel.setText(QtGui.QApplication.translate("MainWindow", "Roll-off Factor", None, QtGui.QApplication.UnicodeUTF8))
+        self.rrcNumTapsLabel.setText(QtGui.QApplication.translate("MainWindow", "Number of Taps", None, QtGui.QApplication.UnicodeUTF8))
+        self.gausSymbolRateLabel.setText(QtGui.QApplication.translate("MainWindow", "Symbol Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.gausBTLabel.setText(QtGui.QApplication.translate("MainWindow", "Roll-off Factor", None, QtGui.QApplication.UnicodeUTF8))
+        self.gausNumTapsLabel.setText(QtGui.QApplication.translate("MainWindow", "Number of Taps", None, QtGui.QApplication.UnicodeUTF8))
+        self.filterPropsBox.setTitle(QtGui.QApplication.translate("MainWindow", "Filter Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.nTapsLabel.setText(QtGui.QApplication.translate("MainWindow", "Number of Taps:", None, QtGui.QApplication.UnicodeUTF8))
+        self.sysParamsBox.setTitle(QtGui.QApplication.translate("MainWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.nfftLabel.setText(QtGui.QApplication.translate("MainWindow", "Num FFT points", None, QtGui.QApplication.UnicodeUTF8))
+        self.designButton.setText(QtGui.QApplication.translate("MainWindow", "Design", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.freqTab), QtGui.QApplication.translate("MainWindow", "Frequency Domain", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.timeTab), QtGui.QApplication.translate("MainWindow", "Time Domain", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.phaseTab), QtGui.QApplication.translate("MainWindow", "Phase", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.groupTab), QtGui.QApplication.translate("MainWindow", "Group Delay", None, QtGui.QApplication.UnicodeUTF8))
+        self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_open.setText(QtGui.QApplication.translate("MainWindow", "&Open", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_open.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_exit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+
+from PyQt4 import Qwt5
diff --git a/gr-utils/src/python/pyqt_filter.ui b/gr-utils/src/python/pyqt_filter.ui
new file mode 100644 (file)
index 0000000..9b31112
--- /dev/null
@@ -0,0 +1,676 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1124</width>
+    <height>696</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>GNU Radio Filter Design Tool</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QGridLayout" name="gridLayout" >
+    <item row="1" column="0" >
+     <widget class="QFrame" name="filterFrame" >
+      <property name="minimumSize" >
+       <size>
+        <width>300</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="maximumSize" >
+       <size>
+        <width>300</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="frameShape" >
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow" >
+       <enum>QFrame::Raised</enum>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout" >
+       <item>
+        <widget class="QComboBox" name="filterTypeComboBox" >
+         <item>
+          <property name="text" >
+           <string>Low Pass</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Band Pass</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Complex Band Pass</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Band Notch</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>High Pass</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Root Raised Cosine</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Gaussian</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="filterDesignTypeComboBox" >
+         <item>
+          <property name="text" >
+           <string>Hamming Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Hann Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Blackman Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Rectangular Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Kaiser Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Blackman-harris Window</string>
+          </property>
+         </item>
+         <item>
+          <property name="text" >
+           <string>Equiripple</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item>
+        <layout class="QFormLayout" name="globalParamsLayout" >
+         <property name="fieldGrowthPolicy" >
+          <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+         </property>
+         <item row="0" column="0" >
+          <widget class="QLabel" name="sampleRateLabel" >
+           <property name="maximumSize" >
+            <size>
+             <width>16777215</width>
+             <height>30</height>
+            </size>
+           </property>
+           <property name="text" >
+            <string>Sample Rate (sps)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" >
+          <widget class="QLineEdit" name="sampleRateEdit" >
+           <property name="maximumSize" >
+            <size>
+             <width>16777215</width>
+             <height>30</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0" >
+          <widget class="QLabel" name="filterGainLabel" >
+           <property name="text" >
+            <string>Filter Gain</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" >
+          <widget class="QLineEdit" name="filterGainEdit" />
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="QStackedWidget" name="filterTypeWidget" >
+         <property name="currentIndex" >
+          <number>0</number>
+         </property>
+         <widget class="QWidget" name="firlpfPage" >
+          <layout class="QFormLayout" name="formLayout" >
+           <item row="0" column="0" >
+            <widget class="QLabel" name="endofLpfPassBandLabel" >
+             <property name="text" >
+              <string>End of Pass Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="endofLpfPassBandEdit" />
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="startofLpfStopBandLabel" >
+             <property name="text" >
+              <string>Start of Stop Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="startofLpfStopBandEdit" />
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="lpfStopBandAttenLabel" >
+             <property name="text" >
+              <string>Stop Band Attenuation (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="lpfStopBandAttenEdit" />
+           </item>
+           <item row="3" column="1" >
+            <widget class="QLineEdit" name="lpfPassBandRippleEdit" />
+           </item>
+           <item row="3" column="0" >
+            <widget class="QLabel" name="lpfPassBandRippleLabel" >
+             <property name="text" >
+              <string>Pass Band Ripple (dB)</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="firbpfPage" >
+          <layout class="QFormLayout" name="formLayout_2" >
+           <item row="0" column="0" >
+            <widget class="QLabel" name="startofBpfPassBandLabel" >
+             <property name="text" >
+              <string>Start of Pass Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="startofBpfPassBandEdit" />
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="endofBpfPassBandLabel" >
+             <property name="text" >
+              <string>End of Pass Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="endofBpfPassBandEdit" />
+           </item>
+           <item row="3" column="1" >
+            <widget class="QLineEdit" name="bpfStopBandAttenEdit" />
+           </item>
+           <item row="3" column="0" >
+            <widget class="QLabel" name="bpfStopBandAttenLabel" >
+             <property name="text" >
+              <string>Stop Band Attenuation (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="bpfTransitionLabel" >
+             <property name="text" >
+              <string>Transition Width (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="bpfTransitionEdit" />
+           </item>
+           <item row="4" column="1" >
+            <widget class="QLineEdit" name="bpfPassBandRippleEdit" />
+           </item>
+           <item row="4" column="0" >
+            <widget class="QLabel" name="bpfPassBandRippleLabel" >
+             <property name="text" >
+              <string>Pass Band Ripple (dB)</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="firbnfPage" >
+          <layout class="QFormLayout" name="formLayout_5" >
+           <property name="fieldGrowthPolicy" >
+            <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+           </property>
+           <item row="0" column="0" >
+            <widget class="QLabel" name="startofBnfStopBandLabel" >
+             <property name="text" >
+              <string>Start of Stop Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="startofBnfStopBandEdit" />
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="endofBnfStopBandLabel" >
+             <property name="text" >
+              <string>End of Stop Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="endofBnfStopBandEdit" />
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="bnfTransitionLabel" >
+             <property name="text" >
+              <string>Transition Width (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="bnfTransitionEdit" />
+           </item>
+           <item row="3" column="0" >
+            <widget class="QLabel" name="bnfStopBandAttenLabel" >
+             <property name="text" >
+              <string>Stop Band Attenuation (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="1" >
+            <widget class="QLineEdit" name="bnfStopBandAttenEdit" />
+           </item>
+           <item row="4" column="0" >
+            <widget class="QLabel" name="bnfPassBandRippleLabel" >
+             <property name="text" >
+              <string>Pass Band Ripple (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="1" >
+            <widget class="QLineEdit" name="bnfPassBandRippleEdit" />
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="firhpfPage" >
+          <layout class="QFormLayout" name="formLayout_3" >
+           <property name="fieldGrowthPolicy" >
+            <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+           </property>
+           <item row="0" column="0" >
+            <widget class="QLabel" name="endofHpfStopBandLabel" >
+             <property name="text" >
+              <string>End of Stop Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="endofHpfStopBandEdit" />
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="startofHpfPassBandLabel" >
+             <property name="text" >
+              <string>Start of Pass Band (Hz)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="startofHpfPassBandEdit" />
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="hpfStopBandAttenLabel" >
+             <property name="text" >
+              <string>Stop Band Attenuation (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="hpfStopBandAttenEdit" />
+           </item>
+           <item row="3" column="0" >
+            <widget class="QLabel" name="hpfPassBandRippleLabel" >
+             <property name="text" >
+              <string>Pass Band Ripple (dB)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="1" >
+            <widget class="QLineEdit" name="hpfPassBandRippleEdit" />
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="rrcPage" >
+          <layout class="QFormLayout" name="formLayout_6" >
+           <item row="0" column="0" >
+            <widget class="QLabel" name="rrcSymbolRateLabel" >
+             <property name="text" >
+              <string>Symbol Rate (sps)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="rrcAlphaLabel" >
+             <property name="text" >
+              <string>Roll-off Factor</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="rrcNumTapsLabel" >
+             <property name="text" >
+              <string>Number of Taps</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="rrcSymbolRateEdit" />
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="rrcAlphaEdit" />
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="rrcNumTapsEdit" />
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="gausPage" >
+          <layout class="QFormLayout" name="formLayout_7" >
+           <item row="0" column="0" >
+            <widget class="QLabel" name="gausSymbolRateLabel" >
+             <property name="text" >
+              <string>Symbol Rate (sps)</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1" >
+            <widget class="QLineEdit" name="gausSymbolRateEdit" />
+           </item>
+           <item row="1" column="0" >
+            <widget class="QLabel" name="gausBTLabel" >
+             <property name="text" >
+              <string>Roll-off Factor</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1" >
+            <widget class="QLineEdit" name="gausBTEdit" />
+           </item>
+           <item row="2" column="0" >
+            <widget class="QLabel" name="gausNumTapsLabel" >
+             <property name="text" >
+              <string>Number of Taps</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1" >
+            <widget class="QLineEdit" name="gausNumTapsEdit" />
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="filterPropsBox" >
+         <property name="title" >
+          <string>Filter Properties</string>
+         </property>
+         <layout class="QFormLayout" name="formLayout_8" >
+          <property name="fieldGrowthPolicy" >
+           <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+          </property>
+          <item row="1" column="0" >
+           <widget class="QLabel" name="nTapsLabel" >
+            <property name="minimumSize" >
+             <size>
+              <width>150</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text" >
+             <string>Number of Taps:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1" >
+           <widget class="QLabel" name="nTapsEdit" >
+            <property name="maximumSize" >
+             <size>
+              <width>100</width>
+              <height>16777215</height>
+             </size>
+            </property>
+            <property name="frameShape" >
+             <enum>QFrame::Box</enum>
+            </property>
+            <property name="frameShadow" >
+             <enum>QFrame::Raised</enum>
+            </property>
+            <property name="text" >
+             <string/>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="sysParamsBox" >
+         <property name="title" >
+          <string>System Parameters</string>
+         </property>
+         <layout class="QFormLayout" name="formLayout_4" >
+          <item row="1" column="1" >
+           <widget class="QLineEdit" name="nfftEdit" />
+          </item>
+          <item row="1" column="0" >
+           <widget class="QLabel" name="nfftLabel" >
+            <property name="minimumSize" >
+             <size>
+              <width>150</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text" >
+             <string>Num FFT points</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="designButton" >
+         <property name="minimumSize" >
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize" >
+          <size>
+           <width>200</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Design</string>
+         </property>
+         <property name="autoDefault" >
+          <bool>true</bool>
+         </property>
+         <property name="default" >
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </item>
+    <item row="1" column="1" >
+     <widget class="QTabWidget" name="tabGroup" >
+      <property name="minimumSize" >
+       <size>
+        <width>800</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="currentIndex" >
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="freqTab" >
+       <attribute name="title" >
+        <string>Frequency Domain</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_2" >
+        <item>
+         <widget class="QwtPlot" name="freqPlot" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="timeTab" >
+       <attribute name="title" >
+        <string>Time Domain</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout" >
+        <item>
+         <widget class="QwtPlot" name="timePlot" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="phaseTab" >
+       <attribute name="title" >
+        <string>Phase</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_3" >
+        <item>
+         <widget class="QwtPlot" name="phasePlot" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="groupTab" >
+       <attribute name="title" >
+        <string>Group Delay</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_4" >
+        <item>
+         <widget class="QwtPlot" name="groupPlot" />
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar" >
+   <property name="geometry" >
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1124</width>
+     <height>24</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menu_File" >
+    <property name="title" >
+     <string>&amp;File</string>
+    </property>
+    <addaction name="action_exit" />
+   </widget>
+   <addaction name="menu_File" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="action_open" >
+   <property name="text" >
+    <string>&amp;Open</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+O</string>
+   </property>
+  </action>
+  <action name="action_exit" >
+   <property name="text" >
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QwtPlot</class>
+   <extends>QFrame</extends>
+   <header>qwt_plot.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>filterTypeComboBox</tabstop>
+  <tabstop>filterDesignTypeComboBox</tabstop>
+  <tabstop>sampleRateEdit</tabstop>
+  <tabstop>filterGainEdit</tabstop>
+  <tabstop>endofLpfPassBandEdit</tabstop>
+  <tabstop>startofLpfStopBandEdit</tabstop>
+  <tabstop>lpfStopBandAttenEdit</tabstop>
+  <tabstop>lpfPassBandRippleEdit</tabstop>
+  <tabstop>startofBpfPassBandEdit</tabstop>
+  <tabstop>endofBpfPassBandEdit</tabstop>
+  <tabstop>bpfTransitionEdit</tabstop>
+  <tabstop>bpfStopBandAttenEdit</tabstop>
+  <tabstop>bpfPassBandRippleEdit</tabstop>
+  <tabstop>startofBnfStopBandEdit</tabstop>
+  <tabstop>endofBnfStopBandEdit</tabstop>
+  <tabstop>bnfTransitionEdit</tabstop>
+  <tabstop>bnfStopBandAttenEdit</tabstop>
+  <tabstop>bnfPassBandRippleEdit</tabstop>
+  <tabstop>endofHpfStopBandEdit</tabstop>
+  <tabstop>startofHpfPassBandEdit</tabstop>
+  <tabstop>hpfStopBandAttenEdit</tabstop>
+  <tabstop>hpfPassBandRippleEdit</tabstop>
+  <tabstop>rrcSymbolRateEdit</tabstop>
+  <tabstop>rrcAlphaEdit</tabstop>
+  <tabstop>rrcNumTapsEdit</tabstop>
+  <tabstop>gausSymbolRateEdit</tabstop>
+  <tabstop>gausBTEdit</tabstop>
+  <tabstop>gausNumTapsEdit</tabstop>
+  <tabstop>nfftEdit</tabstop>
+  <tabstop>designButton</tabstop>
+  <tabstop>tabGroup</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>action_exit</sender>
+   <signal>activated()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>399</x>
+     <y>347</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/gr-utils/src/python/pyqt_plot.py b/gr-utils/src/python/pyqt_plot.py
new file mode 100644 (file)
index 0000000..5650135
--- /dev/null
@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'pyqt_plot.ui'
+#
+# Created: Tue Oct  6 10:39:58 2009
+#      by: PyQt4 UI code generator 4.4.4
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.resize(927, 696)
+        self.centralwidget = QtGui.QWidget(MainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
+        self.gridLayout.setObjectName("gridLayout")
+        self.plotHBar = QtGui.QScrollBar(self.centralwidget)
+        self.plotHBar.setOrientation(QtCore.Qt.Horizontal)
+        self.plotHBar.setObjectName("plotHBar")
+        self.gridLayout.addWidget(self.plotHBar, 2, 0, 1, 2)
+        self.tabGroup = QtGui.QTabWidget(self.centralwidget)
+        self.tabGroup.setObjectName("tabGroup")
+        self.timeTab = QtGui.QWidget()
+        self.timeTab.setObjectName("timeTab")
+        self.horizontalLayout = QtGui.QHBoxLayout(self.timeTab)
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.timePlot = Qwt5.QwtPlot(self.timeTab)
+        self.timePlot.setObjectName("timePlot")
+        self.horizontalLayout.addWidget(self.timePlot)
+        self.tabGroup.addTab(self.timeTab, "")
+        self.freqTab = QtGui.QWidget()
+        self.freqTab.setObjectName("freqTab")
+        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.freqTab)
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.fftPropBox = QtGui.QGroupBox(self.freqTab)
+        self.fftPropBox.setMinimumSize(QtCore.QSize(160, 0))
+        self.fftPropBox.setObjectName("fftPropBox")
+        self.formLayout_4 = QtGui.QFormLayout(self.fftPropBox)
+        self.formLayout_4.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_4.setObjectName("formLayout_4")
+        self.psdFFTComboBox = QtGui.QComboBox(self.fftPropBox)
+        self.psdFFTComboBox.setMinimumSize(QtCore.QSize(96, 0))
+        self.psdFFTComboBox.setMaximumSize(QtCore.QSize(96, 16777215))
+        self.psdFFTComboBox.setObjectName("psdFFTComboBox")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.psdFFTComboBox)
+        self.psdFFTSizeLabel = QtGui.QLabel(self.fftPropBox)
+        self.psdFFTSizeLabel.setObjectName("psdFFTSizeLabel")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.LabelRole, self.psdFFTSizeLabel)
+        self.horizontalLayout_2.addWidget(self.fftPropBox)
+        self.freqPlot = Qwt5.QwtPlot(self.freqTab)
+        self.freqPlot.setObjectName("freqPlot")
+        self.horizontalLayout_2.addWidget(self.freqPlot)
+        self.tabGroup.addTab(self.freqTab, "")
+        self.specTab = QtGui.QWidget()
+        self.specTab.setObjectName("specTab")
+        self.horizontalLayout_3 = QtGui.QHBoxLayout(self.specTab)
+        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+        self.groupBox = QtGui.QGroupBox(self.specTab)
+        self.groupBox.setObjectName("groupBox")
+        self.formLayout_3 = QtGui.QFormLayout(self.groupBox)
+        self.formLayout_3.setObjectName("formLayout_3")
+        self.specFFTLabel = QtGui.QLabel(self.groupBox)
+        self.specFFTLabel.setObjectName("specFFTLabel")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.specFFTLabel)
+        self.specFFTComboBox = QtGui.QComboBox(self.groupBox)
+        self.specFFTComboBox.setMinimumSize(QtCore.QSize(96, 0))
+        self.specFFTComboBox.setMaximumSize(QtCore.QSize(96, 16777215))
+        self.specFFTComboBox.setObjectName("specFFTComboBox")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.specFFTComboBox)
+        self.horizontalLayout_3.addWidget(self.groupBox)
+        self.specPlot = Qwt5.QwtPlot(self.specTab)
+        self.specPlot.setObjectName("specPlot")
+        self.horizontalLayout_3.addWidget(self.specPlot)
+        self.tabGroup.addTab(self.specTab, "")
+        self.gridLayout.addWidget(self.tabGroup, 1, 0, 1, 1)
+        self.filePosBox = QtGui.QGroupBox(self.centralwidget)
+        self.filePosBox.setMinimumSize(QtCore.QSize(0, 120))
+        self.filePosBox.setObjectName("filePosBox")
+        self.formLayoutWidget_2 = QtGui.QWidget(self.filePosBox)
+        self.formLayoutWidget_2.setGeometry(QtCore.QRect(0, 20, 160, 92))
+        self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")
+        self.filePosLayout = QtGui.QFormLayout(self.formLayoutWidget_2)
+        self.filePosLayout.setObjectName("filePosLayout")
+        self.filePosStartLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.filePosStartLabel.setObjectName("filePosStartLabel")
+        self.filePosLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.filePosStartLabel)
+        self.filePosStartLineEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.filePosStartLineEdit.setObjectName("filePosStartLineEdit")
+        self.filePosLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.filePosStartLineEdit)
+        self.filePosStopLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.filePosStopLabel.setObjectName("filePosStopLabel")
+        self.filePosLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.filePosStopLabel)
+        self.filePosStopLineEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.filePosStopLineEdit.setObjectName("filePosStopLineEdit")
+        self.filePosLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.filePosStopLineEdit)
+        self.filePosLengthLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.filePosLengthLabel.setObjectName("filePosLengthLabel")
+        self.filePosLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.filePosLengthLabel)
+        self.filePosLengthLineEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.filePosLengthLineEdit.setObjectName("filePosLengthLineEdit")
+        self.filePosLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.filePosLengthLineEdit)
+        self.formLayoutWidget_4 = QtGui.QWidget(self.filePosBox)
+        self.formLayoutWidget_4.setGeometry(QtCore.QRect(180, 20, 231, 92))
+        self.formLayoutWidget_4.setObjectName("formLayoutWidget_4")
+        self.fileTimeLayout = QtGui.QFormLayout(self.formLayoutWidget_4)
+        self.fileTimeLayout.setObjectName("fileTimeLayout")
+        self.fileTimeStartLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.fileTimeStartLabel.setObjectName("fileTimeStartLabel")
+        self.fileTimeLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.fileTimeStartLabel)
+        self.fileTimeStartLineEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.fileTimeStartLineEdit.setObjectName("fileTimeStartLineEdit")
+        self.fileTimeLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.fileTimeStartLineEdit)
+        self.fileTimeStopLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.fileTimeStopLabel.setObjectName("fileTimeStopLabel")
+        self.fileTimeLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.fileTimeStopLabel)
+        self.fileTimeStopLineEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.fileTimeStopLineEdit.setObjectName("fileTimeStopLineEdit")
+        self.fileTimeLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.fileTimeStopLineEdit)
+        self.fileTimeLengthLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.fileTimeLengthLabel.setObjectName("fileTimeLengthLabel")
+        self.fileTimeLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.fileTimeLengthLabel)
+        self.fileTimeLengthLineEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.fileTimeLengthLineEdit.setObjectName("fileTimeLengthLineEdit")
+        self.fileTimeLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.fileTimeLengthLineEdit)
+        self.sysGroupBox = QtGui.QGroupBox(self.filePosBox)
+        self.sysGroupBox.setGeometry(QtCore.QRect(530, 0, 200, 120))
+        self.sysGroupBox.setMinimumSize(QtCore.QSize(200, 0))
+        self.sysGroupBox.setObjectName("sysGroupBox")
+        self.formLayoutWidget_3 = QtGui.QWidget(self.sysGroupBox)
+        self.formLayoutWidget_3.setGeometry(QtCore.QRect(0, 20, 191, 91))
+        self.formLayoutWidget_3.setObjectName("formLayoutWidget_3")
+        self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_3)
+        self.formLayout_2.setObjectName("formLayout_2")
+        self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.sampleRateLabel.setObjectName("sampleRateLabel")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel)
+        self.sampleRateLineEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.sampleRateLineEdit.setMinimumSize(QtCore.QSize(0, 0))
+        self.sampleRateLineEdit.setObjectName("sampleRateLineEdit")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateLineEdit)
+        self.displayGroupBox = QtGui.QGroupBox(self.filePosBox)
+        self.displayGroupBox.setGeometry(QtCore.QRect(730, 0, 170, 120))
+        self.displayGroupBox.setMinimumSize(QtCore.QSize(170, 0))
+        self.displayGroupBox.setObjectName("displayGroupBox")
+        self.verticalLayoutWidget = QtGui.QWidget(self.displayGroupBox)
+        self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 20, 160, 91))
+        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
+        self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.colorComboBox = QtGui.QComboBox(self.verticalLayoutWidget)
+        self.colorComboBox.setObjectName("colorComboBox")
+        self.verticalLayout.addWidget(self.colorComboBox)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.verticalLayout.addItem(spacerItem)
+        self.gridLayout.addWidget(self.filePosBox, 3, 0, 1, 1)
+        MainWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 927, 25))
+        self.menubar.setObjectName("menubar")
+        self.menu_File = QtGui.QMenu(self.menubar)
+        self.menu_File.setObjectName("menu_File")
+        MainWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+        self.action_open = QtGui.QAction(MainWindow)
+        self.action_open.setObjectName("action_open")
+        self.action_exit = QtGui.QAction(MainWindow)
+        self.action_exit.setObjectName("action_exit")
+        self.action_reload = QtGui.QAction(MainWindow)
+        self.action_reload.setObjectName("action_reload")
+        self.menu_File.addAction(self.action_open)
+        self.menu_File.addAction(self.action_reload)
+        self.menu_File.addAction(self.action_exit)
+        self.menubar.addAction(self.menu_File.menuAction())
+
+        self.retranslateUi(MainWindow)
+        self.tabGroup.setCurrentIndex(0)
+        QtCore.QObject.connect(self.action_exit, QtCore.SIGNAL("activated()"), MainWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+    def retranslateUi(self, MainWindow):
+        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.timeTab), QtGui.QApplication.translate("MainWindow", "Time Domain", None, QtGui.QApplication.UnicodeUTF8))
+        self.fftPropBox.setTitle(QtGui.QApplication.translate("MainWindow", "FFT Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.psdFFTSizeLabel.setText(QtGui.QApplication.translate("MainWindow", "FFT Size", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.freqTab), QtGui.QApplication.translate("MainWindow", "Frequency Domain", None, QtGui.QApplication.UnicodeUTF8))
+        self.groupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Spectrogram Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.specFFTLabel.setText(QtGui.QApplication.translate("MainWindow", "FFT Size", None, QtGui.QApplication.UnicodeUTF8))
+        self.tabGroup.setTabText(self.tabGroup.indexOf(self.specTab), QtGui.QApplication.translate("MainWindow", "Spectrogram", None, QtGui.QApplication.UnicodeUTF8))
+        self.filePosBox.setTitle(QtGui.QApplication.translate("MainWindow", "File Position", None, QtGui.QApplication.UnicodeUTF8))
+        self.filePosStartLabel.setText(QtGui.QApplication.translate("MainWindow", "Start", None, QtGui.QApplication.UnicodeUTF8))
+        self.filePosStopLabel.setText(QtGui.QApplication.translate("MainWindow", "Stop", None, QtGui.QApplication.UnicodeUTF8))
+        self.filePosLengthLabel.setText(QtGui.QApplication.translate("MainWindow", "Length", None, QtGui.QApplication.UnicodeUTF8))
+        self.fileTimeStartLabel.setText(QtGui.QApplication.translate("MainWindow", "time start (sec)", None, QtGui.QApplication.UnicodeUTF8))
+        self.fileTimeStopLabel.setText(QtGui.QApplication.translate("MainWindow", "time stop (sec)", None, QtGui.QApplication.UnicodeUTF8))
+        self.fileTimeLengthLabel.setText(QtGui.QApplication.translate("MainWindow", "time length (sec)", None, QtGui.QApplication.UnicodeUTF8))
+        self.sysGroupBox.setTitle(QtGui.QApplication.translate("MainWindow", "System Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.sampleRateLabel.setText(QtGui.QApplication.translate("MainWindow", "Sample Rate", None, QtGui.QApplication.UnicodeUTF8))
+        self.displayGroupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Display Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_open.setText(QtGui.QApplication.translate("MainWindow", "&Open", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_open.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_exit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_reload.setText(QtGui.QApplication.translate("MainWindow", "&Reload", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_reload.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+R", None, QtGui.QApplication.UnicodeUTF8))
+
+from PyQt4 import Qwt5
diff --git a/gr-utils/src/python/pyqt_plot.ui b/gr-utils/src/python/pyqt_plot.ui
new file mode 100644 (file)
index 0000000..55c72fd
--- /dev/null
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>927</width>
+    <height>696</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="2" column="0" colspan="2">
+     <widget class="QScrollBar" name="plotHBar">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="0">
+     <widget class="QTabWidget" name="tabGroup">
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="timeTab">
+       <attribute name="title">
+        <string>Time Domain</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QwtPlot" name="timePlot"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="freqTab">
+       <attribute name="title">
+        <string>Frequency Domain</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QGroupBox" name="fftPropBox">
+          <property name="minimumSize">
+           <size>
+            <width>160</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="title">
+           <string>FFT Properties</string>
+          </property>
+          <layout class="QFormLayout" name="formLayout_4">
+           <property name="fieldGrowthPolicy">
+            <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+           </property>
+           <item row="0" column="1">
+            <widget class="QComboBox" name="psdFFTComboBox">
+             <property name="minimumSize">
+              <size>
+               <width>96</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>96</width>
+               <height>16777215</height>
+              </size>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="0">
+            <widget class="QLabel" name="psdFFTSizeLabel">
+             <property name="text">
+              <string>FFT Size</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item>
+         <widget class="QwtPlot" name="freqPlot"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="specTab">
+       <attribute name="title">
+        <string>Spectrogram</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <widget class="QGroupBox" name="groupBox">
+          <property name="title">
+           <string>Spectrogram Properties</string>
+          </property>
+          <layout class="QFormLayout" name="formLayout_3">
+           <item row="1" column="0">
+            <widget class="QLabel" name="specFFTLabel">
+             <property name="text">
+              <string>FFT Size</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1">
+            <widget class="QComboBox" name="specFFTComboBox">
+             <property name="minimumSize">
+              <size>
+               <width>96</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>96</width>
+               <height>16777215</height>
+              </size>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item>
+         <widget class="QwtPlot" name="specPlot"/>
+        </item>
+       </layout>
+       <zorder>specPlot</zorder>
+       <zorder>groupBox</zorder>
+      </widget>
+     </widget>
+    </item>
+    <item row="3" column="0">
+     <widget class="QGroupBox" name="filePosBox">
+      <property name="minimumSize">
+       <size>
+        <width>0</width>
+        <height>120</height>
+       </size>
+      </property>
+      <property name="title">
+       <string>File Position</string>
+      </property>
+      <widget class="QWidget" name="formLayoutWidget_2">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>20</y>
+         <width>160</width>
+         <height>92</height>
+        </rect>
+       </property>
+       <layout class="QFormLayout" name="filePosLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="filePosStartLabel">
+          <property name="text">
+           <string>Start</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QLineEdit" name="filePosStartLineEdit"/>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="filePosStopLabel">
+          <property name="text">
+           <string>Stop</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLineEdit" name="filePosStopLineEdit"/>
+        </item>
+        <item row="2" column="0">
+         <widget class="QLabel" name="filePosLengthLabel">
+          <property name="text">
+           <string>Length</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QLineEdit" name="filePosLengthLineEdit"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="formLayoutWidget_4">
+       <property name="geometry">
+        <rect>
+         <x>180</x>
+         <y>20</y>
+         <width>231</width>
+         <height>92</height>
+        </rect>
+       </property>
+       <layout class="QFormLayout" name="fileTimeLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="fileTimeStartLabel">
+          <property name="text">
+           <string>time start (sec)</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QLineEdit" name="fileTimeStartLineEdit"/>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="fileTimeStopLabel">
+          <property name="text">
+           <string>time stop (sec)</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLineEdit" name="fileTimeStopLineEdit"/>
+        </item>
+        <item row="2" column="0">
+         <widget class="QLabel" name="fileTimeLengthLabel">
+          <property name="text">
+           <string>time length (sec)</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QLineEdit" name="fileTimeLengthLineEdit"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QGroupBox" name="sysGroupBox">
+       <property name="geometry">
+        <rect>
+         <x>530</x>
+         <y>0</y>
+         <width>200</width>
+         <height>120</height>
+        </rect>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>200</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="title">
+        <string>System Properties</string>
+       </property>
+       <widget class="QWidget" name="formLayoutWidget_3">
+        <property name="geometry">
+         <rect>
+          <x>0</x>
+          <y>20</y>
+          <width>191</width>
+          <height>91</height>
+         </rect>
+        </property>
+        <layout class="QFormLayout" name="formLayout_2">
+         <item row="0" column="0">
+          <widget class="QLabel" name="sampleRateLabel">
+           <property name="text">
+            <string>Sample Rate</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLineEdit" name="sampleRateLineEdit">
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+      <widget class="QGroupBox" name="displayGroupBox">
+       <property name="geometry">
+        <rect>
+         <x>730</x>
+         <y>0</y>
+         <width>170</width>
+         <height>120</height>
+        </rect>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>170</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="title">
+        <string>Display Properties</string>
+       </property>
+       <widget class="QWidget" name="verticalLayoutWidget">
+        <property name="geometry">
+         <rect>
+          <x>0</x>
+          <y>20</y>
+          <width>160</width>
+          <height>91</height>
+         </rect>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout">
+         <item>
+          <widget class="QComboBox" name="colorComboBox"/>
+         </item>
+         <item>
+          <spacer name="verticalSpacer">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>40</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>927</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menu_File">
+    <property name="title">
+     <string>&amp;File</string>
+    </property>
+    <addaction name="action_open"/>
+    <addaction name="action_reload"/>
+    <addaction name="action_exit"/>
+   </widget>
+   <addaction name="menu_File"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="action_open">
+   <property name="text">
+    <string>&amp;Open</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+O</string>
+   </property>
+  </action>
+  <action name="action_exit">
+   <property name="text">
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+  <action name="action_reload">
+   <property name="text">
+    <string>&amp;Reload</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+R</string>
+   </property>
+  </action>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QwtPlot</class>
+   <extends>QFrame</extends>
+   <header>qwt_plot.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>action_exit</sender>
+   <signal>activated()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>399</x>
+     <y>347</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index 1e8cf89ea9f57c15785e59dcbabc773f5526654a..4276e389ac7a98d27e91f74087b0261b41f078f4 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -218,7 +218,7 @@ class app_top_block(stdgui2.std_top_block):
                 self.myform['baseband'].set_value(r.baseband_freq)
                 self.myform['ddc'].set_value(r.dxc_freq)
            if not self.options.oscilloscope:
-               self.scope.win.set_baseband_freq(target_freq)
+               self.scope.set_baseband_freq(target_freq)
            return True
 
         return False
index 4aa70adab9e3bb9085136ca26a046a9e6edc4e61..eda9bd57c0f21055a9fa4ef25be8dc666251c756 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -39,7 +39,7 @@ def pick_subdevice(u):
     """
     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(0, 0).dbid() >= 0:
+    if u.db(1, 0).dbid() >= 0:
         return (1, 0)
     return (0, 0)
 
@@ -255,7 +255,7 @@ class app_top_block(stdgui2.std_top_block):
                 self.myform['baseband'].set_value(r.baseband_freq)
                 self.myform['ddc'].set_value(r.dxc_freq)
            if not self.options.oscilloscope:
-               self.scope.win.set_baseband_freq(target_freq)
+               self.scope.set_baseband_freq(target_freq)
            return True
 
         return False
index f4a539dd59f62bd4e0c17a7fea092c49360effa5..9921e987340a4090cffcfc4a52f84442fed82d82 100755 (executable)
@@ -42,7 +42,7 @@ def pick_subdevice(u):
     """
     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(0, 0).dbid() >= 0:
+    if u.db(1, 0).dbid() >= 0:
         return (1, 0)
     return (0, 0)
 
index 8ae2fbfbfd93ade4518cff28311ab3ba946108d6..da83da770d43429457dc2316f442abb77c34cda1 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru
-from gnuradio import usrp
+DESC_KEY = 'desc'
+SAMP_RATE_KEY = 'samp_rate'
+LINK_RATE_KEY = 'link_rate'
+DAC_RATE_KEY = 'dac_rate'
+INTERP_KEY = 'interp'
+GAIN_KEY = 'gain'
+TX_FREQ_KEY = 'tx_freq'
+DDC_FREQ_KEY = 'ddc_freq'
+BB_FREQ_KEY = 'bb_freq'
+AMPLITUDE_KEY = 'amplitude'
+AMPL_RANGE_KEY = 'ampl_range'
+WAVEFORM_FREQ_KEY = 'waveform_freq'
+WAVEFORM_OFFSET_KEY = 'waveform_offset'
+WAVEFORM2_FREQ_KEY = 'waveform2_freq'
+FREQ_RANGE_KEY = 'freq_range'
+GAIN_RANGE_KEY = 'gain_range'
+TYPE_KEY = 'type'
+
+def setter(ps, key, val): ps[key] = val
+
+from gnuradio import gr, eng_notation
+from gnuradio.gr.pubsub import pubsub
 from gnuradio.eng_option import eng_option
-from gnuradio import eng_notation
+from gnuradio import usrp_options
 from optparse import OptionParser
 import sys
+import math
 
+n2s = eng_notation.num_to_str
 
-class my_top_block(gr.top_block):
-    def __init__ (self, nsamples):
+waveforms = { gr.GR_SIN_WAVE   : "Complex Sinusoid",
+              gr.GR_CONST_WAVE : "Constant",
+              gr.GR_GAUSSIAN   : "Gaussian Noise",
+              gr.GR_UNIFORM    : "Uniform Noise",
+              "2tone"          : "Two Tone",
+              "sweep"          : "Sweep" }
+
+#
+# GUI-unaware GNU Radio flowgraph.  This may be used either with command
+# line applications or GUI applications.
+#
+class top_block(gr.top_block, pubsub):
+    def __init__(self, options, args):
         gr.top_block.__init__(self)
+        pubsub.__init__(self)
+        self._verbose = options.verbose
+        #initialize values from options
+        self._setup_usrpx(options)
+        self.subscribe(INTERP_KEY, lambda i: setter(self, SAMP_RATE_KEY, self[DAC_RATE_KEY]/i))
+        self.subscribe(SAMP_RATE_KEY, lambda e: setter(self, LINK_RATE_KEY, e*32))
+        self[INTERP_KEY] = options.interp or 16
+        self[TX_FREQ_KEY] = options.tx_freq
+        self[AMPLITUDE_KEY] = options.amplitude
+        self[WAVEFORM_FREQ_KEY] = options.waveform_freq
+        self[WAVEFORM_OFFSET_KEY] = options.offset
+        self[WAVEFORM2_FREQ_KEY] = options.waveform2_freq
+        self[BB_FREQ_KEY] = 0
+        self[DDC_FREQ_KEY] = 0
+        #subscribe set methods
+        self.subscribe(INTERP_KEY, self.set_interp)
+        self.subscribe(GAIN_KEY, self.set_gain)
+        self.subscribe(TX_FREQ_KEY, self.set_freq)
+        self.subscribe(AMPLITUDE_KEY, self.set_amplitude)
+        self.subscribe(WAVEFORM_FREQ_KEY, self.set_waveform_freq)
+        self.subscribe(WAVEFORM2_FREQ_KEY, self.set_waveform2_freq)
+        self.subscribe(TYPE_KEY, self.set_waveform)
+        #force update on pubsub keys
+        for key in (INTERP_KEY, GAIN_KEY, TX_FREQ_KEY,
+            AMPLITUDE_KEY, WAVEFORM_FREQ_KEY, WAVEFORM_OFFSET_KEY, WAVEFORM2_FREQ_KEY):
+            self[key] = self[key]
+        self[TYPE_KEY] = options.type #set type last
+
+    def _setup_usrpx(self, options):
+        self._u = usrp_options.create_usrp_sink(options)
+        self.publish(DESC_KEY, lambda: str(self._u))
+        self.publish(DAC_RATE_KEY, self._u.dac_rate)
+        self.publish(FREQ_RANGE_KEY, self._u.freq_range)
+        self.publish(GAIN_RANGE_KEY, self._u.gain_range)
+        self.publish(GAIN_KEY, self._u.gain)
+        if self._verbose: print str(self._u)
+
+    def _set_tx_amplitude(self, ampl):
+        """
+        Sets the transmit amplitude sent to the USRP
+        @param ampl the amplitude or None for automatic
+        """
+        ampl_range = self[AMPL_RANGE_KEY]
+        if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0]
+        self[AMPLITUDE_KEY] = max(ampl_range[0], min(ampl, ampl_range[1]))
+
+    def set_interp(self, interp):
+        if not self._u.set_interp(interp):
+            raise RuntimeError("Failed to set interpolation rate %i" % (interp,))
+
+        if self._verbose:
+            print "USRP interpolation rate:", interp
+            print "USRP IF bandwidth: %sHz" % (n2s(self[SAMP_RATE_KEY]),)
+
+        if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE):
+            self._src.set_sampling_freq(self[SAMP_RATE_KEY])
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_sampling_freq(self[SAMP_RATE_KEY])
+            self._src2.set_sampling_freq(self[SAMP_RATE_KEY])
+        elif self[TYPE_KEY] == "sweep":
+            self._src1.set_sampling_freq(self[SAMP_RATE_KEY])
+            self._src2.set_sampling_freq(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY])
+        else:
+            return True # Waveform not yet set
         
-        # controllable values
-        self.interp = 64
-        self.waveform_type = gr.GR_SIN_WAVE
-        self.waveform_ampl = 16000
-        self.waveform_freq = 100.12345e3
-        self.waveform_offset = 0
-        self.nsamples = nsamples
-        self._instantiate_blocks ()
-        self.set_waveform_type (self.waveform_type)
-
-    def usb_freq (self):
-        return self.u.dac_freq() / self.interp
-
-    def usb_throughput (self):
-        return self.usb_freq () * 4
-        
-    def set_waveform_type (self, type):
-        '''
-        valid waveform types are: gr.GR_SIN_WAVE, gr.GR_CONST_WAVE,
-        gr.GR_UNIFORM and gr.GR_GAUSSIAN
-        '''
-        self._configure_graph (type)
-        self.waveform_type = type
-
-    def set_waveform_ampl (self, ampl):
-        self.waveform_ampl = ampl
-        self.siggen.set_amplitude (ampl)
-        self.noisegen.set_amplitude (ampl)
-
-    def set_waveform_freq (self, freq):
-        self.waveform_freq = freq
-        self.siggen.set_frequency (freq)
-        
-    def set_waveform_offset (self, offset):
-        self.waveform_offset = offset
-        self.siggen.set_offset (offset)
-
-    def set_interpolator (self, interp):
-        self.interp = interp
-        self.siggen.set_sampling_freq (self.usb_freq ())
-        self.u.set_interp_rate (interp)
-
-    def _instantiate_blocks (self):
-        self.src = None
-        self.u = usrp.sink_c (0, self.interp)
-        
-        self.siggen = gr.sig_source_c (self.usb_freq (),
-                                       gr.GR_SIN_WAVE,
-                                       self.waveform_freq,
-                                       self.waveform_ampl,
-                                       self.waveform_offset)
-
-        self.noisegen = gr.noise_source_c (gr.GR_UNIFORM,
-                                           self.waveform_ampl)
-
-        self.head = None
-        if self.nsamples > 0:
-            self.head = gr.head(gr.sizeof_gr_complex, int(self.nsamples))
-
-        # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
-
-    def _configure_graph (self, type):
-        try:
-            self.lock()
-            self.disconnect_all ()
-
-            if self.head:
-                self.connect(self.head, self.u)
-                tail = self.head
-            else:
-                tail = self.u
-                
-            if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
-                self.connect (self.siggen, tail)
-                # self.connect (self.siggen, self.file_sink)
-                self.siggen.set_waveform (type)
-                self.src = self.siggen
-            elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
-                self.connect (self.noisegen, tail)
-                self.noisegen.set_type (type)
-                self.src = self.noisegen
-            else:
-                raise ValueError, type
-        finally:
-            self.unlock()
+        if self._verbose: print "Set interpolation rate to:", interp
+        return True
+
+    def set_gain(self, gain):
+        if gain is None:
+            g = self[GAIN_RANGE_KEY]
+            gain = float(g[0]+g[1])/2
+            if self._verbose:
+                print "Using auto-calculated mid-point TX gain"
+            self[GAIN_KEY] = gain
+            return
+        self._u.set_gain(gain)
+        if self._verbose:
+            print "Set TX gain to:", gain
 
     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=0,
-                       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 ("-g", "--gain", type="eng_float", default=None,
-                       help="set output gain to GAIN [default=%default]")
-    parser.add_option ("-o", "--offset", type="eng_float", default=0,
-                       help="set waveform offset to OFFSET [default=%default]")
-    parser.add_option ("-N", "--nsamples", type="eng_float", default=0,
-                       help="set number of samples to transmit [default=+inf]")
-    (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
-
-    tb = my_top_block(options.nsamples)
-    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(tb.u)
-
-    m = usrp.determine_tx_mux_value(tb.u, options.tx_subdev_spec)
-    #print "mux = %#04x" % (m,)
-    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:
-        tb.subdev.set_gain(tb.subdev.gain_range()[1])    # set max Tx gain
-    else:
-        tb.subdev.set_gain(options.gain)    # set max Tx gain
-
-    if not tb.set_freq(options.rf_freq):
-        sys.stderr.write('Failed to set RF frequency\n')
-        raise SystemExit
+        if target_freq is None:
+            f = self[FREQ_RANGE_KEY]
+            target_freq = float(f[0]+f[1])/2.0
+            if self._verbose:
+                print "Using auto-calculated mid-point frequency"
+            self[TX_FREQ_KEY] = target_freq
+            return
+
+        tr = self._u.set_center_freq(target_freq)
+        fs = "%sHz" % (n2s(target_freq),)
+        if tr is not None:
+            self._freq = target_freq
+            self[DDC_FREQ_KEY] = tr.dxc_freq
+            self[BB_FREQ_KEY] = tr.baseband_freq
+            if self._verbose:
+                print "Set center frequency to", fs
+                print "Tx baseband frequency: %sHz" % (n2s(tr.baseband_freq),)
+                print "Tx DDC frequency: %sHz" % (n2s(tr.dxc_freq),)
+                print "Tx residual frequency: %sHz" % (n2s(tr.residual_freq),)
+        elif self._verbose: print "Failed to set freq." 
+        return tr
+
+    def set_waveform_freq(self, freq):
+        if self[TYPE_KEY] == gr.GR_SIN_WAVE:
+            self._src.set_frequency(freq)
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_frequency(freq)
+        elif self[TYPE_KEY] == 'sweep':
+            #there is no set sensitivity, redo fg
+            self[TYPE_KEY] = self[TYPE_KEY]
+        return True
+
+    def set_waveform2_freq(self, freq):
+        if freq is None:
+            self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY]
+            return
+        if self[TYPE_KEY] == "2tone":
+            self._src2.set_frequency(freq)
+        elif self[TYPE_KEY] == "sweep":
+            self._src1.set_frequency(freq)
+        return True
+
+    def set_waveform(self, type):
+        self.lock()
+        self.disconnect_all()
+        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+            self._src = gr.sig_source_c(self[SAMP_RATE_KEY],      # Sample rate
+                                        type,                # Waveform type
+                                        self[WAVEFORM_FREQ_KEY], # Waveform frequency
+                                        self[AMPLITUDE_KEY],     # Waveform amplitude
+                                        self[WAVEFORM_OFFSET_KEY])        # Waveform offset
+        elif type == gr.GR_GAUSSIAN or type == gr.GR_UNIFORM:
+            self._src = gr.noise_source_c(type, self[AMPLITUDE_KEY])
+        elif type == "2tone":
+            self._src1 = gr.sig_source_c(self[SAMP_RATE_KEY],
+                                         gr.GR_SIN_WAVE,
+                                         self[WAVEFORM_FREQ_KEY],
+                                         self[AMPLITUDE_KEY]/2.0,
+                                         0)
+            if(self[WAVEFORM2_FREQ_KEY] is None):
+                self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY]
+
+            self._src2 = gr.sig_source_c(self[SAMP_RATE_KEY],
+                                         gr.GR_SIN_WAVE,
+                                         self[WAVEFORM2_FREQ_KEY],
+                                         self[AMPLITUDE_KEY]/2.0,
+                                         0)
+            self._src = gr.add_cc()
+            self.connect(self._src1,(self._src,0))
+            self.connect(self._src2,(self._src,1))
+        elif type == "sweep":
+            # rf freq is center frequency
+            # waveform_freq is total swept width
+            # waveform2_freq is sweep rate
+            # will sweep from (rf_freq-waveform_freq/2) to (rf_freq+waveform_freq/2)
+            if self[WAVEFORM2_FREQ_KEY] is None:
+                self[WAVEFORM2_FREQ_KEY] = 0.1
+
+            self._src1 = gr.sig_source_f(self[SAMP_RATE_KEY],
+                                         gr.GR_TRI_WAVE,
+                                         self[WAVEFORM2_FREQ_KEY],
+                                         1.0,
+                                         -0.5)
+            self._src2 = gr.frequency_modulator_fc(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY])
+            self._src = gr.multiply_const_cc(self[AMPLITUDE_KEY])
+            self.connect(self._src1,self._src2,self._src)
+        else:
+            raise RuntimeError("Unknown waveform type")
+
+        self.connect(self._src, self._u)
+        self.unlock()
+
+        if self._verbose:
+            print "Set baseband modulation to:", waveforms[type]
+            if type == gr.GR_SIN_WAVE:
+                print "Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
+                print "Initial phase:", self[WAVEFORM_OFFSET_KEY]
+            elif type == "2tone":
+                print "Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
+                print "Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
+            elif type == "sweep":
+                print "Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0))
+                print "Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
+            print "TX amplitude:", self[AMPLITUDE_KEY]
+
+
+    def set_amplitude(self, amplitude):
+        if amplitude < 0.0 or amplitude > 1.0:
+            if self._verbose: print "Amplitude out of range:", amplitude
+            return False
+
+        if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE, gr.GR_GAUSSIAN, gr.GR_UNIFORM):
+            self._src.set_amplitude(amplitude)
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_amplitude(amplitude/2.0)
+            self._src2.set_amplitude(amplitude/2.0)
+        elif self[TYPE_KEY] == "sweep":
+            self._src.set_k(amplitude)
+        else:
+            return True # Waveform not yet set
+        
+        if self._verbose: print "Set amplitude to:", amplitude
+        return True
+
+def get_options():
+    usage="%prog: [options]"
+
+    parser = OptionParser(option_class=eng_option, usage=usage)
+    usrp_options.add_tx_options(parser)
+    parser.add_option("-f", "--tx-freq", type="eng_float", default=None,
+                      help="Set carrier frequency to FREQ [default=mid-point]", metavar="FREQ")
+    parser.add_option("-x", "--waveform-freq", type="eng_float", default=0,
+                      help="Set baseband waveform frequency to FREQ [default=%default]")
+    parser.add_option("-y", "--waveform2-freq", type="eng_float", default=None,
+                      help="Set 2nd waveform frequency to FREQ [default=%default]")
+    parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
+                      help="Generate a carrier modulated by a complex sine wave", default=gr.GR_SIN_WAVE)
+    parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, 
+                      help="Generate a constant carrier")
+    parser.add_option("--offset", type="eng_float", default=0,
+                      help="Set waveform phase offset to OFFSET [default=%default]")
+    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("--2tone", dest="type", action="store_const", const="2tone",
+                      help="Generate Two Tone signal for IMD testing")
+    parser.add_option("--sweep", dest="type", action="store_const", const="sweep",
+                      help="Generate a swept sine wave")
+    parser.add_option("-A", "--amplitude", type="eng_float", default=0.15,
+                      help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", metavar="AMPL")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="Use verbose console output [default=%default]")
+
+    (options, args) = parser.parse_args()
+
+    return (options, args)
+
+# If this script is executed, the following runs. If it is imported, the below does not run.
+def main():
+    if gr.enable_realtime_scheduling() != gr.RT_OK:
+        print "Note: failed to enable realtime scheduling, continuing"
     
-    tb.subdev.set_enable(True)                       # enable transmitter
-
+    # Grab command line options and create top block
     try:
-        tb.run()
-    except KeyboardInterrupt:
-        pass
-
-
-if __name__ == '__main__':
-    main ()
+        (options, args) = get_options()
+        tb = top_block(options, args)
+
+    except RuntimeError, e:
+        print e
+        sys.exit(1)
+
+    tb.start()
+    raw_input('Press Enter to quit: ')
+    tb.stop()
+    tb.wait()
+
+# Make sure to create the top block (tb) within a function:
+# That code in main will allow tb to go out of scope on return,
+# which will call the decontructor on usrp and stop transmit.
+# Whats odd is that grc works fine with tb in the __main__,
+# perhaps its because the try/except clauses around tb.
+if __name__ == "__main__": main()
diff --git a/gr-utils/src/python/usrp_siggen_gui.py b/gr-utils/src/python/usrp_siggen_gui.py
new file mode 100755 (executable)
index 0000000..47d47bd
--- /dev/null
@@ -0,0 +1,317 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import wx
+from gnuradio import gr
+from gnuradio.gr.pubsub import pubsub
+from gnuradio.wxgui import gui, forms
+import usrp_siggen
+import sys, math
+
+class app_gui(pubsub):
+    def __init__(self, frame, panel, vbox, top_block, options, args):
+        pubsub.__init__(self)
+        self.frame = frame      # Use for top-level application window frame
+        self.panel = panel      # Use as parent class for created windows
+        self.vbox = vbox        # Use as sizer for created windows
+        self.tb = top_block     # GUI-unaware flowgraph class
+        self.options = options  # Supplied command-line options
+        self.args = args        # Supplied command-line arguments
+        self.build_gui()
+
+    # Event response handlers
+    def evt_set_status_msg(self, msg):
+        self.frame.SetStatusText(msg, 0)
+
+    # GUI construction
+    def build_gui(self):
+        self.vbox.AddSpacer(5)
+        self.vbox.AddStretchSpacer()
+        ##################################################
+        # Baseband controls
+        ##################################################
+        bb_vbox = forms.static_box_sizer(parent=self.panel, label="Baseband Modulation", orient=wx.VERTICAL, bold=True)
+        self.vbox.Add(bb_vbox, 0, wx.EXPAND)
+        sine_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        sweep_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        tone_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        #callback to show/hide forms
+        def set_type(type):
+            sine_bb_hbox.ShowItems(type == gr.GR_SIN_WAVE)
+            sweep_bb_hbox.ShowItems(type == 'sweep')
+            tone_bb_hbox.ShowItems(type == '2tone')
+            self.vbox.Layout()
+        self.tb.subscribe(usrp_siggen.TYPE_KEY, set_type)
+        #create sine forms
+        sine_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=sine_bb_hbox,
+            label='Frequency (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sine_bb_hbox.AddStretchSpacer()
+        #create sweep forms
+        sweep_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=sweep_bb_hbox,
+            label='Sweep Width (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sweep_bb_hbox.AddStretchSpacer()
+        forms.text_box(
+            parent=self.panel, sizer=sweep_bb_hbox,
+            label='Sweep Rate (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM2_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sweep_bb_hbox.AddStretchSpacer()
+        #create 2tone forms
+        tone_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=tone_bb_hbox,
+            label='Tone 1 (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        tone_bb_hbox.AddStretchSpacer()
+        forms.text_box(
+            parent=self.panel, sizer=tone_bb_hbox,
+            label='Tone 2 (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM2_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        tone_bb_hbox.AddStretchSpacer()
+        forms.radio_buttons(
+            parent=self.panel, sizer=bb_vbox,
+            choices=usrp_siggen.waveforms.keys(),
+            labels=usrp_siggen.waveforms.values(),
+            ps=self.tb,
+            key=usrp_siggen.TYPE_KEY,
+            style=wx.NO_BORDER | wx.RA_HORIZONTAL,
+        )
+        bb_vbox.AddSpacer(10)
+        bb_vbox.Add(sine_bb_hbox, 0, wx.EXPAND)
+        bb_vbox.Add(sweep_bb_hbox, 0, wx.EXPAND)
+        bb_vbox.Add(tone_bb_hbox, 0, wx.EXPAND)
+        set_type(self.tb[usrp_siggen.TYPE_KEY])
+        ##################################################
+        # Frequency controls
+        ##################################################
+        fc_vbox = forms.static_box_sizer(parent=self.panel, label="Center Frequency", orient=wx.VERTICAL, bold=True)
+        fc_vbox.AddSpacer(5)
+        # First row of frequency controls (center frequency)
+        freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
+        fc_vbox.AddSpacer(10)
+        # Second row of frequency controls (results)
+        tr_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        fc_vbox.Add(tr_hbox, 0, wx.EXPAND)
+        fc_vbox.AddSpacer(5)
+        # Add frequency controls to top window sizer
+        self.vbox.Add(fc_vbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        freq_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=freq_hbox,
+            proportion=1,
+            converter=forms.float_converter(),
+            ps=self.tb,
+            key=usrp_siggen.TX_FREQ_KEY,
+        )
+        freq_hbox.AddSpacer(10)
+        forms.slider(
+            parent=self.panel, sizer=freq_hbox,
+            proportion=2,
+            ps=self.tb,
+            key=usrp_siggen.TX_FREQ_KEY,
+            minimum=self.tb[usrp_siggen.FREQ_RANGE_KEY][0],
+            maximum=self.tb[usrp_siggen.FREQ_RANGE_KEY][1],
+            num_steps=100,
+        )
+        freq_hbox.AddSpacer(5)
+        tr_hbox.AddSpacer(5)
+        forms.static_text(
+            parent=self.panel, sizer=tr_hbox,
+            label='Daughterboard (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.BB_FREQ_KEY,
+            converter=forms.float_converter(),
+            proportion=1,
+        )
+        tr_hbox.AddSpacer(10)
+        forms.static_text(
+            parent=self.panel, sizer=tr_hbox,
+            label='USRP DDC (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.DDC_FREQ_KEY,
+            converter=forms.float_converter(),
+            proportion=1,
+        )
+        tr_hbox.AddSpacer(5)
+        ##################################################
+        # Amplitude controls
+        ##################################################
+        amp_hbox = forms.static_box_sizer(parent=self.panel, label="Amplitude", orient=wx.VERTICAL, bold=True)
+        amp_hbox.AddSpacer(5)
+        # First row of amp controls (ampl)
+        lvl_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        amp_hbox.Add(lvl_hbox, 0, wx.EXPAND)
+        amp_hbox.AddSpacer(10)
+        # Second row of amp controls (tx gain)
+        gain_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        amp_hbox.Add(gain_hbox, 0, wx.EXPAND)
+        amp_hbox.AddSpacer(5)
+        self.vbox.Add(amp_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        lvl_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=lvl_hbox,
+            proportion=1,
+            converter=forms.float_converter(),
+            ps=self.tb,
+            key=usrp_siggen.AMPLITUDE_KEY,
+            label="Level (0.0-1.0)",
+        )
+        lvl_hbox.AddSpacer(10)
+        forms.log_slider(
+            parent=self.panel, sizer=lvl_hbox,
+            proportion=2,
+            ps=self.tb,
+            key=usrp_siggen.AMPLITUDE_KEY,
+            min_exp=-6,
+            max_exp=0,
+            base=10,
+            num_steps=100,
+        )
+        lvl_hbox.AddSpacer(5)
+        if self.tb[usrp_siggen.GAIN_RANGE_KEY][0] < self.tb[usrp_siggen.GAIN_RANGE_KEY][1]:
+            gain_hbox.AddSpacer(5)
+            forms.text_box(
+                parent=self.panel, sizer=gain_hbox,
+                proportion=1,
+                converter=forms.float_converter(),
+                ps=self.tb,
+                key=usrp_siggen.GAIN_KEY,
+                label="TX Gain (dB)",
+            )
+            gain_hbox.AddSpacer(10)
+            forms.slider(
+                parent=self.panel, sizer=gain_hbox,
+                proportion=2,
+                ps=self.tb,
+                key=usrp_siggen.GAIN_KEY,
+                minimum=self.tb[usrp_siggen.GAIN_RANGE_KEY][0],
+                maximum=self.tb[usrp_siggen.GAIN_RANGE_KEY][1],
+                step_size=self.tb[usrp_siggen.GAIN_RANGE_KEY][2],
+            )
+            gain_hbox.AddSpacer(5)
+        ##################################################
+        # Sample Rate controls
+        ##################################################
+        sam_hbox = forms.static_box_sizer(parent=self.panel, label="Sample Rate", orient=wx.HORIZONTAL, bold=True)
+        self.vbox.Add(sam_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        sam_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=sam_hbox,
+            converter=forms.int_converter(),
+            ps=self.tb,
+            key=usrp_siggen.INTERP_KEY,
+            label="Interpolation",
+        )
+        sam_hbox.AddStretchSpacer(20)
+        forms.static_text(
+            parent=self.panel, sizer=sam_hbox,
+            label='Sample Rate (sps)',
+            ps=self.tb,
+            key=usrp_siggen.SAMP_RATE_KEY,
+            converter=forms.float_converter(),
+        )
+        sam_hbox.AddStretchSpacer(20)
+        forms.static_text(
+            parent=self.panel, sizer=sam_hbox,
+            label='Link Rate (bits/sec)',
+            ps=self.tb,
+            key=usrp_siggen.LINK_RATE_KEY,
+            converter=forms.float_converter(),
+        )
+        sam_hbox.AddSpacer(5)
+        ##################################################
+        # USRP status
+        ##################################################
+        u2_hbox = forms.static_box_sizer(parent=self.panel, label="USRP Status", orient=wx.HORIZONTAL, bold=True)
+        self.vbox.Add(u2_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        u2_hbox.AddSpacer(10)
+        forms.static_text(
+            parent=self.panel, sizer=u2_hbox,
+            ps=self.tb,
+            key=usrp_siggen.DESC_KEY,
+            converter=forms.str_converter(),
+        )
+        self.vbox.AddSpacer(5)
+        self.vbox.AddStretchSpacer()
+
+def main():
+    try:
+        # Get command line parameters
+        (options, args) = usrp_siggen.get_options()
+
+        # Create the top block using these
+        tb = usrp_siggen.top_block(options, args)
+
+        # Create the GUI application
+        app = gui.app(top_block=tb,                    # Constructed top block
+                      gui=app_gui,                     # User interface class
+                      options=options,                 # Command line options
+                      args=args,                       # Command line args
+                      title="USRP Signal Generator",  # Top window title
+                      nstatus=1,                       # Number of status lines
+                      start=True,                      # Whether to start flowgraph
+                      realtime=True)                   # Whether to set realtime priority
+
+        # And run it
+        app.MainLoop()
+
+    except RuntimeError, e:
+        print e
+        sys.exit(1)
+
+# Make sure to create the top block (tb) within a function:
+# That code in main will allow tb to go out of scope on return,
+# which will call the decontructor on usrp and stop transmit.
+# Whats odd is that grc works fine with tb in the __main__,
+# perhaps its because the try/except clauses around tb.
+if __name__ == "__main__": main()
diff --git a/gr-video-sdl/.gitignore b/gr-video-sdl/.gitignore
new file mode 100644 (file)
index 0000000..53edad3
--- /dev/null
@@ -0,0 +1,32 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
+/stamp-h1.in
+/stamp-h2.in
index 2b6e6c8f33e7f8543497fae7289d13dd5732fd84..75efb3b602650d5030c121e4d539634a955e619e 100644 (file)
@@ -22,3 +22,6 @@
 include $(top_srcdir)/Makefile.common
 
 SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-video-sdl.pc
diff --git a/gr-video-sdl/gnuradio-video-sdl.pc.in b/gr-video-sdl/gnuradio-video-sdl.pc.in
new file mode 100644 (file)
index 0000000..8586a28
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-comedi
+Description: GNU Radio blocks for the SDL library
+Requires: gnuradio-core sdl
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-video-sdl
+Cflags: -I${includedir}
diff --git a/gr-video-sdl/src/.gitignore b/gr-video-sdl/src/.gitignore
new file mode 100644 (file)
index 0000000..e068ddb
--- /dev/null
@@ -0,0 +1,12 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/video_sdl.cc
+/video_sdl.py
+/run_tests
index 04139afde5f51d5516a544d5e8192c4381605f69..45cedfb212a518936f5c4700397553ed935d13bf 100644 (file)
@@ -23,22 +23,33 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = run_tests.in
 
-TESTS = run_tests
-
-DISTCLEANFILES = run_tests
+AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(SDL_CFLAGS) \
+       $(WITH_INCLUDES)
 
 noinst_PYTHON =                                \
        qa_video_sdl.py
 
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(SDL_CFLAGS) \
-       $(WITH_INCLUDES)
-
 grinclude_HEADERS =                    \
        video_sdl_sink_uc.h             \
        video_sdl_sink_s.h
 
+lib_LTLIBRARIES = libgnuradio-video-sdl.la
+
+libgnuradio_video_sdl_la_SOURCES =     \
+       video_sdl_sink_uc.cc            \
+       video_sdl_sink_s.cc
+
+libgnuradio_video_sdl_la_LIBADD =      \
+       $(SDL_LIBS)                     \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_video_sdl_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS)
+
+if PYTHON
 #################################
 # SWIG interface and library
+TESTS = run_tests
+DISTCLEANFILES = run_tests
 
 TOP_SWIG_IFILES =                      \
        video_sdl.i
@@ -50,15 +61,9 @@ TOP_SWIG_IFILES =                    \
 video_sdl_pythondir_category =         \
        gnuradio
 
-# additional sources for the SWIG-generated library
-video_sdl_la_swig_sources =            \
-       video_sdl_sink_uc.cc            \
-       video_sdl_sink_s.cc
-
 # additional libraries for linking with the SWIG-generated library
 video_sdl_la_swig_libadd =             \
-       $(SDL_LIBS)                     \
-       $(GNURADIO_CORE_LA)
+       libgnuradio-video-sdl.la
 
 include $(top_srcdir)/Makefile.swig
 
@@ -67,3 +72,4 @@ BUILT_SOURCES = $(swig_built_sources)
 
 # Do not distribute the output of SWIG
 no_dist_files = $(swig_built_sources)
+endif
diff --git a/gr-wxgui/.gitignore b/gr-wxgui/.gitignore
new file mode 100644 (file)
index 0000000..cdcf41b
--- /dev/null
@@ -0,0 +1,30 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/mkinstalldirs
+/py-compile
+/stamp-h
+/stamp-h.in
+/stamp-h1
index d0680d7ec688c37b739c43d44a7adc2f323d2034..335ebe43f8f8d06c72498b5924688c1cb10644fd 100644 (file)
@@ -26,10 +26,12 @@ EXTRA_DIST = \
     README \
     README.gl
 
+if PYTHON
 SUBDIRS = src
 
-etcdir = $(gr_sysconfdir)
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = gr-wxgui.conf
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = gr-wxgui.pc
+endif
index a3e352f0f7f3bffe49c5bdf817fdea8581530b94..f7138978951e9aeca719a405b230afd730c48377 100644 (file)
@@ -6,6 +6,6 @@ includedir=@includedir@
 Name: gr-wxgui
 Description: A simple wx gui for GNU Radio applications
 Requires: gnuradio-core
-Version: @VERSION@
+Version: @LIBVER@
 Libs:
 Cflags:
diff --git a/gr-wxgui/src/.gitignore b/gr-wxgui/src/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
diff --git a/gr-wxgui/src/python/.gitignore b/gr-wxgui/src/python/.gitignore
new file mode 100644 (file)
index 0000000..f9c5da0
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
index e06298a2d081b93ae561e93b421df0124e2b2e40..2382d599c0b9a96d72f1506640f9afa14f0e47d9 100644 (file)
@@ -1,23 +1,23 @@
 #
-# Copyright 2004,2005,2008 Free Software Foundation, Inc.
-# 
+# Copyright 2004,2005,2008,2009 Free Software Foundation, Inc.
+#
 # This file is part of GNU Radio
-# 
+#
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3, or (at your option)
 # any later version.
-# 
+#
 # GNU Radio is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with GNU Radio; see the file COPYING.  If not, write to
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
-# 
+#
 
 include $(top_srcdir)/Makefile.common
 
@@ -53,6 +53,7 @@ ourpython_PYTHON =                    \
        scopesink_nongl.py              \
        scopesink_gl.py                 \
        scope_window.py                 \
+       termsink.py                     \
        waterfallsink2.py               \
        waterfallsink_nongl.py          \
        waterfallsink_gl.py             \
index d555a1f055a9c3b824e2b71cb0c793c0ec562fcb..17a7dc0de550fa8ae5fa32da1f938d3f5fd7edd8 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
 # Boston, MA 02110-1301, USA.
 #
 
+##################################################
+# conditional disconnections of wx flow graph
+##################################################
+import wx
+from gnuradio import gr
+
+class wxgui_hb(object):
+       """
+       The wxgui hier block helper/wrapper class:
+       A hier block should inherit from this class to make use of the wxgui connect method.
+       To use, call wxgui_connect in place of regular connect; self.win must be defined.
+       The implementation will conditionally enable the copy block after the source (self).
+       This condition depends on weather or not the window is visible with the parent notebooks.
+       This condition will be re-checked on every ui update event.
+       """
+
+       def wxgui_connect(self, *points):
+               """
+               Use wxgui connect when the first point is the self source of the hb.
+               The win property of this object should be set to the wx window.
+               When this method tries to connect self to the next point,
+               it will conditionally make this connection based on the visibility state.
+               All other points will be connected normally.
+               """
+               try:
+                       assert points[0] == self or points[0][0] == self
+                       copy = gr.copy(self._hb.input_signature().sizeof_stream_item(0))
+                       handler = self._handler_factory(copy.set_enabled)
+                       handler(False) #initially disable the copy block
+                       self._bind_to_visible_event(win=self.win, handler=handler)
+                       points = list(points)
+                       points.insert(1, copy) #insert the copy block into the chain
+               except (AssertionError, IndexError): pass
+               self.connect(*points) #actually connect the blocks
+
+       @staticmethod
+       def _handler_factory(handler):
+               """
+               Create a function that will cache the visibility flag,
+               and only call the handler when that flag changes.
+               @param handler the function to call on a change
+               @return a function of 1 argument
+               """
+               cache = [None]
+               def callback(visible):
+                       if cache[0] == visible: return
+                       cache[0] = visible
+                       #print visible, handler
+                       handler(visible)
+               return callback
+
+       @staticmethod
+       def _bind_to_visible_event(win, handler):
+               """
+               Bind a handler to a window when its visibility changes.
+               Specifically, call the handler when the window visibility changes.
+               This condition is checked on every update ui event.
+               @param win the wx window
+               @param handler a function of 1 param
+               """
+               #is the window visible in the hierarchy
+               def is_wx_window_visible(my_win):
+                       while True:
+                               parent = my_win.GetParent()
+                               if not parent: return True #reached the top of the hierarchy
+                               #if we are hidden, then finish, otherwise keep traversing up
+                               if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False
+                               my_win = parent
+               #call the handler, the arg is shown or not
+               def handler_factory(my_win, my_handler):
+                       def callback(evt):
+                               my_handler(is_wx_window_visible(my_win))
+                               evt.Skip() #skip so all bound handlers are called
+                       return callback
+               handler = handler_factory(win, handler)
+               #bind the handler to all the parent notebooks
+               win.Bind(wx.EVT_UPDATE_UI, handler)
+
+##################################################
+# Helpful Functions
+##################################################
+
 #A macro to apply an index to a key
 index_key = lambda key, i: "%s_%d"%(key, i+1)
 
@@ -134,9 +216,29 @@ def get_min_max(samples):
        @param samples the array of real values
        @return a tuple of min, max
        """
-       scale_factor = 3
+       factor = 2.0
        mean = numpy.average(samples)
-       rms = numpy.max([scale_factor*((numpy.sum((samples-mean)**2)/len(samples))**.5), .1])
-       min = mean - rms
-       max = mean + rms
-       return min, max
+       std = numpy.std(samples)
+       fft = numpy.abs(numpy.fft.fft(samples - mean))
+       envelope = 2*numpy.max(fft)/len(samples)
+       ampl = max(std, envelope) or 0.1
+       return mean - factor*ampl, mean + factor*ampl
+
+def get_min_max_fft(fft_samps):
+       """
+       Get the minimum and maximum bounds for an array of fft samples.
+       @param samples the array of real values
+       @return a tuple of min, max
+       """
+       #get the peak level (max of the samples)
+       peak_level = numpy.max(fft_samps)
+       #separate noise samples
+       noise_samps = numpy.sort(fft_samps)[:len(fft_samps)/2]
+       #get the noise floor
+       noise_floor = numpy.average(noise_samps)
+       #get the noise deviation
+       noise_dev = numpy.std(noise_samps)
+       #determine the maximum and minimum levels
+       max_level = peak_level
+       min_level = noise_floor - abs(2*noise_dev)
+       return min_level, max_level
index b128a4a989a181291226b354992da2523c63b47e..f7c7caf07691be5e80be1fa1279277b35b4a1e82 100644 (file)
@@ -64,6 +64,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = forms.static_box_sizer(
                        parent=self, label='Options',
                        bold=True, orient=wx.VERTICAL,
index 5e1395701eaa9c923ea5c0280aa92c7a9ffdfbb3..9612f36ddec1f0679c72c8811181a45cd32582fe 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -27,6 +27,8 @@ ALPHA_KEY = 'alpha'
 AUTORANGE_KEY = 'autorange'
 AVERAGE_KEY = 'average'
 AVG_ALPHA_KEY = 'avg_alpha'
+USE_PERSISTENCE_KEY = 'use_persistence'
+PERSIST_ALPHA_KEY = 'persist_alpha'
 BASEBAND_FREQ_KEY = 'baseband_freq'
 BETA_KEY = 'beta'
 COLOR_MODE_KEY = 'color_mode'
@@ -41,6 +43,8 @@ MSG_KEY = 'msg'
 NUM_LINES_KEY = 'num_lines'
 OMEGA_KEY = 'omega'
 PEAK_HOLD_KEY = 'peak_hold'
+TRACE_STORE_KEY = 'trace_store'
+TRACE_SHOW_KEY = 'trace_show'
 REF_LEVEL_KEY = 'ref_level'
 RUNNING_KEY = 'running'
 SAMPLE_RATE_KEY = 'sample_rate'
@@ -67,3 +71,4 @@ MINIMUM_KEY = 'minimum'
 NUM_BINS_KEY = 'num_bins'
 FRAME_SIZE_KEY = 'frame_size'
 CHANNEL_OPTIONS_KEY = 'channel_options'
+SHOW_CONTROL_PANEL_KEY = 'show_control_panel'
index b3a1625b09b5ab412ce3f239c285d4c2c58a91ad..91bc65d9fb6a3142492b44a4cdc8cc553072e3dc 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Constellation sink block (wrapper for old wxgui)
 ##################################################
-class const_sink_c(gr.hier_block2):
+class const_sink_c(gr.hier_block2, common.wxgui_hb):
        """
        A constellation block with a gui window.
        """
@@ -94,8 +94,6 @@ class const_sink_c(gr.hier_block2):
                agc = gr.feedforward_agc_cc(16, 1)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_gr_complex*const_size, msgq, True)
-               #connect
-               self.connect(self, self._costas, self._retime, agc, sd, sink)
                #controller
                def setter(p, k, x): p[k] = x
                self.controller = pubsub()
@@ -131,5 +129,7 @@ class const_sink_c(gr.hier_block2):
                        sample_rate_key=SAMPLE_RATE_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, self._costas, self._retime, agc, sd, sink)
 
 
index fded1a8fa9caa1b1a48e46d773177ae8bcbbf0ee..f4f485f4b06030f67522ddb65162bebbc8b568c2 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -37,12 +37,18 @@ import forms
 ##################################################
 SLIDER_STEPS = 100
 AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
+PERSIST_ALPHA_MIN_EXP, PERSIST_ALPHA_MAX_EXP = -2, 0
 DEFAULT_WIN_SIZE = (600, 300)
 DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'fft_rate', 30)
-DIV_LEVELS = (1, 2, 5, 10, 20)
+DB_DIV_MIN, DB_DIV_MAX = 1, 20
 FFT_PLOT_COLOR_SPEC = (0.3, 0.3, 1.0)
 PEAK_VALS_COLOR_SPEC = (0.0, 0.8, 0.0)
-NO_PEAK_VALS = list()
+EMPTY_TRACE = list()
+TRACES = ('A', 'B')
+TRACES_COLOR_SPEC = {
+       'A': (1.0, 0.0, 0.0),
+       'B': (0.8, 0.0, 0.8),
+}
 
 ##################################################
 # FFT window control panel
@@ -59,11 +65,13 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                control_box.AddStretchSpacer()
                #checkboxes for average and peak hold
                options_box = forms.static_box_sizer(
-                       parent=self, sizer=control_box, label='Options',
+                       parent=self, sizer=control_box, label='Trace Options',
                        bold=True, orient=wx.VERTICAL,
                )
                forms.check_box(
@@ -90,17 +98,63 @@ class control_panel(wx.Panel):
                for widget in (avg_alpha_text, avg_alpha_slider):
                        parent.subscribe(AVERAGE_KEY, widget.Enable)
                        widget.Enable(parent[AVERAGE_KEY])
+                       parent.subscribe(AVERAGE_KEY, widget.ShowItems)
+                        #allways show initially, so room is reserved for them
+                       widget.ShowItems(True) # (parent[AVERAGE_KEY])
+
+                parent.subscribe(AVERAGE_KEY, self._update_layout)
+
+               forms.check_box(
+                       sizer=options_box, parent=self, label='Persistence',
+                       ps=parent, key=USE_PERSISTENCE_KEY,
+               )
+               #static text and slider for persist alpha
+               persist_alpha_text = forms.static_text(
+                       sizer=options_box, parent=self, label='Persist Alpha',
+                       converter=forms.float_converter(lambda x: '%.4f'%x),
+                       ps=parent, key=PERSIST_ALPHA_KEY, width=50,
+               )
+               persist_alpha_slider = forms.log_slider(
+                       sizer=options_box, parent=self,
+                       min_exp=PERSIST_ALPHA_MIN_EXP,
+                       max_exp=PERSIST_ALPHA_MAX_EXP,
+                       num_steps=SLIDER_STEPS,
+                       ps=parent, key=PERSIST_ALPHA_KEY,
+               )
+               for widget in (persist_alpha_text, persist_alpha_slider):
+                       parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
+                       widget.Enable(parent[USE_PERSISTENCE_KEY])
+                       parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
+                        #allways show initially, so room is reserved for them
+                       widget.ShowItems(True) # (parent[USE_PERSISTENCE_KEY])
+               
+                parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)
+
+               #trace menu
+               for trace in TRACES:
+                       trace_box = wx.BoxSizer(wx.HORIZONTAL)
+                       options_box.Add(trace_box, 0, wx.EXPAND)
+                       forms.check_box(
+                               sizer=trace_box, parent=self,
+                               ps=parent, key=TRACE_SHOW_KEY+trace,
+                               label='Trace %s'%trace,
+                       )
+                       trace_box.AddSpacer(10)
+                       forms.single_button(
+                               sizer=trace_box, parent=self,
+                               ps=parent, key=TRACE_STORE_KEY+trace,
+                               label='Store', style=wx.BU_EXACTFIT,
+                       )
+                       trace_box.AddSpacer(10)
                #radio buttons for div size
                control_box.AddStretchSpacer()
                y_ctrl_box = forms.static_box_sizer(
                        parent=self, sizer=control_box, label='Axis Options',
                        bold=True, orient=wx.VERTICAL,
                )
-               forms.radio_buttons(
-                       sizer=y_ctrl_box, parent=self,
-                       ps=parent, key=Y_PER_DIV_KEY,
-                       style=wx.RA_VERTICAL|wx.NO_BORDER, choices=DIV_LEVELS,
-                       labels=map(lambda x: '%s dB/div'%x, DIV_LEVELS),
+               forms.incr_decr_buttons(
+                       parent=self, sizer=y_ctrl_box, label='dB/Div',
+                       on_incr=self._on_incr_db_div, on_decr=self._on_decr_db_div,
                )
                #ref lvl buttons
                forms.incr_decr_buttons(
@@ -122,6 +176,7 @@ class control_panel(wx.Panel):
                )
                #set sizer
                self.SetSizerAndFit(control_box)
+
                #mouse wheel event
                def on_mouse_wheel(event):
                        if event.GetWheelRotation() < 0: self._on_incr_ref_level(event)
@@ -135,6 +190,18 @@ class control_panel(wx.Panel):
                self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[Y_PER_DIV_KEY]
        def _on_decr_ref_level(self, event):
                self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[Y_PER_DIV_KEY]
+       def _on_incr_db_div(self, event):
+               self.parent[Y_PER_DIV_KEY] = min(DB_DIV_MAX, common.get_clean_incr(self.parent[Y_PER_DIV_KEY]))
+       def _on_decr_db_div(self, event):
+               self.parent[Y_PER_DIV_KEY] = max(DB_DIV_MIN, common.get_clean_decr(self.parent[Y_PER_DIV_KEY]))
+       ##################################################
+       # subscriber handlers
+       ##################################################
+        def _update_layout(self,key):
+          # Just ignore the key value we get
+          # we only need to now that the visability or size of something has changed
+          self.parent.Layout()
+          #self.parent.Fit()          
 
 ##################################################
 # FFT window with plotter and control panel
@@ -157,15 +224,17 @@ class fft_window(wx.Panel, pubsub.pubsub):
                avg_alpha_key,
                peak_hold,
                msg_key,
+                use_persistence,
+                persist_alpha,
        ):
+
                pubsub.pubsub.__init__(self)
-               #ensure y_per_div
-               if y_per_div not in DIV_LEVELS: y_per_div = DIV_LEVELS[0]
                #setup
-               self.samples = list()
+               self.samples = EMPTY_TRACE
                self.real = real
                self.fft_size = fft_size
                self._reset_peak_vals()
+               self._traces = dict()
                #proxy the keys
                self.proxy(MSG_KEY, controller, msg_key)
                self.proxy(AVERAGE_KEY, controller, average_key)
@@ -179,6 +248,28 @@ class fft_window(wx.Panel, pubsub.pubsub):
                self[REF_LEVEL_KEY] = ref_level
                self[BASEBAND_FREQ_KEY] = baseband_freq
                self[RUNNING_KEY] = True
+               self[USE_PERSISTENCE_KEY] = use_persistence
+               self[PERSIST_ALPHA_KEY] = persist_alpha
+               for trace in TRACES:
+                       #a function that returns a function
+                       #so the function wont use local trace
+                       def new_store_trace(my_trace):
+                               def store_trace(*args):
+                                       self._traces[my_trace] = self.samples
+                                       self.update_grid()
+                               return store_trace
+                       def new_toggle_trace(my_trace):
+                               def toggle_trace(toggle):
+                                       #do an automatic store if toggled on and empty trace
+                                       if toggle and not len(self._traces[my_trace]):
+                                               self._traces[my_trace] = self.samples
+                                       self.update_grid()
+                               return toggle_trace
+                       self._traces[trace] = EMPTY_TRACE
+                       self[TRACE_STORE_KEY+trace] = False
+                       self[TRACE_SHOW_KEY+trace] = False
+                       self.subscribe(TRACE_STORE_KEY+trace, new_store_trace(trace))
+                       self.subscribe(TRACE_SHOW_KEY+trace, new_toggle_trace(trace))
                #init panel and plot
                wx.Panel.__init__(self, parent, style=wx.SIMPLE_BORDER)
                self.plotter = plotter.channel_plotter(self)
@@ -187,6 +278,8 @@ class fft_window(wx.Panel, pubsub.pubsub):
                self.plotter.enable_legend(True)
                self.plotter.enable_point_label(True)
                self.plotter.enable_grid_lines(True)
+                self.plotter.set_use_persistence(use_persistence)
+                self.plotter.set_persist_alpha(persist_alpha)
                #setup the box with plot and controls
                self.control_panel = control_panel(self)
                main_box = wx.BoxSizer(wx.HORIZONTAL)
@@ -194,7 +287,7 @@ class fft_window(wx.Panel, pubsub.pubsub):
                main_box.Add(self.control_panel, 0, wx.EXPAND)
                self.SetSizerAndFit(main_box)
                #register events
-               self.subscribe(AVERAGE_KEY, lambda x: self._reset_peak_vals())
+               self.subscribe(AVERAGE_KEY, self._reset_peak_vals)
                self.subscribe(MSG_KEY, self.handle_msg)
                self.subscribe(SAMPLE_RATE_KEY, self.update_grid)
                for key in (
@@ -202,28 +295,25 @@ class fft_window(wx.Panel, pubsub.pubsub):
                        Y_PER_DIV_KEY, X_DIVS_KEY,
                        Y_DIVS_KEY, REF_LEVEL_KEY,
                ): self.subscribe(key, self.update_grid)
+               self.subscribe(USE_PERSISTENCE_KEY, self.plotter.set_use_persistence)
+               self.subscribe(PERSIST_ALPHA_KEY, self.plotter.set_persist_alpha)
                #initial update
                self.update_grid()
 
+
        def autoscale(self, *args):
                """
                Autoscale the fft plot to the last frame.
                Set the dynamic range and reference level.
                """
                if not len(self.samples): return
-               #get the peak level (max of the samples)
-               peak_level = numpy.max(self.samples)
-               #get the noise floor (averge the smallest samples)
-               noise_floor = numpy.average(numpy.sort(self.samples)[:len(self.samples)/4])
-               #padding
-               noise_floor -= abs(noise_floor)*.5
-               peak_level += abs(peak_level)*.1
-               #set the reference level to a multiple of y divs
-               self[REF_LEVEL_KEY] = self[Y_DIVS_KEY]*math.ceil(peak_level/self[Y_DIVS_KEY])
+               min_level, max_level = common.get_min_max_fft(self.samples)
                #set the range to a clean number of the dynamic range
-               self[Y_PER_DIV_KEY] = common.get_clean_num((peak_level - noise_floor)/self[Y_DIVS_KEY])
+               self[Y_PER_DIV_KEY] = common.get_clean_num(1+(max_level - min_level)/self[Y_DIVS_KEY])
+               #set the reference level to a multiple of y per div
+               self[REF_LEVEL_KEY] = self[Y_PER_DIV_KEY]*round(.5+max_level/self[Y_PER_DIV_KEY])
 
-       def _reset_peak_vals(self): self.peak_vals = NO_PEAK_VALS
+       def _reset_peak_vals(self, *args): self.peak_vals = EMPTY_TRACE
 
        def handle_msg(self, msg):
                """
@@ -239,8 +329,8 @@ class fft_window(wx.Panel, pubsub.pubsub):
                samples = numpy.fromstring(msg, numpy.float32)[:self.fft_size] #only take first frame
                num_samps = len(samples)
                #reorder fft
-               if self.real: samples = samples[:num_samps/2]
-               else: samples = numpy.concatenate((samples[num_samps/2:], samples[:num_samps/2]))
+               if self.real: samples = samples[:(num_samps+1)/2]
+               else: samples = numpy.concatenate((samples[num_samps/2+1:], samples[:(num_samps+1)/2]))
                self.samples = samples
                #peak hold calculation
                if self[PEAK_HOLD_KEY]:
@@ -272,6 +362,15 @@ class fft_window(wx.Panel, pubsub.pubsub):
                The x axis depends on sample rate, baseband freq, and x divs.
                The y axis depends on y per div, y divs, and ref level.
                """
+               for trace in TRACES:
+                       channel = '%s'%trace.upper()
+                       if self[TRACE_SHOW_KEY+trace]:
+                               self.plotter.set_waveform(
+                                       channel=channel,
+                                       samples=self._traces[trace],
+                                       color_spec=TRACES_COLOR_SPEC[trace],
+                               )
+                       else: self.plotter.clear_waveform(channel=channel)
                #grid parameters
                sample_rate = self[SAMPLE_RATE_KEY]
                baseband_freq = self[BASEBAND_FREQ_KEY]
index 3f0a93fc8b3056fa34771ae998d17746d04a919e..e0306d919302caf335521bf810fbb3518d5a44d6 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -27,11 +27,12 @@ import common
 from gnuradio import gr, blks2
 from pubsub import pubsub
 from constants import *
+import math
 
 ##################################################
 # FFT sink block (wrapper for old wxgui)
 ##################################################
-class _fft_sink_base(gr.hier_block2):
+class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -52,9 +53,22 @@ class _fft_sink_base(gr.hier_block2):
                title='',
                size=fft_window.DEFAULT_WIN_SIZE,
                peak_hold=False,
+               win=None,
+                use_persistence=False,
+                persist_alpha=None,
+               **kwargs #do not end with a comma
        ):
                #ensure avg alpha
                if avg_alpha is None: avg_alpha = 2.0/fft_rate
+                #ensure analog alpha
+                if persist_alpha is None: 
+                  actual_fft_rate=float(sample_rate/fft_size)/float(max(1,int(float((sample_rate/fft_size)/fft_rate))))
+                  #print "requested_fft_rate ",fft_rate
+                  #print "actual_fft_rate    ",actual_fft_rate
+                  analog_cutoff_freq=0.5 # Hertz
+                  #calculate alpha from wanted cutoff freq
+                  persist_alpha = 1.0 - math.exp(-2.0*math.pi*analog_cutoff_freq/actual_fft_rate)
+                  
                #init
                gr.hier_block2.__init__(
                        self,
@@ -70,11 +84,12 @@ class _fft_sink_base(gr.hier_block2):
                        ref_scale=ref_scale,
                        avg_alpha=avg_alpha,
                        average=average,
+                       win=win,
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
-               #connect
-               self.connect(self, fft, sink)
+
+
                #controller
                self.controller = pubsub()
                self.controller.subscribe(AVERAGE_KEY, fft.set_average)
@@ -102,10 +117,14 @@ class _fft_sink_base(gr.hier_block2):
                        avg_alpha_key=AVG_ALPHA_KEY,
                        peak_hold=peak_hold,
                        msg_key=MSG_KEY,
+                        use_persistence=use_persistence,
+                        persist_alpha=persist_alpha,
                )
                common.register_access_methods(self, self.win)
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
                setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS
+               #connect
+               self.wxgui_connect(self, fft, sink)
 
 class fft_sink_f(_fft_sink_base):
        _fft_chain = blks2.logpwrfft_f
@@ -131,11 +150,14 @@ class test_app_block (stdgui2.std_top_block):
         fft_size = 256
 
         # build our flow graph
-        input_rate = 20.48e3
+        input_rate = 2048.0e3
+
+        #Generate some noise
+        noise =gr.noise_source_c(gr.GR_UNIFORM, 1.0/10)
 
         # Generate a complex sinusoid
         #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 57.50e3, 1)
 
         # We add these throttle blocks so that this demo doesn't
         # suck down all the CPU available.  Normally you wouldn't use these.
@@ -146,17 +168,25 @@ class test_app_block (stdgui2.std_top_block):
                             ref_level=0, y_per_div=20, y_divs=10)
         vbox.Add (sink1.win, 1, wx.EXPAND)
 
-        self.connect(src1, thr1, sink1)
+        combine1=gr.add_cc()
+        self.connect(src1, (combine1,0))
+        self.connect(noise,(combine1,1))
+        self.connect(combine1,thr1, sink1)
 
         #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 57.50e3, 1)
         thr2 = gr.throttle(gr.sizeof_float, input_rate)
         sink2 = fft_sink_f (panel, title="Real Data", fft_size=fft_size*2,
                             sample_rate=input_rate, baseband_freq=100e3,
                             ref_level=0, y_per_div=20, y_divs=10)
         vbox.Add (sink2.win, 1, wx.EXPAND)
 
-        self.connect(src2, thr2, sink2)
+        combine2=gr.add_ff()
+        c2f2=gr.complex_to_float()
+
+        self.connect(src2, (combine2,0))
+        self.connect(noise,c2f2,(combine2,1))
+        self.connect(combine2, thr2,sink2)
 
 def main ():
     app = stdgui2.stdapp (test_app_block, "FFT Sink Test App")
index ca5e91fdbea3d708a7927281505c8a133ad105bf..508b4e772f5b8f1ae741e1193ca6ee2048589710 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2003,2004,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -37,7 +37,7 @@ class fft_sink_base(object):
                  y_divs=8, ref_level=50,
                  sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate,
-                 average=False, avg_alpha=None, title='', peak_hold=False):
+                 average=False, avg_alpha=None, title='', peak_hold=False,use_persistence=False,persist_alpha=0.2):
 
         # initialize common attributes
         self.baseband_freq = baseband_freq
@@ -52,6 +52,9 @@ class fft_sink_base(object):
             self.avg_alpha = 2.0 / fft_rate
         else:
             self.avg_alpha = avg_alpha
+        self.use_persistence = use_persistence
+        self.persist_alpha = persist_alpha
+
         self.title = title
         self.peak_hold = peak_hold
         self.input_is_real = input_is_real
@@ -75,6 +78,14 @@ class fft_sink_base(object):
         self.peak_hold = enable
         self.win.set_peak_hold(enable)
 
+    def set_use_persistence(self, enable):
+        self.use_persistence = enable
+        self.win.set_use_persistence(enable)
+
+    def set_persist_alpha(self, persist_alpha):
+        self.persist_alpha = persist_alpha
+        self.win.set_persist_alpha(persist_alpha)
+
     def set_avg_alpha(self, avg_alpha):
         self.avg_alpha = avg_alpha
 
@@ -93,7 +104,7 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, use_persistence=False,persist_alpha=0.2, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_f",
                                 gr.io_signature(1, 1, gr.sizeof_float),
@@ -104,7 +115,7 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
                                sample_rate=sample_rate, fft_size=fft_size,
                                fft_rate=fft_rate,
                                average=average, avg_alpha=avg_alpha, title=title,
-                               peak_hold=peak_hold)
+                               peak_hold=peak_hold,use_persistence=use_persistence,persist_alpha=persist_alpha)
                                
         self.s2p = gr.stream_to_vector(gr.sizeof_float, self.fft_size)
         self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size,
@@ -131,12 +142,14 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
         self.win = fft_window(self, parent, size=size)
         self.set_average(self.average)
         self.set_peak_hold(self.peak_hold)
+        self.set_use_persistence(self.use_persistence)
+        self.set_persist_alpha(self.persist_alpha)
 
 class fft_sink_c(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, use_persistence=False,persist_alpha=0.2, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_c",
                                 gr.io_signature(1, 1, gr.sizeof_gr_complex),
@@ -147,7 +160,7 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
                                sample_rate=sample_rate, fft_size=fft_size,
                                fft_rate=fft_rate,
                                average=average, avg_alpha=avg_alpha, title=title,
-                               peak_hold=peak_hold)
+                               peak_hold=peak_hold, use_persistence=use_persistence,persist_alpha=persist_alpha)
 
         self.s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
         self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size,
@@ -173,6 +186,8 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
 
         self.win = fft_window(self, parent, size=size)
         self.set_average(self.average)
+        self.set_use_persistence(self.use_persistence)
+        self.set_persist_alpha(self.persist_alpha)
         self.set_peak_hold(self.peak_hold)
 
 
@@ -236,6 +251,9 @@ class control_panel(wx.Panel):
         self.average_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Average")
         self.average_check_box.Bind(wx.EVT_CHECKBOX, parent.on_average)
         control_box.Add(self.average_check_box, 0, wx.EXPAND)
+        self.use_persistence_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Persistence")
+        self.use_persistence_check_box.Bind(wx.EVT_CHECKBOX, parent.on_use_persistence)
+        control_box.Add(self.use_persistence_check_box, 0, wx.EXPAND)
         self.peak_hold_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Peak Hold")
         self.peak_hold_check_box.Bind(wx.EVT_CHECKBOX, parent.on_peak_hold) 
         control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND)
@@ -276,6 +294,7 @@ class control_panel(wx.Panel):
         """
         #update checkboxes
         self.average_check_box.SetValue(self.parent.fftsink.average)
+        self.use_persistence_check_box.SetValue(self.parent.fftsink.use_persistence)
         self.peak_hold_check_box.SetValue(self.parent.fftsink.peak_hold)
         #update radio buttons    
         try:
@@ -306,6 +325,10 @@ class fft_window (wx.Panel):
         
         self.peak_hold = False
         self.peak_vals = None
+
+        self.use_persistence=False
+        self.persist_alpha=0.2
+
         
         self.plot.SetEnableGrid (True)
         # self.SetEnableZoom (True)
@@ -394,6 +417,14 @@ class fft_window (wx.Panel):
         y_range = ymin, ymax
         self.plot.Draw (graphics, xAxis=x_range, yAxis=y_range, step=self.fftsink.y_per_div)        
 
+    def set_use_persistence(self, enable):
+        self.use_persistence = enable
+        self.plot.set_use_persistence( enable)
+
+    def set_persist_alpha(self, persist_alpha):
+        self.persist_alpha = persist_alpha
+        self.plot.set_persist_alpha(persist_alpha)
+
     def set_peak_hold(self, enable):
         self.peak_hold = enable
         self.peak_vals = None
@@ -403,6 +434,11 @@ class fft_window (wx.Panel):
         self.fftsink.set_average(evt.IsChecked())
         self.control_panel.update()
 
+    def on_use_persistence(self, evt):
+        # print "on_analog"
+        self.fftsink.set_use_persistence(evt.IsChecked())
+        self.control_panel.update()
+
     def on_peak_hold(self, evt):
         # print "on_peak_hold"
         self.fftsink.set_peak_hold(evt.IsChecked())
@@ -486,9 +522,11 @@ class fft_window (wx.Panel):
         self.id_y_per_div_10 = wx.NewId()
         self.id_y_per_div_20 = wx.NewId()
         self.id_average = wx.NewId()
+        self.id_use_persistence = wx.NewId()
         self.id_peak_hold = wx.NewId()
         
         self.plot.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        self.plot.Bind(wx.EVT_MENU, self.on_use_persistence, id=self.id_use_persistence)
         self.plot.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)
         self.plot.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
         self.plot.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
@@ -504,6 +542,7 @@ class fft_window (wx.Panel):
         menu = wx.Menu()
         self.popup_menu = menu
         menu.AppendCheckItem(self.id_average, "Average")
+        menu.AppendCheckItem(self.id_use_persistence, "Persistence")
         menu.AppendCheckItem(self.id_peak_hold, "Peak Hold")
         menu.Append(self.id_incr_ref_level, "Incr Ref Level")
         menu.Append(self.id_decr_ref_level, "Decr Ref Level")
@@ -519,6 +558,7 @@ class fft_window (wx.Panel):
 
         self.checkmarks = {
             self.id_average : lambda : self.fftsink.average,
+            self.id_use_persistence : lambda : self.fftsink.use_persistence,
             self.id_peak_hold : lambda : self.fftsink.peak_hold,
             self.id_y_per_div_1 : lambda : self.fftsink.y_per_div == 1,
             self.id_y_per_div_2 : lambda : self.fftsink.y_per_div == 2,
@@ -561,11 +601,11 @@ class test_app_block (stdgui2.std_top_block):
         fft_size = 256
 
         # build our flow graph
-        input_rate = 20.48e3
+        input_rate = 100*20.48e3
 
         # Generate a complex sinusoid
-        #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 100*2e3, 1)
+        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 100*5.75e3, 1)
 
         # We add these throttle blocks so that this demo doesn't
         # suck down all the CPU available.  Normally you wouldn't use these.
@@ -578,8 +618,8 @@ class test_app_block (stdgui2.std_top_block):
 
         self.connect(src1, thr1, sink1)
 
-        #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 100*2e3, 1)
+        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 100*5.75e3, 1)
         thr2 = gr.throttle(gr.sizeof_float, input_rate)
         sink2 = fft_sink_f (panel, title="Real Data", fft_size=fft_size*2,
                             sample_rate=input_rate, baseband_freq=100e3,
diff --git a/gr-wxgui/src/python/forms/.gitignore b/gr-wxgui/src/python/forms/.gitignore
new file mode 100644 (file)
index 0000000..a74b07a
--- /dev/null
@@ -0,0 +1 @@
+/*.pyc
index 9f757aa8410eb24b7d226e9c828da4caa8a2fd6c..db14d2752c19ba6f3fa891129e86dc71407607bf 100644 (file)
@@ -72,12 +72,14 @@ class bool_converter(abstract_converter):
                self._true = true
                self._false = false
        def external_to_internal(self, v):
-               return bool(v)
+               if v == self._true: return True
+               if v == self._false: return False
+               raise Exception, 'Value "%s" is not a possible option.'%v
        def internal_to_external(self, v):
                if v: return self._true
                else: return self._false
        def help(self):
-               return "Value must be cast-able to type bool."
+               return "Value must be in (%s, %s)."%(self._true, self._false)
 
 class eval_converter(abstract_converter):
        """
@@ -134,8 +136,7 @@ class slider_converter(abstract_converter):
                self._scaler = float(maximum - minimum)/num_steps
                self._cast = cast
        def external_to_internal(self, v):
-               #slider's internal representation is an integer
-               return int(round((v - self._offset)/self._scaler))
+               return (v - self._offset)/self._scaler
        def internal_to_external(self, v):
                return self._cast(v*self._scaler + self._offset)
        def help(self):
index c69315b0358906c531bd1ceaeaeb23defe9237e1..19b30ffb0a2998a04f3960266a95ca5938aaf6d4 100644 (file)
@@ -176,7 +176,7 @@ class _slider_base(_form_base):
                self._add_widget(self._slider, label, flag=wx.EXPAND)
 
        def _handle(self, event): self[INT_KEY] = self._slider.GetValue()
-       def _update(self, value): self._slider.SetValue(value)
+       def _update(self, value): self._slider.SetValue(int(round(value)))
 
 ########################################################################
 # Static Text Form
@@ -194,15 +194,19 @@ class static_text(_form_base):
        @param label title label for this widget (optional)
        @param width the width of the form in px
        @param bold true to bold-ify the text (default=False)
+       @param units a suffix to add after the text
        @param converter forms.str_converter(), int_converter(), float_converter()...
        """
-       def __init__(self, label='', width=-1, bold=False, converter=converters.str_converter(), **kwargs):
+       def __init__(self, label='', width=-1, bold=False, units='', converter=converters.str_converter(), **kwargs):
+               self._units = units
                _form_base.__init__(self, converter=converter, **kwargs)
                self._static_text = wx.StaticText(self._parent, size=wx.Size(width, -1))
                if bold: make_bold(self._static_text)
                self._add_widget(self._static_text, label)
 
-       def _update(self, label): self._static_text.SetLabel(label); self._parent.Layout()
+       def _update(self, label):
+                       if self._units: label += ' ' + self._units
+                       self._static_text.SetLabel(label); self._parent.Layout()
 
 ########################################################################
 # Text Box Form
@@ -224,11 +228,18 @@ class text_box(_form_base):
        def __init__(self, label='', width=-1, converter=converters.eval_converter(), **kwargs):
                _form_base.__init__(self, converter=converter, **kwargs)
                self._text_box = wx.TextCtrl(self._parent, size=wx.Size(width, -1), style=wx.TE_PROCESS_ENTER)
+               self._default_bg_colour = self._text_box.GetBackgroundColour()
                self._text_box.Bind(wx.EVT_TEXT_ENTER, self._handle)
+               self._text_box.Bind(wx.EVT_TEXT, self._update_color)
                self._add_widget(self._text_box, label)
 
+       def _update_color(self, *args):
+               if self._text_box.GetValue() == self[INT_KEY]:
+                       self._text_box.SetBackgroundColour(self._default_bg_colour)
+               else: self._text_box.SetBackgroundColour('#EEDDDD')
+
        def _handle(self, event): self[INT_KEY] = self._text_box.GetValue()
-       def _update(self, value): self._text_box.SetValue(value)
+       def _update(self, value): self._text_box.SetValue(value); self._update_color()
 
 ########################################################################
 # Slider Form
index 5f434d70ee79064dbe952882c0c6055d1bccdc06..a1b520f9c121acbc3d9e7498c2b4c0fbcfd7c445 100644 (file)
@@ -52,6 +52,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                SIZE = (100, -1)
                control_box = forms.static_box_sizer(
index db6606e413c14cbd94274bba1e8c572997f22b42..509f746be68a9e763c0d6c6f6ac83e073546d39d 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # histo sink block (wrapper for old wxgui)
 ##################################################
-class histo_sink_f(gr.hier_block2):
+class histo_sink_f(gr.hier_block2, common.wxgui_hb):
        """
        A histogram block and a gui window.
        """
@@ -56,8 +56,6 @@ class histo_sink_f(gr.hier_block2):
                histo = gr.histo_sink_f(msgq)
                histo.set_num_bins(num_bins)
                histo.set_frame_size(frame_size)
-               #connect
-               self.connect(self, histo)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(NUM_BINS_KEY, histo.set_num_bins)
@@ -79,6 +77,8 @@ class histo_sink_f(gr.hier_block2):
                        msg_key=MSG_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, histo)
 
 # ----------------------------------------------------------------
 # Standalone test app
index 8a8249764c03e94acdb573b6cbbeed42aaeff3dd..ab9d1ebc004e064f6ec66de9641b408a60244546 100644 (file)
@@ -58,6 +58,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                #checkboxes for average and peak hold
                control_box.AddStretchSpacer()
index 7f853e6a4f3f7b73b2acda44b0d8d1f0d87d5c3b..011acdfd5e93e01b8c7907c9d264b40e5bcd7f66 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Number sink block (wrapper for old wxgui)
 ##################################################
-class _number_sink_base(gr.hier_block2):
+class _number_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An decimator block with a number window display
        """
@@ -81,8 +81,6 @@ class _number_sink_base(gr.hier_block2):
                        avg = gr.single_pole_iir_filter_cc(1.0)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(self._item_size, msgq, True)
-               #connect
-               self.connect(self, sd, mult, add, avg, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate)
@@ -118,6 +116,8 @@ class _number_sink_base(gr.hier_block2):
                common.register_access_methods(self, self.controller)
                #backwards compadibility
                self.set_show_gauge = self.win.show_gauges
+               #connect
+               self.wxgui_connect(self, sd, mult, add, avg, sink)
 
 class number_sink_f(_number_sink_base):
        _item_size = gr.sizeof_float
index 5d50ee313e7b1c799e9d3f82ac3492052ea868ad..e0bc4ca6082721c5699a8c2257685d4adbc0d18e 100644 (file)
@@ -5,8 +5,8 @@
 # Author:      Gordon Williams
 #
 # Created:     2003/11/03
-# RCS-ID:      $Id: plot.py 8585 2008-06-12 21:33:40Z jblum $
-# Copyright:   (c) 2002,2007
+# RCS-ID:      $Id$
+# Copyright:   (c) 2002,2007,2010
 # Licence:     Use as you wish.
 #-----------------------------------------------------------------------------
 # 12/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
@@ -36,6 +36,9 @@
 #   
 # May 27, 2007 Johnathan Corgan (jcorgan@corganenterprises.com)
 #   - Converted from numarray to numpy
+#
+# Apr 23, 2010 Martin Dudok van Heel (http://www.olifantasia.com/gnuradio/contact_olifantasia.gif)
+#   - Added Persistence option (emulate after glow of an analog CRT display using IIR)
 
 """
 This is a simple light weight plotting module that can be used with
@@ -422,6 +425,11 @@ class PlotCanvas(wx.Window):
 
     def __init__(self, parent, id = -1, pos=wx.DefaultPosition,
             size=wx.DefaultSize, style= wx.DEFAULT_FRAME_STYLE, name= ""):
+
+        self.use_persistence=False
+        self.alpha=0.3
+        self.decimation=10
+        self.decim_counter=0
         """Constucts a window, which can be a child of a frame, dialog or
         any other non-control window"""
     
@@ -488,6 +496,14 @@ class PlotCanvas(wx.Window):
         # platforms at initialization, but little harm done.
         self.OnSize(None) # sets the initial size based on client size
                           # UNCONDITIONAL, needed to create self._Buffer
+
+
+    def set_use_persistence(self, enable):
+        self.use_persistence = enable
+
+    def set_persist_alpha(self, persist_alpha):
+        self.alpha = persist_alpha
+
         
     # SaveFile
     def SaveFile(self, fileName= ''):
@@ -791,12 +807,19 @@ class PlotCanvas(wx.Window):
             
         if dc == None:
             # sets new dc and clears it 
-            dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
-            dc.Clear()
-            
+            if self.use_persistence:
+              dc = wx.MemoryDC()
+              dc.SelectObject(self._Buffer)
+              dc.Clear()
+            else:
+              dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
+              dc.Clear() 
+           
         dc.BeginDrawing()
         # dc.Clear()
-        
+
+       
         # set font size for every thing but title and legend
         dc.SetFont(self._getFont(self._fontSizeAxis))
 
@@ -818,6 +841,15 @@ class PlotCanvas(wx.Window):
 
         self.last_draw = (graphics, xAxis, yAxis)       # saves most recient values
 
+        if False:
+          ptx,pty,rectWidth,rectHeight= self._point2ClientCoord(p1, p2)
+          #dc.SetPen(wx.Pen(wx.BLACK))
+          dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) ) #wx.SOLID wx.TRANSPARENT ) )
+          #dc.SetLogicalFunction(wx.INVERT) #wx.XOR wx.INVERT
+          dc.DrawRectangle( ptx,pty, rectWidth,rectHeight)
+          #dc.SetBrush(wx.Brush( wx.WHITE, wx.SOLID ) ) 
+          #dc.SetLogicalFunction(wx.COPY)
+
         # Get ticks and textExtents for axis if required
         if self._xSpec is not 'none':
             if self._xUseScopeTicks:
@@ -874,8 +906,11 @@ class PlotCanvas(wx.Window):
         scale = (self.plotbox_size-textSize_scale) / (p2-p1)* _numpy.array((1,-1))
         shift = -p1*scale + self.plotbox_origin + textSize_shift * _numpy.array((1,-1))
         self._pointScale= scale  # make available for mouse events
-        self._pointShift= shift        
+        self._pointShift= shift
+
+        #dc.SetLogicalFunction(wx.INVERT) #wx.XOR wx.INVERT      
         self._drawAxes(dc, p1, p2, scale, shift, xticks, yticks)
+        #dc.SetLogicalFunction(wx.COPY) 
         
         graphics.scaleAndShift(scale, shift)
         graphics.setPrinterScale(self.printerScale)  # thicken up lines and markers if printing
@@ -885,11 +920,44 @@ class PlotCanvas(wx.Window):
         dc.SetClippingRegion(ptx,pty,rectWidth,rectHeight)
         # Draw the lines and markers
         #start = _time.clock()
+
         graphics.draw(dc)
         # print "entire graphics drawing took: %f second"%(_time.clock() - start)
         # remove the clipping region
         dc.DestroyClippingRegion()
         dc.EndDrawing()
+
+
+        if self.use_persistence:
+          dc=None
+          self._Buffer.CopyToBuffer(self._Bufferarray) #, format=wx.BitmapBufferFormat_RGB, stride=-1)
+          ## do the IIR filter
+          alpha_int=int(float(self.alpha*256))
+          if True:
+            _numpy.add(self._Bufferarray,0,self._Buffer3array)
+            _numpy.multiply(self._Buffer3array,alpha_int,self._Buffer3array)
+            _numpy.multiply(self._Buffer2array,(256-alpha_int),self._Buffer2array)
+            _numpy.add(self._Buffer3array,self._Buffer2array,self._Buffer2array)
+            _numpy.right_shift(self._Buffer2array,8,self._Buffer2array)
+          elif False:
+            self._Buffer2array=(self._Bufferarray.astype(_numpy.uint32) *alpha_int + self._Buffer2array*(256-alpha_int)).__rshift__(8)
+          elif False:
+            self._Buffer2array *=(256-alpha_int)
+            self._Buffer2array +=self._Bufferarray.astype(_numpy.uint32)*alpha_int
+            self._Buffer2array /=256
+
+          ##copy back to image buffer 
+          self._Buffer2.CopyFromBuffer(self._Buffer2array.astype(_numpy.uint8)) #, format=wx.BitmapBufferFormat_RGB, stride=-1)
+
+          #draw to the screen
+          #self.decim_counter=self.decim_counter+1
+          if True: #self.decim_counter>self.decimation:
+            #self.decim_counter=0
+            dc2 = wx.ClientDC( self )
+            dc2.BeginDrawing()
+            dc2.DrawBitmap(self._Buffer2, 0, 0, False)
+            #dc2.DrawBitmap(self._Buffer, 0, 0, False)
+            dc2.EndDrawing()
         
     def Redraw(self, dc= None):
         """Redraw the existing plot."""
@@ -1031,6 +1099,8 @@ class PlotCanvas(wx.Window):
         if self.last_PointLabel != None:
             self._drawPointLabel(self.last_PointLabel) #erase old
             self.last_PointLabel = None
+
+        #paint current buffer to screen
         dc = wx.BufferedPaintDC(self, self._Buffer)
 
     def OnSize(self,event):
@@ -1041,7 +1111,23 @@ class PlotCanvas(wx.Window):
         # Make new offscreen bitmap: this bitmap will always have the
         # current drawing in it, so it can be used to save the image to
         # a file, or whatever.
-        self._Buffer = wx.EmptyBitmap(Size[0],Size[1])
+        self._Buffer = wx.EmptyBitmap(Size[0],Size[1],24)
+
+        
+        if True: #self.use_persistence:
+          #self._Bufferarray = _numpy.zeros((Size[0], Size[1],3), dtype=_numpy.uint8)
+          self._Bufferarray = _numpy.zeros((Size[0]* Size[1]*3), dtype=_numpy.uint8)
+
+          # Make new second offscreen bitmap: this bitmap will always have the
+          # last drawing in it, so it can be used to do display time dependent processing 
+          # like averaging (IIR) or show differences between updates
+          self._Buffer2 = wx.EmptyBitmap(Size[0],Size[1],24)
+          # now the extra buffers for the IIR processing
+          # note the different datatype uint32
+          self._Buffer2array = _numpy.zeros((Size[0]* Size[1]*3), dtype=_numpy.uint32) #dtype=_numpy.float
+          self._Buffer3array = _numpy.zeros((Size[0]* Size[1]*3), dtype=_numpy.uint32) #dtype=_numpy.float
+          # optional you can set the ufunct buffer size to improve speed
+          #_numpy.setbufsize(16*((Size[0]* Size[1]*3)/16 +1))
         self._setSize()
 
         self.last_PointLabel = None        #reset pointLabel
diff --git a/gr-wxgui/src/python/plotter/.gitignore b/gr-wxgui/src/python/plotter/.gitignore
new file mode 100644 (file)
index 0000000..b695091
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/*.pyc
index ff0a3a160d9cb7ddc48bd4538377617a2a1133dc..a3a2b645194b6f6620479b9f72824d0c1ea69049 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008, 2009 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -47,6 +47,7 @@ class channel_plotter(grid_plotter_base):
                """
                #init
                grid_plotter_base.__init__(self, parent, MIN_PADDING)
+                self.set_use_persistence(False)
                #setup legend cache
                self._legend_cache = self.new_gl_cache(self._draw_legend, 50)
                self.enable_legend(False)
index 7699986aad1e65d61c8637980d323c8702771bc9..4c50cd7872e1750cf61180eb651dd1661e02d85e 100644 (file)
@@ -102,6 +102,7 @@ class point_label_thread(threading.Thread, mutex):
                #bind plotter mouse events
                self._plotter.Bind(wx.EVT_MOTION, lambda evt: self.enqueue(evt.GetPosition()))
                self._plotter.Bind(wx.EVT_LEAVE_WINDOW, lambda evt: self.enqueue(None))
+               self._plotter.Bind(wx.EVT_RIGHT_DOWN, lambda evt: plotter.enable_point_label(not plotter.enable_point_label()))
                #start the thread
                threading.Thread.__init__(self)
                self.start()
index 39bed181111140abb52b9ca01ddfd134cacc8726..a9bd02731479ac3be8780eb8631a3792a7316772 100644 (file)
@@ -36,8 +36,9 @@ AXIS_LABEL_PADDING = 5
 TICK_LABEL_PADDING = 5
 TITLE_LABEL_PADDING = 7
 POINT_LABEL_FONT_SIZE = 8
-POINT_LABEL_COLOR_SPEC = (1, 1, .5)
+POINT_LABEL_COLOR_SPEC = (1, 1, 0.5, 0.75)
 POINT_LABEL_PADDING = 3
+POINT_LABEL_OFFSET = 10
 GRID_LINE_DASH_LEN = 4
 
 ##################################################
@@ -395,8 +396,12 @@ class grid_plotter_base(plotter_base):
                if not label_str: return
                txt = gltext.Text(label_str, font_size=POINT_LABEL_FONT_SIZE)
                w, h = txt.get_size()
+               #enable transparency
+               GL.glEnable(GL.GL_BLEND)
+               GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
                #draw rect + text
-               GL.glColor3f(*POINT_LABEL_COLOR_SPEC)
-               if x > self.width/2: x -= w+2*POINT_LABEL_PADDING
+               GL.glColor4f(*POINT_LABEL_COLOR_SPEC)
+               if x > self.width/2: x -= w+2*POINT_LABEL_PADDING + POINT_LABEL_OFFSET
+               else: x += POINT_LABEL_OFFSET
                self._draw_rect(x, y-h-2*POINT_LABEL_PADDING, w+2*POINT_LABEL_PADDING, h+2*POINT_LABEL_PADDING)
                txt.draw_text(wx.Point(x+POINT_LABEL_PADDING, y-h-POINT_LABEL_PADDING))
index dede5a0ad51b8d5abbf231c02ef40634d66acd77..b856215e9ba458069b72bf8e77a8a8815c6c29f0 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008, 2009 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -87,7 +87,10 @@ class plotter_base(wx.glcanvas.GLCanvas, common.mutex):
                @param parent the parent widgit
                """
                attribList = (wx.glcanvas.WX_GL_DOUBLEBUFFER, wx.glcanvas.WX_GL_RGBA)
-               wx.glcanvas.GLCanvas.__init__(self, parent, attribList=attribList)
+               wx.glcanvas.GLCanvas.__init__(self, parent, attribList=attribList);
+                self.use_persistence=False
+                self.persist_alpha=2.0/15
+                self.clear_accum=True
                self._gl_init_flag = False
                self._resized_flag = True
                self._init_fcns = list()
@@ -97,6 +100,13 @@ class plotter_base(wx.glcanvas.GLCanvas, common.mutex):
                self.Bind(wx.EVT_SIZE, self._on_size)
                self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
 
+        def set_use_persistence(self,enable):
+                self.use_persistence=enable 
+                self.clear_accum=True
+
+        def set_persist_alpha(self,analog_alpha):
+                self.persist_alpha=analog_alpha
+
        def new_gl_cache(self, draw_fcn, draw_pri=50):
                """
                Create a new gl cache.
@@ -131,6 +141,7 @@ class plotter_base(wx.glcanvas.GLCanvas, common.mutex):
                """
                self.lock()
                self._resized_flag = True
+                self.clear_accum=True
                self.unlock()
 
        def _on_paint(self, event):
@@ -160,7 +171,30 @@ class plotter_base(wx.glcanvas.GLCanvas, common.mutex):
                        self._resized_flag = False
                #clear, draw functions, swap
                GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+                if False:
+                  GL.glEnable (GL.GL_LINE_SMOOTH)
+                  GL.glEnable (GL.GL_POLYGON_SMOOTH)
+                  GL.glEnable (GL.GL_BLEND)
+                  GL.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
+                  GL.glHint (GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST) #GL.GL_DONT_CARE)
+                  GL.glHint(GL.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST)
+                  #GL.glLineWidth (1.5)
+
+                  GL.glEnable(GL.GL_MULTISAMPLE) #Enable Multisampling anti-aliasing
+
+
                for fcn in self._draw_fcns: fcn[1]()
+
+                if self.use_persistence:
+                  if self.clear_accum:
+                    #GL.glClear(GL.GL_ACCUM_BUFFER_BIT)
+                    GL.glAccum(GL.GL_LOAD, 1.0)
+                    self.clear_accum=False
+
+                  GL.glAccum(GL.GL_MULT, 1.0-self.persist_alpha)
+                  GL.glAccum(GL.GL_ACCUM, self.persist_alpha)
+                  GL.glAccum(GL.GL_RETURN, 1.0)
                self.SwapBuffers()
                self.unlock()
 
index 2e0669961badf81da5e6494186746600bc47145a..0af64b826121badeca5745b27aaf7181b7c3d408 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008, 2009 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -26,6 +26,7 @@ import common
 import numpy
 import gltext
 import math
+import struct
 
 LEGEND_LEFT_PAD = 7
 LEGEND_NUM_BLOCKS = 256
@@ -37,6 +38,9 @@ MIN_PADDING = 0, 60, 0, 0 #top, right, bottom, left
 
 ceil_log2 = lambda x: 2**int(math.ceil(math.log(x)/math.log(2)))
 
+pack_color   = lambda x: struct.unpack('I', struct.pack('BBBB', *x))[0]
+unpack_color = lambda x: struct.unpack('BBBB', struct.pack('I', int(x)))
+
 def _get_rbga(red_pts, green_pts, blue_pts, alpha_pts=[(0, 0), (1, 0)]):
        """
        Get an array of 256 rgba values where each index maps to a color.
@@ -53,11 +57,10 @@ def _get_rbga(red_pts, green_pts, blue_pts, alpha_pts=[(0, 0), (1, 0)]):
                        #linear interpolation
                        if x <= x2: return float(y1 - y2)/(x1 - x2)*(x - x1) + y1
                raise Exception
-       return [numpy.array(map(
-                       lambda pw: int(255*_fcn(i/255.0, pw)),
-                       (red_pts, green_pts, blue_pts, alpha_pts),
-               ), numpy.uint8).tostring() for i in range(0, 256)
-       ]
+       return numpy.array([pack_color(map(
+               lambda pw: int(255*_fcn(i/255.0, pw)),
+               (red_pts, green_pts, blue_pts, alpha_pts),
+       )) for i in range(0, 256)], numpy.uint32)
 
 COLORS = {
        'rgb1': _get_rbga( #http://www.ks.uiuc.edu/Research/vmd/vmd-1.7.1/ug/img47.gif
@@ -179,8 +182,8 @@ class waterfall_plotter(grid_plotter_base):
                block_height = float(legend_height)/LEGEND_NUM_BLOCKS
                x = self.width - self.padding_right + LEGEND_LEFT_PAD
                for i in range(LEGEND_NUM_BLOCKS):
-                       color = COLORS[self._color_mode][int(255*i/float(LEGEND_NUM_BLOCKS-1))]
-                       GL.glColor4f(*map(lambda c: ord(c)/255.0, color))
+                       color = unpack_color(COLORS[self._color_mode][int(255*i/float(LEGEND_NUM_BLOCKS-1))])
+                       GL.glColor4f(*numpy.array(color)/255.0)
                        y = self.height - (i+1)*block_height - self.padding_bottom
                        self._draw_rect(x, y, LEGEND_WIDTH, block_height)
                #draw rectangle around color scale border
@@ -209,7 +212,7 @@ class waterfall_plotter(grid_plotter_base):
                self._pointer = 0
                if self._num_lines and self._fft_size:
                        GL.glBindTexture(GL.GL_TEXTURE_2D, self._waterfall_texture)
-                       data = numpy.zeros(self._num_lines*self._fft_size*4, numpy.uint8).tostring()
+                       data = numpy.zeros(self._num_lines*ceil_log2(self._fft_size)*4, numpy.uint8).tostring()
                        GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, ceil_log2(self._fft_size), self._num_lines, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, data)
                self._resize_texture_flag = False
 
@@ -261,7 +264,7 @@ class waterfall_plotter(grid_plotter_base):
                samples = numpy.clip(samples, 0, 255) #clip
                samples = numpy.array(samples, numpy.uint8)
                #convert the samples to RGBA data
-               data = numpy.choose(samples, COLORS[self._color_mode]).tostring()
+               data = COLORS[self._color_mode][samples].tostring()
                self._buffer.append(data)
                self._waterfall_cache.changed(True)
                self.unlock()
index 449046402ca2a08c486e4fe3f165b91ebc0454c9..c03b71f1e0c84494791265be416f9eef29ea2d55 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -36,6 +36,8 @@ import forms
 # Constants
 ##################################################
 DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'scope_rate', 30)
+PERSIST_ALPHA_MIN_EXP, PERSIST_ALPHA_MAX_EXP = -2, 0
+SLIDER_STEPS = 100
 DEFAULT_WIN_SIZE = (600, 300)
 COUPLING_MODES = (
        ('DC', False),
@@ -55,6 +57,9 @@ CHANNEL_COLOR_SPECS = (
        (0.0, 0.8, 0.0),
        (1.0, 0.0, 0.0),
        (0.8, 0.0, 0.8),
+        (0.7, 0.7, 0.0),
+        (0.15, 0.90, 0.98),
+
 )
 TRIGGER_COLOR_SPEC = (1.0, 0.4, 0.0)
 AUTORANGE_UPDATE_RATE = 0.5 #sec
@@ -82,7 +87,40 @@ class control_panel(wx.Panel):
                WIDTH = 90
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
+
+               ##################################################
+               # Persistence
+               ##################################################
+
+               forms.check_box(
+                       sizer=control_box, parent=self, label='Persistence',
+                       ps=parent, key=USE_PERSISTENCE_KEY,
+               )
+               #static text and slider for analog alpha
+               persist_alpha_text = forms.static_text(
+                       sizer=control_box, parent=self, label='Analog Alpha',
+                       converter=forms.float_converter(lambda x: '%.4f'%x),
+                       ps=parent, key=PERSIST_ALPHA_KEY, width=50,
+               )
+               persist_alpha_slider = forms.log_slider(
+                       sizer=control_box, parent=self,
+                       min_exp=PERSIST_ALPHA_MIN_EXP,
+                       max_exp=PERSIST_ALPHA_MAX_EXP,
+                       num_steps=SLIDER_STEPS,
+                       ps=parent, key=PERSIST_ALPHA_KEY,
+               )
+               for widget in (persist_alpha_text, persist_alpha_slider):
+                       parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
+                       widget.Enable(parent[USE_PERSISTENCE_KEY])
+                       parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
+                        #allways show initially, so room is reserved for them
+                       widget.ShowItems(True) # (parent[USE_PERSISTENCE_KEY])
+               
+                parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)
+
                ##################################################
                # Axes Options
                ##################################################
@@ -359,6 +397,15 @@ class control_panel(wx.Panel):
        def _on_decr_y_off(self, event):
                self.parent[Y_OFF_KEY] = self.parent[Y_OFF_KEY] - self.parent[Y_PER_DIV_KEY]
 
+       ##################################################
+       # subscriber handlers
+       ##################################################
+        def _update_layout(self,key):
+          # Just ignore the key value we get
+          # we only need to now that the visability or size of something has changed
+          self.parent.Layout()
+          #self.parent.Fit()  
+
 ##################################################
 # Scope window with plotter and control panel
 ##################################################
@@ -374,6 +421,7 @@ class scope_window(wx.Panel, pubsub.pubsub):
                sample_rate_key,
                t_scale,
                v_scale,
+               v_offset,
                xy_mode,
                ac_couple_key,
                trigger_level_key,
@@ -382,6 +430,8 @@ class scope_window(wx.Panel, pubsub.pubsub):
                trigger_channel_key,
                decimation_key,
                msg_key,
+                use_persistence,
+                persist_alpha,
        ):
                pubsub.pubsub.__init__(self)
                #check num inputs
@@ -413,8 +463,8 @@ class scope_window(wx.Panel, pubsub.pubsub):
                self[X_PER_DIV_KEY] = v_scale
                self[Y_PER_DIV_KEY] = v_scale
                self[T_OFF_KEY] = 0
-               self[X_OFF_KEY] = 0
-               self[Y_OFF_KEY] = 0
+               self[X_OFF_KEY] = v_offset
+               self[Y_OFF_KEY] = v_offset
                self[T_DIVS_KEY] = 8
                self[X_DIVS_KEY] = 8
                self[Y_DIVS_KEY] = 8
@@ -424,6 +474,8 @@ class scope_window(wx.Panel, pubsub.pubsub):
                self[TRIGGER_MODE_KEY] = gr.gr_TRIG_MODE_AUTO
                self[TRIGGER_SLOPE_KEY] = gr.gr_TRIG_SLOPE_POS
                self[T_FRAC_OFF_KEY] = 0.5
+               self[USE_PERSISTENCE_KEY] = use_persistence
+               self[PERSIST_ALPHA_KEY] = persist_alpha
                for i in range(num_inputs):
                        self.proxy(common.index_key(AC_COUPLE_KEY, i), controller, common.index_key(ac_couple_key, i))
                #init panel and plot
@@ -434,6 +486,8 @@ class scope_window(wx.Panel, pubsub.pubsub):
                self.plotter.enable_legend(True)
                self.plotter.enable_point_label(True)
                self.plotter.enable_grid_lines(True)
+                self.plotter.set_use_persistence(use_persistence)
+                self.plotter.set_persist_alpha(persist_alpha)
                #setup the box with plot and controls
                self.control_panel = control_panel(self)
                main_box = wx.BoxSizer(wx.HORIZONTAL)
@@ -451,6 +505,9 @@ class scope_window(wx.Panel, pubsub.pubsub):
                        XY_MODE_KEY, AUTORANGE_KEY, T_FRAC_OFF_KEY,
                        TRIGGER_SHOW_KEY, XY_MARKER_KEY, X_CHANNEL_KEY, Y_CHANNEL_KEY,
                ]: self.subscribe(key, self.update_grid)
+                #register events for plotter settings
+               self.subscribe(USE_PERSISTENCE_KEY, self.plotter.set_use_persistence)
+               self.subscribe(PERSIST_ALPHA_KEY, self.plotter.set_persist_alpha)
                #initial update
                self.update_grid()
 
@@ -615,3 +672,4 @@ class scope_window(wx.Panel, pubsub.pubsub):
                        self.plotter.set_y_grid(self.get_y_min(), self.get_y_max(), self[Y_PER_DIV_KEY])
                #redraw current sample
                self.handle_samples()
+
index b4ae0f3391df3a86b51e5b20dbcd7a746a05ba6e..ebf9b29398479ff260b7f72b089f77571f1ca37e 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -27,6 +27,7 @@ import common
 from gnuradio import gr
 from pubsub import pubsub
 from constants import *
+import math
 
 class ac_couple_block(gr.hier_block2):
        """
@@ -34,7 +35,7 @@ class ac_couple_block(gr.hier_block2):
        Mute the low pass filter to disable ac coupling.
        """
 
-       def __init__(self, controller, ac_couple_key, ac_couple, sample_rate_key):
+       def __init__(self, controller, ac_couple_key, sample_rate_key):
                gr.hier_block2.__init__(
                        self,
                        "ac_couple",
@@ -50,15 +51,15 @@ class ac_couple_block(gr.hier_block2):
                self.connect(self, lpf, mute, (sub, 1))
                #subscribe
                controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
-               controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(2.0/x))
+               controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05))
                #initialize
-               controller[ac_couple_key] = ac_couple
+               controller[ac_couple_key] = controller[ac_couple_key]
                controller[sample_rate_key] = controller[sample_rate_key]
 
 ##################################################
 # Scope sink block (wrapper for old wxgui)
 ##################################################
-class _scope_sink_base(gr.hier_block2):
+class _scope_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        A scope block with a gui window.
        """
@@ -71,12 +72,22 @@ class _scope_sink_base(gr.hier_block2):
                size=scope_window.DEFAULT_WIN_SIZE,
                v_scale=0,
                t_scale=0,
+               v_offset=0,
                xy_mode=False,
                ac_couple=False,
                num_inputs=1,
                frame_rate=scope_window.DEFAULT_FRAME_RATE,
+                use_persistence=False,
+                persist_alpha=None,
                **kwargs #do not end with a comma
        ):
+                #ensure analog alpha
+                if persist_alpha is None: 
+                  actual_frame_rate=float(frame_rate)
+                  analog_cutoff_freq=0.5 # Hertz
+                  #calculate alpha from wanted cutoff freq
+                  persist_alpha = 1.0 - math.exp(-2.0*math.pi*analog_cutoff_freq/actual_frame_rate)
+
                if not t_scale: t_scale = 10.0/sample_rate
                #init
                gr.hier_block2.__init__(
@@ -102,25 +113,10 @@ class _scope_sink_base(gr.hier_block2):
                self.controller.publish(TRIGGER_SLOPE_KEY, scope.get_trigger_slope)
                self.controller.subscribe(TRIGGER_CHANNEL_KEY, scope.set_trigger_channel)
                self.controller.publish(TRIGGER_CHANNEL_KEY, scope.get_trigger_channel)
-               #connect
-               if self._real:
-                       for i in range(num_inputs):
-                               self.connect(
-                                       (self, i),
-                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), ac_couple, SAMPLE_RATE_KEY),
-                                       (scope, i),
-                               )
-               else:
-                       for i in range(num_inputs):
-                               c2f = gr.complex_to_float() 
-                               self.connect((self, i), c2f)
-                               for j in range(2):
-                                       self.connect(
-                                               (c2f, j), 
-                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), ac_couple, SAMPLE_RATE_KEY),
-                                               (scope, 2*i+j),
-                                       )
-                       num_inputs *= 2
+               actual_num_inputs = self._real and num_inputs or num_inputs*2
+               #init ac couple
+               for i in range(actual_num_inputs):
+                       self.controller[common.index_key(AC_COUPLE_KEY, i)] = ac_couple
                #start input watcher
                common.input_watcher(msgq, self.controller, MSG_KEY)
                #create window
@@ -130,10 +126,11 @@ class _scope_sink_base(gr.hier_block2):
                        size=size,
                        title=title,
                        frame_rate=frame_rate,
-                       num_inputs=num_inputs,
+                       num_inputs=actual_num_inputs,
                        sample_rate_key=SAMPLE_RATE_KEY,
                        t_scale=t_scale,
                        v_scale=v_scale,
+                       v_offset=v_offset,
                        xy_mode=xy_mode,
                        ac_couple_key=AC_COUPLE_KEY,
                        trigger_level_key=TRIGGER_LEVEL_KEY,
@@ -142,8 +139,28 @@ class _scope_sink_base(gr.hier_block2):
                        trigger_channel_key=TRIGGER_CHANNEL_KEY,
                        decimation_key=DECIMATION_KEY,
                        msg_key=MSG_KEY,
+                        use_persistence=use_persistence,
+                        persist_alpha=persist_alpha,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               if self._real:
+                       for i in range(num_inputs):
+                               self.wxgui_connect(
+                                       (self, i),
+                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), SAMPLE_RATE_KEY),
+                                       (scope, i),
+                               )
+               else:
+                       for i in range(num_inputs):
+                               c2f = gr.complex_to_float() 
+                               self.wxgui_connect((self, i), c2f)
+                               for j in range(2):
+                                       self.connect(
+                                               (c2f, j), 
+                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), SAMPLE_RATE_KEY),
+                                               (scope, 2*i+j),
+                                       )
 
 class scope_sink_f(_scope_sink_base):
        _item_size = gr.sizeof_float
@@ -164,10 +181,11 @@ class test_top_block (stdgui2.std_top_block):
     def __init__(self, frame, panel, vbox, argv):
         stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
 
+        default_input_rate = 1e6
         if len(argv) > 1:
-            frame_decim = int(argv[1]) 
+            input_rate = int(argv[1]) 
         else:
-            frame_decim = 1
+            input_rate = default_input_rate
 
         if len(argv) > 2:
             v_scale = float(argv[2])  # start up at this v_scale value
@@ -177,14 +195,17 @@ class test_top_block (stdgui2.std_top_block):
         if len(argv) > 3:
             t_scale = float(argv[3])  # start up at this t_scale value
         else:
-            t_scale = .00003  # old behavior
+            t_scale = .00003*default_input_rate/input_rate # old behavior
 
-        print "frame decim %s  v_scale %s  t_scale %s" % (frame_decim,v_scale,t_scale)
+        print "input rate %s  v_scale %s  t_scale %s" % (input_rate,v_scale,t_scale)
             
-        input_rate = 1e6
 
         # Generate a complex sinusoid
-        self.src0 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 25.1e3, 1e3)
+        ampl=1.0e3
+        self.src0 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 25.1e3*input_rate/default_input_rate, ampl)
+        self.noise =gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 11.1*25.1e3*input_rate/default_input_rate, ampl/10) 
+        #self.noise =gr.noise_source_c(gr.GR_GAUSSIAN, ampl/10)
+        self.combine=gr.add_cc()
 
         # We add this throttle block so that this demo doesn't suck down
         # all the CPU available.  You normally wouldn't use it...
@@ -196,7 +217,9 @@ class test_top_block (stdgui2.std_top_block):
 
         # Ultimately this will be
         # self.connect("src0 throttle scope")
-       self.connect(self.src0, self.thr, scope) 
+       self.connect(self.src0,(self.combine,0))
+        self.connect(self.noise,(self.combine,1))
+        self.connect(self.combine, self.thr, scope) 
 
 def main ():
     app = stdgui2.stdapp (test_top_block, "O'Scope Test App")
diff --git a/gr-wxgui/src/python/termsink.py b/gr-wxgui/src/python/termsink.py
new file mode 100644 (file)
index 0000000..a0cfd57
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright 2009 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 gru
+import wx
+
+DEFAULT_WIN_SIZE = (600, 300)
+APPEND_EVENT = wx.NewEventType()
+EVT_APPEND_EVENT = wx.PyEventBinder(APPEND_EVENT, 0)
+
+class AppendEvent(wx.PyEvent):
+    def __init__(self, text):
+        wx.PyEvent.__init__(self)
+        self.SetEventType(APPEND_EVENT)
+        self.text = text
+
+    def Clone(self):
+        self.__class__(self.GetId())
+
+class termsink(wx.Panel):
+       def __init__(self,
+                    parent,
+                    msgq,
+                    size=DEFAULT_WIN_SIZE,
+                    ):
+
+               wx.Panel.__init__(self,
+                                 parent,
+                                 size=size,
+                                 style=wx.SIMPLE_BORDER,
+                                 )
+
+               self.text_ctrl = wx.TextCtrl(self,
+                                            wx.ID_ANY,
+                                            value="",
+                                            size=size,
+                                            style=wx.TE_MULTILINE|wx.TE_READONLY,
+                                            )
+
+               main_sizer = wx.BoxSizer(wx.VERTICAL)
+               main_sizer.Add(self.text_ctrl, 1, wx.EXPAND)
+               self.SetSizerAndFit(main_sizer)
+
+                EVT_APPEND_EVENT(self, self.evt_append)
+               self.runner = gru.msgq_runner(msgq, self.handle_msg)
+
+       def handle_msg(self, msg):
+               # This gets called in the queue runner thread context
+               # For now, just add whatever the user sends to the text control
+               text = msg.to_string()
+
+               # Create a wxPython event and post it to the event queue
+               evt = AppendEvent(text)
+               wx.PostEvent(self, evt)
+               del evt
+
+        def evt_append(self, evt):
+               # This gets called by the wxPython event queue runner
+               self.text_ctrl.AppendText(evt.text)
index 77819b7339589e72b4ef13e43f3f1b03c93c2289..b7904e4d9742412269345dd870c8bb6657c9f89f 100644 (file)
@@ -41,6 +41,7 @@ DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'waterfall_rate', 30)
 DEFAULT_WIN_SIZE = (600, 300)
 DIV_LEVELS = (1, 2, 5, 10, 20)
 MIN_DYNAMIC_RANGE, MAX_DYNAMIC_RANGE = 10, 200
+DYNAMIC_RANGE_STEP = 10.
 COLOR_MODES = (
        ('RGB1', 'rgb1'),
        ('RGB2', 'rgb2'),
@@ -63,6 +64,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                control_box.AddStretchSpacer()
                options_box = forms.static_box_sizer(
@@ -143,13 +146,13 @@ class control_panel(wx.Panel):
        def _on_clear_button(self, event):
                self.parent[NUM_LINES_KEY] = self.parent[NUM_LINES_KEY]
        def _on_incr_dynamic_range(self, event):
-               self.parent[DYNAMIC_RANGE_KEY] = min(self.parent[DYNAMIC_RANGE_KEY] + 10, MAX_DYNAMIC_RANGE)
+               self.parent[DYNAMIC_RANGE_KEY] = min(MAX_DYNAMIC_RANGE, common.get_clean_incr(self.parent[DYNAMIC_RANGE_KEY]))
        def _on_decr_dynamic_range(self, event):
-               self.parent[DYNAMIC_RANGE_KEY] = max(self.parent[DYNAMIC_RANGE_KEY] - 10, MIN_DYNAMIC_RANGE)
+               self.parent[DYNAMIC_RANGE_KEY] = max(MIN_DYNAMIC_RANGE, common.get_clean_decr(self.parent[DYNAMIC_RANGE_KEY]))
        def _on_incr_ref_level(self, event):
-               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[DYNAMIC_RANGE_KEY]*.1
+               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[DYNAMIC_RANGE_KEY]/DYNAMIC_RANGE_STEP
        def _on_decr_ref_level(self, event):
-               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[DYNAMIC_RANGE_KEY]*.1
+               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[DYNAMIC_RANGE_KEY]/DYNAMIC_RANGE_STEP
        def _on_incr_time_scale(self, event):
                old_rate = self.parent[FRAME_RATE_KEY]
                self.parent[FRAME_RATE_KEY] *= 0.75
@@ -237,16 +240,10 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
                Does not affect the current data in the waterfall.
                """
                if not len(self.samples): return
-               #get the peak level (max of the samples)
-               peak_level = numpy.max(self.samples)
-               #get the noise floor (averge the smallest samples)
-               noise_floor = numpy.average(numpy.sort(self.samples)[:len(self.samples)/4])
-               #padding
-               noise_floor -= abs(noise_floor)*.5
-               peak_level += abs(peak_level)*.1
+               min_level, max_level = common.get_min_max_fft(self.samples)
                #set the range and level
-               self[REF_LEVEL_KEY] = peak_level
-               self[DYNAMIC_RANGE_KEY] = peak_level - noise_floor
+               self[DYNAMIC_RANGE_KEY] = common.get_clean_num(max_level - min_level)
+               self[REF_LEVEL_KEY] = DYNAMIC_RANGE_STEP*round(.5+max_level/DYNAMIC_RANGE_STEP)
 
        def handle_msg(self, msg):
                """
@@ -261,8 +258,8 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
                self.samples = samples = numpy.fromstring(msg, numpy.float32)[:self.fft_size] #only take first frame
                num_samps = len(samples)
                #reorder fft
-               if self.real: samples = samples[:num_samps/2]
-               else: samples = numpy.concatenate((samples[num_samps/2:], samples[:num_samps/2]))
+               if self.real: samples = samples[:(num_samps+1)/2]
+               else: samples = numpy.concatenate((samples[num_samps/2+1:], samples[:(num_samps+1)/2]))
                #plot the fft
                self.plotter.set_samples(
                        samples=samples,
index 2d4c959f8a8f14baafb64409092c807513409ac4..c2c4e8df7a1481ce165c5746ae7f65610aebd3ef 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Waterfall sink block (wrapper for old wxgui)
 ##################################################
-class _waterfall_sink_base(gr.hier_block2):
+class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -51,6 +51,7 @@ class _waterfall_sink_base(gr.hier_block2):
                ref_scale=2.0,
                dynamic_range=80,
                num_lines=256,
+               win=None,
                **kwargs #do not end with a comma
        ):
                #ensure avg alpha
@@ -70,11 +71,10 @@ class _waterfall_sink_base(gr.hier_block2):
                        ref_scale=ref_scale,
                        avg_alpha=avg_alpha,
                        average=average,
+                       win=win,
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
-               #connect
-               self.connect(self, fft, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(AVERAGE_KEY, fft.set_average)
@@ -110,6 +110,8 @@ class _waterfall_sink_base(gr.hier_block2):
                )
                common.register_access_methods(self, self.win)
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
+               #connect
+               self.wxgui_connect(self, fft, sink)
 
 class waterfall_sink_f(_waterfall_sink_base):
        _fft_chain = blks2.logpwrfft_f
index bb478c7cf541adacf6f2f9aea405b55b0e510570..3c25a9d9f25e1f7a71bd179093ba1719aaa25fc2 100644 (file)
@@ -75,7 +75,7 @@ class waterfall_sink_f(gr.hier_block2, waterfall_sink_base):
     def __init__(self, parent, baseband_freq=0,
                  y_per_div=10, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size):
+                 title='', size=default_fftsink_size, **kwargs):
 
         gr.hier_block2.__init__(self, "waterfall_sink_f",
                                 gr.io_signature(1, 1, gr.sizeof_float),
@@ -106,7 +106,7 @@ class waterfall_sink_c(gr.hier_block2, waterfall_sink_base):
     def __init__(self, parent, baseband_freq=0,
                  y_per_div=10, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None, 
-                 title='', size=default_fftsink_size):
+                 title='', size=default_fftsink_size, **kwargs):
 
         gr.hier_block2.__init__(self, "waterfall_sink_f",
                                 gr.io_signature(1, 1, gr.sizeof_gr_complex),
diff --git a/grc/.gitignore b/grc/.gitignore
new file mode 100644 (file)
index 0000000..8e70007
--- /dev/null
@@ -0,0 +1,3 @@
+/grc.conf
+/Makefile
+/Makefile.in
index a4090beab57919541718086d1b8fc61cab1c447c..2b5dc730b5e3184b9c25c6ad3e1a34f4b0dd0cde 100644 (file)
 # Boston, MA 02110-1301, USA.
 #
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
+if PYTHON
 SUBDIRS = \
        base \
        blocks \
-       examples \
        grc_gnuradio \
        gui \
        python \
@@ -35,24 +35,15 @@ if XDG_UTILS
 SUBDIRS += freedesktop
 endif
 
-ourpythondir = $(grc_src_prefix)
+ourpythondir = $(pkgpythondir)/grc
 ourpython_PYTHON = __init__.py
 
-etcdir = $(gr_sysconfdir)
+etcdir = $(gr_prefsdir)
 dist_etc_DATA = grc.conf
 
-EXTRA_DIST = \
-       $(srcdir)/__init__.py.in \
-       $(srcdir)/grc.conf.in
+EXTRA_DIST = $(srcdir)/grc.conf.in
 
-BUILT_SOURCES = \
-       __init__.py \
-       grc.conf
-
-__init__.py: $(srcdir)/__init__.py.in Makefile
-       sed \
-               -e 's|@VERSION[@]|$(VERSION)|g' \
-       $< > $@
+BUILT_SOURCES = grc.conf
 
 grc.conf: $(srcdir)/grc.conf.in Makefile
        sed \
@@ -60,3 +51,5 @@ grc.conf: $(srcdir)/grc.conf.in Makefile
                -e 's|@blocksdir[@]|$(grc_blocksdir)|g' \
                -e 's|@docdir[@]|$(gr_docdir)|g' \
        $< > $@
+
+endif
index 28f810d91cd79f0dc671144f36a5360d3c736c04..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,21 +0,0 @@
-"""
-Copyright 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-"""
-
-#package and version constants
-VERSION = '3.2.2'
diff --git a/grc/base/.gitignore b/grc/base/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 867a14f57b9de30f2ef97619c823d7ee9a1cece4..42eb6b3fbcfb23368bbf9417977eda07df2667f0 100644 (file)
@@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from . import odict
 from Element import Element
-from Param import Param
-from Port import Port
 
 from Cheetah.Template import Template
 from UserDict import UserDict
@@ -46,6 +44,11 @@ class TemplateArg(UserDict):
        def __call__(self):
                return self._param.get_evaluated()
 
+def _get_keys(lst): return [elem.get_key() for elem in lst]
+def _get_elem(lst, key):
+       try: return lst[_get_keys(lst).index(key)]
+       except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
+
 class Block(Element):
 
        def __init__(self, flow_graph, n):
@@ -66,59 +69,51 @@ class Block(Element):
                self._category = n.find('category') or ''
                self._block_wrapper_path = n.find('block_wrapper_path')
                #create the param objects
-               self._params = odict()
+               self._params = list()
                #add the id param
-               self._params['id'] = self.get_parent().get_parent().Param(
-                       self,
-                       odict({
+               self.get_params().append(self.get_parent().get_parent().Param(
+                       block=self,
+                       n=odict({
                                'name': 'ID',
                                'key': 'id',
                                'type': 'id',
                        })
-               )
-               self._params['_enabled'] = self.get_parent().get_parent().Param(
-                       self,
-                       odict({
+               ))
+               self.get_params().append(self.get_parent().get_parent().Param(
+                       block=self,
+                       n=odict({
                                'name': 'Enabled',
                                'key': '_enabled',
                                'type': 'raw',
                                'value': 'True',
                                'hide': 'all',
                        })
-               )
-               for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params):
+               ))
+               for param in map(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params):
                        key = param.get_key()
                        #test against repeated keys
                        try: assert key not in self.get_param_keys()
                        except AssertionError: raise Exception, 'Key "%s" already exists in params'%key
                        #store the param
-                       self._params[key] = param
+                       self.get_params().append(param)
                #create the source objects
-               self._sources = odict()
-               for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources):
+               self._sources = list()
+               for source in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='source'), sources):
                        key = source.get_key()
                        #test against repeated keys
                        try: assert key not in self.get_source_keys()
                        except AssertionError: raise Exception, 'Key "%s" already exists in sources'%key
                        #store the port
-                       self._sources[key] = source
+                       self.get_sources().append(source)
                #create the sink objects
-               self._sinks = odict()
-               for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks):
+               self._sinks = list()
+               for sink in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
                        key = sink.get_key()
                        #test against repeated keys
                        try: assert key not in self.get_sink_keys()
                        except AssertionError: raise Exception, 'Key "%s" already exists in sinks'%key
                        #store the port
-                       self._sinks[key] = sink
-               #begin the testing
-               self.test()
-
-       def test(self):
-               """
-               Call test on all children.
-               """
-               map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources())
+                       self.get_sinks().append(sink)
 
        def get_enabled(self):
                """
@@ -135,21 +130,6 @@ class Block(Element):
                """
                self.get_param('_enabled').set_value(str(enabled))
 
-       def validate(self):
-               """
-               Validate the block.
-               All ports and params must be valid.
-               All checks must evaluate to true.
-               """
-               Element.validate(self)
-               for c in self.get_params() + self.get_ports() + self.get_connections():
-                       try:
-                               c.validate()
-                               assert c.is_valid()
-                       except AssertionError:
-                               for msg in c.get_error_messages():
-                                       self.add_error_message('>>> %s:\n\t%s'%(c, msg))
-
        def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
 
        def get_id(self): return self.get_param('id').get_value()
@@ -159,28 +139,29 @@ class Block(Element):
        def get_category(self): return self._category
        def get_doc(self): return ''
        def get_ports(self): return self.get_sources() + self.get_sinks()
+       def get_children(self): return self.get_ports() + self.get_params()
        def get_block_wrapper_path(self): return self._block_wrapper_path
 
        ##############################################
        # Access Params
        ##############################################
-       def get_param_keys(self): return self._params.keys()
-       def get_param(self, key): return self._params[key]
-       def get_params(self): return self._params.values()
+       def get_param_keys(self): return _get_keys(self._params)
+       def get_param(self, key): return _get_elem(self._params, key)
+       def get_params(self): return self._params
 
        ##############################################
        # Access Sinks
        ##############################################
-       def get_sink_keys(self): return self._sinks.keys()
-       def get_sink(self, key): return self._sinks[key]
-       def get_sinks(self): return self._sinks.values()
+       def get_sink_keys(self): return _get_keys(self._sinks)
+       def get_sink(self, key): return _get_elem(self._sinks, key)
+       def get_sinks(self): return self._sinks
 
        ##############################################
        # Access Sources
        ##############################################
-       def get_source_keys(self): return self._sources.keys()
-       def get_source(self, key): return self._sources[key]
-       def get_sources(self): return self._sources.values()
+       def get_source_keys(self): return _get_keys(self._sources)
+       def get_source(self, key): return _get_elem(self._sources, key)
+       def get_sources(self): return self._sources
 
        def get_connections(self):
                return sum([port.get_connections() for port in self.get_ports()], [])
@@ -250,12 +231,22 @@ class Block(Element):
                """
                Import this block's params from nested data.
                Any param keys that do not exist will be ignored.
+               Since params can be dynamically created based another param,
+               call rewrite, and repeat the load until the params stick.
+               This call to rewrite will also create any dynamic ports
+               that are needed for the connections creation phase.
                @param n the nested data odict
                """
-               params_n = n.findall('param')
-               for param_n in params_n:
-                       key = param_n.find('key')
-                       value = param_n.find('value')
-                       #the key must exist in this block's params
-                       if key in self.get_param_keys():
-                               self.get_param(key).set_value(value)
+               get_hash = lambda: hash(tuple(map(hash, self.get_params())))
+               my_hash = 0
+               while get_hash() != my_hash:
+                       params_n = n.findall('param')
+                       for param_n in params_n:
+                               key = param_n.find('key')
+                               value = param_n.find('value')
+                               #the key must exist in this block's params
+                               if key in self.get_param_keys():
+                                       self.get_param(key).set_value(value)
+                       #store hash and call rewrite
+                       my_hash = get_hash()
+                       self.rewrite()
index 16000c46c0a87068491da35f6228c58577c3be37..a57090f3b24a2f5928d3f7c6facb1bfee48b7969 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008 Free Software Foundation, Inc.
+Copyright 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -21,37 +21,59 @@ class Element(object):
 
        def __init__(self, parent=None):
                self._parent = parent
-               self.flag()
-
-       def test(self):
-               """
-               Test the element against failures.
-               Overload this method in sub-classes.
-               """
-               pass
 
        ##################################################
        # Element Validation API
        ##################################################
-       def validate(self): self._error_messages = list()
-       def is_valid(self): return not self.get_error_messages() or not self.get_enabled()
-       def add_error_message(self, msg): self._error_messages.append(msg)
-       def get_error_messages(self): return self._error_messages
+       def validate(self):
+               """
+               Validate this element and call validate on all children.
+               Call this base method before adding error messages in the subclass.
+               """
+               self._error_messages = list()
+               for child in self.get_children(): child.validate()
 
-       def get_enabled(self): return True
+       def is_valid(self):
+               """
+               Is this element valid?
+               @return true when the element is enabled and has no error messages
+               """
+               return not self.get_error_messages() or not self.get_enabled()
 
-       def get_parent(self): return self._parent
+       def add_error_message(self, msg):
+               """
+               Add an error message to the list of errors.
+               @param msg the error message string
+               """
+               self._error_messages.append(msg)
+
+       def get_error_messages(self):
+               """
+               Get the list of error messages from this element and all of its children.
+               Do not include the error messages from disabled children.
+               Cleverly indent the children error messages for printing purposes.
+               @return a list of error message strings
+               """
+               error_messages = list(self._error_messages) #make a copy
+               for child in filter(lambda c: c.get_enabled(), self.get_children()):
+                       for msg in child.get_error_messages():
+                               error_messages.append("%s:\n\t%s"%(child, msg.replace("\n", "\n\t")))
+               return error_messages
+
+       def rewrite(self):
+               """
+               Rewrite this element and call rewrite on all children.
+               Call this base method before rewriting the element.
+               """
+               for child in self.get_children(): child.rewrite()
+
+       def get_enabled(self): return True
 
        ##############################################
-       ## Update flagging
+       ## Tree-like API
        ##############################################
-       def is_flagged(self): return self._flag
-       def flag(self):
-               self._flag = True
-               if self.get_parent(): self.get_parent().flag()
-       def deflag(self):
-               self._flag = False
-               if self.get_parent(): self.get_parent().deflag()
+       def get_parent(self): return self._parent
+       def get_children(self): return list()
 
        ##############################################
        ## Type testing methods
index ea489e948679b6106d9ea4d85b75534ca2627e0a..b4ac8fc3a2bf6a489d027cd07d77c8dae7b48eec 100644 (file)
@@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from . import odict
 from Element import Element
-from Block import Block
-from Connection import Connection
 from .. gui import Messages
 
 class FlowGraph(Element):
@@ -68,6 +66,7 @@ class FlowGraph(Element):
        def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
        def get_blocks(self): return filter(lambda e: e.is_block(), self.get_elements())
        def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
+       def get_children(self): return self.get_elements()
        def get_elements(self):
                """
                Get a list of all the elements.
@@ -102,7 +101,6 @@ class FlowGraph(Element):
                @param key the block key
                @return the new block or None if not found
                """
-               self.flag()
                if key not in self.get_parent().get_block_keys(): return None
                block = self.get_parent().get_new_block(self, key)
                self.get_elements().append(block)
@@ -116,8 +114,7 @@ class FlowGraph(Element):
                @throw Exception bad connection
                @return the new connection
                """
-               self.flag()
-               connection = self.get_parent().Connection(self, porta, portb)
+               connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
                self.get_elements().append(connection)
                return connection
 
@@ -128,7 +125,6 @@ class FlowGraph(Element):
                If the element is a block, remove its connections.
                If the element is a connection, just remove the connection.
                """
-               self.flag()
                if element not in self.get_elements(): return
                #found a port, set to parent signal block
                if element.is_port():
@@ -147,18 +143,6 @@ class FlowGraph(Element):
                """
                raise NotImplementedError
 
-       def validate(self):
-               """
-               Validate the flow graph.
-               All connections and blocks must be valid.
-               """
-               Element.validate(self)
-               for c in self.get_elements():
-                       try:
-                               c.validate()
-                               assert c.is_valid()
-                       except AssertionError: self.add_error_message('Element "%s" is not valid.'%c)
-
        ##############################################
        ## Import/Export Methods
        ##############################################
@@ -198,7 +182,6 @@ class FlowGraph(Element):
                        #only load the block when the block key was valid
                        if block: block.import_data(block_n)
                        else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
-               self.validate() #validate all blocks before connections are made (in case of nports)
                #build the connections
                for connection_n in connections_n:
                        #try to make the connection
@@ -225,3 +208,4 @@ class FlowGraph(Element):
                                #build the connection
                                self.connect(source, sink)
                        except AssertionError: Messages.send_error_load('Connection between %s(%s) and %s(%s) could not be made.'%(source_block_id, source_key, sink_block_id, sink_key))
+               self.rewrite() #global rewrite
index e489601db264095dbb23149f265ba0e306ae734a..6a95e33b983b841dcb691e0aa4eeb2ff05b6769e 100644 (file)
@@ -19,9 +19,9 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
-ourpythondir = $(grc_src_prefix)/base
+ourpythondir = $(pkgpythondir)/grc/base
 ourpython_PYTHON = \
        odict.py \
        ParseXML.py \
@@ -35,7 +35,7 @@ ourpython_PYTHON = \
        Port.py \
        __init__.py
 
-ourdatadir = $(grc_src_prefix)/base
+ourdatadir = $(pkgpythondir)/grc/base
 dist_ourdata_DATA = \
        block_tree.dtd \
        flow_graph.dtd
index 8166d54ecca0d1a6bf892ea3cc0f98c80b6e7322..e56eac36e172a4185c2b6f0c2b3d17c10deef984 100644 (file)
@@ -19,74 +19,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from . import odict
 from Element import Element
-import pygtk
-pygtk.require('2.0')
-import gtk
 
-class InputParam(gtk.HBox):
-       """The base class for an input parameter inside the input parameters dialog."""
-
-       def __init__(self, param, _handle_changed):
-               gtk.HBox.__init__(self)
-               self.param = param
-               self._handle_changed = _handle_changed
-               self.label = gtk.Label('') #no label, markup is added by set_markup
-               self.label.set_size_request(150, -1)
-               self.pack_start(self.label, False)
-               self.set_markup = lambda m: self.label.set_markup(m)
-               self.tp = None
-       def set_color(self, color): pass
-
-class EntryParam(InputParam):
-       """Provide an entry box for strings and numbers."""
-
-       def __init__(self, *args, **kwargs):
-               InputParam.__init__(self, *args, **kwargs)
-               self.entry = input = gtk.Entry()
-               input.set_text(self.param.get_value())
-               input.connect('changed', self._handle_changed)
-               self.pack_start(input, True)
-               self.get_text = input.get_text
-               #tool tip
-               self.tp = gtk.Tooltips()
-               self.tp.set_tip(self.entry, '')
-               self.tp.enable()
-       def set_color(self, color): self.entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-
-class EnumParam(InputParam):
-       """Provide an entry box for Enum types with a drop down menu."""
-
-       def __init__(self, *args, **kwargs):
-               InputParam.__init__(self, *args, **kwargs)
-               self._input = gtk.combo_box_new_text()
-               for option in self.param.get_options(): self._input.append_text(option.get_name())
-               self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
-               self._input.connect('changed', self._handle_changed)
-               self.pack_start(self._input, False)
-       def get_text(self): return self.param.get_option_keys()[self._input.get_active()]
-
-class EnumEntryParam(InputParam):
-       """Provide an entry box and drop down menu for Raw Enum types."""
-
-       def __init__(self, *args, **kwargs):
-               InputParam.__init__(self, *args, **kwargs)
-               self._input = gtk.combo_box_entry_new_text()
-               for option in self.param.get_options(): self._input.append_text(option.get_name())
-               try: self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
-               except:
-                       self._input.set_active(-1)
-                       self._input.get_child().set_text(self.param.get_value())
-               self._input.connect('changed', self._handle_changed)
-               self._input.get_child().connect('changed', self._handle_changed)
-               self.pack_start(self._input, False)
-       def get_text(self):
-               if self._input.get_active() == -1: return self._input.get_child().get_text()
-               return self.param.get_option_keys()[self._input.get_active()]
-       def set_color(self, color):
-               if self._input.get_active() == -1: #custom entry, use color
-                       self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-               else: #from enum, make white background
-                       self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
+def _get_keys(lst): return [elem.get_key() for elem in lst]
+def _get_elem(lst, key):
+       try: return lst[_get_keys(lst).index(key)]
+       except ValueError: raise ValueError, 'Key "%s" not found in %s.'%(key, _get_keys(lst))
 
 class Option(Element):
 
@@ -123,15 +60,11 @@ class Option(Element):
 
 class Param(Element):
 
-       ##possible param types
-       TYPES = ['enum', 'raw']
-
        def __init__(self, block, n):
                """
                Make a new param from nested data.
                @param block the parent element
                @param n the nested odict
-               @return a new param
                """
                #grab the data
                self._name = n.find('name')
@@ -142,22 +75,22 @@ class Param(Element):
                #build the param
                Element.__init__(self, block)
                #create the Option objects from the n data
-               self._options = odict()
-               for option in map(lambda o: Option(self, o), n.findall('option')):
+               self._options = list()
+               for option in map(lambda o: Option(param=self, n=o), n.findall('option')):
                        key = option.get_key()
                        #test against repeated keys
                        try: assert key not in self.get_option_keys()
                        except AssertionError: raise Exception, 'Key "%s" already exists in options'%key
                        #store the option
-                       self._options[key] = option
+                       self.get_options().append(option)
                #test the enum options
                if self.is_enum():
                        #test against options with identical keys
-                       try: assert len(set(self.get_option_keys())) == len(self._options)
+                       try: assert len(set(self.get_option_keys())) == len(self.get_options())
                        except AssertionError: raise Exception, 'Options keys "%s" are not unique.'%self.get_option_keys()
                        #test against inconsistent keys in options
-                       opt_keys = self._options.values()[0].get_opt_keys()
-                       for option in self._options.values():
+                       opt_keys = self.get_options()[0].get_opt_keys()
+                       for option in self.get_options():
                                try: assert set(opt_keys) == set(option.get_opt_keys())
                                except AssertionError: raise Exception, 'Opt keys "%s" are not identical across all options.'%opt_keys
                        #if a value is specified, it must be in the options keys
@@ -166,19 +99,13 @@ class Param(Element):
                        except AssertionError: raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())
                else: self._value = value or ''
 
-       def test(self):
-               """
-               call test on all children
-               """
-               map(lambda c: c.test(), self.get_options())
-
        def validate(self):
                """
                Validate the param.
                The value must be evaluated and type must a possible type.
                """
                Element.validate(self)
-               try: assert self.get_type() in self.TYPES
+               try: assert self.get_type() in self.get_types()
                except AssertionError: self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
 
        def get_evaluated(self): raise NotImplementedError
@@ -190,12 +117,19 @@ class Param(Element):
                """
                raise NotImplementedError
 
+       def get_types(self):
+               """
+               Get a list of all possible param types.
+               @throw NotImplementedError
+               """
+               raise NotImplementedError
+
        def get_color(self): return '#FFFFFF'
        def __str__(self): return 'Param - %s(%s)'%(self.get_name(), self.get_key())
        def is_param(self): return True
        def get_name(self): return self._name
        def get_key(self): return self._key
-       def get_hide(self): return self.get_parent().resolve_dependencies(self._hide)
+       def get_hide(self): return self.get_parent().resolve_dependencies(self._hide).strip()
 
        def get_value(self):
                value = self._value
@@ -204,9 +138,7 @@ class Param(Element):
                        self.set_value(value)
                return value
 
-       def set_value(self, value):
-               self.flag()
-               self._value = str(value) #must be a string
+       def set_value(self, value): self._value = str(value) #must be a string
 
        def get_type(self): return self.get_parent().resolve_dependencies(self._type)
        def is_enum(self): return self._type == 'enum'
@@ -221,31 +153,19 @@ class Param(Element):
                if self.is_enum(): return self.get_option(self.get_value()).get_name()
                return self.get_value()
 
-       def get_input_class(self):
-               """
-               Get the graphical gtk class to represent this parameter.
-               An enum requires and combo parameter.
-               A non-enum with options gets a combined entry/combo parameter.
-               All others get a standard entry parameter.
-               @return gtk input class
-               """
-               if self.is_enum(): return EnumParam
-               if self.get_options(): return EnumEntryParam
-               return EntryParam
-
        ##############################################
        # Access Options
        ##############################################
-       def get_option_keys(self): return self._options.keys()
-       def get_option(self, key): return self._options[key]
-       def get_options(self): return self._options.values()
+       def get_option_keys(self): return _get_keys(self.get_options())
+       def get_option(self, key): return _get_elem(self.get_options(), key)
+       def get_options(self): return self._options
 
        ##############################################
        # Access Opts
        ##############################################
-       def get_opt_keys(self): return self._options[self.get_value()].get_opt_keys()
-       def get_opt(self, key): return self._options[self.get_value()].get_opt(key)
-       def get_opts(self): return self._options[self.get_value()].get_opts()
+       def get_opt_keys(self): return self.get_option(self.get_value()).get_opt_keys()
+       def get_opt(self, key): return self.get_option(self.get_value()).get_opt(key)
+       def get_opts(self): return self.get_option(self.get_value()).get_opts()
 
        ##############################################
        ## Import/Export Methods
index 02d6d2319257e969c1b8b4f151b02556698df6ab..51a3b2f871eb824aea1fee2227201515a06e2dee 100644 (file)
@@ -146,7 +146,7 @@ class Platform(_Element):
 
        def is_platform(self): return True
 
-       def get_new_flow_graph(self): return self.FlowGraph(self)
+       def get_new_flow_graph(self): return self.FlowGraph(platform=self)
 
        def get_generator(self): return self._generator
 
@@ -171,6 +171,5 @@ class Platform(_Element):
        FlowGraph = _FlowGraph
        Connection = _Connection
        Block = _Block
-       Source = _Port
-       Sink = _Port
+       Port = _Port
        Param = _Param
index f4e8e5e1fb2a6f648aef6118b545b5a9e0d3354d..494ea894f7bdcf55551fc403845472b3aef1207d 100644 (file)
@@ -21,25 +21,20 @@ from Element import Element
 
 class Port(Element):
 
-       ##possible port types
-       TYPES = []
-
-       def __init__(self, block, n):
+       def __init__(self, block, n, dir):
                """
                Make a new port from nested data.
                @param block the parent element
                @param n the nested odict
-               @return a new port
+               @param dir the direction source or sink
                """
-               #grab the data
-               name = n['name']
-               key = n['key']
-               type = n['type']
                #build the port
                Element.__init__(self, block)
-               self._name = name
-               self._key = key
-               self._type = type
+               #grab the data
+               self._name = n['name']
+               self._key = n['key']
+               self._type = n['type']
+               self._dir = dir
 
        def validate(self):
                """
@@ -47,7 +42,7 @@ class Port(Element):
                The port must be non-empty and type must a possible type.
                """
                Element.validate(self)
-               try: assert self.get_type() in self.TYPES
+               try: assert self.get_type() in self.get_types()
                except AssertionError: self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
 
        def __str__(self):
@@ -56,12 +51,19 @@ class Port(Element):
                if self.is_sink():
                        return 'Sink - %s(%s)'%(self.get_name(), self.get_key())
 
+       def get_types(self):
+               """
+               Get a list of all possible port types.
+               @throw NotImplementedError
+               """
+               raise NotImplementedError
+
        def is_port(self): return True
        def get_color(self): return '#FFFFFF'
        def get_name(self): return self._name
        def get_key(self): return self._key
-       def is_sink(self): return self in self.get_parent().get_sinks()
-       def is_source(self): return self in self.get_parent().get_sources()
+       def is_sink(self): return self._dir == 'sink'
+       def is_source(self): return self._dir == 'source'
        def get_type(self): return self.get_parent().resolve_dependencies(self._type)
 
        def get_connections(self):
diff --git a/grc/blocks/.gitignore b/grc/blocks/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 025c261f4fe420ca3cadddd8c5704591bce7e6ec..2596eae45600c74013af035c18b07594c1368f67 100644 (file)
@@ -19,7 +19,7 @@
 # Boston, MA 02110-1301, USA.
 #
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
 ourdatadir = $(grc_blocksdir)
 dist_ourdata_DATA = \
@@ -30,8 +30,12 @@ dist_ourdata_DATA = \
        band_reject_filter.xml \
        blks2_am_demod_cf.xml \
        blks2_analysis_filterbank.xml \
+       blks2_cvsd_encode.xml \
+       blks2_cvsd_decode.xml \
        blks2_dxpsk_demod.xml \
        blks2_dxpsk_mod.xml \
+       blks2_dxpsk2_demod.xml \
+       blks2_dxpsk2_mod.xml \
        blks2_error_rate.xml \
        blks2_fm_deemph.xml \
        blks2_fm_demod_cf.xml \
@@ -45,6 +49,7 @@ dist_ourdata_DATA = \
        blks2_ofdm_mod.xml \
        blks2_packet_decoder.xml \
        blks2_packet_encoder.xml \
+       blks2_pfb_arb_resampler.xml \
        blks2_qamx_demod.xml \
        blks2_qamx_mod.xml \
        blks2_rational_resampler_xxx.xml \
@@ -62,6 +67,7 @@ dist_ourdata_DATA = \
        const_source_x.xml \
        gr_add_const_vxx.xml \
        gr_add_xx.xml \
+       gr_additive_scrambler_bb.xml \
        gr_agc2_xx.xml \
        gr_agc_xx.xml \
        gr_and_xx.xml \
@@ -81,10 +87,10 @@ dist_ourdata_DATA = \
        gr_complex_to_real.xml \
        gr_conjugate_cc.xml \
        gr_constellation_decoder_cb.xml \
+       gr_copy.xml \
        gr_correlate_access_code_bb.xml \
        gr_costas_loop_cc.xml \
        gr_cpfsk_bc.xml \
-       gr_dd_mpsk_sync_cc.xml \
        gr_decode_ccsds_27_fb.xml \
        gr_deinterleave.xml \
        gr_delay.xml \
@@ -102,6 +108,7 @@ dist_ourdata_DATA = \
        gr_file_source.xml \
        gr_filter_delay_fc.xml \
        gr_fir_filter_xxx.xml \
+       gr_fll_band_edge_cc.xml \
        gr_float_to_char.xml \
        gr_float_to_complex.xml \
        gr_float_to_short.xml \
@@ -123,6 +130,8 @@ dist_ourdata_DATA = \
        gr_kludge_copy.xml \
        gr_map_bb.xml \
        gr_max_xx.xml \
+       gr_message_sink.xml \
+       gr_message_source.xml \
        gr_moving_average_xx.xml \
        gr_mpsk_receiver_cc.xml \
        gr_mpsk_sync_cc.xml \
@@ -139,6 +148,7 @@ dist_ourdata_DATA = \
        gr_packed_to_unpacked_xx.xml \
        gr_peak_detector2_fb.xml \
        gr_peak_detector_xb.xml \
+       gr_pfb_clock_sync.xml \
        gr_phase_modulator_fc.xml \
        gr_pll_carriertracking_cc.xml \
        gr_pll_freqdet_cf.xml \
@@ -161,6 +171,7 @@ dist_ourdata_DATA = \
        gr_simple_squelch_cc.xml \
        gr_single_pole_iir_filter_xx.xml \
        gr_skiphead.xml \
+       gr_stream_mux.xml \
        gr_stream_to_streams.xml \
        gr_stream_to_vector.xml \
        gr_streams_to_stream.xml \
@@ -215,11 +226,14 @@ dist_ourdata_DATA = \
        variable_slider.xml \
        variable_static_text.xml \
        variable_text_box.xml \
+       virtual_sink.xml \
+       virtual_source.xml \
        wxgui_constellationsink2.xml \
        wxgui_fftsink2.xml \
        wxgui_histosink2.xml \
        wxgui_numbersink2.xml \
        wxgui_scopesink2.xml \
+       wxgui_termsink.xml \
        wxgui_waterfallsink2.xml \
        xmlrpc_client.xml \
        xmlrpc_server.xml
index e2e9acf4ebf9148fff3514ea0fdda93ba718bdd4..af083473d3a59f9a5fd3e76e6dc9b473973a5df1 100644 (file)
@@ -10,8 +10,8 @@
        <import>from gnuradio import gr</import>
        <import>from gnuradio.gr import firdes</import>
        <make>gr.$(type)(#if str($type).startswith('interp') then $interp else $decim#, firdes.$(type.fcn)(
-       $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</make>
-       <callback>set_taps(firdes.$(type.fcn)($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</callback>
+       $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, $win, $beta))</make>
+       <callback>set_taps(firdes.$(type.fcn)($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, $win, $beta))</callback>
        <param>
                <name>FIR Type</name>
                <key>type</key>
        </param>
        <param>
                <name>Window</name>
-               <key>window</key>
-               <type>enum</type>
+               <key>win</key>
+               <value>firdes.WIN_HAMMING</value>
+               <type>int</type>
                <option>
                        <name>Hamming</name>
-                       <key>WIN_HAMMING</key>
+                       <key>firdes.WIN_HAMMING</key>
                </option>
                <option>
                        <name>Hann</name>
-                       <key>WIN_HANN</key>
+                       <key>firdes.WIN_HANN</key>
                </option>
                <option>
                        <name>Blackman</name>
-                       <key>WIN_BLACKMAN</key>
+                       <key>firdes.WIN_BLACKMAN</key>
                </option>
                <option>
                        <name>Rectangular</name>
-                       <key>WIN_RECTANGULAR</key>
+                       <key>firdes.WIN_RECTANGULAR</key>
                </option>
                <option>
                        <name>Kaiser</name>
-                       <key>WIN_KAISER</key>
+                       <key>firdes.WIN_KAISER</key>
                </option>
        </param>
        <param>
index 3b58f0b51431a1d555c650dcd0e6ddf9a2b6c7de..dd5e7a9d7664a814867dad3ab34b83b7aebabfa5 100644 (file)
@@ -10,8 +10,8 @@
        <import>from gnuradio import gr</import>
        <import>from gnuradio.gr import firdes</import>
        <make>gr.$(type)(#if str($type).startswith('interp') then $interp else $decim#, firdes.band_reject(
-       $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</make>
-       <callback>set_taps(firdes.band_reject($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, firdes.$window, $beta))</callback>
+       $gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, $win, $beta))</make>
+       <callback>set_taps(firdes.band_reject($gain, $samp_rate, $low_cutoff_freq, $high_cutoff_freq, $width, $win, $beta))</callback>
        <param>
                <name>FIR Type</name>
                <key>type</key>
        </param>
        <param>
                <name>Window</name>
-               <key>window</key>
-               <type>enum</type>
+               <key>win</key>
+               <value>firdes.WIN_HAMMING</value>
+               <type>int</type>
                <option>
                        <name>Hamming</name>
-                       <key>WIN_HAMMING</key>
+                       <key>firdes.WIN_HAMMING</key>
                </option>
                <option>
                        <name>Hann</name>
-                       <key>WIN_HANN</key>
+                       <key>firdes.WIN_HANN</key>
                </option>
                <option>
                        <name>Blackman</name>
-                       <key>WIN_BLACKMAN</key>
+                       <key>firdes.WIN_BLACKMAN</key>
                </option>
                <option>
                        <name>Rectangular</name>
-                       <key>WIN_RECTANGULAR</key>
+                       <key>firdes.WIN_RECTANGULAR</key>
                </option>
                <option>
                        <name>Kaiser</name>
-                       <key>WIN_KAISER</key>
+                       <key>firdes.WIN_KAISER</key>
                </option>
        </param>
        <param>
diff --git a/grc/blocks/blks2_cvsd_decode.xml b/grc/blocks/blks2_cvsd_decode.xml
new file mode 100644 (file)
index 0000000..6be7daa
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## CVSD Encoder
+###################################################
+ -->
+<block>
+       <name>CVSD Decoder</name>
+       <key>blks2_cvsd_decode</key>
+       <import>from gnuradio import blks2</import>
+       <make>blks2.cvsd_decode($resample,$bw)</make>
+       <param>
+         <name>Resample</name>
+         <key>resample</key>
+         <value>8</value>
+         <type>int</type>
+       </param>
+       <param>
+         <name>Frac. Bandwidth</name>
+         <key>bw</key>
+         <value>0.5</value>
+         <type>real</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>byte</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>float</type>
+       </source>
+</block>
diff --git a/grc/blocks/blks2_cvsd_encode.xml b/grc/blocks/blks2_cvsd_encode.xml
new file mode 100644 (file)
index 0000000..3123b1a
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## CVSD Encoder
+###################################################
+ -->
+<block>
+       <name>CVSD Encoder</name>
+       <key>blks2_cvsd_encode</key>
+       <import>from gnuradio import blks2</import>
+       <make>blks2.cvsd_encode($resample,$bw)</make>
+       <param>
+         <name>Resample</name>
+         <key>resample</key>
+         <value>8</value>
+         <type>int</type>
+       </param>
+       <param>
+         <name>Frac. Bandwidth</name>
+         <key>bw</key>
+         <value>0.5</value>
+         <type>real</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>float</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>byte</type>
+       </source>
+</block>
diff --git a/grc/blocks/blks2_dxpsk2_demod.xml b/grc/blocks/blks2_dxpsk2_demod.xml
new file mode 100644 (file)
index 0000000..ce8305c
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##DPSK2 Demod - 2, 4
+###################################################
+ -->
+<block>
+       <name>DPSK2 Demod</name>
+       <key>blks2_dxpsk2_demod</key>
+       <import>from gnuradio import blks2</import>
+       <make>blks2.$(type)2_demod(
+       samples_per_symbol=$samples_per_symbol,
+       excess_bw=$excess_bw,
+       costas_alpha=$costas_alpha,
+       timing_alpha=$timing_alpha,
+       timing_max_dev=$timing_max_dev,
+       gray_code=$gray_code,
+       verbose=$verbose,
+       log=$log,
+       sync_out=$sync_out,
+)</make>
+       <callback>clock_recov.set_alpha($costas_alpha)</callback>
+       <callback>clock_recov.set_beta(0.25*$costas_alpha**2)</callback>
+       <callback>time_recov.set_alpha($timing_alpha)</callback>
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>DBPSK</name>
+                       <key>dbpsk</key>
+               </option>
+               <option>
+                       <name>DQPSK</name>
+                       <key>dqpsk</key>
+               </option>
+       </param>
+       <param>
+               <name>Samples/Symbol</name>
+               <key>samples_per_symbol</key>
+               <value>2</value>
+               <type>int</type>
+       </param>
+       <param>
+               <name>Excess BW</name>
+               <key>excess_bw</key>
+               <value>0.35</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Costas Alpha</name>
+               <key>costas_alpha</key>
+               <value>0.175</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Timing Alpha</name>
+               <key>timing_alpha</key>
+               <value>0.100</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Timing Max Dev</name>
+               <key>timing_max_dev</key>
+               <value>1.5</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Omega Relative Limit</name>
+               <key>omega_relative_limit</key>
+               <value>0.005</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Gray Code</name>
+               <key>gray_code</key>
+               <value>True</value>
+               <type>bool</type>
+               <option>
+                       <name>Yes</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>No</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Verbose</name>
+               <key>verbose</key>
+               <value>False</value>
+               <type>bool</type>
+               <hide>#if str($verbose) == 'False' then 'part' else 'none'#</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Logging</name>
+               <key>log</key>
+               <value>False</value>
+               <type>bool</type>
+               <hide>#if str($log) == 'False' then 'part' else 'none'#</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Sync Out</name>
+               <key>sync_out</key>
+               <value>False</value>
+               <type>bool</type>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>complex</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>byte</type>
+       </source>
+       <source>
+               <name>sync</name>
+               <type>complex</type>
+               <optional>1</optional>
+       </source>
+</block>
diff --git a/grc/blocks/blks2_dxpsk2_mod.xml b/grc/blocks/blks2_dxpsk2_mod.xml
new file mode 100644 (file)
index 0000000..bf292be
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##DPSK2 Mod - 2, 4
+###################################################
+ -->
+<block>
+       <name>DPSK2 Mod</name>
+       <key>blks2_dxpsk2_mod</key>
+       <import>from gnuradio import blks2</import>
+       <make>blks2.$(type)2_mod(
+       samples_per_symbol=$samples_per_symbol,
+       excess_bw=$excess_bw,
+       gray_code=$gray_code,
+       verbose=$verbose,
+       log=$log,
+)</make>
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>DBPSK</name>
+                       <key>dbpsk</key>
+               </option>
+               <option>
+                       <name>DQPSK</name>
+                       <key>dqpsk</key>
+               </option>
+       </param>
+       <param>
+               <name>Samples/Symbol</name>
+               <key>samples_per_symbol</key>
+               <value>2</value>
+               <type>int</type>
+       </param>
+       <param>
+               <name>Excess BW</name>
+               <key>excess_bw</key>
+               <value>0.35</value>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Gray Code</name>
+               <key>gray_code</key>
+               <value>True</value>
+               <type>bool</type>
+               <option>
+                       <name>Yes</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>No</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Verbose</name>
+               <key>verbose</key>
+               <value>False</value>
+               <type>bool</type>
+               <hide>#if str($verbose) == 'False' then 'part' else 'none'#</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Logging</name>
+               <key>log</key>
+               <value>False</value>
+               <type>bool</type>
+               <hide>#if str($log) == 'False' then 'part' else 'none'#</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>byte</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>complex</type>
+       </source>
+</block>
index 4c13b3415e73ec5f2beeb82bc3c7c7f3229c1dd6..1c96b6cec62ab7d0e554ff90b3ce9857ea395e5c 100644 (file)
@@ -76,7 +76,7 @@
                <name>Gray Code</name>
                <key>gray_code</key>
                <value>True</value>
-               <type>enum</type>
+               <type>bool</type>
                <option>
                        <name>Yes</name>
                        <key>True</key>
index 28fd742fa6b9400c238b5d1b58f99b24bce2de27..77505d8ad588f54b3e7def2f00dd43de9f3ae233 100644 (file)
@@ -48,7 +48,7 @@
                <name>Gray Code</name>
                <key>gray_code</key>
                <value>True</value>
-               <type>enum</type>
+               <type>bool</type>
                <option>
                        <name>Yes</name>
                        <key>True</key>
diff --git a/grc/blocks/blks2_pfb_arb_resampler.xml b/grc/blocks/blks2_pfb_arb_resampler.xml
new file mode 100644 (file)
index 0000000..062b0dd
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Polyphase Arbitrary Resampler
+###################################################
+ -->
+<block>
+       <name>Polyphase Resampler</name>
+       <key>blks2_pfb_arb_resampler_ccf</key>
+       <import>from gnuradio import blks2</import>
+       <import>from gnuradio.gr import firdes</import>
+       <make>blks2.pfb_arb_resampler_ccf(
+       $rate,
+       $taps,
+       $size,
+)</make>
+       <callback>set_taps($taps)</callback>
+       <param>
+               <name>Resample Rate</name>
+               <key>rate</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Taps</name>
+               <key>taps</key>
+               <type>real_vector</type>
+       </param>
+       <param>
+               <name>Size (# phases)</name>
+               <key>size</key>
+               <value>32</value>
+               <type>int</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>complex</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>complex</type>
+       </source>
+</block>
index 9eda2fdcf80fa113638e63dcba8fc9d92c1bf627..8d91258e516f08417a64f361c0ff2007b57da3db 100644 (file)
@@ -20,7 +20,9 @@
                <block>gr_udp_source</block>
                <block>audio_source</block>
                <block>gr_wavfile_source</block>
+               <block>gr_message_source</block>
                <block>pad_source</block>
+               <block>virtual_source</block>
        </cat>
        <cat>
                <name>Sinks</name>
@@ -32,7 +34,9 @@
                <block>gr_udp_sink</block>
                <block>audio_sink</block>
                <block>gr_wavfile_sink</block>
+               <block>gr_message_sink</block>
                <block>pad_sink</block>
+               <block>virtual_sink</block>
        </cat>
        <cat>
                <name>Graphical Sinks</name>
@@ -42,6 +46,7 @@
                <block>wxgui_constellationsink2</block>
                <block>wxgui_waterfallsink2</block>
                <block>wxgui_histosink2</block>
+               <block>wxgui_termsink</block>
        </cat>
        <cat>
                <name>Operators</name>
 
                <block>gr_stream_to_vector</block>
                <block>gr_vector_to_stream</block>
-               
+
                <block>blks2_stream_to_vector_decimator</block>
+
+               <block>gr_stream_mux</block>
        </cat>
        <cat>
                <name>Misc Conversions</name>
        <cat>
                <name>Synchronizers</name>
                <block>gr_clock_recovery_mm_xx</block>
+               <block>gr_pfb_clock_sync_xxx</block>
 
                <block>gr_costas_loop_cc</block>
-               <block>gr_dd_mpsk_sync_cc</block>
                <block>gr_mpsk_sync_cc</block>
                <block>gr_mpsk_receiver_cc</block>
 
                <block>gr_pll_freqdet_cf</block>
                <block>gr_pll_refout_cc</block>
 
+                <block>gr_fll_band_edge_cc</block>
+
                <block>gr_correlate_access_code_bb</block>
                <block>gr_pn_correlator_cc</block>
                <block>gr_simple_correlator</block>
                <block>band_pass_filter</block>
                <block>band_reject_filter</block>
                <block>root_raised_cosine_filter</block>
-               <!-- Filters that take taps as aruments -->
+               <!-- Filters that take taps as arguments -->
                <block>gr_fir_filter_xxx</block>
                <block>gr_interp_fir_filter_xxx</block>
                <block>gr_fft_filter_xxx</block>
                <!-- Filter banks -->
                <block>blks2_synthesis_filterbank</block>
                <block>blks2_analysis_filterbank</block>
+               <!-- Polyphase filters -->
+               <block>blks2_pfb_arb_resampler_ccf</block>
                <!-- Other filters -->
                <block>gr_single_pole_iir_filter_xx</block>
                <block>gr_hilbert_fc</block>
                <block>blks2_dxpsk_mod</block>
                <block>blks2_dxpsk_demod</block>
 
+               <block>blks2_dxpsk2_mod</block>
+               <block>blks2_dxpsk2_demod</block>
+
                <block>blks2_gmsk_mod</block>
                <block>blks2_gmsk_demod</block>
 
                <name>Line Coding</name>
                <block>gr_scrambler_bb</block>
                <block>gr_descrambler_bb</block>
+               <block>gr_additive_scrambler_bb</block>
+       </cat>
+       <cat>
+               <name>Vocoders</name>
+               <block>blks2_cvsd_encode</block>
+               <block>blks2_cvsd_decode</block>
        </cat>
        <cat>
                <name>Probes</name>
                <block>gr_skiphead</block>
 
                <block>gr_kludge_copy</block>
+               <block>gr_copy</block>
                <block>gr_nop</block>
 
                <block>xmlrpc_server</block>
diff --git a/grc/blocks/gr_additive_scrambler_bb.xml b/grc/blocks/gr_additive_scrambler_bb.xml
new file mode 100644 (file)
index 0000000..a15d6ee
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Additive Scrambler
+###################################################
+ -->
+<block>
+       <name>Additive Scrambler</name>
+       <key>gr_additive_scrambler_bb</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.additive_scrambler_bb($mask, $seed, $len, $count)</make>
+       <param>
+               <name>Mask</name>
+               <key>mask</key>
+               <value>0x8A</value>
+               <type>hex</type>
+       </param>
+       <param>
+               <name>Seed</name>
+               <key>seed</key>
+               <value>0x7F</value>
+               <type>hex</type>
+       </param>
+       <param>
+               <name>Length</name>
+               <key>len</key>
+               <value>7</value>
+               <type>int</type>
+       </param>
+       <param>
+               <name>Count</name>
+               <key>count</key>
+               <value>0</value>
+               <type>int</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>byte</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>byte</type>
+       </source>
+</block>
index b54e710ef96bb974bda3d18f82b3f514f6aa675b..e9da38e9a5604a5f402e7c6dc3d15a19481bdcda 100644 (file)
                <value>2</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$num_ports &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$in_type</type>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$out_type</type>
+               <nports>$num_ports</nports>
        </source>
 </block>
diff --git a/grc/blocks/gr_copy.xml b/grc/blocks/gr_copy.xml
new file mode 100644 (file)
index 0000000..8b12eac
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Copy
+###################################################
+ -->
+<block>
+       <name>Copy</name>
+       <key>gr_copy</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.copy($type.size*$vlen)
+self.$(id).set_enabled($enabled)</make>
+       <callback>set_enabled($enabled)</callback>
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex</name>
+                       <key>complex</key>
+                       <opt>size:gr.sizeof_gr_complex</opt>
+               </option>
+               <option>
+                       <name>Float</name>
+                       <key>float</key>
+                       <opt>size:gr.sizeof_float</opt>
+               </option>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>size:gr.sizeof_int</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>size:gr.sizeof_short</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>size:gr.sizeof_char</opt>
+               </option>
+       </param>
+       <param>
+               <name>Enabled</name>
+               <key>enabled</key>
+               <value>True</value>
+               <type>bool</type>
+               <option>
+                       <name>Enabled</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Disabled</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Vec Length</name>
+               <key>vlen</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$vlen &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </source>
+</block>
index 64a774defa36612720b39a17721f684b1888953b..5cc411a7820b17811481a741f2027ebf631d2ef6 100644 (file)
                <value>0</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <check>$num_ports &gt; 0</check>
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </source>
 </block>
diff --git a/grc/blocks/gr_fll_band_edge_cc.xml b/grc/blocks/gr_fll_band_edge_cc.xml
new file mode 100644 (file)
index 0000000..5a13ac4
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## FLL using Band-Edge Filters
+###################################################
+ -->
+<block>
+       <name>FLL Band-Edge</name>
+       <key>gr_fll_band_edge_cc</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.fll_band_edge_cc($samps_per_sym, $rolloff, $filter_size, $alpha, $beta)</make>
+       <callback>set_alpha($alpha)</callback>
+       <callback>set_beta($beta)</callback>
+
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex->Complex</name>
+                       <key>cc</key>
+                       <opt>input:complex</opt>
+                       <opt>output:complex</opt>
+               </option>
+       </param>
+
+       <param>
+               <name>Samples Per Symbol</name>
+               <key>samps_per_sym</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Filter Rolloff Factor</name>
+               <key>rolloff</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Prototype Filter Size</name>
+               <key>filter_size</key>
+               <type>int</type>
+       </param>
+
+       <param>
+               <name>Alpha</name>
+               <key>alpha</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Beta</name>
+               <key>beta</key>
+               <type>real</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>$type.input</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type.output</type>
+       </source>
+       <source>
+               <name>freq</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+       <source>
+               <name>phase</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+       <source>
+               <name>error</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+</block>
index 3c817c5726709402a6fe48152f7ab1864f6d2145..8058b082dbd370fa540a0cbe9f8dfb77e7b5a738 100644 (file)
@@ -5,7 +5,7 @@
 ###################################################
  -->
 <block>
-       <name>Copy</name>
+       <name>Kludge Copy</name>
        <key>gr_kludge_copy</key>
        <import>from gnuradio import gr</import>
        <make>gr.kludge_copy($type.size*$vlen)</make>
                        <opt>size:gr.sizeof_char</opt>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <check>$num_ports &gt; 0</check>
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </source>
 </block>
diff --git a/grc/blocks/gr_message_sink.xml b/grc/blocks/gr_message_sink.xml
new file mode 100644 (file)
index 0000000..18e92ad
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Message Sink (the source port is a message)
+###################################################
+ -->
+<block>
+       <name>Message Sink</name>
+       <key>gr_message_sink</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.message_sink($type.size*$vlen, $(id)_msgq_out, $dont_block)</make>
+       <param>
+               <name>Input Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex</name>
+                       <key>complex</key>
+                       <opt>size:gr.sizeof_gr_complex</opt>
+               </option>
+               <option>
+                       <name>Float</name>
+                       <key>float</key>
+                       <opt>size:gr.sizeof_float</opt>
+               </option>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>size:gr.sizeof_int</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>size:gr.sizeof_short</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>size:gr.sizeof_char</opt>
+               </option>
+       </param>
+       <param>
+               <name>Don't Block</name>
+               <key>dont_block</key>
+               <value>False</value>
+               <type>enum</type>
+               <option>
+                       <name>Don't Block</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Block</name>
+                       <key>False</key>
+               </option>
+       </param>
+       <param>
+               <name>Vec Length</name>
+               <key>vlen</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$vlen &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>msg</type>
+       </source>
+</block>
diff --git a/grc/blocks/gr_message_source.xml b/grc/blocks/gr_message_source.xml
new file mode 100644 (file)
index 0000000..72367b2
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Message Source (the sink port is a message)
+###################################################
+ -->
+<block>
+       <name>Message Source</name>
+       <key>gr_message_source</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.message_source($type.size*$vlen, $(id)_msgq_in)</make>
+       <param>
+               <name>Output Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex</name>
+                       <key>complex</key>
+                       <opt>size:gr.sizeof_gr_complex</opt>
+               </option>
+               <option>
+                       <name>Float</name>
+                       <key>float</key>
+                       <opt>size:gr.sizeof_float</opt>
+               </option>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>size:gr.sizeof_int</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>size:gr.sizeof_short</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>size:gr.sizeof_char</opt>
+               </option>
+       </param>
+       <param>
+               <name>Vec Length</name>
+               <key>vlen</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$vlen &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>msg</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </source>
+</block>
index 4fcef5148d53e167627f2d76e5f892238d2426e5..4789b4400b8a71d3ca7b20ab74ebab56413e066b 100644 (file)
@@ -40,7 +40,7 @@
                <name>Noise Type</name>
                <key>noise_type</key>
                <value>gr.GR_GAUSSIAN</value>
-               <type>raw</type>
+               <type>int</type>
                <option>
                        <name>Uniform</name>
                        <key>gr.GR_UNIFORM</key>
index 127a78a55364cfbc739fcc74ac6856e5acfeed22..bd884d6b8bff7f22f95d83c1a0361c4cd470ea15 100644 (file)
                        <opt>size:gr.sizeof_char</opt>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <check>$num_ports &gt; 0</check>
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </source>
 </block>
index 7af7e4b6bc523f47067851f319c7c93fb6cc070c..1c2bb870965fc71e0a4e28f17849e3918f0e9dda 100644 (file)
                        <opt>fcn:bb</opt>
                </option>
        </param>
-       <param>
-               <name>Num Inputs</name>
-               <key>num_inputs</key>
-               <value>2</value>
-               <type>int</type>
-       </param>
-       <check>$num_inputs &gt;= 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
-               <nports>$num_inputs</nports>
        </sink>
        <source>
                <name>out</name>
index 5fd9729a4097f8a66a87181ae6ea1ba54eb4c32a..c1477dd9ca882c879fcf0052d2ea0bc88bb808c8 100644 (file)
@@ -38,7 +38,7 @@
        <param>
                <name>Endianness</name>
                <key>endianness</key>
-               <type>enum</type>
+               <type>int</type>
                <option>
                        <name>MSB</name>
                        <key>gr.GR_MSB_FIRST</key>
                        <key>gr.GR_LSB_FIRST</key>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$num_ports &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
+               <nports>$num_ports</nports>
        </source>
 </block>
diff --git a/grc/blocks/gr_pfb_clock_sync.xml b/grc/blocks/gr_pfb_clock_sync.xml
new file mode 100644 (file)
index 0000000..26cacfb
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Polyphase Filter based Clock Sync
+###################################################
+ -->
+<block>
+       <name>Polyphase Clock Sync</name>
+       <key>gr_pfb_clock_sync_xxx</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.pfb_clock_sync_$(type)($sps, $alpha, $taps, $filter_size, $init_phase, $max_dev)
+self.$(id).set_beta($beta)</make>
+       <callback>set_taps($taps)</callback>
+       <callback>set_alpha($alpha)</callback>
+       <callback>set_beta($beta)</callback>
+
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex->Complex (Real Taps)</name>
+                       <key>ccf</key>
+                       <opt>input:complex</opt>
+                       <opt>output:complex</opt>
+                       <opt>taps:real_vector</opt>
+               </option>
+               <option>
+                       <name>Float->Float (Real Taps)</name>
+                       <key>fff</key>
+                       <opt>input:float</opt>
+                       <opt>output:float</opt>
+                       <opt>taps:real_vector</opt>
+               </option>
+       </param>
+
+       <param>
+               <name>Samples/Symbol</name>
+               <key>sps</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Alpha</name>
+               <key>alpha</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Beta</name>
+               <key>beta</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Taps</name>
+               <key>taps</key>
+               <type>real_vector</type>
+       </param>
+       <param>
+               <name>Filter Size</name>
+               <key>filter_size</key>
+               <type>int</type>
+       </param>
+       <param>
+               <name>Initial Phase</name>
+               <key>init_phase</key>
+               <type>real</type>
+       </param>
+       <param>
+               <name>Maximum Rate Deviation</name>
+               <key>max_dev</key>
+               <type>real</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type>$type.input</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type.output</type>
+       </source>
+       <source>
+               <name>err</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+       <source>
+               <name>rate</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+       <source>
+               <name>phase</name>
+               <type>float</type>
+               <optional>1</optional>
+       </source>
+</block>
index bfe66bb00bcdf8f4e7a4491f1f4e2875174e3861..2a036c3fdbbe76a0ecde8898956d39b5f6d467a1 100644 (file)
@@ -40,7 +40,7 @@
        </sink>
        <sink>
                <name>ctrl</name>
-               <type>$type</type>
+               <type>byte</type>
        </sink>
        <source>
                <name>out</name>
index c329dba67fb0e34790fcc0fe93f44c4c5717f089..644cf52d0c7d50e4f5ea331e38584b190693c242 100644 (file)
@@ -53,7 +53,7 @@
                <name>Waveform</name>
                <key>waveform</key>
                <value>gr.GR_COS_WAVE</value>
-               <type>raw</type>
+               <type>int</type>
                <option>
                        <name>Constant</name>
                        <key>gr.GR_CONST_WAVE</key>
diff --git a/grc/blocks/gr_stream_mux.xml b/grc/blocks/gr_stream_mux.xml
new file mode 100644 (file)
index 0000000..8efe7b6
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Stream Mux:
+##     all types, many inputs, only one output
+###################################################
+ -->
+<block>
+       <name>Stream Mux</name>
+       <key>gr_stream_mux</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.stream_mux($type.size*$vlen, $lengths)</make>
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex</name>
+                       <key>complex</key>
+                       <opt>size:gr.sizeof_gr_complex</opt>
+               </option>
+               <option>
+                       <name>Float</name>
+                       <key>float</key>
+                       <opt>size:gr.sizeof_float</opt>
+               </option>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>size:gr.sizeof_int</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>size:gr.sizeof_short</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>size:gr.sizeof_char</opt>
+               </option>
+       </param>
+       <param>
+               <name>Lengths</name>
+               <key>lengths</key>
+               <value>1, 1</value>
+               <type>int_vector</type>
+       </param>
+       <param>
+               <name>Num Inputs</name>
+               <key>num_inputs</key>
+               <value>2</value>
+               <type>int</type>
+       </param>
+       <param>
+               <name>Vec Length</name>
+               <key>vlen</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$num_inputs &gt; 0</check>
+       <check>$num_inputs == len($lengths)</check>
+       <check>$vlen &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+               <nports>$num_inputs</nports>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </source>
+</block>
index e9f6c2be8bf8d0960c953050d89302e81461a3f8..45f81075f0faaa1df1a35a6c45e62571f835f5a8 100644 (file)
@@ -8,7 +8,7 @@
        <name>UDP Sink</name>
        <key>gr_udp_sink</key>
        <import>from gnuradio import gr</import>
-       <make>gr.udp_sink($type.size*$vlen, $ipaddr_local, $port_local, $ipaddr_remote, $port_remote, $mtu)</make>
+       <make>gr.udp_sink($type.size*$vlen, $ipaddr, $port, $psize, $eof)</make>
        <callback>set_mtu($mtu)</callback>
        <param>
                <name>Input Type</name>
                </option>
        </param>
        <param>
-               <name>Local IP Address</name>
-               <key>ipaddr_local</key>
-               <value>127.0.0.1</value>
+               <name>Destination IP Address</name>
+               <key>ipaddr</key>
                <type>string</type>
        </param>
        <param>
-               <name>Local Port</name>
-               <key>port_local</key>
-               <value>0</value>
+               <name>Destination Port</name>
+               <key>port</key>
                <type>int</type>
        </param>
        <param>
-               <name>Remote IP Address</name>
-               <key>ipaddr_remote</key>
-               <value>127.0.0.1</value>
-               <type>string</type>
-       </param>
-       <param>
-               <name>Remote Port</name>
-               <key>port_remote</key>
-               <value>1234</value>
+               <name>Payload Size</name>
+               <key>psize</key>
+               <value>1472</value>
                <type>int</type>
        </param>
        <param>
-               <name>MTU</name>
-               <key>mtu</key>
-               <value>1024</value>
-               <type>int</type>
+               <name>Send Null Pkt as EOF</name>
+               <key>eof</key>
+               <value>True</value>
+               <type>bool</type>
        </param>
        <param>
                <name>Vec Length</name>
index f03adf8024d43f3b9c2d4644e5e8769dbd0246c8..a1b961651f33eac2abba43a26a5f36ca3f7b8e30 100644 (file)
@@ -8,7 +8,7 @@
        <name>UDP Source</name>
        <key>gr_udp_source</key>
        <import>from gnuradio import gr</import>
-       <make>gr.udp_source($type.size*$vlen, $ipaddr, $port, $mtu)</make>
+       <make>gr.udp_source($type.size*$vlen, $ipaddr, $port, $psize, $eof, $wait)</make>
        <callback>set_mtu($mtu)</callback>
        <param>
                <name>Output Type</name>
                <type>int</type>
        </param>
        <param>
-               <name>MTU</name>
-               <key>mtu</key>
-               <value>1024</value>
+               <name>Payload Size</name>
+               <key>psize</key>
+               <value>1472</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Null Pkt is EOF</name>
+               <key>eof</key>
+               <value>True</value>
+               <type>bool</type>
+       </param>
+       <param>
+               <name>Wait for Data</name>
+               <key>wait</key>
+               <value>True</value>
+               <type>bool</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
index f7457eb5c1a2376b8cd6cd0e4c12a2b205df4305..427c800824ef331aaee7a78f2edf739e327c8288 100644 (file)
@@ -38,7 +38,7 @@
        <param>
                <name>Endianness</name>
                <key>endianness</key>
-               <type>enum</type>
+               <type>int</type>
                <option>
                        <name>MSB</name>
                        <key>gr.GR_MSB_FIRST</key>
                        <key>gr.GR_LSB_FIRST</key>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$num_ports &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
+               <nports>$num_ports</nports>
        </source>
 </block>
index 5be916fa97be3cfab26297f21926411d875d47fb..0e29cbb36f3a9ca8113786f5e5e80a5ac72e2061 100644 (file)
@@ -10,8 +10,8 @@
        <import>from gnuradio import gr</import>
        <import>from gnuradio.gr import firdes</import>
        <make>gr.$(type)(#if str($type).startswith('interp') then $interp else $decim#, firdes.high_pass(
-       $gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</make>
-       <callback>set_taps(firdes.high_pass($gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</callback>
+       $gain, $samp_rate, $cutoff_freq, $width, $win, $beta))</make>
+       <callback>set_taps(firdes.high_pass($gain, $samp_rate, $cutoff_freq, $width, $win, $beta))</callback>
        <param>
                <name>FIR Type</name>
                <key>type</key>
        </param>
        <param>
                <name>Window</name>
-               <key>window</key>
-               <type>enum</type>
+               <key>win</key>
+               <value>firdes.WIN_HAMMING</value>
+               <type>int</type>
                <option>
                        <name>Hamming</name>
-                       <key>WIN_HAMMING</key>
+                       <key>firdes.WIN_HAMMING</key>
                </option>
                <option>
                        <name>Hann</name>
-                       <key>WIN_HANN</key>
+                       <key>firdes.WIN_HANN</key>
                </option>
                <option>
                        <name>Blackman</name>
-                       <key>WIN_BLACKMAN</key>
+                       <key>firdes.WIN_BLACKMAN</key>
                </option>
                <option>
                        <name>Rectangular</name>
-                       <key>WIN_RECTANGULAR</key>
+                       <key>firdes.WIN_RECTANGULAR</key>
                </option>
                <option>
                        <name>Kaiser</name>
-                       <key>WIN_KAISER</key>
+                       <key>firdes.WIN_KAISER</key>
                </option>
        </param>
        <param>
index 27120c0471d9120bea28748f3005c3a8563038f3..26435fd4d8f36dde9d6ae5f6f7b920fa5f766c85 100644 (file)
@@ -10,8 +10,8 @@
        <import>from gnuradio import gr</import>
        <import>from gnuradio.gr import firdes</import>
        <make>gr.$(type)(#if str($type).startswith('interp') then $interp else $decim#, firdes.low_pass(
-       $gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</make>
-       <callback>set_taps(firdes.low_pass($gain, $samp_rate, $cutoff_freq, $width, firdes.$window, $beta))</callback>
+       $gain, $samp_rate, $cutoff_freq, $width, $win, $beta))</make>
+       <callback>set_taps(firdes.low_pass($gain, $samp_rate, $cutoff_freq, $width, $win, $beta))</callback>
        <param>
                <name>FIR Type</name>
                <key>type</key>
        </param>
        <param>
                <name>Window</name>
-               <key>window</key>
-               <type>enum</type>
+               <key>win</key>
+               <value>firdes.WIN_HAMMING</value>
+               <type>int</type>
                <option>
                        <name>Hamming</name>
-                       <key>WIN_HAMMING</key>
+                       <key>firdes.WIN_HAMMING</key>
                </option>
                <option>
                        <name>Hann</name>
-                       <key>WIN_HANN</key>
+                       <key>firdes.WIN_HANN</key>
                </option>
                <option>
                        <name>Blackman</name>
-                       <key>WIN_BLACKMAN</key>
+                       <key>firdes.WIN_BLACKMAN</key>
                </option>
                <option>
                        <name>Rectangular</name>
-                       <key>WIN_RECTANGULAR</key>
+                       <key>firdes.WIN_RECTANGULAR</key>
                </option>
                <option>
                        <name>Kaiser</name>
-                       <key>WIN_KAISER</key>
+                       <key>firdes.WIN_KAISER</key>
                </option>
        </param>
        <param>
index 18d6e2f0c99fc0818a5177950cc438672e6f55d0..4d0dd28999f4bfbbc8c6c541cc8b6ffbb695553a 100644 (file)
@@ -9,16 +9,17 @@
 <block>
        <name>Options</name>
        <key>options</key>
-       <import>from gnuradio import gr
-#if $generate_options() == 'wx_gui'
+       <import>from gnuradio import gr</import>
+       <import>from gnuradio.gr import firdes</import>
+       <import>#if $generate_options() == 'wx_gui'
 from grc_gnuradio import wxgui as grc_wxgui
 import wx
 #end if
 #if $generate_options() != 'hb'
 from optparse import OptionParser
 from gnuradio.eng_option import eng_option
-#end if
-</import>
+from gnuradio import eng_notation
+#end if</import>
        <make></make>
        <callback>if $run: self.start()
 else: self.stop(); self.wait()</callback>
@@ -76,20 +77,37 @@ else: self.stop(); self.wait()</callback>
                <type>string</type>
                <hide>#if $generate_options() == 'hb' then 'none' else 'all'#</hide>
        </param>
+       <param>
+               <name>Run Options</name>
+               <key>run_options</key>
+               <value>prompt</value>
+               <type>enum</type>
+               <hide>#if $generate_options() == 'no_gui' then 'none' else 'all'#</hide>
+               <option>
+                       <name>Run to Completion</name>
+                       <key>run</key>
+               </option>
+               <option>
+                       <name>Prompt for Exit</name>
+                       <key>prompt</key>
+               </option>
+       </param>
        <param>
                <name>Run</name>
                <key>run</key>
                <value>True</value>
                <type>bool</type>
-               <hide>#if $generate_options() == 'wx_gui'
-       #if str($run) == 'True'
-part#slurp
+               <hide>
+#if $generate_options() == 'wx_gui'
+       #if $run()
+               part
        #else
-none#slurp
+               none
        #end if
 #else
-all#slurp
-#end if</hide>
+       all
+#end if
+               </hide>
                <option>
                        <name>Autostart</name>
                        <key>True</key>
index 477f2ad13a044a8911bd2e8db37488fdb522059a..2e949526039150e0e166c9deb1bcfc415815bfcc 100644 (file)
@@ -9,10 +9,10 @@
        <key>pad_sink</key>
        <make></make>
        <param>
-               <name>Num Inputs</name>
-               <key>nports</key>
-               <value>1</value>
-               <type>int</type>
+               <name>Label</name>
+               <key>label</key>
+               <value>out</value>
+               <type>string</type>
        </param>
        <param>
                <name>Input Type</name>
                <type>int</type>
        </param>
        <check>$vlen &gt; 0</check>
-       <check>0 &lt; $nports</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
-               <nports>$nports</nports>
        </sink>
        <doc>
-This is a sink pad block for creating hierarchical flow graphs. \
-The inputs of this block will become the outputs to this flow graph when it is instantiated as a hierarchical block. \
-Limit one sink pad block per flow graph.
+The inputs of this block will become the outputs to this flow graph when it is instantiated as a hierarchical block.
 
-Remember to set the generate options to hier block.
+Pad sink will be ordered alphabetically by their ids. The first pad sink will have an index of 0.
        </doc>
 </block>
index b6ef2c55d1e2f2e6bbc3770ff066716d4da2b644..7b2210cbbc75f74df47c526f7d4040ab414edb19 100644 (file)
@@ -9,10 +9,10 @@
        <key>pad_source</key>
        <make></make>
        <param>
-               <name>Num Outputs</name>
-               <key>nports</key>
-               <value>1</value>
-               <type>int</type>
+               <name>Label</name>
+               <key>label</key>
+               <value>in</value>
+               <type>string</type>
        </param>
        <param>
                <name>Output Type</name>
                <type>int</type>
        </param>
        <check>$vlen &gt; 0</check>
-       <check>0 &lt; $nports</check>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
-               <nports>$nports</nports>
        </source>
        <doc>
-This is a source pad block for creating hierarchical flow graphs. \
-The outputs of this block will become the inputs to this flow graph when it is instantiated as a hierarchical block. \
-Limit one source pad block per flow graph.
+The outputs of this block will become the inputs to this flow graph when it is instantiated as a hierarchical block.
 
-Remember to set the generate options to hier block.
+Pad sources will be ordered alphabetically by their ids. The first pad source will have an index of 0.
        </doc>
 </block>
index 5d08c4b394662f8824877f13ea2153cd559e1c86..e35b8f4d1d8bc7c7ac9bd14a06acf6cb6a1eb0ae 100644 (file)
@@ -45,7 +45,7 @@
                </option>
                <option>
                        <name>Int</name>
-                       <key>int</key>
+                       <key>intx</key>
                        <opt>type:int</opt>
                </option>
                <option>
                        <key>string</key>
                        <opt>type:string</opt>
                </option>
+               <!-- not supported yet in tmpl
+               <option>
+                       <name>Boolean</name>
+                       <key>bool</key>
+                       <opt>type:bool</opt>
+               </option>
+               -->
        </param>
        <param>
                <name>Short ID</name>
index 639f96cf48bffd08bfcb4aeda0c09f46c0975fca..f9fb25361feac11dd11ee4e49214ea5d5fd2ee0d 100644 (file)
@@ -2,6 +2,7 @@
 <!--
 ###################################################
 ##USRP2 Sink
+##  Note: the center freq must be set after the lo offset
 ###################################################
  -->
 <block>
@@ -16,14 +17,17 @@ usrp2.sink_$(type.fcn)($interface)
 usrp2.sink_$(type.fcn)($interface, $mac_addr)
 #end if
 self.$(id).set_interp($interpolation)
-self.$(id).set_center_freq($frequency)
-self.$(id).set_gain($gain)
 #if $lo_offset() != float('inf')
 self.$(id).set_lo_offset($lo_offset)
-#end if</make>
-       <callback>set_lo_offset($lo_offset)</callback>
+#end if
+self.$(id).set_center_freq($frequency)
+self.$(id).set_gain($gain)
+self.$(id).config_mimo($usrp2_clock_src)</make>
        <callback>set_interp($interpolation)</callback>
-       <callback>set_center_freq($frequency)</callback>
+       <callback>#if $lo_offset() != float('inf')
+self.$(id).set_lo_offset($lo_offset)
+#end if
+self.$(id).set_center_freq($frequency)</callback>
        <callback>set_gain($gain)</callback>
        <param>
                <name>Output Type</name>
@@ -33,11 +37,13 @@ self.$(id).set_lo_offset($lo_offset)
                        <name>Complex</name>
                        <key>complex</key>
                        <opt>fcn:32fc</opt>
+                       <opt>vlen:1</opt>
                </option>
                <option>
                        <name>Short</name>
                        <key>short</key>
                        <opt>fcn:16sc</opt>
+                       <opt>vlen:2</opt>
                </option>
        </param>
        <param>
@@ -79,9 +85,28 @@ self.$(id).set_lo_offset($lo_offset)
                <value>0</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Clock Source</name>
+               <key>usrp2_clock_src</key>
+               <value>usrp2.MC_WE_DONT_LOCK</value>
+               <type>enum</type>
+               <option>
+                       <name>Internal</name>
+                       <key>usrp2.MC_WE_DONT_LOCK</key>
+               </option>
+               <option>
+                       <name>External SMA</name>
+                       <key>usrp2.MC_WE_LOCK_TO_SMA</key>
+               </option>
+               <option>
+                       <name>External MIMO</name>
+                       <key>usrp2.MC_WE_LOCK_TO_MIMO</key>
+               </option>
+       </param>
        <sink>
                <name>in</name>
                <type>$type</type>
+               <vlen>$type.vlen</vlen>
        </sink>
        <doc>
 The USRP2 sink inputs 100 Megasamples per second / interpolation.
index 6c776d0ad37deaa54f32b3d7b570eb717a0caf37..584199798f1b18325f0a31236747fc82f9bb91f5 100644 (file)
@@ -2,6 +2,7 @@
 <!--
 ###################################################
 ##USRP2 Source
+##  Note: the center freq must be set after the lo offset
 ###################################################
  -->
 <block>
@@ -16,14 +17,17 @@ usrp2.source_$(type.fcn)($interface)
 usrp2.source_$(type.fcn)($interface, $mac_addr)
 #end if
 self.$(id).set_decim($decimation)
-self.$(id).set_center_freq($frequency)
-self.$(id).set_gain($gain)
 #if $lo_offset() != float('inf')
 self.$(id).set_lo_offset($lo_offset)
-#end if</make>
-       <callback>set_lo_offset($lo_offset)</callback>
+#end if
+self.$(id).set_center_freq($frequency)
+self.$(id).set_gain($gain)
+self.$(id).config_mimo($usrp2_clock_src)</make>
        <callback>set_decim($decimation)</callback>
-       <callback>set_center_freq($frequency)</callback>
+       <callback>#if $lo_offset() != float('inf')
+self.$(id).set_lo_offset($lo_offset)
+#end if
+self.$(id).set_center_freq($frequency)</callback>
        <callback>set_gain($gain)</callback>
        <param>
                <name>Output Type</name>
@@ -33,11 +37,13 @@ self.$(id).set_lo_offset($lo_offset)
                        <name>Complex</name>
                        <key>complex</key>
                        <opt>fcn:32fc</opt>
+                       <opt>vlen:1</opt>
                </option>
                <option>
                        <name>Short</name>
                        <key>short</key>
                        <opt>fcn:16sc</opt>
+                       <opt>vlen:2</opt>
                </option>
        </param>
        <param>
@@ -79,9 +85,28 @@ self.$(id).set_lo_offset($lo_offset)
                <value>0</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Clock Source</name>
+               <key>usrp2_clock_src</key>
+               <value>usrp2.MC_WE_DONT_LOCK</value>
+               <type>enum</type>
+               <option>
+                       <name>Internal</name>
+                       <key>usrp2.MC_WE_DONT_LOCK</key>
+               </option>
+               <option>
+                       <name>External SMA</name>
+                       <key>usrp2.MC_WE_LOCK_TO_SMA</key>
+               </option>
+               <option>
+                       <name>External MIMO</name>
+                       <key>usrp2.MC_WE_LOCK_TO_MIMO</key>
+               </option>
+       </param>
        <source>
                <name>out</name>
                <type>$type</type>
+               <vlen>$type.vlen</vlen>
        </source>
        <doc>
 The USRP2 source outputs 100 Megasamples per second / decimation.
index 8f418becdba36e2db73eb4eded6e5827a62ceadd..4539b62f9527f1ef552022baa0f02a7c1e8d4a7b 100644 (file)
        <import>from grc_gnuradio import usrp as grc_usrp</import>
        <make>grc_usrp.dual_sink_$(type.fcn)(which=$which)
 self.$(id).set_interp_rate($interpolation)
-self.$(id).set_frequency_a($frequency_a, verbose=True)
-self.$(id).set_frequency_b($frequency_b, verbose=True)
-self.$(id).set_gain_a($gain_a)
-self.$(id).set_gain_b($gain_b)
+self.$(id).set_frequency_a($frequency_a, verbose=True#slurp
 #if $lo_offset_a() != float('inf')
-self.$(id).set_lo_offset_a($lo_offset_a)
+, lo_offset=$lo_offset_a#slurp
 #end if
+)
+self.$(id).set_frequency_b($frequency_b, verbose=True#slurp
 #if $lo_offset_b() != float('inf')
-self.$(id).set_lo_offset_b($lo_offset_b)
+, lo_offset=$lo_offset_b#slurp
 #end if
+)
+self.$(id).set_gain_a($gain_a)
+self.$(id).set_gain_b($gain_b)
 ##################################################
 ## Flex RF A
 ##################################################
@@ -39,8 +41,16 @@ self.$(id).set_enable_b(True)
 self.$(id).set_auto_tr_b(True)
 #end if</make>
        <callback>set_interp_rate($interpolation)</callback>
-       <callback>set_frequency_a($frequency_a)</callback>
-       <callback>set_frequency_b($frequency_b)</callback>
+       <callback>set_frequency_a($frequency_a#slurp
+#if $lo_offset_a() != float('inf')
+, lo_offset=$lo_offset_a#slurp
+#end if
+)</callback>
+       <callback>set_frequency_b($frequency_b#slurp
+#if $lo_offset_b() != float('inf')
+, lo_offset=$lo_offset_b#slurp
+#end if
+)</callback>
        <callback>set_gain_a($gain_a)</callback>
        <callback>set_gain_b($gain_b)</callback>
        <param>
index 740895d424697b8712c86c74a0ebba30cdb65f15..07d3174bb538f588957b23b0a9667d231451f86e 100644 (file)
@@ -8,24 +8,38 @@
        <name>USRP Dual Source</name>
        <key>usrp_dual_source_x</key>
        <import>from grc_gnuradio import usrp as grc_usrp</import>
-       <make>grc_usrp.dual_source_$(type.fcn)(which=$which, rx_ant_a=$rx_ant_a, rx_ant_b=$rx_ant_b)
+       <make>grc_usrp.dual_source_$(type.fcn)(
+       which=$which,
+       rx_ant_a=$rx_ant_a, rx_ant_b=$rx_ant_b,
+       rx_source_a=$rx_source_a, rx_source_b=$rx_source_b,
+)
 #if $format()
 self.$(id).set_format(width=$format.width, shift=$format.shift)
 #end if
 self.$(id).set_decim_rate($decimation)
-self.$(id).set_frequency_a($frequency_a, verbose=True)
-self.$(id).set_frequency_b($frequency_b, verbose=True)
-self.$(id).set_gain_a($gain_a)
-self.$(id).set_gain_b($gain_b)
+self.$(id).set_frequency_a($frequency_a, verbose=True#slurp
 #if $lo_offset_a() != float('inf')
-self.$(id).set_lo_offset_a($lo_offset_a)
+, lo_offset=$lo_offset_a#slurp
 #end if
+)
+self.$(id).set_frequency_b($frequency_b, verbose=True#slurp
 #if $lo_offset_b() != float('inf')
-self.$(id).set_lo_offset_b($lo_offset_b)
-#end if</make>
+, lo_offset=$lo_offset_b#slurp
+#end if
+)
+self.$(id).set_gain_a($gain_a)
+self.$(id).set_gain_b($gain_b)</make>
        <callback>set_decim_rate($decimation)</callback>
-       <callback>set_frequency_a($frequency_a)</callback>
-       <callback>set_frequency_b($frequency_b)</callback>
+       <callback>set_frequency_a($frequency_a#slurp
+#if $lo_offset_a() != float('inf')
+, lo_offset=$lo_offset_a#slurp
+#end if
+)</callback>
+       <callback>set_frequency_b($frequency_b#slurp
+#if $lo_offset_b() != float('inf')
+, lo_offset=$lo_offset_b#slurp
+#end if
+)</callback>
        <callback>set_gain_a($gain_a)</callback>
        <callback>set_gain_b($gain_b)</callback>
        <param>
@@ -179,6 +193,36 @@ self.$(id).set_lo_offset_b($lo_offset_b)
                        <key>RX2</key>
                </option>
        </param>
+       <param>
+               <name>RX Source A</name>
+               <key>rx_source_a</key>
+               <value>A</value>
+               <type>string</type>
+               <hide>#if $rx_source_a() == 'A' then 'part' else 'none'#</hide>
+               <option>
+                       <name>Side A</name>
+                       <key>A</key>
+               </option>
+               <option>
+                       <name>Side B</name>
+                       <key>B</key>
+               </option>
+       </param>
+       <param>
+               <name>RX Source B</name>
+               <key>rx_source_b</key>
+               <value>B</value>
+               <type>string</type>
+               <hide>#if $rx_source_b() == 'B' then 'part' else 'none'#</hide>
+               <option>
+                       <name>Side A</name>
+                       <key>A</key>
+               </option>
+               <option>
+                       <name>Side B</name>
+                       <key>B</key>
+               </option>
+       </param>
        <source>
                <name>Aout</name>
                <type>$type</type>
index f3ccf1263c5671dfdb1da27ac3114f7eb1418dbf..b52cd4880913a2357c57227255e75bc1cc75c70e 100644 (file)
        <import>from grc_gnuradio import usrp as grc_usrp</import>
        <make>grc_usrp.simple_sink_$(type.fcn)(which=$which, side=$side)
 self.$(id).set_interp_rate($interpolation)
-self.$(id).set_frequency($frequency, verbose=True)
+self.$(id).set_frequency($frequency, verbose=True#slurp
+#if $lo_offset() != float('inf')
+, lo_offset=$lo_offset#slurp
+#end if
+)
 self.$(id).set_gain($gain)
 #if $transmit.tx_enb
 self.$(id).set_enable(True)
 #end if
 #if $transmit.auto_tr
 self.$(id).set_auto_tr(True)
-#end if
-#if $lo_offset() != float('inf')
-self.$(id).set_lo_offset($lo_offset)
 #end if</make>
-       <callback>set_lo_offset($lo_offset)</callback>
        <callback>set_interp_rate($interpolation)</callback>
-       <callback>set_frequency($frequency)</callback>
+       <callback>set_frequency($frequency#slurp
+#if $lo_offset() != float('inf')
+, lo_offset=$lo_offset#slurp
+#end if
+)</callback>
        <callback>set_gain($gain)</callback>
        <param>
                <name>Input Type</name>
index 1a777bd6302c7cf017703ce06556150a4e19e461..7fcc7a22cf37eeff7d924a95694c109718ba971b 100644 (file)
 self.$(id).set_format(width=$format.width, shift=$format.shift)
 #end if
 self.$(id).set_decim_rate($decimation)
-self.$(id).set_frequency($frequency, verbose=True)
-self.$(id).set_gain($gain)
+self.$(id).set_frequency($frequency, verbose=True#slurp
 #if $lo_offset() != float('inf')
-self.$(id).set_lo_offset($lo_offset)
-#end if</make>
-       <callback>set_lo_offset($lo_offset)</callback>
+, lo_offset=$lo_offset#slurp
+#end if
+)
+self.$(id).set_gain($gain)</make>
        <callback>set_decim_rate($decimation)</callback>
-       <callback>set_frequency($frequency)</callback>
+       <callback>set_frequency($frequency#slurp
+#if $lo_offset() != float('inf')
+, lo_offset=$lo_offset#slurp
+#end if
+)</callback>
        <callback>set_gain($gain)</callback>
        <param>
                <name>Output Type</name>
diff --git a/grc/blocks/virtual_sink.xml b/grc/blocks/virtual_sink.xml
new file mode 100644 (file)
index 0000000..35fb27e
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Virtual Sink
+###################################################
+ -->
+<block>
+       <name>Virtual Sink</name>
+       <key>virtual_sink</key>
+       <make></make>
+       <param>
+               <name>Stream ID</name>
+               <key>stream_id</key>
+               <value></value>
+               <type>stream_id</type>
+       </param>
+       <sink>
+               <name>in</name>
+               <type></type>
+       </sink>
+</block>
diff --git a/grc/blocks/virtual_source.xml b/grc/blocks/virtual_source.xml
new file mode 100644 (file)
index 0000000..e0c7754
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Virtual Source
+###################################################
+ -->
+<block>
+       <name>Virtual Source</name>
+       <key>virtual_source</key>
+       <make></make>
+       <param>
+               <name>Stream ID</name>
+               <key>stream_id</key>
+               <value></value>
+               <type>stream_id</type>
+       </param>
+       <source>
+               <name>out</name>
+               <type></type>
+       </source>
+</block>
index 5969d8405322138bc227aeda083bb52c964bc976..598b550642d1dbeb321be11f1e317d5c68970aea 100644 (file)
@@ -23,6 +23,9 @@ constsink_gl.const_sink_c(
        gain_mu=$gain_mu,
        symbol_rate=$symbol_rate,
        omega_limit=$omega_limit,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -102,6 +105,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>0.005</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -114,11 +124,14 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>complex</type>
        </sink>
        <doc>
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index faeca37e3217bea7f8db5860e29ad5117693c1c5..8df8f90d0192de8a5e21d8cdadcb6070c85ddd53 100644 (file)
@@ -7,6 +7,7 @@
 <block>
        <name>FFT Sink</name>
        <key>wxgui_fftsink2</key>
+       <import>from gnuradio import window</import>
        <import>from gnuradio.wxgui import fftsink2</import>
        <make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
 fftsink2.$(type.fcn)(
@@ -15,6 +16,7 @@ fftsink2.$(type.fcn)(
        y_per_div=$y_per_div,
        y_divs=$y_divs,
        ref_level=$ref_level,
+       ref_scale=$ref_scale,
        sample_rate=$samp_rate,
        fft_size=$fft_size,
        fft_rate=$fft_rate,
@@ -22,6 +24,12 @@ fftsink2.$(type.fcn)(
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
        peak_hold=$peak_hold,
+#if $win()
+       win=$win,
+#end if
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -102,6 +110,12 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>50</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Ref Scale (p2p)</name>
+               <key>ref_scale</key>
+               <value>2.0</value>
+               <type>real</type>
+       </param>
        <param>
                <name>FFT Size</name>
                <key>fft_size</key>
@@ -134,7 +148,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <key>average</key>
                <value>False</value>
                <type>enum</type>
-               <hide>#if $average() == 'True' then 'none' else 'part'#</hide>
+               <hide>part</hide>
                <option>
                        <name>On</name>
                        <key>True</key>
@@ -151,6 +165,44 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <type>real</type>
                <hide>#if $average() == 'True' then 'none' else 'all'#</hide>
        </param>
+       <param>
+               <name>Window</name>
+               <key>win</key>
+               <value>None</value>
+               <type>raw</type>
+               <hide>#if $win() is None then 'part' else 'none'#</hide>
+               <option>
+                       <name>Automatic</name>
+                       <key>None</key>
+               </option>
+               <option>
+                       <name>Blackman-Harris</name>
+                       <key>window.blackmanharris</key>
+               </option>
+               <option>
+                       <name>Hamming</name>
+                       <key>window.hamming</key>
+               </option>
+               <option>
+                       <name>Hanning</name>
+                       <key>window.hanning</key>
+               </option>
+               <option>
+                       <name>Rectangular</name>
+                       <key>window.rectangular</key>
+               </option>
+               <option>
+                       <name>Flattop</name>
+                       <key>window.flattop</key>
+               </option>
+       </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -163,6 +215,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -170,6 +223,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 454a4932cfab4aefbd5d00e93c674ec08537a492..9edf9650d849575de9ee471cb706d5604cb856e4 100644 (file)
@@ -14,6 +14,9 @@ histosink_gl.histo_sink_f(
        title=$title,
        num_bins=$num_bins,
        frame_size=$frame_size,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -40,6 +43,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>1000</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -52,11 +62,14 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>float</type>
        </sink>
        <doc>
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index cc66cdcb088e75d2d7fc820e2cf3dddd8f3f3b2d..ad93dec08db14d59504bfe998fb59eb29d2a0ecd 100644 (file)
@@ -24,6 +24,9 @@ numbersink2.$(type.fcn)(
        label=$title,
        peak_hold=$peak_hold,
        show_gauge=$show_gauge,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -120,7 +123,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <key>average</key>
                <value>False</value>
                <type>enum</type>
-               <hide>#if $average() == 'True' then 'none' else 'part'#</hide>
+               <hide>part</hide>
                <option>
                        <name>On</name>
                        <key>True</key>
@@ -151,6 +154,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                        <key>False</key>
                </option>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -163,6 +173,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -170,6 +181,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 503d529727662578e219011abf2117c6c8e574aa..eba45f48981af825c5ec658017b3e221b2e00f43 100644 (file)
@@ -15,10 +15,14 @@ scopesink2.$(type.fcn)(
        title=$title,
        sample_rate=$samp_rate,
        v_scale=$v_scale,
+       v_offset=$v_offset,
        t_scale=$t_scale,
        ac_couple=$ac_couple,
        xy_mode=$xy_mode,
        num_inputs=$num_inputs,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -59,19 +63,28 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <key>v_scale</key>
                <value>0</value>
                <type>real</type>
+               <hide>#if $v_scale() then 'none' else 'part'#</hide>
+       </param>
+       <param>
+               <name>V Offset</name>
+               <key>v_offset</key>
+               <value>0</value>
+               <type>real</type>
+               <hide>#if $v_offset() then 'none' else 'part'#</hide>
        </param>
        <param>
                <name>T Scale</name>
                <key>t_scale</key>
                <value>0</value>
                <type>real</type>
+               <hide>#if $t_scale() then 'none' else 'part'#</hide>
        </param>
        <param>
                <name>AC Couple</name>
                <key>ac_couple</key>
                <value>False</value>
-               <type>enum</type>
-               <hide>#if $ac_couple() == 'True' then 'none' else 'part'#</hide>
+               <type>bool</type>
+               <hide>#if $ac_couple() then 'none' else 'part'#</hide>
                <option>
                        <name>Off</name>
                        <key>False</key>
@@ -102,6 +115,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>1</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -114,6 +134,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <check>not $xy_mode or '$type' == 'complex' or $num_inputs != 1</check>
        <sink>
                <name>in</name>
@@ -127,6 +148,8 @@ Set the T Scale to 0 for automatic setting.
 
 XY Mode allows the scope to initialize as an XY plotter.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
diff --git a/grc/blocks/wxgui_termsink.xml b/grc/blocks/wxgui_termsink.xml
new file mode 100644 (file)
index 0000000..985d89b
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Terminal window
+###################################################
+ -->
+<block>
+       <name>Terminal Sink</name>
+       <key>wxgui_termsink</key>
+
+       <import>from gnuradio.wxgui import termsink</import>
+
+       <make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
+termsink.termsink(
+       parent=$(parent).GetWin(),
+#if $win_size()
+       size=$win_size,
+#end if
+       msgq=$(id)_msgq_in,
+)
+#if not $grid_pos()
+$(parent).Add(self.$(id))
+#else
+$(parent).GridAdd(self.$(id), $(', '.join(map(str, $grid_pos()))))
+#end if</make>
+
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
+       <param>
+               <name>Grid Position</name>
+               <key>grid_pos</key>
+               <value></value>
+               <type>grid_pos</type>
+       </param>
+
+       <param>
+               <name>Notebook</name>
+               <key>notebook</key>
+               <value></value>
+               <type>notebook</type>
+       </param>
+
+       <check>not $win_size or len($win_size) == 2</check>
+
+       <sink>
+               <name>in</name>
+               <type>msg</type>
+       </sink>
+
+</block>
index c7d53f9f2164752c0007f34519d86797f3ff94a8..3de67597f7bb24097e9b5adebf762bb38d06f7a1 100644 (file)
@@ -7,19 +7,27 @@
 <block>
        <name>Waterfall Sink</name>
        <key>wxgui_waterfallsink2</key>
+       <import>from gnuradio import window</import>
        <import>from gnuradio.wxgui import waterfallsink2</import>
        <make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
 waterfallsink2.$(type.fcn)(
        $(parent).GetWin(),
        baseband_freq=$baseband_freq,
-       y_per_div=$y_per_div,
+       dynamic_range=$dynamic_range,
        ref_level=$ref_level,
+       ref_scale=$ref_scale,
        sample_rate=$samp_rate,
        fft_size=$fft_size,
        fft_rate=$fft_rate,
-       average=$options.average,
+       average=$average,
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
+#if $win()
+       win=$win,
+#end if
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -63,9 +71,9 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <type>real</type>
        </param>
        <param>
-               <name>Y per Div</name>
-               <key>y_per_div</key>
-               <value>10</value>
+               <name>Dynamic Range</name>
+               <key>dynamic_range</key>
+               <value>100</value>
                <type>real</type>
        </param>
        <param>
@@ -74,6 +82,12 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>50</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Ref Scale (p2p)</name>
+               <key>ref_scale</key>
+               <value>2.0</value>
+               <type>real</type>
+       </param>
        <param>
                <name>FFT Size</name>
                <key>fft_size</key>
@@ -86,28 +100,66 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>15</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Average</name>
+               <key>average</key>
+               <value>False</value>
+               <type>enum</type>
+               <hide>part</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
        <param>
                <name>Average Alpha</name>
                <key>avg_alpha</key>
                <value>0</value>
                <type>real</type>
+               <hide>#if $average() == 'True' then 'none' else 'all'#</hide>
        </param>
        <param>
-               <name>Options</name>
-               <key>options</key>
-               <value>none</value>
-               <type>enum</type>
+               <name>Window</name>
+               <key>win</key>
+               <value>None</value>
+               <type>raw</type>
+               <hide>#if $win() is None then 'part' else 'none'#</hide>
                <option>
-                       <name>None</name>
-                       <key>none</key>
-                       <opt>average:False</opt>
+                       <name>Automatic</name>
+                       <key>None</key>
                </option>
                <option>
-                       <name>Average</name>
-                       <key>average</key>
-                       <opt>average:True</opt>
+                       <name>Blackman-Harris</name>
+                       <key>window.blackmanharris</key>
+               </option>
+               <option>
+                       <name>Hamming</name>
+                       <key>window.hamming</key>
+               </option>
+               <option>
+                       <name>Hanning</name>
+                       <key>window.hanning</key>
+               </option>
+               <option>
+                       <name>Rectangular</name>
+                       <key>window.rectangular</key>
+               </option>
+               <option>
+                       <name>Flattop</name>
+                       <key>window.flattop</key>
                </option>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -120,6 +172,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -127,6 +180,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
diff --git a/grc/cpp/README b/grc/cpp/README
new file mode 100644 (file)
index 0000000..3eccc5d
--- /dev/null
@@ -0,0 +1,5 @@
+GRC could be used to generate c++ based flowgraphs:
+
+* A few base and gui classes would be overridden.
+* Block info could be extracted from the doxygen xml.
+* New flowgraph templates would be designed.
diff --git a/grc/freedesktop/.gitignore b/grc/freedesktop/.gitignore
new file mode 100644 (file)
index 0000000..ff07a10
--- /dev/null
@@ -0,0 +1,3 @@
+/grc_setup_freedesktop
+/Makefile
+/Makefile.in
index 8c01338e72160af6f3fe865ab7923d338e4d7fac..23bb70bf54db8ef94a816e1b41e78cfdec70c40a 100644 (file)
@@ -19,7 +19,7 @@
 # Boston, MA 02110-1301, USA.
 #
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
 ourdatadir = $(pkgdatadir)/grc/freedesktop
 
diff --git a/grc/freedesktop/grc-icon-256.svg b/grc/freedesktop/grc-icon-256.svg
new file mode 100644 (file)
index 0000000..87526d4
--- /dev/null
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="256"
+   height="256"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   version="1.0"
+   sodipodi:docbase="/home/past/src"
+   sodipodi:docname="grc-icon-v3.svg"
+   inkscape:export-filename="/home/past/src/grc-icon-v3.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3661">
+      <stop
+         style="stop-color:#0012dc;stop-opacity:1;"
+         offset="0"
+         id="stop3663" />
+      <stop
+         style="stop-color:#8b92ff;stop-opacity:0.55371898;"
+         offset="1"
+         id="stop3665" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3661"
+       id="linearGradient2801"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-162.6648,798.0997)"
+       x1="17.664845"
+       y1="132.0565"
+       x2="157.82524"
+       y2="132.0565" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.7382812"
+     inkscape:cx="126.48791"
+     inkscape:cy="128.00013"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     gridoriginx="1px"
+     gridoriginy="1px"
+     gridspacingx="2px"
+     gridspacingy="2px"
+     guidecolor="#00ff0a"
+     guideopacity="0.49803922"
+     inkscape:grid-points="true"
+     inkscape:window-width="1098"
+     inkscape:window-height="904"
+     inkscape:window-x="149"
+     inkscape:window-y="42"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:object-points="true"
+     inkscape:object-nodes="true"
+     inkscape:object-bbox="true">
+    <sodipodi:guide
+       orientation="vertical"
+       position="224"
+       id="guide10639" />
+    <sodipodi:guide
+       orientation="vertical"
+       position="227.64729"
+       id="guide10641" />
+    <sodipodi:guide
+       orientation="vertical"
+       position="220"
+       id="guide10643" />
+    <sodipodi:guide
+       orientation="horizontal"
+       position="268.4015"
+       id="guide10645" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Patrick Strasser &lt;patrick.strasser@tugraz.at&gt;</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:description>Icon/Symbol for the GNURadio Companion</dc:description>
+        <dc:title>grc-icon.svg</dc:title>
+        <dc:date>2007-02-23</dc:date>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.5/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-796.3622)">
+    <g
+       id="g7451"
+       transform="matrix(1.025628,0,0,1.030546,-0.101723,-32.00742)">
+      <path
+         id="rect2760"
+         d="M 4.1981031,916.37787 L 160.00074,916.37787 L 160.00074,1048.3467 L 4.1981031,1048.3467 L 4.1981031,916.37787 z "
+         style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.78145933;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <g
+         transform="matrix(0.995753,0,0,1.003897,164.8198,-8.972397)"
+         id="g2789"
+         style="stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none">
+        <rect
+           style="fill:url(#linearGradient2801);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.78288651;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect9020"
+           width="140.1604"
+           height="16.796082"
+           x="-145"
+           y="921.75818" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.78288651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M -161.50649,938.55428 L -4.8395996,938.55428"
+           id="path9005" />
+      </g>
+    </g>
+    <g
+       id="g5503"
+       transform="matrix(1.028571,0,0,1.172413,-5.14284,-137.9928)">
+      <rect
+         y="800.36212"
+         x="40"
+         height="116.00005"
+         width="140"
+         id="rect4562"
+         style="fill:#f3c690;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.28504848;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <g
+         transform="matrix(0.921053,0,0,1,26.93956,1.859948)"
+         id="g3694">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.59084845;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M 44,820.3622 L 136.35974,820.3622"
+           id="path4564" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.59084749;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M 80,811.74976 L 80,828.3622"
+           id="path5451" />
+      </g>
+      <g
+         id="g5499">
+        <rect
+           style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.28504944;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect7223"
+           width="140"
+           height="68.000015"
+           x="40"
+           y="848.36218" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:7.28505039;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M 57.001362,905.90132 C 88.923615,905.8552 86.182775,867.89142 95.399136,867.52563 C 104.60967,867.16008 113.73233,867.60291 124.38688,868.00066 C 137.23411,868.48027 130.39915,906.48027 162.99863,906.48027"
+           id="path7225"
+           sodipodi:nodetypes="czss" />
+      </g>
+    </g>
+    <rect
+       style="fill:#b890f3;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999952;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect14319"
+       width="79.999992"
+       height="64.000023"
+       x="27.999992"
+       y="960.36249" />
+    <rect
+       style="fill:#f3c690;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999905;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect15206"
+       width="24.000004"
+       height="24.000004"
+       x="108"
+       y="980.36218" />
+    <path
+       id="path13320"
+       style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:7.99999666;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 220.97574,800.36203 L 220.97574,865.80513 C 236.42474,865.93437 248.49884,861.19996 248.96304,854.45866 C 249.42721,847.71737 237.26568,843.20829 221.81667,846.27676 C 206.36767,849.34522 193.45938,858.02071 192.98843,867.61976 C 192.53101,876.94268 204.68583,884.63729 220.13479,885.43882 C 235.58379,885.69443 248.49884,880.72833 248.96304,873.98703 C 249.42721,867.24575 237.26567,862.73666 221.81666,865.80513 C 206.36766,868.8736 193.45939,877.54909 192.98843,887.14813 C 192.53101,896.47106 204.68582,904.16566 220.13479,904.86701 C 235.5838,905.02246 248.49885,900.05636 248.96305,893.31506 C 249.42722,886.57378 237.26568,882.06469 221.81667,885.13316 C 206.36767,888.20162 193.45939,896.87711 192.98844,906.47616 C 192.53102,915.79909 204.68583,923.49369 220.13479,923.98015 C 235.58379,923.92069 248.49884,918.95459 248.96304,912.21329 C 249.42721,905.47201 237.26567,900.96293 221.81666,904.0314 C 206.36766,907.09986 193.45939,915.77535 192.98843,925.37439 C 192.53101,934.69732 207.20989,943.06708 221.81667,943.00644 L 221.81667,967.97713 C 221.63716,982.45754 209.62079,992.36197 195.88792,992.36199 L 132.42659,992.36199"
+       sodipodi:nodetypes="cccssscssscssscssccc" />
+  </g>
+</svg>
index db8d7459d834c92e87928f7f3ebc10dee790c016..a0c5ac193bde67f06bf58ae60d6ea4564202d86f 100644 (file)
@@ -20,11 +20,12 @@ case "$1" in
        echo "Begin freedesktop install..."
        for size in ${ICON_SIZES}; do \
                echo "Install icon: ${size}x${size}"
-               xdg-icon-resource install --context mimetypes --theme gnome --size ${size} ${SRCDIR}/grc-icon-${size}.png application-gnuradio-grc; \
-               xdg-icon-resource install --context mimetypes --size ${size} ${SRCDIR}/grc-icon-${size}.png application-gnuradio-grc; \
-               xdg-icon-resource install --context apps --theme gnome --size ${size} ${SRCDIR}/grc-icon-${size}.png gnuradio-grc; \
-               xdg-icon-resource install --context apps --size ${size} ${SRCDIR}/grc-icon-${size}.png gnuradio-grc; \
+               xdg-icon-resource install --noupdate --context mimetypes --theme gnome --size ${size} ${SRCDIR}/grc-icon-${size}.png application-gnuradio-grc; \
+               xdg-icon-resource install --noupdate --context mimetypes --size ${size} ${SRCDIR}/grc-icon-${size}.png application-gnuradio-grc; \
+               xdg-icon-resource install --noupdate --context apps --theme gnome --size ${size} ${SRCDIR}/grc-icon-${size}.png gnuradio-grc; \
+               xdg-icon-resource install --noupdate --context apps --size ${size} ${SRCDIR}/grc-icon-${size}.png gnuradio-grc; \
        done
+       xdg-icon-resource forceupdate
        echo "Install mime type"
        xdg-mime install ${SRCDIR}/gnuradio-grc.xml
        echo "Install menu items"
diff --git a/grc/grc_gnuradio/.gitignore b/grc/grc_gnuradio/.gitignore
new file mode 100644 (file)
index 0000000..908cf90
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/Constants.py
index 1ecf7c47fe4e980d2eba74d25f0ca5538236fc21..66b76b2df95571d9bbb0b24f67c5fad13ac396b2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2009 Free Software Foundation, Inc.
+# Copyright 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -19,7 +19,7 @@
 #
 
 import common
-from gnuradio import gr, usrp
+from gnuradio import gr
 
 ####################################################################
 # Dual USRP Source
@@ -27,7 +27,7 @@ from gnuradio import gr, usrp
 class _dual_source(gr.hier_block2):
        """A dual usrp source of IO type short or complex."""
 
-       def __init__(self, which, rx_ant_a='RXA', rx_ant_b='RXA'):
+       def __init__(self, which, rx_ant_a='RXA', rx_ant_b='RXA', rx_source_a='A', rx_source_b='B'):
                """
                USRP dual source contructor.
                @param which the unit number
@@ -42,8 +42,8 @@ class _dual_source(gr.hier_block2):
                )
                #create usrp object
                self._make_usrp(which=which, nchan=2)
-               subdev_spec_a = common.to_spec('A', rx_ant_a)
-               subdev_spec_b = common.to_spec('B', rx_ant_b)
+               subdev_spec_a = common.to_spec(rx_source_a, rx_ant_a)
+               subdev_spec_b = common.to_spec(rx_source_b, rx_ant_b)
                self._get_u().set_mux(self._get_u().determine_rx_mux_value(subdev_spec_a, subdev_spec_b))
                self._subdev_a = self._get_u().selected_subdev(subdev_spec_a)
                self._subdev_b = self._get_u().selected_subdev(subdev_spec_b)
@@ -53,22 +53,22 @@ class _dual_source(gr.hier_block2):
                for i in range(2): self.connect((deinter, i), (self, i))
 
        def set_decim_rate(self, decim): self._get_u().set_decim_rate(int(decim))
-       def set_frequency_a(self, frequency, verbose=False):
+       def set_frequency_a(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev_a.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=0, #ddc0
                        subdev=self._subdev_a,
                        frequency=frequency,
                        verbose=verbose,
                )
-       def set_frequency_b(self, frequency, verbose=False):
+       def set_frequency_b(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev_b.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=1, #ddc1
                        subdev=self._subdev_b,
                        frequency=frequency,
                        verbose=verbose,
                )
-       def set_lo_offset_a(self, lo_offset): self._subdev_a.set_lo_offset(lo_offset)
-       def set_lo_offset_b(self, lo_offset): self._subdev_b.set_lo_offset(lo_offset)
        def set_gain_a(self, gain): self._subdev_a.set_gain(gain)
        def set_gain_b(self, gain): self._subdev_b.set_gain(gain)
 
@@ -105,22 +105,22 @@ class _dual_sink(gr.hier_block2):
                for i in range(2): self.connect((self, i), (inter, i))
 
        def set_interp_rate(self, interp): self._get_u().set_interp_rate(int(interp))
-       def set_frequency_a(self, frequency, verbose=False):
+       def set_frequency_a(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev_a.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=self._subdev_a.which(),
                        subdev=self._subdev_a,
                        frequency=frequency,
                        verbose=verbose,
                )
-       def set_frequency_b(self, frequency, verbose=False):
+       def set_frequency_b(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev_b.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=self._subdev_b.which(),
                        subdev=self._subdev_b,
                        frequency=frequency,
                        verbose=verbose,
                )
-       def set_lo_offset_a(self, lo_offset): self._subdev_a.set_lo_offset(lo_offset)
-       def set_lo_offset_b(self, lo_offset): self._subdev_b.set_lo_offset(lo_offset)
        def set_gain_a(self, gain): self._subdev_a.set_gain(gain)
        def set_gain_b(self, gain): self._subdev_b.set_gain(gain)
        def set_enable_a(self, enable): self._subdev_a.set_enable(enable)
index 9065c7fe93ed2decbba24ee49484807b52b8acd1..fb7a39570f0dead666abe6a4290e688f2580117b 100644 (file)
@@ -19,7 +19,7 @@
 #
 
 import common
-from gnuradio import gr, usrp
+from gnuradio import gr
 
 ####################################################################
 # Simple USRP Source
@@ -56,8 +56,8 @@ class _simple_source(gr.hier_block2):
                self._get_u().set_decim_rate(int(decim))
                if self._no_hb: #set the BW to half the sample rate
                        self._subdev.set_bw(self._get_u().converter_rate()/decim/2)
-       def set_lo_offset(self, lo_offset): self._subdev.set_lo_offset(lo_offset)
-       def set_frequency(self, frequency, verbose=False):
+       def set_frequency(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=0, #ddc0
                        subdev=self._subdev,
@@ -96,14 +96,14 @@ class _simple_sink(gr.hier_block2):
                self.connect(self, self._get_u())
 
        def set_interp_rate(self, interp): self._get_u().set_interp_rate(int(interp))
-       def set_frequency(self, frequency, verbose=False):
+       def set_frequency(self, frequency, verbose=False, lo_offset=None):
+               if lo_offset is not None: self._subdev.set_lo_offset(lo_offset)
                self._set_frequency(
                        chan=self._subdev.which(),
                        subdev=self._subdev,
                        frequency=frequency,
                        verbose=verbose,
                )
-       def set_lo_offset(self, lo_offset): self._subdev.set_lo_offset(lo_offset)
        def set_gain(self, gain): self._subdev.set_gain(gain)
        def set_enable(self, enable): self._subdev.set_enable(enable)
        def set_auto_tr(self, auto_tr): self._subdev.set_auto_tr(auto_tr)
index 998575897399c6d7db643dfb0a37d735c1644b45..333ccf1c1203a2caca749a324efc677188917f8b 100644 (file)
@@ -19,7 +19,6 @@
 #
 
 import wx
-import sys, os
 from gnuradio import gr
 import panel
 
diff --git a/grc/gui/.gitignore b/grc/gui/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index ff137f6697074b657ece3f5ab2d90ce6a2db2c50..108e23a2355da942434e81f6a5d856401f830728 100644 (file)
@@ -29,10 +29,8 @@ import Preferences
 from threading import Thread
 import Messages
 from .. base import ParseXML
-import random
-from Platform import Platform
 from MainWindow import MainWindow
-from ParamsDialog import ParamsDialog
+from PropsDialog import PropsDialog
 import Dialogs
 from FileDialogs import OpenFlowGraphFileDialog, SaveFlowGraphFileDialog, SaveImageFileDialog
 
@@ -53,11 +51,10 @@ class ActionHandler:
                @param platform platform module
                """
                self.clipboard = None
-               platform = Platform(platform)
-               for action in Actions.get_all_actions(): action.connect('activate', self._handle_actions)
+               for action in Actions.get_all_actions(): action.connect('activate', self._handle_action)
                #setup the main window
-               self.main_window = MainWindow(self.handle_states, platform)
-               self.main_window.connect('delete_event', self._quit)
+               self.main_window = MainWindow(platform)
+               self.main_window.connect('delete-event', self._quit)
                self.main_window.connect('key-press-event', self._handle_key_press)
                self.get_page = self.main_window.get_page
                self.get_flow_graph = self.main_window.get_flow_graph
@@ -67,7 +64,7 @@ class ActionHandler:
                Messages.send_init(platform)
                #initialize
                self.init_file_paths = file_paths
-               self.handle_states(Actions.APPLICATION_INITIALIZE)
+               Actions.APPLICATION_INITIALIZE()
                #enter the mainloop
                gtk.main()
 
@@ -81,17 +78,9 @@ class ActionHandler:
                When not in focus, gtk and the accelerators handle the the key press.
                @return false to let gtk handle the key action
                """
-               #dont allow key presses to queue up
-               if gtk.events_pending(): return True
-               #extract action name from this key press
-               key_name = gtk.gdk.keyval_name(event.keyval)
-               mod_mask = event.state
-               action_name = Actions.get_action_name_from_key_name(key_name, mod_mask)
-               #handle the action if flow graph is in focus
-               if action_name and self.get_focus_flag():
-                       self.handle_states(action_name)
-                       return True #handled by this method
-               return False #let gtk handle the key press
+               try: assert self.get_focus_flag()
+               except AssertionError: return False
+               return Actions.handle_key_press(event)
 
        def _quit(self, window, event):
                """
@@ -100,41 +89,24 @@ class ActionHandler:
                This method in turns calls the state handler to quit.
                @return true
                """
-               self.handle_states(Actions.APPLICATION_QUIT)
+               Actions.APPLICATION_QUIT()
                return True
 
-       def _handle_actions(self, event):
-               """
-               Handle all of the activate signals from the gtk actions.
-               The action signals derive from clicking on a toolbar or menu bar button.
-               Forward the action to the state handler.
-               """
-               self.handle_states(event.get_name())
-
-       def handle_states(self, state=''):
-               """
-               Handle the state changes in the GUI.
-               Handle all of the state changes that arise from the action handler or other gui and
-               inputs in the application. The state passed to the handle_states method is a string descriping
-               the change. A series of if/elif statements handle the state by greying out action buttons, causing
-               changes in the flow graph, saving/opening files... The handle_states method is passed to the
-               contructors of many of the classes used in this application enabling them to report any state change.
-               @param state a string describing the state change
-               """
-               #print state
+       def _handle_action(self, action):
+               #print action
                ##################################################
                # Initalize/Quit
                ##################################################
-               if state == Actions.APPLICATION_INITIALIZE:
+               if action == Actions.APPLICATION_INITIALIZE:
                        for action in Actions.get_all_actions(): action.set_sensitive(False) #set all actions disabled
-                       # enable a select few actions
+                       #enable a select few actions
                        for action in (
                                Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
                                Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
                                Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
                                Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
-                               Actions.COLORS_WINDOW_DISPLAY,
-                       ): Actions.get_action_from_name(action).set_sensitive(True)
+                               Actions.TYPES_WINDOW_DISPLAY,
+                       ): action.set_sensitive(True)
                        if not self.init_file_paths:
                                self.init_file_paths = Preferences.files_open()
                        if not self.init_file_paths: self.init_file_paths = ['']
@@ -143,26 +115,26 @@ class ActionHandler:
                        if Preferences.file_open() in self.init_file_paths:
                                self.main_window.new_page(Preferences.file_open(), show=True)
                        if not self.get_page(): self.main_window.new_page() #ensure that at least a blank page exists
-               elif state == Actions.APPLICATION_QUIT:
+               elif action == Actions.APPLICATION_QUIT:
                        if self.main_window.close_pages():
                                gtk.main_quit()
                                exit(0)
                ##################################################
                # Selections
                ##################################################
-               elif state == Actions.ELEMENT_SELECT:
+               elif action == Actions.ELEMENT_SELECT:
                        pass #do nothing, update routines below
-               elif state == Actions.NOTHING_SELECT:
+               elif action == Actions.NOTHING_SELECT:
                        self.get_flow_graph().unselect()
                ##################################################
                # Enable/Disable
                ##################################################
-               elif state == Actions.BLOCK_ENABLE:
+               elif action == Actions.BLOCK_ENABLE:
                        if self.get_flow_graph().enable_selected(True):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.BLOCK_DISABLE:
+               elif action == Actions.BLOCK_DISABLE:
                        if self.get_flow_graph().enable_selected(False):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
@@ -170,12 +142,12 @@ class ActionHandler:
                ##################################################
                # Cut/Copy/Paste
                ##################################################
-               elif state == Actions.BLOCK_CUT:
-                       self.handle_states(Actions.BLOCK_COPY)
-                       self.handle_states(Actions.ELEMENT_DELETE)
-               elif state == Actions.BLOCK_COPY:
+               elif action == Actions.BLOCK_CUT:
+                       Actions.BLOCK_COPY()
+                       Actions.ELEMENT_DELETE()
+               elif action == Actions.BLOCK_COPY:
                        self.clipboard = self.get_flow_graph().copy_to_clipboard()
-               elif state == Actions.BLOCK_PASTE:
+               elif action == Actions.BLOCK_PASTE:
                        if self.clipboard:
                                self.get_flow_graph().paste_from_clipboard(self.clipboard)
                                self.get_flow_graph().update()
@@ -184,81 +156,88 @@ class ActionHandler:
                ##################################################
                # Move/Rotate/Delete/Create
                ##################################################
-               elif state == Actions.BLOCK_MOVE:
+               elif action == Actions.BLOCK_MOVE:
                        self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                        self.get_page().set_saved(False)
-               elif state == Actions.BLOCK_ROTATE_CCW:
+               elif action == Actions.BLOCK_ROTATE_CCW:
                        if self.get_flow_graph().rotate_selected(90):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.BLOCK_ROTATE_CW:
+               elif action == Actions.BLOCK_ROTATE_CW:
                        if self.get_flow_graph().rotate_selected(-90):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.ELEMENT_DELETE:
+               elif action == Actions.ELEMENT_DELETE:
                        if self.get_flow_graph().remove_selected():
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-                               self.handle_states(Actions.NOTHING_SELECT)
+                               Actions.NOTHING_SELECT()
                                self.get_page().set_saved(False)
-               elif state == Actions.ELEMENT_CREATE:
+               elif action == Actions.ELEMENT_CREATE:
                        self.get_flow_graph().update()
                        self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-                       self.handle_states(Actions.NOTHING_SELECT)
+                       Actions.NOTHING_SELECT()
                        self.get_page().set_saved(False)
-               elif state == Actions.BLOCK_INC_TYPE:
+               elif action == Actions.BLOCK_INC_TYPE:
                        if self.get_flow_graph().type_controller_modify_selected(1):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.BLOCK_DEC_TYPE:
+               elif action == Actions.BLOCK_DEC_TYPE:
                        if self.get_flow_graph().type_controller_modify_selected(-1):
                                self.get_flow_graph().update()
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.PORT_CONTROLLER_INC:
+               elif action == Actions.PORT_CONTROLLER_INC:
                        if self.get_flow_graph().port_controller_modify_selected(1):
                                self.get_flow_graph().update()
-                               self.get_flow_graph().update() #2 times
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
-               elif state == Actions.PORT_CONTROLLER_DEC:
+               elif action == Actions.PORT_CONTROLLER_DEC:
                        if self.get_flow_graph().port_controller_modify_selected(-1):
                                self.get_flow_graph().update()
-                               self.get_flow_graph().update() #2 times
                                self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
                                self.get_page().set_saved(False)
                ##################################################
                # Window stuff
                ##################################################
-               elif state == Actions.ABOUT_WINDOW_DISPLAY:
+               elif action == Actions.ABOUT_WINDOW_DISPLAY:
                        Dialogs.AboutDialog(self.get_flow_graph().get_parent())
-               elif state == Actions.HELP_WINDOW_DISPLAY:
+               elif action == Actions.HELP_WINDOW_DISPLAY:
                        Dialogs.HelpDialog()
-               elif state == Actions.COLORS_WINDOW_DISPLAY:
-                       Dialogs.ColorsDialog(self.get_flow_graph().get_parent())
+               elif action == Actions.TYPES_WINDOW_DISPLAY:
+                       Dialogs.TypesDialog(self.get_flow_graph().get_parent())
+               elif action == Actions.ERRORS_WINDOW_DISPLAY:
+                       Dialogs.ErrorsDialog(self.get_flow_graph())
                ##################################################
                # Param Modifications
                ##################################################
-               elif state == Actions.BLOCK_PARAM_MODIFY:
+               elif action == Actions.BLOCK_PARAM_MODIFY:
                        selected_block = self.get_flow_graph().get_selected_block()
-                       if selected_block and ParamsDialog(selected_block).run():
-                               self.get_flow_graph().update()
-                               self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
-                               self.get_page().set_saved(False)
+                       if selected_block:
+                               if PropsDialog(selected_block).run():
+                                       #save the new state
+                                       self.get_flow_graph().update()
+                                       self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+                                       self.get_page().set_saved(False)
+                               else:
+                                       #restore the current state
+                                       n = self.get_page().get_state_cache().get_current_state()
+                                       self.get_flow_graph().import_data(n)
+                                       self.get_flow_graph().update()
                ##################################################
                # Undo/Redo
                ##################################################
-               elif state == Actions.FLOW_GRAPH_UNDO:
+               elif action == Actions.FLOW_GRAPH_UNDO:
                        n = self.get_page().get_state_cache().get_prev_state()
                        if n:
                                self.get_flow_graph().unselect()
                                self.get_flow_graph().import_data(n)
                                self.get_flow_graph().update()
                                self.get_page().set_saved(False)
-               elif state == Actions.FLOW_GRAPH_REDO:
+               elif action == Actions.FLOW_GRAPH_REDO:
                        n = self.get_page().get_state_cache().get_next_state()
                        if n:
                                self.get_flow_graph().unselect()
@@ -268,19 +247,19 @@ class ActionHandler:
                ##################################################
                # New/Open/Save/Close
                ##################################################
-               elif state == Actions.FLOW_GRAPH_NEW:
+               elif action == Actions.FLOW_GRAPH_NEW:
                        self.main_window.new_page()
-               elif state == Actions.FLOW_GRAPH_OPEN:
+               elif action == Actions.FLOW_GRAPH_OPEN:
                        file_paths = OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
                        if file_paths: #open a new page for each file, show only the first
                                for i,file_path in enumerate(file_paths):
                                        self.main_window.new_page(file_path, show=(i==0))
-               elif state == Actions.FLOW_GRAPH_CLOSE:
+               elif action == Actions.FLOW_GRAPH_CLOSE:
                        self.main_window.close_page()
-               elif state == Actions.FLOW_GRAPH_SAVE:
+               elif action == Actions.FLOW_GRAPH_SAVE:
                        #read-only or undefined file path, do save-as
                        if self.get_page().get_read_only() or not self.get_page().get_file_path():
-                               self.handle_states(Actions.FLOW_GRAPH_SAVE_AS)
+                               Actions.FLOW_GRAPH_SAVE_AS()
                        #otherwise try to save
                        else:
                                try:
@@ -289,12 +268,12 @@ class ActionHandler:
                                except IOError:
                                        Messages.send_fail_save(self.get_page().get_file_path())
                                        self.get_page().set_saved(False)
-               elif state == Actions.FLOW_GRAPH_SAVE_AS:
+               elif action == Actions.FLOW_GRAPH_SAVE_AS:
                        file_path = SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
                        if file_path is not None:
                                self.get_page().set_file_path(file_path)
-                               self.handle_states(Actions.FLOW_GRAPH_SAVE)
-               elif state == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
+                               Actions.FLOW_GRAPH_SAVE()
+               elif action == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
                        file_path = SaveImageFileDialog(self.get_page().get_file_path()).run()
                        if file_path is not None:
                                pixbuf = self.get_flow_graph().get_drawing_area().get_pixbuf()
@@ -302,10 +281,10 @@ class ActionHandler:
                ##################################################
                # Gen/Exec/Stop
                ##################################################
-               elif state == Actions.FLOW_GRAPH_GEN:
+               elif action == Actions.FLOW_GRAPH_GEN:
                        if not self.get_page().get_pid():
                                if not self.get_page().get_saved() or not self.get_page().get_file_path():
-                                       self.handle_states(Actions.FLOW_GRAPH_SAVE) #only save if file path missing or not saved
+                                       Actions.FLOW_GRAPH_SAVE() #only save if file path missing or not saved
                                if self.get_page().get_saved() and self.get_page().get_file_path():
                                        generator = self.get_page().get_generator()
                                        try:
@@ -313,37 +292,38 @@ class ActionHandler:
                                                generator.write()
                                        except Exception,e: Messages.send_fail_gen(e)
                                else: self.generator = None
-               elif state == Actions.FLOW_GRAPH_EXEC:
+               elif action == Actions.FLOW_GRAPH_EXEC:
                        if not self.get_page().get_pid():
-                               self.handle_states(Actions.FLOW_GRAPH_GEN)
+                               Actions.FLOW_GRAPH_GEN()
                                if self.get_page().get_saved() and self.get_page().get_file_path():
                                        ExecFlowGraphThread(self)
-               elif state == Actions.FLOW_GRAPH_KILL:
+               elif action == Actions.FLOW_GRAPH_KILL:
                        if self.get_page().get_pid():
                                try: os.kill(self.get_page().get_pid(), signal.SIGKILL)
                                except: print "could not kill pid: %s"%self.get_page().get_pid()
-               elif state == '': #pass and run the global actions
+               elif action == Actions.PAGE_CHANGE: #pass and run the global actions
                        pass
-               else: print '!!! State "%s" not handled !!!'%state
+               else: print '!!! Action "%s" not handled !!!'%action
                ##################################################
                # Global Actions for all States
                ##################################################
                #update general buttons
-               Actions.get_action_from_name(Actions.ELEMENT_DELETE).set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
-               Actions.get_action_from_name(Actions.BLOCK_PARAM_MODIFY).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
-               Actions.get_action_from_name(Actions.BLOCK_ROTATE_CCW).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-               Actions.get_action_from_name(Actions.BLOCK_ROTATE_CW).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.ERRORS_WINDOW_DISPLAY.set_sensitive(not self.get_flow_graph().is_valid())
+               Actions.ELEMENT_DELETE.set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
+               Actions.BLOCK_PARAM_MODIFY.set_sensitive(bool(self.get_flow_graph().get_selected_block()))
+               Actions.BLOCK_ROTATE_CCW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.BLOCK_ROTATE_CW.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
                #update cut/copy/paste
-               Actions.get_action_from_name(Actions.BLOCK_CUT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-               Actions.get_action_from_name(Actions.BLOCK_COPY).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-               Actions.get_action_from_name(Actions.BLOCK_PASTE).set_sensitive(bool(self.clipboard))
+               Actions.BLOCK_CUT.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.BLOCK_COPY.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.BLOCK_PASTE.set_sensitive(bool(self.clipboard))
                #update enable/disable
-               Actions.get_action_from_name(Actions.BLOCK_ENABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
-               Actions.get_action_from_name(Actions.BLOCK_DISABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.BLOCK_ENABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+               Actions.BLOCK_DISABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
                #set the exec and stop buttons
                self.update_exec_stop()
                #saved status
-               Actions.get_action_from_name(Actions.FLOW_GRAPH_SAVE).set_sensitive(not self.get_page().get_saved())
+               Actions.FLOW_GRAPH_SAVE.set_sensitive(not self.get_page().get_saved())
                self.main_window.update()
                try: #set the size of the flow graph area (if changed)
                        new_size = self.get_flow_graph().get_option('window_size')
@@ -353,6 +333,7 @@ class ActionHandler:
                #draw the flow graph
                self.get_flow_graph().update_selected()
                self.get_flow_graph().queue_draw()
+               return True #action was handled
 
        def update_exec_stop(self):
                """
@@ -360,9 +341,9 @@ class ActionHandler:
                Lock and unlock the mutex for race conditions with exec flow graph threads.
                """
                sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_pid()
-               Actions.get_action_from_name(Actions.FLOW_GRAPH_GEN).set_sensitive(sensitive)
-               Actions.get_action_from_name(Actions.FLOW_GRAPH_EXEC).set_sensitive(sensitive)
-               Actions.get_action_from_name(Actions.FLOW_GRAPH_KILL).set_sensitive(self.get_page().get_pid() != None)
+               Actions.FLOW_GRAPH_GEN.set_sensitive(sensitive)
+               Actions.FLOW_GRAPH_EXEC.set_sensitive(sensitive)
+               Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_pid() != None)
 
 class ExecFlowGraphThread(Thread):
        """Execute the flow graph as a new process and wait on it to finish."""
index 3695e09ef3d7abdddc7b178d132099f83f46e92d..f374efde18d9e5d8d9ec6cbd2e814322e583ce96 100644 (file)
@@ -21,149 +21,254 @@ import pygtk
 pygtk.require('2.0')
 import gtk
 
-######################################################################################################
-# Action Names
-######################################################################################################
-APPLICATION_INITIALIZE = 'app init'
-APPLICATION_QUIT = 'app quit'
-PARAM_MODIFY = 'param modify'
-BLOCK_MOVE = 'block move'
-BLOCK_ROTATE_CCW = 'block rotate ccw'
-BLOCK_ROTATE_CW = 'block rotate cw'
-BLOCK_PARAM_MODIFY = 'block param modify'
-BLOCK_INC_TYPE = 'block increment type'
-BLOCK_DEC_TYPE = 'block decrement type'
-BLOCK_ENABLE = 'block enable'
-BLOCK_DISABLE = 'block disable'
-BLOCK_CUT = 'block cut'
-BLOCK_COPY = 'block copy'
-BLOCK_PASTE = 'block paste'
-PORT_CONTROLLER_INC = 'port controller increment'
-PORT_CONTROLLER_DEC = 'port controller decrement'
-ELEMENT_CREATE = 'element create'
-ELEMENT_DELETE = 'element delete'
-ELEMENT_SELECT = 'element select'
-NOTHING_SELECT = 'nothing select'
-FLOW_GRAPH_OPEN = 'flow graph open'
-FLOW_GRAPH_UNDO = 'flow graph undo'
-FLOW_GRAPH_REDO = 'flow graph redo'
-FLOW_GRAPH_SAVE = 'flow graph save'
-FLOW_GRAPH_SAVE_AS = 'flow graph save as'
-FLOW_GRAPH_CLOSE = 'flow graph close'
-FLOW_GRAPH_NEW = 'flow graph new'
-FLOW_GRAPH_GEN = 'flow graph gen'
-FLOW_GRAPH_EXEC = 'flow graph exec'
-FLOW_GRAPH_KILL = 'flow graph kill'
-FLOW_GRAPH_SCREEN_CAPTURE = 'flow graph screen capture'
-ABOUT_WINDOW_DISPLAY = 'about window display'
-HELP_WINDOW_DISPLAY = 'help window display'
-COLORS_WINDOW_DISPLAY = 'colors window display'
+NO_MODS_MASK = 0
 
-######################################################################################################
-# Action Key Map
-######################################################################################################
-_actions_key_list = (
-       #action name, key name, mod mask
-       (FLOW_GRAPH_NEW, 'n', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_OPEN, 'o', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_SAVE, 's', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_SAVE_AS, 's', gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK),
-       (FLOW_GRAPH_CLOSE, 'w', gtk.gdk.CONTROL_MASK),
-       (APPLICATION_QUIT, 'q', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_UNDO, 'z', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_REDO, 'y', gtk.gdk.CONTROL_MASK),
-       (ELEMENT_DELETE, 'Delete', 0),
-       (BLOCK_ROTATE_CCW, 'Left', 0),
-       (BLOCK_ROTATE_CW, 'Right', 0),
-       (BLOCK_DEC_TYPE, 'Up', 0),
-       (BLOCK_INC_TYPE, 'Down', 0),
-       (BLOCK_PARAM_MODIFY, 'Return', 0),
-       (BLOCK_ENABLE, 'e', 0),
-       (BLOCK_DISABLE, 'd', 0),
-       (BLOCK_CUT, 'x', gtk.gdk.CONTROL_MASK),
-       (BLOCK_COPY, 'c', gtk.gdk.CONTROL_MASK),
-       (BLOCK_PASTE, 'v', gtk.gdk.CONTROL_MASK),
-       (FLOW_GRAPH_GEN, 'F5', 0),
-       (FLOW_GRAPH_EXEC, 'F6', 0),
-       (FLOW_GRAPH_KILL, 'F7', 0),
-       (FLOW_GRAPH_SCREEN_CAPTURE, 'Print', 0),
-       (HELP_WINDOW_DISPLAY, 'F1', 0),
-       #the following have no associated gtk.Action
-       (PORT_CONTROLLER_INC, 'equal', 0),
-       (PORT_CONTROLLER_INC, 'plus', 0),
-       (PORT_CONTROLLER_INC, 'KP_Add', 0),
-       (PORT_CONTROLLER_DEC, 'minus', 0),
-       (PORT_CONTROLLER_DEC, 'KP_Subtract', 0),
-)
-
-_actions_key_dict = dict(((key_name, mod_mask), action_name) for action_name, key_name, mod_mask in _actions_key_list)
-def get_action_name_from_key_name(key_name, mod_mask=0):
+########################################################################
+# Actions API
+########################################################################
+_actions_keypress_dict = dict()
+_keymap = gtk.gdk.keymap_get_default()
+_used_mods_mask = NO_MODS_MASK
+def handle_key_press(event):
        """
-       Get the action name associated with the key name and mask.
-       Both keyname and mask have to match.
-       @param key_name the name of the key
-       @param mod_mask the key press mask (shift, ctrl) 0 for none
-       @return the action name or blank string
+       Call the action associated with the key press event.
+       Both the key value and the mask must have a match.
+       @param event a gtk key press event
+       @return true if handled
        """
-       key_name_mod_mask = (key_name, mod_mask)
-       if key_name_mod_mask in _actions_key_dict: return _actions_key_dict[key_name_mod_mask]
-       return ''
+       _used_mods_mask = reduce(lambda x, y: x | y, [mod_mask for keyval, mod_mask in _actions_keypress_dict], NO_MODS_MASK)
+       #extract the key value and the consumed modifiers
+       keyval, egroup, level, consumed = _keymap.translate_keyboard_state(
+               event.hardware_keycode, event.state, event.group)
+       #get the modifier mask and ignore irrelevant modifiers
+       mod_mask = event.state & ~consumed & _used_mods_mask
+       #look up the keypress and call the action
+       try: _actions_keypress_dict[(keyval, mod_mask)]()
+       except KeyError: return False #not handled
+       return True #handled here
 
-######################################################################################################
-# Actions
-######################################################################################################
-_actions_list = (
-       gtk.Action(FLOW_GRAPH_NEW, '_New', 'Create a new flow graph', gtk.STOCK_NEW),
-       gtk.Action(FLOW_GRAPH_OPEN, '_Open', 'Open an existing flow graph', gtk.STOCK_OPEN),
-       gtk.Action(FLOW_GRAPH_SAVE, '_Save', 'Save the current flow graph', gtk.STOCK_SAVE),
-       gtk.Action(FLOW_GRAPH_SAVE_AS, 'Save _As', 'Save the current flow graph as...', gtk.STOCK_SAVE_AS),
-       gtk.Action(FLOW_GRAPH_CLOSE, '_Close', 'Close the current flow graph', gtk.STOCK_CLOSE),
-       gtk.Action(APPLICATION_QUIT, '_Quit', 'Quit program', gtk.STOCK_QUIT),
-       gtk.Action(FLOW_GRAPH_UNDO, '_Undo', 'Undo a change to the flow graph', gtk.STOCK_UNDO),
-       gtk.Action(FLOW_GRAPH_REDO, '_Redo', 'Redo a change to the flow graph', gtk.STOCK_REDO),
-       gtk.Action(ELEMENT_DELETE, '_Delete', 'Delete the selected blocks', gtk.STOCK_DELETE),
-       gtk.Action(BLOCK_ROTATE_CCW, 'Rotate Counterclockwise', 'Rotate the selected blocks 90 degrees to the left', gtk.STOCK_GO_BACK),
-       gtk.Action(BLOCK_ROTATE_CW, 'Rotate Clockwise', 'Rotate the selected blocks 90 degrees to the right', gtk.STOCK_GO_FORWARD),
-       gtk.Action(BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for the selected block', gtk.STOCK_PROPERTIES),
-       gtk.Action(BLOCK_ENABLE, 'E_nable', 'Enable the selected blocks', gtk.STOCK_CONNECT),
-       gtk.Action(BLOCK_DISABLE, 'D_isable', 'Disable the selected blocks', gtk.STOCK_DISCONNECT),
-       gtk.Action(BLOCK_CUT, 'Cu_t', 'Cut', gtk.STOCK_CUT),
-       gtk.Action(BLOCK_COPY, '_Copy', 'Copy', gtk.STOCK_COPY),
-       gtk.Action(BLOCK_PASTE, '_Paste', 'Paste', gtk.STOCK_PASTE),
-       gtk.Action(ABOUT_WINDOW_DISPLAY, '_About', 'About this program', gtk.STOCK_ABOUT),
-       gtk.Action(HELP_WINDOW_DISPLAY, '_Help', 'Usage Tips', gtk.STOCK_HELP),
-       gtk.Action(COLORS_WINDOW_DISPLAY, '_Colors', 'Color Mapping', gtk.STOCK_DIALOG_INFO),
-       gtk.Action(FLOW_GRAPH_GEN, '_Generate', 'Generate the flow graph', gtk.STOCK_CONVERT),
-       gtk.Action(FLOW_GRAPH_EXEC, '_Execute', 'Execute the flow graph', gtk.STOCK_EXECUTE),
-       gtk.Action(FLOW_GRAPH_KILL, '_Kill', 'Kill the flow graph', gtk.STOCK_STOP),
-       gtk.Action(FLOW_GRAPH_SCREEN_CAPTURE, 'S_creen Capture', 'Create a screen capture of the flow graph', gtk.STOCK_PRINT),
-)
-def get_all_actions(): return _actions_list
+_all_actions_list = list()
+def get_all_actions(): return _all_actions_list
+
+_accel_group = gtk.AccelGroup()
+def get_accel_group(): return _accel_group
 
-_actions_dict = dict((action.get_name(), action) for action in _actions_list)
-def get_action_from_name(action_name):
+class Action(gtk.Action):
        """
-       Retrieve the action from the action list.
-       Search the list and find an action with said name.
-       @param action_name the action name(string)
-       @throw KeyError bad action name
-       @return a gtk action object
+       A custom Action class based on gtk.Action.
+       Pass additional arguments such as keypresses.
+       Register actions and keypresses with this module.
        """
-       if action_name in _actions_dict: return _actions_dict[action_name]
-       raise KeyError('Action Name: "%s" does not exist'%action_name)
 
-######################################################################################################
-# Accelerators
-######################################################################################################
-_accel_group = gtk.AccelGroup()
-def get_accel_group(): return _accel_group
+       def __init__(self, keypresses=(), name=None, label=None, tooltip=None, stock_id=None):
+               """
+               Create a new Action instance.
+               @param key_presses a tuple of (keyval1, mod_mask1, keyval2, mod_mask2, ...)
+               @param the regular gtk.Action parameters (defaults to None)
+               """
+               if name is None: name = label
+               gtk.Action.__init__(self,
+                       name=name, label=label,
+                       tooltip=tooltip, stock_id=stock_id,
+               )
+               #register this action
+               _all_actions_list.append(self)
+               for i in range(len(keypresses)/2):
+                       keyval, mod_mask = keypresses[i*2:(i+1)*2]
+                       #register this keypress
+                       assert not _actions_keypress_dict.has_key((keyval, mod_mask))
+                       _actions_keypress_dict[(keyval, mod_mask)] = self
+                       #set the accelerator group, and accelerator path
+                       #register the key name and mod mask with the accelerator path
+                       if label is None: continue #dont register accel
+                       accel_path = '<main>/'+self.get_name()
+                       self.set_accel_group(get_accel_group())
+                       self.set_accel_path(accel_path)
+                       gtk.accel_map_add_entry(accel_path, keyval, mod_mask)
+
+       def __str__(self):
+               """
+               The string representation should be the name of the action id.
+               Try to find the action id for this action by searching this module.
+               """
+               try:
+                       import Actions
+                       return filter(lambda attr: getattr(Actions, attr) == self, dir(Actions))[0]
+               except: return self.get_name()
+
+       def __repr__(self): return str(self)
+
+       def __call__(self):
+               """
+               Emit the activate signal when called with ().
+               """
+               self.emit('activate')
 
-#set the accelerator group, and accelerator path
-#register the key name and mod mask with the accelerator path
-for action_name, key_name, mod_mask in _actions_key_list:
-       try:
-               accel_path = '<main>/'+action_name
-               get_action_from_name(action_name).set_accel_group(get_accel_group())
-               get_action_from_name(action_name).set_accel_path(accel_path)
-               gtk.accel_map_add_entry(accel_path, gtk.gdk.keyval_from_name(key_name), mod_mask)
-       except KeyError: pass #no action was created for this action name
+########################################################################
+# Actions
+########################################################################
+PAGE_CHANGE = Action()
+FLOW_GRAPH_NEW = Action(
+       label='_New',
+       tooltip='Create a new flow graph',
+       stock_id=gtk.STOCK_NEW,
+       keypresses=(gtk.keysyms.n, gtk.gdk.CONTROL_MASK),
+)
+FLOW_GRAPH_OPEN = Action(
+       label='_Open',
+       tooltip='Open an existing flow graph',
+       stock_id=gtk.STOCK_OPEN,
+       keypresses=(gtk.keysyms.o, gtk.gdk.CONTROL_MASK),
+)
+FLOW_GRAPH_SAVE = Action(
+       label='_Save',
+       tooltip='Save the current flow graph',
+       stock_id=gtk.STOCK_SAVE,
+       keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK),
+)
+FLOW_GRAPH_SAVE_AS = Action(
+       label='Save _As',
+       tooltip='Save the current flow graph as...',
+       stock_id=gtk.STOCK_SAVE_AS,
+       keypresses=(gtk.keysyms.s, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK),
+)
+FLOW_GRAPH_CLOSE = Action(
+       label='_Close',
+       tooltip='Close the current flow graph',
+       stock_id=gtk.STOCK_CLOSE,
+       keypresses=(gtk.keysyms.w, gtk.gdk.CONTROL_MASK),
+)
+APPLICATION_INITIALIZE = Action()
+APPLICATION_QUIT = Action(
+       label='_Quit',
+       tooltip='Quit program',
+       stock_id=gtk.STOCK_QUIT,
+       keypresses=(gtk.keysyms.q, gtk.gdk.CONTROL_MASK),
+)
+FLOW_GRAPH_UNDO = Action(
+       label='_Undo',
+       tooltip='Undo a change to the flow graph',
+       stock_id=gtk.STOCK_UNDO,
+       keypresses=(gtk.keysyms.z, gtk.gdk.CONTROL_MASK),
+)
+FLOW_GRAPH_REDO = Action(
+       label='_Redo',
+       tooltip='Redo a change to the flow graph',
+       stock_id=gtk.STOCK_REDO,
+       keypresses=(gtk.keysyms.y, gtk.gdk.CONTROL_MASK),
+)
+NOTHING_SELECT = Action()
+ELEMENT_SELECT = Action()
+ELEMENT_CREATE = Action()
+ELEMENT_DELETE = Action(
+       label='_Delete',
+       tooltip='Delete the selected blocks',
+       stock_id=gtk.STOCK_DELETE,
+       keypresses=(gtk.keysyms.Delete, NO_MODS_MASK),
+)
+BLOCK_MOVE = Action()
+BLOCK_ROTATE_CCW = Action(
+       label='Rotate Counterclockwise',
+       tooltip='Rotate the selected blocks 90 degrees to the left',
+       stock_id=gtk.STOCK_GO_BACK,
+       keypresses=(gtk.keysyms.Left, NO_MODS_MASK),
+)
+BLOCK_ROTATE_CW = Action(
+       label='Rotate Clockwise',
+       tooltip='Rotate the selected blocks 90 degrees to the right',
+       stock_id=gtk.STOCK_GO_FORWARD,
+       keypresses=(gtk.keysyms.Right, NO_MODS_MASK),
+)
+BLOCK_PARAM_MODIFY = Action(
+       label='_Properties',
+       tooltip='Modify params for the selected block',
+       stock_id=gtk.STOCK_PROPERTIES,
+       keypresses=(gtk.keysyms.Return, NO_MODS_MASK),
+)
+BLOCK_ENABLE = Action(
+       label='E_nable',
+       tooltip='Enable the selected blocks',
+       stock_id=gtk.STOCK_CONNECT,
+       keypresses=(gtk.keysyms.e, NO_MODS_MASK),
+)
+BLOCK_DISABLE = Action(
+       label='D_isable',
+       tooltip='Disable the selected blocks',
+       stock_id=gtk.STOCK_DISCONNECT,
+       keypresses=(gtk.keysyms.d, NO_MODS_MASK),
+)
+BLOCK_CUT = Action(
+       label='Cu_t',
+       tooltip='Cut',
+       stock_id=gtk.STOCK_CUT,
+       keypresses=(gtk.keysyms.x, gtk.gdk.CONTROL_MASK),
+)
+BLOCK_COPY = Action(
+       label='_Copy',
+       tooltip='Copy',
+       stock_id=gtk.STOCK_COPY,
+       keypresses=(gtk.keysyms.c, gtk.gdk.CONTROL_MASK),
+)
+BLOCK_PASTE = Action(
+       label='_Paste',
+       tooltip='Paste',
+       stock_id=gtk.STOCK_PASTE,
+       keypresses=(gtk.keysyms.v, gtk.gdk.CONTROL_MASK),
+)
+ERRORS_WINDOW_DISPLAY = Action(
+       label='_Errors',
+       tooltip='View flow graph errors',
+       stock_id=gtk.STOCK_DIALOG_ERROR,
+)
+ABOUT_WINDOW_DISPLAY = Action(
+       label='_About',
+       tooltip='About this program',
+       stock_id=gtk.STOCK_ABOUT,
+)
+HELP_WINDOW_DISPLAY = Action(
+       label='_Help',
+       tooltip='Usage tips',
+       stock_id=gtk.STOCK_HELP,
+       keypresses=(gtk.keysyms.F1, NO_MODS_MASK),
+)
+TYPES_WINDOW_DISPLAY = Action(
+       label='_Types',
+       tooltip='Types color mapping',
+       stock_id=gtk.STOCK_DIALOG_INFO,
+)
+FLOW_GRAPH_GEN = Action(
+       label='_Generate',
+       tooltip='Generate the flow graph',
+       stock_id=gtk.STOCK_CONVERT,
+       keypresses=(gtk.keysyms.F5, NO_MODS_MASK),
+)
+FLOW_GRAPH_EXEC = Action(
+       label='_Execute',
+       tooltip='Execute the flow graph',
+       stock_id=gtk.STOCK_EXECUTE,
+       keypresses=(gtk.keysyms.F6, NO_MODS_MASK),
+)
+FLOW_GRAPH_KILL = Action(
+       label='_Kill',
+       tooltip='Kill the flow graph',
+       stock_id=gtk.STOCK_STOP,
+       keypresses=(gtk.keysyms.F7, NO_MODS_MASK),
+)
+FLOW_GRAPH_SCREEN_CAPTURE = Action(
+       label='S_creen Capture',
+       tooltip='Create a screen capture of the flow graph',
+       stock_id=gtk.STOCK_PRINT,
+       keypresses=(gtk.keysyms.Print, NO_MODS_MASK),
+)
+PORT_CONTROLLER_DEC = Action(
+       keypresses=(gtk.keysyms.minus, NO_MODS_MASK, gtk.keysyms.KP_Subtract, NO_MODS_MASK),
+)
+PORT_CONTROLLER_INC = Action(
+       keypresses=(gtk.keysyms.plus, NO_MODS_MASK, gtk.keysyms.KP_Add, NO_MODS_MASK),
+)
+BLOCK_INC_TYPE = Action(
+       keypresses=(gtk.keysyms.Down, NO_MODS_MASK),
+)
+BLOCK_DEC_TYPE = Action(
+       keypresses=(gtk.keysyms.Up, NO_MODS_MASK),
+)
index e0c547eba5348af90130848d0c4b737aff961cdf..8fd167869828f163d619b271441b6a60bd9c5d93 100644 (file)
@@ -39,6 +39,7 @@ TOOLBAR_LIST = (
        Actions.FLOW_GRAPH_UNDO,
        Actions.FLOW_GRAPH_REDO,
        None,
+       Actions.ERRORS_WINDOW_DISPLAY,
        Actions.FLOW_GRAPH_GEN,
        Actions.FLOW_GRAPH_EXEC,
        Actions.FLOW_GRAPH_KILL,
@@ -81,6 +82,9 @@ MENU_BAR_LIST = (
                None,
                Actions.BLOCK_PARAM_MODIFY,
        ]),
+       (gtk.Action('View', '_View', None, None), [
+               Actions.ERRORS_WINDOW_DISPLAY,
+       ]),
        (gtk.Action('Build', '_Build', None, None), [
                Actions.FLOW_GRAPH_GEN,
                Actions.FLOW_GRAPH_EXEC,
@@ -88,7 +92,7 @@ MENU_BAR_LIST = (
        ]),
        (gtk.Action('Help', '_Help', None, None), [
                Actions.HELP_WINDOW_DISPLAY,
-               Actions.COLORS_WINDOW_DISPLAY,
+               Actions.TYPES_WINDOW_DISPLAY,
                None,
                Actions.ABOUT_WINDOW_DISPLAY,
        ]),
@@ -104,9 +108,8 @@ class Toolbar(gtk.Toolbar):
                """
                gtk.Toolbar.__init__(self)
                self.set_style(gtk.TOOLBAR_ICONS)
-               for action_name in TOOLBAR_LIST:
-                       if action_name: #add a tool item
-                               action = Actions.get_action_from_name(action_name)
+               for action in TOOLBAR_LIST:
+                       if action: #add a tool item
                                self.add(action.create_tool_item())
                                #this reset of the tooltip property is required (after creating the tool item) for the tooltip to show
                                action.set_property('tooltip', action.get_property('tooltip'))
@@ -123,16 +126,15 @@ class MenuBar(gtk.MenuBar):
                Add the submenu to the menu bar.
                """
                gtk.MenuBar.__init__(self)
-               for main_action,action_names in MENU_BAR_LIST:
+               for main_action, actions in MENU_BAR_LIST:
                        #create the main menu item
                        main_menu_item = main_action.create_menu_item()
                        self.append(main_menu_item)
                        #create the menu
                        main_menu = gtk.Menu()
                        main_menu_item.set_submenu(main_menu)
-                       for action_name in action_names:
-                               if action_name: #append a menu item
-                                       action = Actions.get_action_from_name(action_name)
+                       for action in actions:
+                               if action: #append a menu item
                                        main_menu.append(action.create_menu_item())
                                else: main_menu.append(gtk.SeparatorMenuItem())
                        main_menu.show_all() #this show all is required for the separators to show
index 0496f0a28432a0ce7cc871a8ddf50a82b4703b78..27143e070420ccdd6cec709f0b2d098e509a5e30 100644 (file)
@@ -29,6 +29,7 @@ from Constants import \
 import pygtk
 pygtk.require('2.0')
 import gtk
+import pango
 
 BLOCK_MARKUP_TMPL="""\
 #set $foreground = $block.is_valid() and 'black' or 'red'
@@ -37,32 +38,32 @@ BLOCK_MARKUP_TMPL="""\
 class Block(Element):
        """The graphical signal block."""
 
-       def __init__(self, *args, **kwargs):
+       def __init__(self):
                """
                Block contructor.
                Add graphics related params to the block.
                """
                #add the position param
-               self._params['_coordinate'] = self.get_parent().get_parent().Param(
-                       self,
-                       odict({
+               self.get_params().append(self.get_parent().get_parent().Param(
+                       block=self,
+                       n=odict({
                                'name': 'GUI Coordinate',
                                'key': '_coordinate',
                                'type': 'raw',
                                'value': '(0, 0)',
                                'hide': 'all',
                        })
-               )
-               self._params['_rotation'] = self.get_parent().get_parent().Param(
-                       self,
-                       odict({
+               ))
+               self.get_params().append(self.get_parent().get_parent().Param(
+                       block=self,
+                       n=odict({
                                'name': 'GUI Rotation',
                                'key': '_rotation',
                                'type': 'raw',
                                'value': '0',
                                'hide': 'all',
                        })
-               )
+               ))
                Element.__init__(self)
 
        def get_coordinate(self):
@@ -113,23 +114,16 @@ class Block(Element):
                """
                self.get_param('_rotation').set_value(str(rot))
 
-       def update(self):
+       def create_shapes(self):
                """Update the block, parameters, and ports when a change occurs."""
-               self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
-               self.clear()
-               self._create_labels()
-               self.W = self.label_width + 2*BLOCK_LABEL_PADDING
-               self.H = max(*(
-                       [self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
-                       sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
-                       for ports in (self.get_sources(), self.get_sinks())]
-               ))
+               Element.create_shapes(self)
                if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
                elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
-               map(lambda p: p.update(), self.get_ports())
 
-       def _create_labels(self):
+       def create_labels(self):
                """Create the labels for the signal block."""
+               Element.create_labels(self)
+               self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
                layouts = list()
                #create the main layout
                layout = gtk.DrawingArea().create_pango_layout('')
@@ -137,12 +131,15 @@ class Block(Element):
                layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
                self.label_width, self.label_height = layout.get_pixel_size()
                #display the params
-               for param in filter(lambda p: p.get_hide() not in ('all', 'part'), self.get_params()):
-                       layout = param.get_layout()
+               markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
+               if markups:
+                       layout = gtk.DrawingArea().create_pango_layout('')
+                       layout.set_spacing(LABEL_SEPARATION*pango.SCALE)
+                       layout.set_markup('\n'.join(markups))
                        layouts.append(layout)
                        w,h = layout.get_pixel_size()
                        self.label_width = max(w, self.label_width)
-                       self.label_height = self.label_height + h + LABEL_SEPARATION
+                       self.label_height += h + LABEL_SEPARATION
                width = self.label_width
                height = self.label_height
                #setup the pixmap
@@ -158,13 +155,18 @@ class Block(Element):
                        else: w_off = 0
                        pixmap.draw_layout(gc, w_off, h_off, layout)
                        h_off = h + h_off + LABEL_SEPARATION
-               #create vertical and horizontal images
-               self.horizontal_label = image = pixmap.get_image(0, 0, width, height)
+               #create vertical and horizontal pixmaps
+               self.horizontal_label = pixmap
                if self.is_vertical():
-                       self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
-                       for i in range(width):
-                               for j in range(height): vimage.put_pixel(j, width-i-1, image.get_pixel(i, j))
-               map(lambda p: p._create_labels(), self.get_ports())
+                       self.vertical_label = self.get_parent().new_pixmap(height, width)
+                       Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
+               #calculate width and height needed
+               self.W = self.label_width + 2*BLOCK_LABEL_PADDING
+               self.H = max(*(
+                       [self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
+                       sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
+                       for ports in (self.get_sources(), self.get_sinks())]
+               ))
 
        def draw(self, gc, window):
                """
@@ -180,9 +182,9 @@ class Block(Element):
                )
                #draw label image
                if self.is_horizontal():
-                       window.draw_image(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
+                       window.draw_drawable(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
                elif self.is_vertical():
-                       window.draw_image(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
+                       window.draw_drawable(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
                #draw ports
                for port in self.get_ports(): port.draw(gc, window)
 
index 379c4a6a25e04b0d2ca6db6431efa250cb1e4fab..c12120eaff068c48be870b956376a057102bf250 100644 (file)
@@ -28,6 +28,15 @@ NAME_INDEX = 0
 KEY_INDEX = 1
 DOC_INDEX = 2
 
+DOC_MARKUP_TMPL="""\
+#if $doc
+$encode($doc)#slurp
+#else
+undocumented#slurp
+#end if"""
+
+CAT_MARKUP_TMPL="""Category: $cat"""
+
 class BlockTreeWindow(gtk.VBox):
        """The block selection panel."""
 
@@ -48,13 +57,16 @@ class BlockTreeWindow(gtk.VBox):
                self.treeview = gtk.TreeView(self.treestore)
                self.treeview.set_enable_search(False) #disable pop up search box
                self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
-               self.treeview.connect('button_press_event', self._handle_mouse_button_press)
+               self.treeview.connect('button-press-event', self._handle_mouse_button_press)
                selection = self.treeview.get_selection()
                selection.set_mode('single')
                selection.connect('changed', self._handle_selection_change)
                renderer = gtk.CellRendererText()
                column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
                self.treeview.append_column(column)
+               #setup the search
+               self.treeview.set_enable_search(True)
+               self.treeview.set_search_equal_func(self._handle_search)
                #try to enable the tooltips (available in pygtk 2.12 and above) 
                try: self.treeview.set_tooltip_column(DOC_INDEX)
                except: pass
@@ -97,14 +109,14 @@ class BlockTreeWindow(gtk.VBox):
                                iter = self.treestore.insert_before(self._categories[sub_category[:-1]], None)
                                self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
                                self.treestore.set_value(iter, KEY_INDEX, '')
-                               self.treestore.set_value(iter, DOC_INDEX, Utils.xml_encode('Category: %s'%cat_name))
+                               self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
                                self._categories[sub_category] = iter
                #add block
                if block is None: return
                iter = self.treestore.insert_before(self._categories[category], None)
                self.treestore.set_value(iter, NAME_INDEX, block.get_name())
                self.treestore.set_value(iter, KEY_INDEX, block.get_key())
-               self.treestore.set_value(iter, DOC_INDEX, Utils.xml_encode(block.get_doc() or 'undocumented'))
+               self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
 
        ############################################################
        ## Helper Methods
@@ -136,6 +148,22 @@ class BlockTreeWindow(gtk.VBox):
        ############################################################
        ## Event Handlers
        ############################################################
+       def _handle_search(self, model, column, key, iter):
+               #determine which blocks match the search key
+               blocks = self.get_flow_graph().get_parent().get_blocks()
+               matching_blocks = filter(lambda b: key in b.get_key() or key in b.get_name().lower(), blocks)
+               #remove the old search category
+               try: self.treestore.remove(self._categories.pop((self._search_category, )))
+               except (KeyError, AttributeError): pass #nothing to remove
+               #create a search category
+               if not matching_blocks: return
+               self._search_category = 'Search: %s'%key
+               for block in matching_blocks: self.add_block(self._search_category, block)
+               #expand the search category
+               path = self.treestore.get_path(self._categories[(self._search_category, )])
+               self.treeview.collapse_all()
+               self.treeview.expand_row(path, open_all=False)
+
        def _handle_drag_get_data(self, widget, drag_context, selection_data, info, time):
                """
                Handle a drag and drop by setting the key to the selection object.
index 013bcb00f81556c469ca48f610154e334c423664..fabf34ee727c75bdb70320bbc8e9ef91a6732bac 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007, 2008 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -32,6 +32,8 @@ class Connection(Element):
        The arrow coloring exposes the enabled and valid states.
        """
 
+       def __init__(self): Element.__init__(self)
+
        def get_coordinate(self):
                """
                Get the 0,0 coordinate.
@@ -48,8 +50,9 @@ class Connection(Element):
                """
                return 0
 
-       def update(self):
+       def create_shapes(self):
                """Precalculate relative coordinates."""
+               Element.create_shapes(self)
                self._sink_rot = None
                self._source_rot = None
                self._sink_coor = None
@@ -72,7 +75,7 @@ class Connection(Element):
 
        def _update_after_move(self):
                """Calculate coordinates."""
-               self.clear()
+               self.clear() #FIXME do i want this here?
                #source connector
                source = self.get_source()
                X, Y = source.get_connector_coordinate()
@@ -123,7 +126,7 @@ class Connection(Element):
                sink = self.get_sink()
                source = self.get_source()
                #check for changes
-               if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.update()
+               if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.create_shapes()
                elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate(): self._update_after_move()
                #cache values
                self._sink_rot = sink.get_rotation()
index 8d764e28e38e8584302026ccae4fbde33133495d..473c796aff23bf6efe931612cc859f52f30f891d 100644 (file)
@@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 import pygtk
 pygtk.require('2.0')
 import gtk
-import Preferences
 import Utils
 
 class TextDisplay(gtk.TextView):
@@ -57,6 +56,20 @@ def MessageDialogHelper(type, buttons, title=None, markup=None):
        message_dialog.destroy()
        return response
 
+
+ERRORS_MARKUP_TMPL="""\
+#for $i, $err_msg in enumerate($errors)
+<b>Error $i:</b>
+$encode($err_msg.replace('\t', '  '))
+
+#end for"""
+def ErrorsDialog(flowgraph): MessageDialogHelper(
+       type=gtk.MESSAGE_ERROR,
+       buttons=gtk.BUTTONS_CLOSE,
+       title='Flow Graph Errors',
+       markup=Utils.parse_template(ERRORS_MARKUP_TMPL, errors=flowgraph.get_error_messages()),
+)
+
 class AboutDialog(gtk.AboutDialog):
        """A cute little about dialog."""
 
@@ -98,8 +111,8 @@ COLORS_DIALOG_MARKUP_TMPL = """\
 #end if
 """
 
-def ColorsDialog(platform): MessageDialogHelper(
+def TypesDialog(platform): MessageDialogHelper(
        type=gtk.MESSAGE_INFO,
        buttons=gtk.BUTTONS_CLOSE,
-       title='Colors',
+       title='Types',
        markup=Utils.parse_template(COLORS_DIALOG_MARKUP_TMPL, colors=platform.get_colors()))
index b70468ed03f44ba481d0a7f1e88e621fe02b445c..790df7c3fa6c282c353e698c883e77d45a01ee63 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -82,19 +82,21 @@ class DrawingArea(gtk.DrawingArea):
                Forward button click information to the flow graph.
                """
                self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
-               self._flow_graph.handle_mouse_button_press(
-                       left_click=(event.button == 1),
+               if event.button == 1: self._flow_graph.handle_mouse_selector_press(
                        double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
                        coordinate=(event.x, event.y),
                )
+               if event.button == 3: self._flow_graph.handle_mouse_context_press(
+                       coordinate=(event.x, event.y),
+                       event=event,
+               )
 
        def _handle_mouse_button_release(self, widget, event):
                """
                Forward button release information to the flow graph.
                """
                self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
-               self._flow_graph.handle_mouse_button_release(
-                       left_click=(event.button == 1),
+               if event.button == 1: self._flow_graph.handle_mouse_selector_release(
                        coordinate=(event.x, event.y),
                )
 
index 3151917237785ad299ac0cc7b756e74ba8d2d2a8..e020c5caa9ba5854bf91f2dc0b8ff0deb00acfa6 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -17,11 +17,6 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-import Colors
-import pygtk
-pygtk.require('2.0')
-import gtk
-import pango
 from Constants import LINE_SELECT_SENSITIVITY
 from Constants import POSSIBLE_ROTATIONS
 
@@ -32,7 +27,7 @@ class Element(object):
        and methods to detect selection of those areas.
        """
 
-       def __init__(self, *args, **kwargs):
+       def __init__(self):
                """
                Make a new list of rectangular areas and lines, and set the coordinate and the rotation.
                """
@@ -61,6 +56,21 @@ class Element(object):
                rotation = rotation or self.get_rotation()
                return rotation in (90, 270)
 
+       def create_labels(self):
+               """
+               Create labels (if applicable) and call on all children.
+               Call this base method before creating labels in the element.
+               """
+               for child in self.get_children(): child.create_labels()
+
+       def create_shapes(self):
+               """
+               Create shapes (if applicable) and call on all children.
+               Call this base method before creating shapes in the element.
+               """
+               self.clear()
+               for child in self.get_children(): child.create_shapes()
+
        def draw(self, gc, window, border_color, bg_color):
                """
                Draw in the given window.
@@ -70,14 +80,14 @@ class Element(object):
                @param bg_color the color for the inside of the rectangle
                """
                X,Y = self.get_coordinate()
-               for (rX,rY),(W,H) in self.areas_dict[self.get_rotation()]:
+               for (rX,rY),(W,H) in self._areas_list:
                        aX = X + rX
                        aY = Y + rY
                        gc.set_foreground(bg_color)
                        window.draw_rectangle(gc, True, aX, aY, W, H)
                        gc.set_foreground(border_color)
                        window.draw_rectangle(gc, False, aX, aY, W, H)
-               for (x1, y1),(x2, y2) in self.lines_dict[self.get_rotation()]:
+               for (x1, y1),(x2, y2) in self._lines_list:
                        gc.set_foreground(border_color)
                        window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
 
@@ -90,8 +100,8 @@ class Element(object):
 
        def clear(self):
                """Empty the lines and areas."""
-               self.areas_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS)
-               self.lines_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS)
+               self._areas_list = list()
+               self._lines_list = list()
 
        def set_coordinate(self, coor):
                """
@@ -136,7 +146,7 @@ class Element(object):
                X, Y = self.get_coordinate()
                self.set_coordinate((X+deltaX, Y+deltaY))
 
-       def add_area(self, rel_coor, area, rotation=None):
+       def add_area(self, rel_coor, area):
                """
                Add an area to the area list.
                An area is actually a coordinate relative to the main coordinate
@@ -144,25 +154,21 @@ class Element(object):
                A positive width is to the right of the coordinate.
                A positive height is above the coordinate.
                The area is associated with a rotation.
-               If rotation is not specified, the element's current rotation is used.
                @param rel_coor (x,y) offset from this element's coordinate
                @param area (width,height) tuple
-               @param rotation rotation in degrees
                """
-               self.areas_dict[rotation or self.get_rotation()].append((rel_coor, area))
+               self._areas_list.append((rel_coor, area))
 
-       def add_line(self, rel_coor1, rel_coor2, rotation=None):
+       def add_line(self, rel_coor1, rel_coor2):
                """
                Add a line to the line list.
                A line is defined by 2 relative coordinates.
                Lines must be horizontal or vertical.
                The line is associated with a rotation.
-               If rotation is not specified, the element's current rotation is used.
                @param rel_coor1 relative (x1,y1) tuple
                @param rel_coor2 relative (x2,y2) tuple
-               @param rotation rotation in degrees
                """
-               self.lines_dict[rotation or self.get_rotation()].append((rel_coor1, rel_coor2))
+               self._lines_list.append((rel_coor1, rel_coor2))
 
        def what_is_selected(self, coor, coor_m=None):
                """
@@ -183,24 +189,24 @@ class Element(object):
                if coor_m:
                        x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())]
                        #handle rectangular areas
-                       for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
+                       for (x1,y1), (w,h) in self._areas_list:
                                if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
                                        in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \
                                        in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \
                                        in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m):
                                        return self
                        #handle horizontal or vertical lines
-                       for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]:
+                       for (x1, y1), (x2, y2) in self._lines_list:
                                if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
                                        in_between(x2, x, x_m) and in_between(y2, y, y_m):
                                        return self
                        return None
                else:
                        #handle rectangular areas
-                       for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
+                       for (x1,y1), (w,h) in self._areas_list:
                                if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self
                        #handle horizontal or vertical lines
-                       for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]:
+                       for (x1, y1), (x2, y2) in self._lines_list:
                                if x1 == x2: x1, x2 = x1-LINE_SELECT_SENSITIVITY, x2+LINE_SELECT_SENSITIVITY
                                if y1 == y2: y1, y2 = y1-LINE_SELECT_SENSITIVITY, y2+LINE_SELECT_SENSITIVITY
                                if in_between(x, x1, x2) and in_between(y, y1, y2): return self
@@ -220,7 +226,3 @@ class Element(object):
                if rotation not in POSSIBLE_ROTATIONS:
                        raise Exception('"%s" is not one of the possible rotations: (%s)'%(rotation, POSSIBLE_ROTATIONS))
                self.rotation = rotation
-
-       def update(self):
-               """Do nothing for the update. Dummy method."""
-               pass
index f8028f199add9ca85120ea7ab19f53dbc93a8352..897145a1dba7dc503c643875980bf77129b6e952 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -18,14 +18,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from Constants import SCROLL_PROXIMITY_SENSITIVITY, SCROLL_DISTANCE
-from Actions import \
-       ELEMENT_CREATE, ELEMENT_SELECT, \
-       BLOCK_PARAM_MODIFY, BLOCK_MOVE, \
-       ELEMENT_DELETE
+import Actions
 import Colors
 import Utils
 from Element import Element
-from .. base import FlowGraph as _FlowGraph
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -39,7 +35,7 @@ class FlowGraph(Element):
        and the connections between inputs and outputs.
        """
 
-       def __init__(self, *args, **kwargs):
+       def __init__(self):
                """
                FlowGraph contructor.
                Create a list for signal blocks and connections. Connect mouse handlers.
@@ -55,6 +51,19 @@ class FlowGraph(Element):
                #selected ports
                self._old_selected_port = None
                self._new_selected_port = None
+               #context menu
+               self._context_menu = gtk.Menu()
+               for action in [
+                       Actions.BLOCK_CUT,
+                       Actions.BLOCK_COPY,
+                       Actions.BLOCK_PASTE,
+                       Actions.ELEMENT_DELETE,
+                       Actions.BLOCK_ROTATE_CCW,
+                       Actions.BLOCK_ROTATE_CW,
+                       Actions.BLOCK_ENABLE,
+                       Actions.BLOCK_DISABLE,
+                       Actions.BLOCK_PARAM_MODIFY,
+               ]: self._context_menu.append(action.create_menu_item())
 
        ###########################################################################
        # Access Drawing Area
@@ -86,7 +95,7 @@ class FlowGraph(Element):
                block.set_coordinate(coor)
                block.set_rotation(0)
                block.get_param('id').set_value(id)
-               self.handle_states(ELEMENT_CREATE)
+               Actions.ELEMENT_CREATE()
 
        ###########################################################################
        # Copy Paste
@@ -291,10 +300,13 @@ class FlowGraph(Element):
 
        def update(self):
                """
-               Call update on all elements.
+               Call the top level rewrite and validate.
+               Call the top level create labels and shapes.
                """
+               self.rewrite()
                self.validate()
-               for element in self.get_elements(): element.update()
+               self.create_labels()
+               self.create_shapes()
 
        ##########################################################################
        ## Get Selected
@@ -406,7 +418,7 @@ class FlowGraph(Element):
                        self._old_selected_port is not self._new_selected_port:
                        try:
                                self.connect(self._old_selected_port, self._new_selected_port)
-                               self.handle_states(ELEMENT_CREATE)
+                               Actions.ELEMENT_CREATE()
                        except: Messages.send_fail_connection()
                        self._old_selected_port = None
                        self._new_selected_port = None
@@ -421,19 +433,32 @@ class FlowGraph(Element):
                        self._selected_elements = list(
                                set.union(old_elements, new_elements) - set.intersection(old_elements, new_elements)
                        )
-               self.handle_states(ELEMENT_SELECT)
+               Actions.ELEMENT_SELECT()
 
        ##########################################################################
        ## Event Handlers
        ##########################################################################
-       def handle_mouse_button_press(self, left_click, double_click, coordinate):
+       def handle_mouse_context_press(self, coordinate, event):
                """
-               A mouse button is pressed, only respond to left clicks.
+               The context mouse button was pressed:
+               If no elements were selected, perform re-selection at this coordinate.
+               Then, show the context menu at the mouse click location.
+               """
+               selections = self.what_is_selected(coordinate)
+               if not set(selections).intersection(self.get_selected_elements()):
+                       self.set_coordinate(coordinate)
+                       self.mouse_pressed = True
+                       self.update_selected_elements()
+                       self.mouse_pressed = False
+               self._context_menu.popup(None, None, None, event.button, event.time)
+
+       def handle_mouse_selector_press(self, double_click, coordinate):
+               """
+               The selector mouse button was pressed:
                Find the selected element. Attempt a new connection if possible.
                Open the block params window on a double click.
                Update the selection state of the flow graph.
                """
-               if not left_click: return
                self.press_coor = coordinate
                self.set_coordinate(coordinate)
                self.time = 0
@@ -443,18 +468,19 @@ class FlowGraph(Element):
                #double click detected, bring up params dialog if possible
                if double_click and self.get_selected_block():
                        self.mouse_pressed = False
-                       self.handle_states(BLOCK_PARAM_MODIFY)
+                       Actions.BLOCK_PARAM_MODIFY()
 
-       def handle_mouse_button_release(self, left_click, coordinate):
+       def handle_mouse_selector_release(self, coordinate):
                """
-               A mouse button is released, record the state.
+               The selector mouse button was released:
+               Update the state, handle motion (dragging).
+               And update the selected flowgraph elements.
                """
-               if not left_click: return
                self.set_coordinate(coordinate)
                self.time = 0
                self.mouse_pressed = False
                if self.element_moved:
-                       self.handle_states(BLOCK_MOVE)
+                       Actions.BLOCK_MOVE()
                        self.element_moved = False
                self.update_selected_elements()
 
@@ -484,7 +510,7 @@ class FlowGraph(Element):
                                adj.emit('changed')
                #remove the connection if selected in drag event
                if len(self.get_selected_elements()) == 1 and self.get_selected_element().is_connection():
-                       self.handle_states(ELEMENT_DELETE)
+                       Actions.ELEMENT_DELETE()
                #move the selected elements and record the new coordinate
                X, Y = self.get_coordinate()
                if not self.get_ctrl_mask(): self.move_selected((int(x - X), int(y - Y)))
index 6d36f4cf70dcc8d79615bef50f7615458d747ebe..9fcbe2a6cb95304fba5a28b3c22a18a897ed8022 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008 Free Software Foundation, Inc.
+Copyright 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -19,9 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from Constants import \
        NEW_FLOGRAPH_TITLE, DEFAULT_REPORTS_WINDOW_WIDTH
-from Actions import \
-       APPLICATION_QUIT, FLOW_GRAPH_KILL, \
-       FLOW_GRAPH_SAVE, get_accel_group
+import Actions
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -67,20 +65,19 @@ PAGE_TITLE_MARKUP_TMPL = """\
 class MainWindow(gtk.Window):
        """The topmost window with menus, the tool bar, and other major windows."""
 
-       def __init__(self, handle_states, platform):
+       def __init__(self, platform):
                """
-               MainWindow contructor.
-               @param handle_states the callback function
+               MainWindow contructor
+               Setup the menu, toolbar, flowgraph editor notebook, block selection window...
                """
                self._platform = platform
                #setup window
-               self.handle_states = handle_states
                gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
                vbox = gtk.VBox()
                self.hpaned = gtk.HPaned()
                self.add(vbox)
                #create the menu bar and toolbar
-               self.add_accel_group(get_accel_group())
+               self.add_accel_group(Actions.get_accel_group())
                vbox.pack_start(Bars.MenuBar(), False)
                vbox.pack_start(Bars.Toolbar(), False)
                vbox.pack_start(self.hpaned)
@@ -123,7 +120,7 @@ class MainWindow(gtk.Window):
                This method in turns calls the state handler to quit.
                @return true
                """
-               self.handle_states(APPLICATION_QUIT)
+               Actions.APPLICATION_QUIT()
                return True
 
        def _handle_page_change(self, notebook, page, page_num):
@@ -137,7 +134,7 @@ class MainWindow(gtk.Window):
                """
                self.current_page = self.notebook.get_nth_page(page_num)
                Messages.send_page_switch(self.current_page.get_file_path())
-               self.handle_states()
+               Actions.PAGE_CHANGE()
 
        ############################################################
        # Report Window
@@ -223,12 +220,12 @@ class MainWindow(gtk.Window):
                        self._set_page(self.page_to_be_closed)
                #unsaved? ask the user
                if not self.page_to_be_closed.get_saved() and self._save_changes():
-                       self.handle_states(FLOW_GRAPH_SAVE) #try to save
+                       Actions.FLOW_GRAPH_SAVE() #try to save
                        if not self.page_to_be_closed.get_saved(): #still unsaved?
                                self.page_to_be_closed = None #set the page to be closed back to None
                                return
                #stop the flow graph if executing
-               if self.page_to_be_closed.get_pid(): self.handle_states(FLOW_GRAPH_KILL)
+               if self.page_to_be_closed.get_pid(): Actions.FLOW_GRAPH_KILL()
                #remove the page
                self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
                if ensure and self.notebook.get_n_pages() == 0: self.new_page() #no pages, make a new one
index cb45d535992e208b4e2144e913b83d7be8a5fe7f..a73b6855dc5514fde4b0c1e174cfb08da78cf9b1 100644 (file)
@@ -19,9 +19,9 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
-ourpythondir = $(grc_src_prefix)/gui
+ourpythondir = $(pkgpythondir)/grc/gui
 ourpython_PYTHON = \
        Block.py \
        Colors.py \
@@ -43,7 +43,7 @@ ourpython_PYTHON = \
        MainWindow.py \
        Messages.py \
        NotebookPage.py \
-       ParamsDialog.py \
+       PropsDialog.py \
        Preferences.py \
        StateCache.py \
        __init__.py
index cb6b7ed3079d7b1df77d207d20b18ab6eef2cde1..fddfeaf5f1cf7b07d2708d602ea99bb3164ae70b 100644 (file)
@@ -17,10 +17,10 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-from Actions import FLOW_GRAPH_CLOSE
 import pygtk
 pygtk.require('2.0')
 import gtk
+import Actions
 from StateCache import StateCache
 from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT
 from DrawingArea import DrawingArea
@@ -80,9 +80,8 @@ class NotebookPage(gtk.HBox):
                self.drawing_area = DrawingArea(self.get_flow_graph())
                self.scrolled_window.add_with_viewport(self.get_drawing_area())
                self.pack_start(self.scrolled_window)
-               #inject drawing area and handle states into flow graph
+               #inject drawing area into flow graph
                self.get_flow_graph().drawing_area = self.get_drawing_area()
-               self.get_flow_graph().handle_states = main_window.handle_states
                self.show_all()
 
        def get_drawing_area(self): return self.drawing_area
@@ -104,7 +103,7 @@ class NotebookPage(gtk.HBox):
                @param the button
                """
                self.main_window.page_to_be_closed = self
-               self.main_window.handle_states(FLOW_GRAPH_CLOSE)
+               Actions.FLOW_GRAPH_CLOSE()
 
        def set_markup(self, markup):
                """
index a11fd906591c02870701c8599a2b090bec9f2bea..7c00c1b67f04b73cbc109f5ef9882b869d36eb68 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -23,6 +23,108 @@ import pygtk
 pygtk.require('2.0')
 import gtk
 
+class InputParam(gtk.HBox):
+       """The base class for an input parameter inside the input parameters dialog."""
+
+       def __init__(self, param, callback=None):
+               gtk.HBox.__init__(self)
+               self.param = param
+               self._callback = callback
+               self.label = gtk.Label() #no label, markup is added by set_markup
+               self.label.set_size_request(150, -1)
+               self.pack_start(self.label, False)
+               self.set_markup = lambda m: self.label.set_markup(m)
+               self.tp = None
+               #connect events
+               self.connect('show', self._update_gui)
+       def set_color(self, color): pass
+       def set_tooltip_text(self, text): pass
+
+       def _update_gui(self, *args):
+               """
+               Set the markup, color, tooltip, show/hide.
+               """
+               #set the markup
+               has_cb = \
+                       hasattr(self.param.get_parent(), 'get_callbacks') and \
+                       filter(lambda c: self.param.get_key() in c, self.param.get_parent()._callbacks)
+               self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self.param, has_cb=has_cb))
+               #set the color
+               self.set_color(self.param.get_color())
+               #set the tooltip
+               self.set_tooltip_text(
+                       Utils.parse_template(TIP_MARKUP_TMPL, param=self.param).strip(),
+               )
+               #show/hide
+               if self.param.get_hide() == 'all': self.hide_all()
+               else: self.show_all()
+
+       def _handle_changed(self, *args):
+               """
+               Handle a gui change by setting the new param value,
+               calling the callback (if applicable), and updating.
+               """
+               #set the new value
+               self.param.set_value(self.get_text())
+               #call the callback
+               if self._callback: self._callback(*args)
+               else: self.param.validate()
+               #gui update
+               self._update_gui()
+
+class EntryParam(InputParam):
+       """Provide an entry box for strings and numbers."""
+
+       def __init__(self, *args, **kwargs):
+               InputParam.__init__(self, *args, **kwargs)
+               self._input = gtk.Entry()
+               self._input.set_text(self.param.get_value())
+               self._input.connect('changed', self._handle_changed)
+               self.pack_start(self._input, True)
+       def get_text(self): return self._input.get_text()
+       def set_color(self, color): self._input.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+       def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
+
+class EnumParam(InputParam):
+       """Provide an entry box for Enum types with a drop down menu."""
+
+       def __init__(self, *args, **kwargs):
+               InputParam.__init__(self, *args, **kwargs)
+               self._input = gtk.combo_box_new_text()
+               for option in self.param.get_options(): self._input.append_text(option.get_name())
+               self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
+               self._input.connect('changed', self._handle_changed)
+               self.pack_start(self._input, False)
+       def get_text(self): return self.param.get_option_keys()[self._input.get_active()]
+       def set_tooltip_text(self, text): self._input.set_tooltip_text(text)
+
+class EnumEntryParam(InputParam):
+       """Provide an entry box and drop down menu for Raw Enum types."""
+
+       def __init__(self, *args, **kwargs):
+               InputParam.__init__(self, *args, **kwargs)
+               self._input = gtk.combo_box_entry_new_text()
+               for option in self.param.get_options(): self._input.append_text(option.get_name())
+               try: self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
+               except:
+                       self._input.set_active(-1)
+                       self._input.get_child().set_text(self.param.get_value())
+               self._input.connect('changed', self._handle_changed)
+               self._input.get_child().connect('changed', self._handle_changed)
+               self.pack_start(self._input, False)
+       def get_text(self):
+               if self._input.get_active() == -1: return self._input.get_child().get_text()
+               return self.param.get_option_keys()[self._input.get_active()]
+       def set_tooltip_text(self, text):
+               if self._input.get_active() == -1: #custom entry
+                       self._input.get_child().set_tooltip_text(text)
+               else: self._input.set_tooltip_text(text)
+       def set_color(self, color):
+               if self._input.get_active() == -1: #custom entry, use color
+                       self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+               else: #from enum, make white background
+                       self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
+
 PARAM_MARKUP_TMPL="""\
 #set $foreground = $param.is_valid() and 'black' or 'red'
 <span foreground="$foreground" font_desc="Sans 7.5"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>"""
@@ -33,10 +135,21 @@ PARAM_LABEL_MARKUP_TMPL="""\
 <span underline="$underline" foreground="$foreground" font_desc="Sans 9">$encode($param.get_name())</span>"""
 
 TIP_MARKUP_TMPL="""\
+########################################
+#def truncate(string)
+       #set $max_len = 100
+       #set $string = str($string)
+       #if len($string) > $max_len
+$('%s...%s'%($string[:$max_len/2], $string[-$max_len/2:]))#slurp
+       #else
+$string#slurp
+       #end if
+#end def
+########################################
 Key: $param.get_key()
 Type: $param.get_type()
 #if $param.is_valid()
-Value: $param.get_evaluated()
+Value: $truncate($param.get_evaluated())
 #elif len($param.get_error_messages()) == 1
 Error: $(param.get_error_messages()[0])
 #else
@@ -49,55 +162,23 @@ Error:
 class Param(Element):
        """The graphical parameter."""
 
-       def update(self):
-               """
-               Called when an external change occurs.
-               Update the graphical input by calling the change handler.
-               """
-               if hasattr(self, '_input'): self._handle_changed()
-
-       def get_input_object(self, callback=None):
-               """
-               Get the graphical gtk object to represent this parameter.
-               Create the input object with this data type and the handle changed method.
-               @param callback a function of one argument(this param) to be called from the change handler
-               @return gtk input object
-               """
-               self._callback = callback
-               self._input = self.get_input_class()(self, self._handle_changed)
-               if not self._callback: self.update()
-               return self._input
+       def __init__(self): Element.__init__(self)
 
-       def _handle_changed(self, widget=None):
+       def get_input(self, *args, **kwargs):
                """
-               When the input changes, write the inputs to the data type.
-               Finish by calling the exteral callback.
+               Get the graphical gtk class to represent this parameter.
+               An enum requires and combo parameter.
+               A non-enum with options gets a combined entry/combo parameter.
+               All others get a standard entry parameter.
+               @return gtk input class
                """
-               self.set_value(self._input.get_text())
-               self.validate()
-               #is param is involved in a callback? #FIXME: messy
-               has_cb = \
-                       hasattr(self.get_parent(), 'get_callbacks') and \
-                       filter(lambda c: self.get_key() in c, self.get_parent()._callbacks)
-               self._input.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self, has_cb=has_cb))
-               #hide/show
-               if self.get_hide() == 'all': self._input.hide_all()
-               else: self._input.show_all()
-               #set the color
-               self._input.set_color(self.get_color())
-               #set the tooltip
-               if self._input.tp: self._input.tp.set_tip(
-                       self._input.entry,
-                       Utils.parse_template(TIP_MARKUP_TMPL, param=self).strip(),
-               )
-               #execute the external callback
-               if self._callback: self._callback(self)
+               if self.is_enum(): return EnumParam(self, *args, **kwargs)
+               if self.get_options(): return EnumEntryParam(self, *args, **kwargs)
+               return EntryParam(self, *args, **kwargs)
 
-       def get_layout(self):
+       def get_markup(self):
                """
-               Create a layout based on the current markup.
-               @return the pango layout
+               Get the markup for this param.
+               @return a pango markup string
                """
-               layout = gtk.DrawingArea().create_pango_layout('')
-               layout.set_markup(Utils.parse_template(PARAM_MARKUP_TMPL, param=self))
-               return layout
+               return Utils.parse_template(PARAM_MARKUP_TMPL, param=self)
index a32b0209ffb2815c2e769a673dac58af1239b26a..8bbfaca2322a5a0a7528733bc83777f2e4e2cd5e 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008 Free Software Foundation, Inc.
+Copyright 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -17,32 +17,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-from FlowGraph import FlowGraph
-from Connection import Connection
-from Block import Block
-from Port import Port
-from Param import Param
+from Element import Element
 
-def conjoin_classes(name, c1, c2):
-       exec("""
-class %s(c1, c2):
-       def __init__(self, *args, **kwargs):
-               c1.__init__(self, *args, **kwargs)
-               c2.__init__(self, *args, **kwargs)
-"""%name, locals())
-       return locals()[name]
-
-def Platform(platform):
-       #combine with gui class
-       for attr, value in (
-               ('FlowGraph', FlowGraph),
-               ('Connection', Connection),
-               ('Block', Block),
-               ('Source', Port),
-               ('Sink', Port),
-               ('Param', Param),
-       ):
-               old_value = getattr(platform, attr)
-               c = conjoin_classes(attr, old_value, value)
-               setattr(platform, attr, c)
-       return platform
+class Platform(Element):
+       def __init__(self): Element.__init__(self)
index d1f36f8b963659aea5d5e8130c8def7ffb3bd965..2896d04c18e0efae889198a503ed1bf99aaeaf52 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2007 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ PORT_MARKUP_TMPL="""\
 class Port(Element):
        """The graphical port."""
 
-       def __init__(self, *args, **kwargs):
+       def __init__(self):
                """
                Port contructor.
                Create list of connector coordinates.
@@ -42,9 +42,9 @@ class Port(Element):
                Element.__init__(self)
                self.connector_coordinates = dict()
 
-       def update(self):
+       def create_shapes(self):
                """Create new areas and labels for the port."""
-               self.clear()
+               Element.create_shapes(self)
                #get current rotation
                rotation = self.get_rotation()
                #get all sibling ports
@@ -82,8 +82,9 @@ class Port(Element):
                #the connector length
                self._connector_length = CONNECTOR_EXTENSION_MINIMAL + CONNECTOR_EXTENSION_INCREMENT*index
 
-       def _create_labels(self):
+       def create_labels(self):
                """Create the labels for the socket."""
+               Element.create_labels(self)
                self._bg_color = Colors.get_color(self.get_color())
                #create the layout
                layout = gtk.DrawingArea().create_pango_layout('')
@@ -96,12 +97,11 @@ class Port(Element):
                gc.set_foreground(self._bg_color)
                pixmap.draw_rectangle(gc, True, 0, 0, self.w, self.h)
                pixmap.draw_layout(gc, 0, 0, layout)
-               #create the images
-               self.horizontal_label = image = pixmap.get_image(0, 0, self.w, self.h)
+               #create vertical and horizontal pixmaps
+               self.horizontal_label = pixmap
                if self.is_vertical():
-                       self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), self.h, self.w)
-                       for i in range(self.w):
-                               for j in range(self.h): vimage.put_pixel(j, self.w-i-1, image.get_pixel(i, j))
+                       self.vertical_label = self.get_parent().get_parent().new_pixmap(self.h, self.w)
+                       Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
 
        def draw(self, gc, window):
                """
@@ -114,11 +114,11 @@ class Port(Element):
                        border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
                )
                X,Y = self.get_coordinate()
-               (x,y),(w,h) = self.areas_dict[self.get_rotation()][0] #use the first area's sizes to place the labels
+               (x,y),(w,h) = self._areas_list[0] #use the first area's sizes to place the labels
                if self.is_horizontal():
-                       window.draw_image(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1)
+                       window.draw_drawable(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1)
                elif self.is_vertical():
-                       window.draw_image(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1)
+                       window.draw_drawable(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1)
 
        def get_connector_coordinate(self):
                """
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
new file mode 100644 (file)
index 0000000..cc84fd0
--- /dev/null
@@ -0,0 +1,170 @@
+"""
+Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from Dialogs import TextDisplay
+from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT
+
+def get_title_label(title):
+       """
+       Get a title label for the params window.
+       The title will be bold, underlined, and left justified.
+       @param title the text of the title
+       @return a gtk object
+       """
+       label = gtk.Label()
+       label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
+       hbox = gtk.HBox()
+       hbox.pack_start(label, False, False, padding=11)
+       return hbox
+
+class PropsDialog(gtk.Dialog):
+       """
+       A dialog to set block parameters, view errors, and view documentation.
+       """
+
+       def __init__(self, block):
+               """
+               Properties dialog contructor.
+               @param block a block instance
+               """
+               self._hash = 0
+               LABEL_SPACING = 7
+               gtk.Dialog.__init__(self,
+                       title='Properties: %s'%block.get_name(),
+                       buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
+               )
+               self._block = block
+               self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
+               vbox = gtk.VBox()
+               #Create the scrolled window to hold all the parameters
+               scrolled_window = gtk.ScrolledWindow()
+               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               scrolled_window.add_with_viewport(vbox)
+               self.vbox.pack_start(scrolled_window, True)
+               #Params box for block parameters
+               self._params_box = gtk.VBox()
+               self._params_box.pack_start(get_title_label('Parameters'), False)
+               self._input_object_params = list()
+               #Error Messages for the block
+               self._error_box = gtk.VBox()
+               self._error_messages_text_display = TextDisplay()
+               self._error_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
+               self._error_box.pack_start(get_title_label('Error Messages'), False)
+               self._error_box.pack_start(self._error_messages_text_display, False)
+               #Docs for the block
+               self._docs_box = err_box = gtk.VBox()
+               self._docs_text_display = TextDisplay()
+               self._docs_box.pack_start(gtk.Label(), False, False, LABEL_SPACING)
+               self._docs_box.pack_start(get_title_label('Documentation'), False)
+               self._docs_box.pack_start(self._docs_text_display, False)
+               #Add the boxes
+               vbox.pack_start(self._params_box, False)
+               vbox.pack_start(self._error_box, False)
+               vbox.pack_start(self._docs_box, False)
+               #connect events
+               self.connect('key-press-event', self._handle_key_press)
+               self.connect('show', self._update_gui)
+               #show all (performs initial gui update)
+               self.show_all()
+
+       def _params_changed(self):
+               """
+               Have the params in this dialog changed?
+               Ex: Added, removed, type change, hide change...
+               To the props dialog, the hide setting of 'none' and 'part' are identical.
+               Therfore, the props dialog only cares if the hide setting is/not 'all'.
+               Make a hash that uniquely represents the params' state.
+               @return true if changed
+               """
+               old_hash = self._hash
+               #create a tuple of things from each param that affects the params box
+               self._hash = hash(tuple([(
+                       hash(param), param.get_type(), param.get_hide() == 'all',
+               ) for param in self._block.get_params()]))
+               return self._hash != old_hash
+
+       def _handle_changed(self, *args):
+               """
+               A change occured within a param:
+               Rewrite/validate the block and update the gui.
+               """
+               #update for the block
+               self._block.rewrite()
+               self._block.validate()
+               self._update_gui()
+
+       def _update_gui(self, *args):
+               """
+               Repopulate the parameters box (if changed).
+               Update all the input parameters.
+               Update the error messages box.
+               Hide the box if there are no errors.
+               Update the documentation block.
+               Hide the box if there are no docs.
+               """
+               #update the params box
+               if self._params_changed():
+                       #hide params box before changing
+                       self._params_box.hide_all()
+                       #empty the params box
+                       for io_param in list(self._input_object_params):
+                               self._params_box.remove(io_param)
+                               self._input_object_params.remove(io_param)
+                               io_param.destroy()
+                       #repopulate the params box
+                       for param in self._block.get_params():
+                               if param.get_hide() == 'all': continue
+                               io_param = param.get_input(self._handle_changed)
+                               self._input_object_params.append(io_param)
+                               self._params_box.pack_start(io_param, False)
+                       #show params box with new params
+                       self._params_box.show_all()
+               #update the errors box
+               if self._block.is_valid(): self._error_box.hide()
+               else: self._error_box.show()
+               messages = '\n\n'.join(self._block.get_error_messages())
+               self._error_messages_text_display.set_text(messages)
+               #update the docs box
+               if self._block.get_doc(): self._docs_box.show()
+               else: self._docs_box.hide()
+               self._docs_text_display.set_text(self._block.get_doc())
+
+       def _handle_key_press(self, widget, event):
+               """
+               Handle key presses from the keyboard.
+               Call the ok response when enter is pressed.
+               @return false to forward the keypress
+               """
+               if event.keyval == gtk.keysyms.Return:
+                       self.response(gtk.RESPONSE_ACCEPT)
+                       return True #handled here
+               return False #forward the keypress
+
+       def run(self):
+               """
+               Run the dialog and get its response.
+               @return true if the response was accept
+               """
+               response = gtk.Dialog.run(self)
+               self.destroy()
+               return response == gtk.RESPONSE_ACCEPT
index 04b18b18aa676013b0f09a49122d035cf948c0d2..3f6b7922405da7364653476c28f64c865c20a85e 100644 (file)
@@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-from Actions import FLOW_GRAPH_UNDO, FLOW_GRAPH_REDO, get_action_from_name
+import Actions
 from Constants import STATE_CACHE_SIZE
 
 class StateCache(object):
@@ -88,5 +88,5 @@ class StateCache(object):
                """
                Update the undo and redo actions based on the number of next and prev states.
                """
-               get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(self.num_next_states != 0)
-               get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(self.num_prev_states != 0)
+               Actions.FLOW_GRAPH_REDO.set_sensitive(self.num_next_states != 0)
+               Actions.FLOW_GRAPH_UNDO.set_sensitive(self.num_prev_states != 0)
index ee6dc6cdc4aa2a62cddc7bc5d6a1ecce71bba496..b5489d56e7ac5cc2c866ee385f9625605a40e750 100644 (file)
@@ -19,6 +19,30 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 from Constants import POSSIBLE_ROTATIONS
 from Cheetah.Template import Template
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+
+def rotate_pixmap(gc, src_pixmap, dst_pixmap, angle=gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE):
+       """
+       Load the destination pixmap with a rotated version of the source pixmap.
+       The source pixmap will be loaded into a pixbuf, rotated, and drawn to the destination pixmap.
+       The pixbuf is a client-side drawable, where a pixmap is a server-side drawable.
+       @param gc the graphics context
+       @param src_pixmap the source pixmap
+       @param dst_pixmap the destination pixmap
+       @param angle the angle to rotate by
+       """
+       width, height = src_pixmap.get_size()
+       pixbuf = gtk.gdk.Pixbuf(
+               colorspace=gtk.gdk.COLORSPACE_RGB,
+               has_alpha=False, bits_per_sample=8,
+               width=width, height=height,
+       )
+       pixbuf.get_from_drawable(src_pixmap, src_pixmap.get_colormap(), 0, 0, 0, 0, -1, -1)
+       pixbuf = pixbuf.rotate_simple(angle)
+       dst_pixmap.draw_pixbuf(gc, pixbuf, 0, 0, 0, 0)
 
 def get_rotated_coordinate(coor, rotation):
        """
@@ -54,23 +78,6 @@ def get_angle_from_coordinates((x1,y1), (x2,y2)):
                if y2 > y1: return 270
                else: return 90
 
-def xml_encode(string):
-       """
-       Encode a string into an xml safe string by replacing special characters.
-       Needed for gtk pango markup in labels.
-       @param string the input string
-       @return output string with safe characters
-       """
-       string = str(string)
-       for char, safe in (
-                       ('&', '&amp;'),
-                       ('<', '&lt;'),
-                       ('>', '&gt;'),
-                       ('"', '&quot;'),
-                       ("'", '&apos;'),
-       ): string = string.replace(char, safe)
-       return string
-
 def parse_template(tmpl_str, **kwargs):
        """
        Parse the template string with the given args.
@@ -78,5 +85,5 @@ def parse_template(tmpl_str, **kwargs):
        @param tmpl_str the template as a string
        @return a string of the parsed template
        """
-       kwargs['encode'] = xml_encode
+       kwargs['encode'] = gobject.markup_escape_text
        return str(Template(tmpl_str, kwargs))
diff --git a/grc/python/.gitignore b/grc/python/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 957fee18ef123aea408a7c5762c41a3121f22011..dd39b095de5a0c14920ee1db2bed655c43e5ae1a 100644 (file)
@@ -18,10 +18,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from .. base.Block import Block as _Block
+from .. gui.Block import Block as _GUIBlock
 import extract_docs
 import extract_category
 
-class Block(_Block):
+class Block(_Block, _GUIBlock):
+
+       def is_virtual_sink(self): return self.get_key() == 'virtual_sink'
+       def is_virtual_source(self): return self.get_key() == 'virtual_source'
 
        ##for make source to keep track of indexes
        _source_count = 0
@@ -48,13 +52,13 @@ class Block(_Block):
                        flow_graph=flow_graph,
                        n=n,
                )
+               _GUIBlock.__init__(self)
 
        def validate(self):
                """
                Validate this block.
                Call the base class validate.
                Evaluate the checks: each check must evaluate to True.
-               Adjust the nports.
                """
                _Block.validate(self)
                #evaluate the checks
@@ -65,17 +69,23 @@ class Block(_Block):
                                try: assert check_eval
                                except AssertionError: self.add_error_message('Check "%s" failed.'%check)
                        except: self.add_error_message('Check "%s" did not evaluate.'%check)
+
+       def rewrite(self):
+               """
+               Add and remove ports to adjust for the nports.
+               """
+               _Block.rewrite(self)
                #adjust nports
-               for ports, Port in (
-                       (self._sources, self.get_parent().get_parent().Source),
-                       (self._sinks, self.get_parent().get_parent().Sink),
+               for get_ports, get_port in (
+                       (self.get_sources, self.get_source),
+                       (self.get_sinks, self.get_sink),
                ):
-                       #how many ports?
-                       num_ports = len(ports)
+                       #how many streaming (non-message) ports?
+                       num_ports = len(filter(lambda p: p.get_type() != 'msg', get_ports()))
                        #do nothing for 0 ports
                        if not num_ports: continue
                        #get the nports setting
-                       port0 = ports[str(0)]
+                       port0 = get_port(str(0))
                        nports = port0.get_nports()
                        #do nothing for no nports
                        if not nports: continue
@@ -85,19 +95,21 @@ class Block(_Block):
                        if nports < num_ports:
                                #remove the connections
                                for key in map(str, range(nports, num_ports)):
-                                       port = ports[key]
+                                       port = get_port(key)
                                        for connection in port.get_connections():
                                                self.get_parent().remove_element(connection)
                                #remove the ports
-                               for key in map(str, range(nports, num_ports)): ports.pop(key)
+                               for key in map(str, range(nports, num_ports)):
+                                       get_ports().remove(get_port(key))
                                continue
                        #add more ports
                        if nports > num_ports:
                                for key in map(str, range(num_ports, nports)):
-                                       n = port0._n
-                                       n['key'] = key
-                                       port = Port(self, n)
-                                       ports[key] = port
+                                       prev_port = get_port(str(int(key)-1))
+                                       get_ports().insert(
+                                               get_ports().index(prev_port)+1,
+                                               prev_port.copy(new_key=key),
+                                       )
                                continue
 
        def port_controller_modify(self, direction):
index d8a894bb176a97556bde92b6f572fb680033567a..edc18841a00b7844d6c203bf6af1ca19263115d4 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008 Free Software Foundation, Inc.
+Copyright 2008, 2009 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -18,8 +18,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from .. base.Connection import Connection as _Connection
+from .. gui.Connection import Connection as _GUIConnection
 
-class Connection(_Connection):
+class Connection(_Connection, _GUIConnection):
+
+       def __init__(self, **kwargs):
+               _Connection.__init__(self, **kwargs)
+               _GUIConnection.__init__(self)
+
+       def is_msg(self):
+               return self.get_source().get_type() == self.get_sink().get_type() == 'msg'
 
        def validate(self):
                """
index 5f203237f30185e4f6d1a7dbad1daa2d9e78cddf..e661c392782a2501fe740a2485278041c41aa77c 100644 (file)
@@ -18,7 +18,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 import os
-import sys
 import stat
 from gnuradio import gr
 
@@ -61,3 +60,4 @@ SHORT_VECTOR_COLOR_SPEC = '#CCCC33'
 BYTE_VECTOR_COLOR_SPEC = '#CC66CC'
 ID_COLOR_SPEC = '#DDDDDD'
 WILDCARD_COLOR_SPEC = '#FFFFFF'
+MSG_COLOR_SPEC = '#777777'
index 8cad8be492216d46c86884750f0badfb9e6b83fa..b2d406bbd65514ffdc155e58fb799cd74a3292fa 100644 (file)
@@ -19,16 +19,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 import expr_utils
 from .. base.FlowGraph import FlowGraph as _FlowGraph
-from Block import Block
-from Connection import Connection
+from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph
 import re
 
 _variable_matcher = re.compile('^(variable\w*)$')
 _parameter_matcher = re.compile('^(parameter)$')
 
-class FlowGraph(_FlowGraph):
+class FlowGraph(_FlowGraph, _GUIFlowGraph):
+
+       def __init__(self, **kwargs):
+               _FlowGraph.__init__(self, **kwargs)
+               _GUIFlowGraph.__init__(self)
+               self._eval_cache = dict()
 
-       _eval_cache = dict()
        def _eval(self, code, namespace, namespace_hash):
                """
                Evaluate the code with the given namespace.
@@ -37,6 +40,7 @@ class FlowGraph(_FlowGraph):
                @param namespace_hash a unique hash for the namespace
                @return the resultant object
                """
+               if not code: raise Exception, 'Cannot evaluate empty statement.'
                my_hash = hash(code) ^ namespace_hash
                #cache if does not exist
                if not self._eval_cache.has_key(my_hash):
@@ -44,44 +48,36 @@ class FlowGraph(_FlowGraph):
                #return from cache
                return self._eval_cache[my_hash]
 
-       def _get_io_signature(self, pad_key):
+       def _get_io_signaturev(self, pad_key):
                """
-               Get an io signature for this flow graph.
+               Get a list of io signatures for this flow graph.
                The pad key determines the directionality of the io signature.
                @param pad_key a string of pad_source or pad_sink
-               @return a dict with: type, nports, vlen, size
+               @return a list of dicts with: type, label, vlen, size
                """
                pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
-               if not pads: return {
-                       'nports': '0',
-                       'type': '',
-                       'vlen': '0',
-                       'size': '0',
-               }
-               pad = pads[0] #take only the first, user should not have more than 1
+               sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
                #load io signature
-               return {
-                       'nports': str(pad.get_param('nports').get_evaluated()),
+               return [{
+                       'label': str(pad.get_param('label').get_evaluated()),
                        'type': str(pad.get_param('type').get_evaluated()),
                        'vlen': str(pad.get_param('vlen').get_evaluated()),
                        'size': pad.get_param('type').get_opt('size'),
-               }
+               } for pad in sorted_pads]
 
-       def get_input_signature(self):
+       def get_input_signaturev(self):
                """
                Get the io signature for the input side of this flow graph.
-               The io signature with be "0", "0" if no pad source is present.
-               @return a string tuple of type, num_ports, port_size
+               @return a list of io signature structures
                """
-               return self._get_io_signature('pad_source')
+               return self._get_io_signaturev('pad_source')
 
-       def get_output_signature(self):
+       def get_output_signaturev(self):
                """
                Get the io signature for the output side of this flow graph.
-               The io signature with be "0", "0" if no pad sink is present.
-               @return a string tuple of type, num_ports, port_size
+               @return a list of io signature structures
                """
-               return self._get_io_signature('pad_sink')
+               return self._get_io_signaturev('pad_sink')
 
        def get_imports(self):
                """
@@ -109,6 +105,13 @@ class FlowGraph(_FlowGraph):
                parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks())
                return parameters
 
+       def rewrite(self):
+               """
+               Flag the namespace to be renewed.
+               """
+               self._renew_eval_ns = True
+               _FlowGraph.rewrite(self)
+
        def evaluate(self, expr):
                """
                Evaluate the expression.
@@ -116,8 +119,8 @@ class FlowGraph(_FlowGraph):
                @throw Exception bad expression
                @return the evaluated data
                """
-               if self.is_flagged():
-                       self.deflag()
+               if self._renew_eval_ns:
+                       self._renew_eval_ns = False
                        #reload namespace
                        n = dict()
                        #load imports
index 33be4a72615e8c6a053e6a87f8de76dd8a75029f..acd98ef8414ef2a6ee1241451efd28d76f70e511 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
 import os
 import subprocess
+import tempfile
 from Cheetah.Template import Template
 import expr_utils
 from Constants import \
@@ -45,6 +46,10 @@ class Generator(object):
                else:
                        self._mode = TOP_BLOCK_FILE_MODE
                        dirname = os.path.dirname(file_path)
+                       #handle the case where the directory is read-only
+                       #in this case, use the system's temp directory
+                       if not os.access(dirname, os.W_OK):
+                               dirname = tempfile.gettempdir()
                filename = self._flow_graph.get_option('id') + '.py'
                self._file_path = os.path.join(dirname, filename)
 
@@ -98,7 +103,8 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
                #list of regular blocks (all blocks minus the special ones)
                blocks = filter(lambda b: b not in (imports + parameters + variables + probes + notebooks), blocks) + probes
                #list of connections where each endpoint is enabled
-               connections = self._flow_graph.get_enabled_connections()
+               connections = filter(lambda c: not c.is_msg(), self._flow_graph.get_enabled_connections())
+               messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections())
                #list of variable names
                var_ids = [var.get_id() for var in parameters + variables]
                #prepend self.
@@ -124,6 +130,7 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
                        'parameters': parameters,
                        'blocks': blocks,
                        'connections': connections,
+                       'messages': messages,
                        'generate_options': self._generate_options,
                        'var_id2cbs': var_id2cbs,
                }
index 0a62c08257a36e9ba3fef5294b899a0933243dd7..67b71bc4723d75cf9b524042d9ca0282bb5aa915 100644 (file)
@@ -19,9 +19,9 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
-ourpythondir = $(grc_src_prefix)/python
+ourpythondir = $(pkgpythondir)/grc/python
 ourpython_PYTHON = \
        convert_hier.py \
        expr_utils.py \
@@ -37,7 +37,7 @@ ourpython_PYTHON = \
        Port.py \
        __init__.py
 
-ourdatadir = $(grc_src_prefix)/python
+ourdatadir = $(pkgpythondir)/grc/python
 dist_ourdata_DATA = \
        block.dtd \
        default_flow_graph.grc \
index f971d0c3fb6330ca7b06d24f5863e777334d6399..6dd008d1d04b5ce181631f275c5be5bc1d997102 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -17,8 +17,9 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-import expr_utils
-from .. base.Param import Param as _Param, EntryParam
+from .. base.Param import Param as _Param
+from .. gui.Param import Param as _GUIParam
+from .. gui.Param import EntryParam
 import Constants
 import numpy
 import os
@@ -64,7 +65,7 @@ class FileParam(EntryParam):
                file_dialog.set_local_only(True)
                if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog
                        file_path = file_dialog.get_filename() #get the file path
-                       self.entry.set_text(file_path)
+                       self._input.set_text(file_path)
                        self._handle_changed()
                file_dialog.destroy() #destroy the dialog
 
@@ -83,28 +84,47 @@ COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
 REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
 INT_TYPES = tuple(INT_TYPES)
 
-class Param(_Param):
+class Param(_Param, _GUIParam):
 
-       _init = False
-       _hostage_cells = list()
+       def __init__(self, **kwargs):
+               _Param.__init__(self, **kwargs)
+               _GUIParam.__init__(self)
+               self._init = False
+               self._hostage_cells = list()
 
-       ##possible param types
-       TYPES = _Param.TYPES + [
+       def get_types(self): return (
+               'raw', 'enum',
                'complex', 'real', 'int',
                'complex_vector', 'real_vector', 'int_vector',
                'hex', 'string', 'bool',
                'file_open', 'file_save',
-               'id',
+               'id', 'stream_id',
                'grid_pos', 'notebook',
                'import',
-       ]
+       )
 
        def __repr__(self):
                """
                Get the repr (nice string format) for this param.
                @return the string representation
                """
-               if not self.is_valid(): return self.get_value()
+               ##################################################
+               # truncate helper method
+               ##################################################
+               def _truncate(string, style=0):
+                       max_len = max(27 - len(self.get_name()), 3)
+                       if len(string) > max_len:
+                               if style < 0: #front truncate
+                                       string = '...' + string[3-max_len:]
+                               elif style == 0: #center truncate
+                                       string = string[:max_len/2 -3] + '...' + string[-max_len/2:]
+                               elif style > 0: #rear truncate
+                                       string = string[:max_len-3] + '...'
+                       return string
+               ##################################################
+               # simple conditions
+               ##################################################
+               if not self.is_valid(): return _truncate(self.get_value())
                if self.get_value() in self.get_option_keys(): return self.get_option(self.get_value()).get_name()
                ##################################################
                # display logic for numbers
@@ -122,7 +142,6 @@ class Param(_Param):
                # split up formatting by type
                ##################################################
                truncate = 0 #default center truncate
-               max_len = max(27 - len(self.get_name()), 3)
                e = self.get_evaluated()
                t = self.get_type()
                if isinstance(e, bool): return str(e)
@@ -137,20 +156,13 @@ class Param(_Param):
                        truncate = -1
                else: dt_str = str(e) #other types
                ##################################################
-               # truncate
+               # done
                ##################################################
-               if len(dt_str) > max_len:
-                       if truncate < 0: #front truncate
-                               dt_str = '...' + dt_str[3-max_len:]
-                       elif truncate == 0: #center truncate
-                               dt_str = dt_str[:max_len/2 -3] + '...' + dt_str[-max_len/2:]
-                       elif truncate > 0: #rear truncate
-                               dt_str = dt_str[:max_len-3] + '...'
-               return dt_str
+               return _truncate(dt_str, truncate)
 
-       def get_input_class(self):
-               if self.get_type() in ('file_open', 'file_save'): return FileParam
-               return _Param.get_input_class(self)
+       def get_input(self, *args, **kwargs):
+               if self.get_type() in ('file_open', 'file_save'): return FileParam(self, *args, **kwargs)
+               return _GUIParam.get_input(self, *args, **kwargs)
 
        def get_color(self):
                """
@@ -172,6 +184,7 @@ class Param(_Param):
                                'hex': Constants.INT_COLOR_SPEC,
                                'string': Constants.BYTE_VECTOR_COLOR_SPEC,
                                'id': Constants.ID_COLOR_SPEC,
+                               'stream_id': Constants.ID_COLOR_SPEC,
                                'grid_pos': Constants.INT_VECTOR_COLOR_SPEC,
                                'notebook': Constants.INT_VECTOR_COLOR_SPEC,
                                'raw': Constants.WILDCARD_COLOR_SPEC,
@@ -245,10 +258,10 @@ class Param(_Param):
                #########################
                # Numeric Types
                #########################
-               elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex', 'bool'):
+               elif t in ('raw', 'complex', 'real', 'int', 'hex', 'bool'):
                        #raise exception if python cannot evaluate this value
                        try: e = self.get_parent().get_parent().evaluate(v)
-                       except Exception, e: raise Exception, 'Value "%s" cannot be evaluated: %s'%(v, e)
+                       except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
                        #raise an exception if the data is invalid
                        if t == 'raw': return e
                        elif t == 'complex':
@@ -263,10 +276,22 @@ class Param(_Param):
                                try: assert isinstance(e, INT_TYPES)
                                except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
                                return e
-                       #########################
-                       # Numeric Vector Types
-                       #########################
-                       elif t == 'complex_vector':
+                       elif t == 'hex': return hex(e)
+                       elif t == 'bool':
+                               try: assert isinstance(e, bool)
+                               except AssertionError: raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
+                               return e
+                       else: raise TypeError, 'Type "%s" not handled'%t
+               #########################
+               # Numeric Vector Types
+               #########################
+               elif t in ('complex_vector', 'real_vector', 'int_vector'):
+                       if not v: v = '()' #turn a blank string into an empty list, so it will eval
+                       #raise exception if python cannot evaluate this value
+                       try: e = self.get_parent().get_parent().evaluate(v)
+                       except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
+                       #raise an exception if the data is invalid
+                       if t == 'complex_vector':
                                if not isinstance(e, VECTOR_TYPES):
                                        self._lisitify_flag = True
                                        e = [e]
@@ -290,12 +315,6 @@ class Param(_Param):
                                        for ei in e: assert isinstance(ei, INT_TYPES)
                                except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
                                return e
-                       elif t == 'hex': return hex(e)
-                       elif t == 'bool':
-                               try: assert isinstance(e, bool)
-                               except AssertionError: raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
-                               return e
-                       else: raise TypeError, 'Type "%s" not handled'%t
                #########################
                # String Types
                #########################
@@ -310,14 +329,31 @@ class Param(_Param):
                        #can python use this as a variable?
                        try: assert _check_id_matcher.match(v)
                        except AssertionError: raise Exception, 'ID "%s" must begin with a letter and may contain letters, numbers, and underscores.'%v
-                       params = self.get_all_params('id')
-                       keys = [param.get_value() for param in params]
-                       try: assert keys.count(v) <= 1 #id should only appear once, or zero times if block is disabled
+                       ids = [param.get_value() for param in self.get_all_params(t)]
+                       try: assert ids.count(v) <= 1 #id should only appear once, or zero times if block is disabled
                        except: raise Exception, 'ID "%s" is not unique.'%v
                        try: assert v not in ID_BLACKLIST
                        except: raise Exception, 'ID "%s" is blacklisted.'%v
                        return v
                #########################
+               # Stream ID Type
+               #########################
+               elif t == 'stream_id':
+                       #get a list of all stream ids used in the virtual sinks 
+                       ids = [param.get_value() for param in filter(
+                               lambda p: p.get_parent().is_virtual_sink(),
+                               self.get_all_params(t),
+                       )]
+                       #check that the virtual sink's stream id is unique
+                       if self.get_parent().is_virtual_sink():
+                               try: assert ids.count(v) <= 1 #id should only appear once, or zero times if block is disabled
+                               except: raise Exception, 'Stream ID "%s" is not unique.'%v
+                       #check that the virtual source's steam id is found
+                       if self.get_parent().is_virtual_source():
+                               try: assert v in ids
+                               except: raise Exception, 'Stream ID "%s" is not found.'%v
+                       return v
+               #########################
                # Grid Position Type
                #########################
                elif t == 'grid_pos':
@@ -362,7 +398,7 @@ class Param(_Param):
                        try: notebook_block = filter(lambda b: b.get_id() == notebook_id, notebook_blocks)[0]
                        except: raise Exception, 'Notebook id "%s" is not an existing notebook id.'%notebook_id
                        #check that page index exists
-                       try: assert int(page_index) in range(len(notebook_block.get_param('labels').get_evaluated()))
+                       try: assert int(page_index) in range(len(notebook_block.get_param('labels').evaluate()))
                        except: raise Exception, 'Page index "%s" is not a valid index number.'%page_index
                        return notebook_id, page_index
                #########################
@@ -380,17 +416,18 @@ class Param(_Param):
        def to_code(self):
                """
                Convert the value to code.
+               For string and list types, check the init flag, call evaluate().
+               This ensures that evaluate() was called to set the xxxify_flags.
                @return a string representing the code
                """
-               #run init tasks in evaluate
-               #such as setting flags
-               if not self._init: self.evaluate()
                v = self.get_value()
                t = self.get_type()
                if t in ('string', 'file_open', 'file_save'): #string types
+                       if not self._init: self.evaluate()
                        if self._stringify_flag: return '"%s"'%v.replace('"', '\"')
                        else: return v
                elif t in ('complex_vector', 'real_vector', 'int_vector'): #vector types
+                       if not self._init: self.evaluate()
                        if self._lisitify_flag: return '(%s, )'%v
                        else: return '(%s)'%v
                else: return v
index 8718fe955a11a074763dcc506e904fdd7e8b62ea..04db0b9b02803b435438b98f08ae6cfefc95530a 100644 (file)
@@ -1,5 +1,5 @@
 """
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 This file is part of GNU Radio
 
 GNU Radio Companion is free software; you can redistribute it and/or
@@ -18,12 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 import os
-from .. import VERSION #TEMP: until gnuradio has __version__
+from gnuradio import gr
 from .. base.Platform import Platform as _Platform
+from .. gui.Platform import Platform as _GUIPlatform
 from FlowGraph import FlowGraph as _FlowGraph
 from Connection import Connection as _Connection
 from Block import Block as _Block
-from Port import Source,Sink
+from Port import Port as _Port
 from Param import Param as _Param
 from Generator import Generator
 from Constants import \
@@ -42,10 +43,11 @@ COLORS = (#title, #color spec
        ('Integer Vector', Constants.INT_VECTOR_COLOR_SPEC),
        ('Short Vector', Constants.SHORT_VECTOR_COLOR_SPEC),
        ('Byte Vector', Constants.BYTE_VECTOR_COLOR_SPEC),
-       ('Wildcard Type', Constants.WILDCARD_COLOR_SPEC),
+       ('Wildcard', Constants.WILDCARD_COLOR_SPEC),
+       ('Message', Constants.MSG_COLOR_SPEC),
 )
 
-class Platform(_Platform):
+class Platform(_Platform, _GUIPlatform):
 
        def __init__(self):
                """
@@ -59,16 +61,17 @@ class Platform(_Platform):
                _Platform.__init__(
                        self,
                        name='GNU Radio Companion',
-                       version=VERSION,
+                       version=gr.version(),
                        key='grc',
                        license=__doc__.strip(),
-                       website='http://gnuradio.org/trac/wiki/GNURadioCompanion',
+                       website='http://gnuradio.org/redmine/wiki/gnuradio/GNURadioCompanion',
                        block_paths=block_paths,
                        block_dtd=BLOCK_DTD,
                        default_flow_graph=DEFAULT_FLOW_GRAPH,
                        generator=Generator,
                        colors=COLORS,
                )
+               _GUIPlatform.__init__(self)
 
        ##############################################
        # Constructors
@@ -76,6 +79,5 @@ class Platform(_Platform):
        FlowGraph = _FlowGraph
        Connection = _Connection
        Block = _Block
-       Source = Source
-       Sink = Sink
+       Port = _Port
        Param = _Param
index 5a2b047f0ef05c4017b5ddc447fd1001a141efb9..6965371df8a9e922dbeb808d78da53bf93c81a59 100644 (file)
@@ -18,32 +18,68 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from .. base.Port import Port as _Port
+from .. gui.Port import Port as _GUIPort
 import Constants
 
-class Port(_Port):
-
-       ##possible port types
-       TYPES = ['complex', 'float', 'int', 'short', 'byte']
-
-       def __init__(self, block, n):
+def _get_source_from_virtual_sink_port(vsp):
+       """
+       Resolve the source port that is connected to the given virtual sink port.
+       Use the get source from virtual source to recursively resolve subsequent ports. 
+       """
+       try: return _get_source_from_virtual_source_port(
+               vsp.get_enabled_connections()[0].get_source())
+       except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
+
+def _get_source_from_virtual_source_port(vsp, traversed=[]):
+       """
+       Recursively resolve source ports over the virtual connections.
+       Keep track of traversed sources to avoid recursive loops.
+       """
+       if not vsp.get_parent().is_virtual_source(): return vsp
+       if vsp in traversed: raise Exception, 'Loop found when resolving virtual source %s'%vsp
+       try: return _get_source_from_virtual_source_port(
+               _get_source_from_virtual_sink_port(
+                       filter(#get all virtual sinks with a matching stream id
+                               lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+                               filter(#get all enabled blocks that are also virtual sinks
+                                       lambda b: b.is_virtual_sink(),
+                                       vsp.get_parent().get_parent().get_enabled_blocks(),
+                               ),
+                       )[0].get_sinks()[0]
+               ), traversed + [vsp],
+       )
+       except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
+
+class Port(_Port, _GUIPort):
+
+       def __init__(self, block, n, dir):
                """
                Make a new port from nested data.
                @param block the parent element
                @param n the nested odict
-               @return a new port
+               @param dir the direction
                """
-               vlen = n.find('vlen') or '1'
-               nports = n.find('nports') or ''
-               optional = n.find('optional') or ''
+               self._n = n
+               if n['type'] == 'msg': n['key'] = 'msg'
+               if dir == 'source' and not n.find('key'):
+                       n['key'] = str(block._source_count)
+                       block._source_count += 1
+               if dir == 'sink' and not n.find('key'):
+                       n['key'] = str(block._sink_count)
+                       block._sink_count += 1
                #build the port
                _Port.__init__(
                        self,
                        block=block,
                        n=n,
+                       dir=dir,
                )
-               self._nports = nports
-               self._vlen = vlen
-               self._optional = bool(optional)
+               _GUIPort.__init__(self)
+               self._nports = n.find('nports') or ''
+               self._vlen = n.find('vlen') or ''
+               self._optional = bool(n.find('optional'))
+
+       def get_types(self): return ('complex', 'float', 'int', 'short', 'byte', 'msg', '')
 
        def validate(self):
                _Port.validate(self)
@@ -51,6 +87,30 @@ class Port(_Port):
                except AssertionError: self.add_error_message('Port is not connected.')
                try: assert self.is_source() or len(self.get_enabled_connections()) <= 1
                except AssertionError: self.add_error_message('Port has too many connections.')
+               #message port logic
+               if self.get_type() == 'msg':
+                       try: assert not self.get_nports()
+                       except AssertionError: self.add_error_message('A port of type "msg" cannot have "nports" set.')
+                       try: assert self.get_vlen() == 1
+                       except AssertionError: self.add_error_message('A port of type "msg" must have a "vlen" of 1.')
+
+       def rewrite(self):
+               """
+               Handle the port cloning for virtual blocks.
+               """
+               _Port.rewrite(self)
+               if self.get_parent().is_virtual_sink() or self.get_parent().is_virtual_source():
+                       try: #clone type and vlen
+                               source = self.resolve_virtual_source()
+                               self._type = str(source.get_type())
+                               self._vlen = str(source.get_vlen())
+                       except: #reset type and vlen
+                               self._type = ''
+                               self._vlen = ''
+
+       def resolve_virtual_source(self):
+               if self.get_parent().is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
+               if self.get_parent().is_virtual_source(): return _get_source_from_virtual_source_port(self)
 
        def get_vlen(self):
                """
@@ -94,6 +154,7 @@ class Port(_Port):
                                        'int': Constants.INT_COLOR_SPEC,
                                        'short': Constants.SHORT_COLOR_SPEC,
                                        'byte': Constants.BYTE_COLOR_SPEC,
+                                       'msg': Constants.MSG_COLOR_SPEC,
                                }[self.get_type()]
                        return {#vlen is non 1
                                'complex': Constants.COMPLEX_VECTOR_COLOR_SPEC,
@@ -104,26 +165,7 @@ class Port(_Port):
                        }[self.get_type()]
                except: return _Port.get_color(self)
 
-class Source(Port):
-
-       def __init__(self, block, n):
-               self._n = n #save n
-               #key is port index
-               n['key'] = str(block._source_count)
-               block._source_count = block._source_count + 1
-               Port.__init__(self, block, n)
-
-       def __del__(self):
-               self.get_parent()._source_count = self.get_parent()._source_count - 1
-
-class Sink(Port):
-
-       def __init__(self, block, n):
-               self._n = n #save n
-               #key is port index
-               n['key'] = str(block._sink_count)
-               block._sink_count = block._sink_count + 1
-               Port.__init__(self, block, n)
-
-       def __del__(self):
-               self.get_parent()._sink_count = self.get_parent()._sink_count - 1
+       def copy(self, new_key=None):
+               n = self._n.copy()
+               if new_key: n['key'] = new_key
+               return self.__class__(self.get_parent(), n, self._dir)
index bdafbcbc13dde8d9dc2fa7c028996f9cc7426c7b..befddccea0ce2e947befdf59c200cae18c603e7f 100644 (file)
@@ -23,8 +23,8 @@ from .. base import odict
 
 def convert_hier(flow_graph, python_file):
        #extract info from the flow graph
-       input_sig = flow_graph.get_input_signature()
-       output_sig = flow_graph.get_output_signature()
+       input_sigs = flow_graph.get_input_signaturev()
+       output_sigs = flow_graph.get_output_signaturev()
        parameters = flow_graph.get_parameters()
        block_key = flow_graph.get_option('id')
        block_name = flow_graph.get_option('title')
@@ -56,20 +56,18 @@ def convert_hier(flow_graph, python_file):
                params_n.append(param_n)
        block_n['param'] = params_n
        #sink data
-       if int(input_sig['nports']):
+       for input_sig in input_sigs:
                sink_n = odict()
-               sink_n['name'] = 'in'
+               sink_n['name'] = input_sig['label']
                sink_n['type'] = input_sig['type']
                sink_n['vlen'] = input_sig['vlen']
-               sink_n['nports'] = input_sig['nports']
                block_n['sink'] = sink_n
        #source data
-       if int(output_sig['nports']):
+       for output_sig in output_sigs:
                source_n = odict()
-               source_n['name'] = 'out'
+               source_n['name'] = output_sig['label']
                source_n['type'] = output_sig['type']
                source_n['vlen'] = output_sig['vlen']
-               source_n['nports'] = output_sig['nports']
                block_n['source'] = source_n
        #doc data
        block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
index f0c1e749cec747b150593d3ce362b63aeb88b488..f41f415b2c96af3f4ba9f4e2fc39d0da166bec42 100644 (file)
@@ -63,7 +63,7 @@ def _extract(key):
                        #extract descriptions
                        comp_name = extract_txt(xml.xpath(DOXYGEN_NAME_XPATH)[0]).strip()
                        comp_name = '   ---   ' + comp_name + '   ---   '
-                       if re.match('(gr|usrp2|trellis)_.*', key):
+                       if re.match('(gr|usrp2|trellis|noaa)_.*', key):
                                brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_GR_XPATH)[0]).strip()
                                detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_GR_XPATH)[0]).strip()
                        else:
index b537c43e2993707cb17f3b0ef24f5c5f445ab637..a1a9308aa30335fb2228a252536c2215421dd83c 100644 (file)
@@ -10,6 +10,7 @@
 ##@param parameters the paramater blocks
 ##@param blocks the signal blocks
 ##@param connections the connections
+##@param messages the msg type connections
 ##@param generate_options the type of flow graph
 ##@param var_id2cbs variable id map to callback strings
 ########################################################
@@ -64,15 +65,25 @@ class $(class_name)(gr.top_block):
        def __init__($param_str):
                gr.top_block.__init__(self, "$title")
 #elif $generate_options == 'hb'
-       #set $in_sig = $flow_graph.get_input_signature()
-       #set $out_sig = $flow_graph.get_output_signature()
+       #set $in_sigs = $flow_graph.get_input_signaturev()
+       #set $out_sigs = $flow_graph.get_output_signaturev()
 class $(class_name)(gr.hier_block2):
+#def make_io_sig($io_sigs)
+       #set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs]
+       #if len($io_sigs) == 0
+gr.io_signature(0, 0, 0)#slurp
+       #elif len($io_sigs) == 1
+gr.io_signature(1, 1, $size_strs[0])#slurp
+       #else
+gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])#slurp
+       #end if
+#end def
 
        def __init__($param_str):
                gr.hier_block2.__init__(
                        self, "$title",
-                       gr.io_signature($in_sig.nports, $in_sig.nports, $in_sig.size*$in_sig.vlen),
-                       gr.io_signature($out_sig.nports, $out_sig.nports, $out_sig.size*$out_sig.vlen),
+                       $make_io_sig($in_sigs),
+                       $make_io_sig($out_sigs),
                )
 #end if
 ########################################################
@@ -125,6 +136,18 @@ class $(class_name)(gr.hier_block2):
                $indent($ctrl.get_make())
 #end for
 ########################################################
+##Create Message Queues
+########################################################
+#if $messages
+
+               $DIVIDER
+               # Message Queues
+               $DIVIDER
+#end if
+#for $msg in $messages
+               $(msg.get_source().get_parent().get_id())_msgq_out = $(msg.get_sink().get_parent().get_id())_msgq_in = gr.msg_queue(2)
+#end for
+########################################################
 ##Create Blocks
 ########################################################
 #if $blocks
@@ -141,6 +164,13 @@ class $(class_name)(gr.hier_block2):
 ##     The port name should be the id of the parent block.
 ##     However, port names for IO pads should be self.
 ########################################################
+#def make_port_name($port)
+       #if $port.get_parent().get_key().startswith('pad_')
+self#slurp
+       #else
+self.$port.get_parent().get_id()#slurp
+       #end if
+#end def
 #if $connections
 
                $DIVIDER
@@ -150,17 +180,14 @@ class $(class_name)(gr.hier_block2):
 #for $con in $connections
        #set $source = $con.get_source()
        #set $sink = $con.get_sink()
-       #if $source.get_parent().get_key() == 'pad_source'
-               #set $source_name = 'self'
-       #else
-               #set $source_name = 'self.' + $source.get_parent().get_id()
+       ##resolve virtual sources to the actual sources
+       #if $source.get_parent().is_virtual_source()
+               #set $source = $source.resolve_virtual_source()
        #end if
-       #if $sink.get_parent().get_key() == 'pad_sink'
-               #set $sink_name = 'self'
-       #else
-               #set $sink_name = 'self.' + $sink.get_parent().get_id()
+       ##do not generate connections with virtual sinks
+       #if not $sink.get_parent().is_virtual_sink()
+               self.connect(($make_port_name($source), $source.get_key()), ($make_port_name($sink), $sink.get_key()))
        #end if
-               self.connect(($source_name, $source.get_key()), ($sink_name, $sink.get_key()))
 #end for
 
 ########################################################
@@ -181,6 +208,20 @@ class $(class_name)(gr.hier_block2):
 ##     For top block code, generate a main routine.
 ##     Instantiate the top block and run as gui or cli.
 ########################################################
+#def make_default($type, $param)
+       #if $type == 'eng_float'
+eng_notation.num_to_str($param.get_make())#slurp
+       #else
+$param.get_make()#slurp
+       #end if
+#end def
+#def make_short_id($param)
+       #set $short_id = $param.get_param('short_id').get_evaluated()
+       #if $short_id
+               #set $short_id = '-' + $short_id
+       #end if
+$short_id#slurp
+#end def
 #if $generate_options != 'hb'
 if __name__ == '__main__':
        parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
@@ -189,12 +230,8 @@ if __name__ == '__main__':
                #set $type = $param.get_param('type').get_value()
                #if $type
                        #silent $params_eq_list.append('%s=options.%s'%($param.get_id(), $param.get_id()))
-                       #set $short_id = $param.get_param('short_id').get_evaluated()
-                       #if $short_id
-                               #set $short_id = '-' + $short_id
-                       #end if
-       parser.add_option("$short_id", "--$param.get_id()", dest="$param.get_id()", type="$type", default=$param.get_make(),
-               help="Set $($param.get_param('label').evaluate() or $param.get_id()) [default=%default]")
+       parser.add_option("$make_short_id($param)", "--$param.get_id().replace('_', '-')", dest="$param.get_id()", type="$type", default=$make_default($type, $param),
+               help="Set $($param.get_param('label').get_evaluated() or $param.get_id()) [default=%default]")
                #end if
        #end for
        (options, args) = parser.parse_args()
@@ -206,9 +243,14 @@ if __name__ == '__main__':
        #if $generate_options == 'wx_gui'
        tb.Run($flow_graph.get_option('run'))
        #elif $generate_options == 'no_gui'
+               #set $run_options = $flow_graph.get_option('run_options')
+               #if $run_options == 'prompt'
        tb.start()
        raw_input('Press Enter to quit: ')
        tb.stop()
+               #elif $run_options == 'run'
+       tb.run()
+               #end if
        #end if
 #end if
 
diff --git a/grc/scripts/.gitignore b/grc/scripts/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 20ba95751d711f56aa8cbe705f7b5ba6054d1324..9019ec5cc9611256ee220318a7cfe60ddb05b917 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -19,6 +19,6 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include $(top_srcdir)/grc/Makefile.inc
+include $(top_srcdir)/Makefile.common
 
 dist_bin_SCRIPTS = gnuradio-companion usrp2_probe usrp_probe
index 00d4366ddfc2c24fc3d9c0094077b96e6ac3d3e1..38c8f655ce854b350e4f0d3b693b91e325061f85 100755 (executable)
@@ -32,9 +32,6 @@ from gnuradio.grc.gui.Dialogs import TextDisplay
 from gnuradio.grc.python.Platform import Platform
 platform = Platform()
 
-from gnuradio.grc.gui.Platform import Platform
-platform = Platform(platform)
-
 flow_graph = platform.get_new_flow_graph()
 block = flow_graph.get_new_block('usrp2_probe')
 
@@ -42,6 +39,11 @@ block = flow_graph.get_new_block('usrp2_probe')
 usrp_interface_param = block.get_param('interface')
 usrp_type_param = block.get_param('type')
 
+def get_input(param):
+       param.validate()
+       input = param.get_input()
+       return input
+
 class USRP2ProbeWindow(gtk.Window):
        """
        The main window for USRP Dignostics.
@@ -69,8 +71,8 @@ class USRP2ProbeWindow(gtk.Window):
                #create vbox for storage
                vbox = gtk.VBox()
                frame.add(vbox)
-               vbox.pack_start(usrp_interface_param.get_input_object(), False)
-               vbox.pack_start(usrp_type_param.get_input_object(), False)
+               vbox.pack_start(get_input(usrp_interface_param), False)
+               vbox.pack_start(get_input(usrp_type_param), False)
                #make the tree model for holding mac addrs
                self.treestore = gtk.TreeStore(gobject.TYPE_STRING)
                self.treeview = gtk.TreeView(self.treestore)
index 6565612c16e87980e5d4e64d2ec6597358827d4b..d2e92e7530ab10dff1b46062ac13840d7209b544 100755 (executable)
@@ -30,9 +30,6 @@ from gnuradio.grc.gui.Dialogs import TextDisplay
 from gnuradio.grc.python.Platform import Platform
 platform = Platform()
 
-from gnuradio.grc.gui.Platform import Platform
-platform = Platform(platform)
-
 flow_graph = platform.get_new_flow_graph()
 block = flow_graph.get_new_block('usrp_probe')
 
@@ -40,6 +37,11 @@ block = flow_graph.get_new_block('usrp_probe')
 usrp_which_param = block.get_param('which')
 usrp_dboard_param = block.get_param('dboard')
 
+def get_input(param):
+       param.validate()
+       input = param.get_input()
+       return input
+
 class USRPProbeWindow(gtk.Window):
        """
        The main window for USRP Dignostics.
@@ -66,8 +68,8 @@ class USRPProbeWindow(gtk.Window):
                #create vbox for storage
                vbox = gtk.VBox()
                frame.add(vbox)
-               vbox.pack_start(usrp_which_param.get_input_object(), False)
-               vbox.pack_start(usrp_dboard_param.get_input_object(), False)
+               vbox.pack_start(get_input(usrp_which_param), False)
+               vbox.pack_start(get_input(usrp_dboard_param), False)
                self.probe_button = gtk.Button('Probe')
                self.probe_button.connect('clicked', self._probe_usrp)
                vbox.pack_start(self.probe_button, False)
diff --git a/grc/todo.txt b/grc/todo.txt
new file mode 100644 (file)
index 0000000..9dad057
--- /dev/null
@@ -0,0 +1,79 @@
+##################################################
+# Examples
+##################################################
+* Push-to-Talk example
+* Start/Stop the flow graph
+
+##################################################
+# Blocks
+##################################################
+* probe: also non-float outputs
+* log slider gui control
+* generic usrp (when its ready)
+* packet mod: whitening offset
+* wx min window size in options block
+* gr_adaptive_fir_ccf
+* ofdm  
+  * gr_ofdm_bpsk_demapper
+  * gr_ofdm_cyclic_prefixer
+  * gr_ofdm_demapper_vcb
+  * gr_ofdm_frame_acquisition
+  * gr_ofdm_frame_sink
+  * gr_ofdm_insert_preamble
+  * gr_ofdm_mapper_bcv
+  * gr_ofdm_sampler
+* size params for the graphical sinks
+* callbacks for set average on fft, waterfall, number sinks
+* add units to params: Sps, Hz, dB...
+* add bool type to command line option store_true or store_false
+* messages for packet blocks and probe blocks
+
+##################################################
+# Features
+##################################################
+* extract category from doxygen
+  * fix up block tree to mirror current doxygen group
+  * remove blocks in block tree covered by doxygen
+* param editor, expand entry boxes in focus
+* change param dialog to panel within main window
+* gui grid editor for configuring grid params/placing wxgui plots and controls
+* drag from one port to another to connect
+* per parameter docs
+  * extract individual param docs from doxygen
+  * doc tag in param for handwritten notes
+* separate generated code into top block and gui class
+  * use gui.py in gr-wxgui and remove custom top_block_gui
+* configuration option for adding block paths
+* orientations for ports (top, right, bottom, left)
+  * source defaults to right, sink defaults to left
+* separation of variables and gui controls
+* speedup w/ background layer and animation layer
+* multiple doxygen directories (doc_dir becomes doc_path)
+* use pango markup in tooltips for params
+* use get_var_make to determine if it is a variable, not regexp
+* concept of a project, or project flow graph
+  * collection of blocks, hier and top
+  * system-wide, default/work, and user created
+* use templates/macros to generate the repetative stuff in the xml
+
+##################################################
+# Problems
+##################################################
+* msg ports dont work with virtual connections
+  * dont fix this until pmts are used?
+* hier block generation
+  * auto generate hier library on changes
+  * auto clean hier library when block removed
+  * add hier blocks to tree without restart
+* dont generate py files in saved flowgraph dir
+* save/restore cwd
+* threads dont die on exit in probe and variable sink
+* align param titles in properties dialog
+* weird grid params misbehaving
+* gr hier blocks have more diverse IO capabilities than we allow for
+
+##################################################
+# Future
+##################################################
+* require pygtk 2.12 for treeview tooltips
+  * remove try/except in BlockTreeWindow.py
diff --git a/gruel/.gitignore b/gruel/.gitignore
new file mode 100644 (file)
index 0000000..ede973f
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/gruel.pc
index 6377f5bb3ae9ccb96a78e62004dd1c89a3b7ecaf..504c4d94983ca1323c49b4bd386168aee8dd236c 100644 (file)
@@ -6,6 +6,6 @@ includedir=@includedir@
 Name: gruel
 Description: The GNU Radio Utility Etcetera Library
 Requires: 
-Version: @VERSION@
+Version: @LIBVER@
 Libs: -L${libdir} -lgruel
 Cflags: -I${includedir}
diff --git a/gruel/src/.gitignore b/gruel/src/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 90c0f88bdd2b142b1a6be8732498f502be80c2ad..71bdd85732b0878a8193cddbb315b581b3b041f0 100644 (file)
@@ -19,4 +19,5 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = include lib
+SUBDIRS = lib include scheme
+
diff --git a/gruel/src/include/.gitignore b/gruel/src/include/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gruel/src/include/gruel/.gitignore b/gruel/src/include/gruel/.gitignore
new file mode 100644 (file)
index 0000000..bbe9639
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/inet.h
+/pmt_serial_tags.h
index 648d53e2050d37cd2e9d9906035a65eb475adb34..67dd129955c5f7695d438fedfa6a30fb25c9a778 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -28,7 +28,16 @@ gruelincludedir = $(prefix)/include/gruel
 
 gruelinclude_HEADERS = \
        $(BUILT_SOURCES) \
+       msg_accepter.h \
+       msg_accepter_msgq.h \
+       msg_queue.h \
+       msg_passing.h \
+       pmt.h \
+       pmt_pool.h \
+       pmt_serial_tags.h \
+       pmt_sugar.h \
        realtime.h \
        sys_pri.h \
        thread_body_wrapper.h \
-       thread_group.h
+       thread_group.h \
+       thread.h
index a98d83e9c57962b02aa78a3dab10eecea725ebaa..7ac01eb56df44114b2f17e5f771bf5cc7ee9be37 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008, 2009 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #ifndef INCLUDED_INET_H
 #define INCLUDED_INET_H
 
+#include <stdint.h>
+
+#if 1 /* missing htonll or ntohll */
+#if @GR_ARCH_BIGENDIAN@  /* GR_ARCH_BIGENDIAN */
+// Nothing to do...
+static inline uint64_t htonll(uint64_t x){ return x;}
+static inline uint64_t ntohll(uint64_t x){ return x;}
+#else
+#if @GR_HAVE_BYTESWAP@  /* GR_HAVE_BYTESWAP */
+#include <byteswap.h>
+#else
+
+static inline uint64_t
+bswap_64(uint64_t x)
+{
+  return ((x & 0x00000000000000ffull) << 56) | ((x & 0x000000000000ff00ull) << 40) |
+         ((x & 0x0000000000ff0000ull) << 24) | ((x & 0x00000000ff000000ull) <<  8) |
+         ((x & 0x000000ff00000000ull) >>  8) | ((x & 0x0000ff0000000000ull) >> 24) |
+         ((x & 0x00ff000000000000ull) >> 40) | ((x & 0xff00000000000000ull) >> 56);
+}
+
+#endif /* GR_HAVE_BYTESWAP */
+
+static inline uint64_t htonll(uint64_t x){ return bswap_64(x);}
+static inline uint64_t ntohll(uint64_t x){ return bswap_64(x);}
+
+#endif /* GR_ARCH_BIGENDIAN */
+#endif /* missing htonll or ntohll */ 
+
 #if @GR_HAVE_ARPA_INET@  /* GR_HAVE_ARPA_INET */
 #include <arpa/inet.h>
 #elif @GR_HAVE_NETINET_IN@  /* GR_HAVE_NETINET_IN */
@@ -61,8 +90,10 @@ static inline uint16_t ntohs(uint16_t x){ return bswap_16(x); }
 static inline uint8_t  ntohx(uint8_t  x){ return x;        }
 static inline uint16_t ntohx(uint16_t x){ return ntohs(x); }
 static inline uint32_t ntohx(uint32_t x){ return ntohl(x); }
+static inline uint64_t ntohx(uint64_t x){ return ntohll(x);}
 static inline uint8_t  htonx(uint8_t  x){ return x;        }
 static inline uint16_t htonx(uint16_t x){ return htons(x); }
 static inline uint32_t htonx(uint32_t x){ return htonl(x); }
+static inline uint64_t htonx(uint64_t x){ return htonll(x);}
 
 #endif /* INCLUDED_INET_H */
diff --git a/gruel/src/include/gruel/msg_accepter.h b/gruel/src/include/gruel/msg_accepter.h
new file mode 100644 (file)
index 0000000..70ac846
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_MSG_ACCEPTER_H
+#define INCLUDED_GRUEL_MSG_ACCEPTER_H
+
+#include <gruel/pmt.h>
+#include <boost/shared_ptr.hpp>
+
+namespace gruel {
+
+  /*!
+   * \brief Virtual base class that accepts messages
+   */
+  class msg_accepter
+  {
+  public:
+    msg_accepter() {};
+    virtual ~msg_accepter();
+
+    /*!
+     * \brief send \p msg to \p msg_accepter
+     *
+     * Sending a message is an asynchronous operation.  The \p post
+     * call will not wait for the message either to arrive at the
+     * destination or to be received.
+     */
+    virtual void post(pmt::pmt_t msg) = 0;
+  };
+
+  typedef boost::shared_ptr<msg_accepter> msg_accepter_sptr;
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_GRUEL_MSG_ACCEPTER_H */
diff --git a/gruel/src/include/gruel/msg_accepter_msgq.h b/gruel/src/include/gruel/msg_accepter_msgq.h
new file mode 100644 (file)
index 0000000..bf1762e
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_MSG_ACCEPTER_MSGQ_H
+#define INCLUDED_MSG_ACCEPTER_MSGQ_H
+
+#include <gruel/msg_accepter.h>
+#include <gruel/msg_queue.h>
+
+namespace gruel {
+
+  /*!
+   * \brief Concrete class that accepts messages and inserts them into a message queue.
+   */
+  class msg_accepter_msgq : public msg_accepter 
+  {
+  protected:
+    msg_queue_sptr d_msg_queue;
+    
+  public:
+    msg_accepter_msgq(msg_queue_sptr msgq);
+    ~msg_accepter_msgq();
+
+    virtual void post(pmt::pmt_t msg);
+
+    msg_queue_sptr msg_queue() const { return d_msg_queue; }
+  };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_ACCEPTER_MSGQ_H */
diff --git a/gruel/src/include/gruel/msg_passing.h b/gruel/src/include/gruel/msg_passing.h
new file mode 100644 (file)
index 0000000..ebbeca8
--- /dev/null
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_MSG_PASSING_H
+#define INCLUDED_GRUEL_MSG_PASSING_H
+
+/*!
+ * \brief Include this header to use the message passing features
+ */
+
+#include <gruel/pmt.h>
+#include <gruel/msg_accepter.h>
+
+
+namespace gruel {
+
+  /*!
+   * \brief send message to msg_accepter
+   *
+   * \param accepter is the target of the send.
+   * \param msg is the message to send.  It's usually a pmt tuple.
+   *
+   * Sending a message is an asynchronous operation.  The \p send
+   * call will not wait for the message either to arrive at the
+   * destination or to be received.
+   *
+   * \returns msg
+   */
+  static inline pmt::pmt_t
+  send(msg_accepter_sptr accepter, const pmt::pmt_t &msg)
+  {
+    accepter->post(msg);
+    return msg;
+  }
+
+  /*!
+   * \brief send message to msg_accepter
+   *
+   * \param accepter is the target of the send.
+   * \param msg is the message to send.  It's usually a pmt tuple.
+   *
+   * Sending a message is an asynchronous operation.  The \p send
+   * call will not wait for the message either to arrive at the
+   * destination or to be received.
+   *
+   * \returns msg
+   */
+  static inline pmt::pmt_t
+  send(msg_accepter *accepter, const pmt::pmt_t &msg)
+  {
+    accepter->post(msg);
+    return msg;
+  }
+
+  /*!
+   * \brief send message to msg_accepter
+   *
+   * \param accepter is the target of the send.
+   * \param msg is the message to send.  It's usually a pmt tuple.
+   *
+   * Sending a message is an asynchronous operation.  The \p send
+   * call will not wait for the message either to arrive at the
+   * destination or to be received.
+   *
+   * \returns msg
+   */
+  static inline pmt::pmt_t
+  send(msg_accepter &accepter, const pmt::pmt_t &msg)
+  {
+    accepter.post(msg);
+    return msg;
+  }
+
+  /*!
+   * \brief send message to msg_accepter
+   *
+   * \param accepter is the target of the send.  precond: pmt_is_msg_accepter(accepter)
+   * \param msg is the message to send.  It's usually a pmt tuple.
+   *
+   * Sending a message is an asynchronous operation.  The \p send
+   * call will not wait for the message either to arrive at the
+   * destination or to be received.
+   *
+   * \returns msg
+   */
+  static inline pmt::pmt_t
+  send(pmt::pmt_t accepter, const pmt::pmt_t &msg)
+  {
+    return send(pmt_msg_accepter_ref(accepter), msg);
+  }
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_GRUEL_MSG_PASSING_H */
diff --git a/gruel/src/include/gruel/msg_queue.h b/gruel/src/include/gruel/msg_queue.h
new file mode 100644 (file)
index 0000000..c24313d
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+#ifndef INCLUDED_MSG_QUEUE_H
+#define INCLUDED_MSG_QUEUE_H
+
+#include <gruel/thread.h>
+#include <gruel/pmt.h>
+#include <deque>
+
+namespace gruel {
+
+  class msg_queue;
+  typedef boost::shared_ptr<msg_queue> msg_queue_sptr;
+
+  msg_queue_sptr make_msg_queue(unsigned int limit=0);
+
+  /*!
+   * \brief thread-safe message queue
+   */
+  class msg_queue {
+
+    gruel::mutex              d_mutex;
+    gruel::condition_variable d_not_empty;
+    gruel::condition_variable d_not_full;
+    unsigned int             d_limit;    // max # of messages in queue.  0 -> unbounded
+
+    std::deque<pmt::pmt_t>    d_msgs;
+
+  public:
+    msg_queue(unsigned int limit);
+    ~msg_queue();
+
+    /*!
+     * \brief Insert message at tail of queue.
+     * \param msg message
+     *
+     * Block if queue if full.
+     */
+    void insert_tail(pmt::pmt_t msg);
+
+    /*!
+     * \brief Delete message from head of queue and return it.
+     * Block if no message is available.
+     */
+    pmt::pmt_t delete_head();
+    
+    /*!
+     * \brief If there's a message in the q, delete it and return it.
+     * If no message is available, return pmt_t().
+     */
+    pmt::pmt_t delete_head_nowait();
+    
+    //! Delete all messages from the queue
+    void flush();
+
+    //! is the queue empty?
+    bool empty_p() const { return d_msgs.empty(); }
+  
+    //! is the queue full?
+    bool full_p() const { return d_limit != 0 && count() >= d_limit; }
+  
+    //! return number of messages in queue
+    unsigned int count() const { return d_msgs.size(); }
+
+    //! return limit on number of message in queue.  0 -> unbounded
+    unsigned int limit() const { return d_limit; }
+  };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_QUEUE_H */
diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h
new file mode 100644 (file)
index 0000000..c371b02
--- /dev/null
@@ -0,0 +1,776 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifndef INCLUDED_PMT_H
+#define INCLUDED_PMT_H
+
+#include <boost/intrusive_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/any.hpp>
+#include <complex>
+#include <string>
+#include <stdint.h>
+#include <iosfwd>
+#include <stdexcept>
+
+namespace gruel {
+  class msg_accepter;
+};
+
+/*!
+ * This file defines a polymorphic type and the operations on it.
+ *
+ * It draws heavily on the idea of scheme and lisp data types.
+ * The interface parallels that in Guile 1.8, with the notable
+ * exception that these objects are transparently reference counted.
+ */
+
+namespace pmt {
+
+/*!
+ * \brief base class of all pmt types
+ */
+class pmt_base;
+/*!
+ * \brief typedef for shared pointer (transparent reference counting).
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ */
+typedef boost::intrusive_ptr<pmt_base> pmt_t;
+
+extern void intrusive_ptr_add_ref(pmt_base*);
+extern void intrusive_ptr_release(pmt_base*);
+
+class pmt_exception : public std::logic_error
+{
+public:
+  pmt_exception(const std::string &msg, pmt_t obj);
+};
+
+class pmt_wrong_type : public pmt_exception
+{
+public:
+  pmt_wrong_type(const std::string &msg, pmt_t obj);
+};
+
+class pmt_out_of_range : public pmt_exception
+{
+public:
+  pmt_out_of_range(const std::string &msg, pmt_t obj);
+};
+
+class pmt_notimplemented : public pmt_exception
+{
+public:
+  pmt_notimplemented(const std::string &msg, pmt_t obj);
+};
+
+/*
+ * ------------------------------------------------------------------------
+ * Booleans.  Two constants, #t and #f.
+ *
+ * In predicates, anything that is not #f is considered true.
+ * I.e., there is a single false value, #f.
+ * ------------------------------------------------------------------------
+ */
+extern const pmt_t PMT_T;      //< \#t : boolean true constant
+extern const pmt_t PMT_F;      //< \#f : boolean false constant
+
+//! Return true if obj is \#t or \#f, else return false.
+bool pmt_is_bool(pmt_t obj);
+
+//! Return false if obj is \#f, else return true.
+bool pmt_is_true(pmt_t obj);
+
+//! Return true if obj is \#f, else return true.
+bool pmt_is_false(pmt_t obj);
+
+//! Return \#f is val is false, else return \#t.
+pmt_t pmt_from_bool(bool val);
+
+//! Return true if val is PMT_T, return false when val is PMT_F, 
+// else raise wrong_type exception.
+bool pmt_to_bool(pmt_t val);
+
+/*
+ * ------------------------------------------------------------------------
+ *                            Symbols
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is a symbol, else false.
+bool pmt_is_symbol(const pmt_t& obj);
+
+//! Return the symbol whose name is \p s.
+pmt_t pmt_string_to_symbol(const std::string &s);
+
+//! Alias for pmt_string_to_symbol
+pmt_t pmt_intern(const std::string &s);
+
+
+/*!
+ * If \p is a symbol, return the name of the symbol as a string.
+ * Otherwise, raise the wrong_type exception.
+ */
+const std::string pmt_symbol_to_string(const pmt_t& sym);
+
+/*
+ * ------------------------------------------------------------------------
+ *           Numbers: we support integer, real and complex
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is any kind of number, else false.
+bool pmt_is_number(pmt_t obj);
+
+/*
+ * ------------------------------------------------------------------------
+ *                            Integers
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an integer number, else false
+bool pmt_is_integer(pmt_t x);
+
+//! Return the pmt value that represents the integer \p x.
+pmt_t pmt_from_long(long x);
+
+/*!
+ * \brief Convert pmt to long if possible.
+ *
+ * When \p x represents an exact integer that fits in a long,
+ * return that integer.  Else raise an exception, either wrong_type
+ * when x is not an exact integer, or out_of_range when it doesn't fit.
+ */
+long pmt_to_long(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ *                             Reals
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * \brief Return true if \p obj is a real number, else false.
+ */
+bool pmt_is_real(pmt_t obj);
+
+//! Return the pmt value that represents double \p x.
+pmt_t pmt_from_double(double x);
+
+/*!
+ * \brief Convert pmt to double if possible.
+ *
+ * Returns the number closest to \p val that is representable
+ * as a double.  The argument \p val must be a real or integer, otherwise
+ * a wrong_type exception is raised.
+ */
+double pmt_to_double(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ *                            Complex
+ * ------------------------------------------------------------------------
+ */
+
+/*!
+ * \brief return true if \p obj is a complex number, false otherwise.
+ */
+bool pmt_is_complex(pmt_t obj);
+
+//! Return a complex number constructed of the given real and imaginary parts.
+pmt_t pmt_make_rectangular(double re, double im);
+
+/*!
+ * If \p z is complex, real or integer, return the closest complex<double>.
+ * Otherwise, raise the wrong_type exception.
+ */
+std::complex<double> pmt_to_complex(pmt_t z);
+
+/*
+ * ------------------------------------------------------------------------
+ *                             Pairs
+ * ------------------------------------------------------------------------
+ */
+
+extern const pmt_t PMT_NIL;    //< the empty list
+
+//! Return true if \p x is the empty list, otherwise return false.
+bool pmt_is_null(const pmt_t& x);
+
+//! Return true if \p obj is a pair, else false.
+bool pmt_is_pair(const pmt_t& obj);
+
+//! Return a newly allocated pair whose car is \p x and whose cdr is \p y.
+pmt_t pmt_cons(const pmt_t& x, const pmt_t& y);
+
+//! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_car(const pmt_t& pair);
+
+//! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_cdr(const pmt_t& pair);
+
+//! Stores \p value in the car field of \p pair.
+void pmt_set_car(pmt_t pair, pmt_t value);
+
+//! Stores \p value in the cdr field of \p pair.
+void pmt_set_cdr(pmt_t pair, pmt_t value);
+
+pmt_t pmt_caar(pmt_t pair);
+pmt_t pmt_cadr(pmt_t pair);
+pmt_t pmt_cdar(pmt_t pair);
+pmt_t pmt_cddr(pmt_t pair);
+pmt_t pmt_caddr(pmt_t pair);
+pmt_t pmt_cadddr(pmt_t pair);
+
+/*
+ * ------------------------------------------------------------------------
+ *                               Tuples
+ *
+ * Store a fixed number of objects.  Tuples are not modifiable, and thus
+ * are excellent for use as messages.  Indexing is zero based.
+ * Access time to an element is O(1).
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a tuple, othewise false.
+bool pmt_is_tuple(pmt_t x);
+
+pmt_t pmt_make_tuple();
+pmt_t pmt_make_tuple(const pmt_t &e0);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9);
+
+/*!
+ * If \p x is a vector or proper list, return a tuple containing the elements of x
+ */
+pmt_t pmt_to_tuple(const pmt_t &x);
+
+/*!
+ * Return the contents of position \p k of \p tuple.
+ * \p k must be a valid index of \p tuple.
+ */
+pmt_t pmt_tuple_ref(const pmt_t &tuple, size_t k);
+
+/*
+ * ------------------------------------------------------------------------
+ *                            Vectors
+ *
+ * These vectors can hold any kind of objects.  Indexing is zero based.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a vector, othewise false.
+bool pmt_is_vector(pmt_t x);
+
+//! Make a vector of length \p k, with initial values set to \p fill
+pmt_t pmt_make_vector(size_t k, pmt_t fill);
+
+/*!
+ * Return the contents of position \p k of \p vector.
+ * \p k must be a valid index of \p vector.
+ */
+pmt_t pmt_vector_ref(pmt_t vector, size_t k);
+
+//! Store \p obj in position \p k.
+void pmt_vector_set(pmt_t vector, size_t k, pmt_t obj);
+
+//! Store \p fill in every position of \p vector
+void pmt_vector_fill(pmt_t vector, pmt_t fill);
+
+/*
+ * ------------------------------------------------------------------------
+ *                   Binary Large Objects (BLOBs)
+ *
+ * Handy for passing around uninterpreted chunks of memory.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a blob, othewise false.
+bool pmt_is_blob(pmt_t x);
+
+/*!
+ * \brief Make a blob given a pointer and length in bytes
+ *
+ * \param buf is the pointer to data to use to create blob
+ * \param len is the size of the data in bytes.
+ *
+ * The data is copied into the blob.
+ */
+pmt_t pmt_make_blob(const void *buf, size_t len);
+
+//! Return a pointer to the blob's data
+const void *pmt_blob_data(pmt_t blob);
+
+//! Return the blob's length in bytes
+size_t pmt_blob_length(pmt_t blob);
+
+/*!
+ * <pre>
+ * ------------------------------------------------------------------------
+ *                    Uniform Numeric Vectors
+ *
+ * A uniform numeric vector is a vector whose elements are all of single
+ * numeric type.  pmt offers uniform numeric vectors for signed and
+ * unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
+ * floating point values, and complex floating-point numbers of these
+ * two sizes.  Indexing is zero based.
+ *
+ * The names of the functions include these tags in their names:
+ *
+ *    u8  unsigned 8-bit integers
+ *    s8  signed 8-bit integers
+ *   u16  unsigned 16-bit integers
+ *   s16  signed 16-bit integers
+ *   u32  unsigned 32-bit integers
+ *   s32  signed 32-bit integers
+ *   u64  unsigned 64-bit integers
+ *   s64  signed 64-bit integers
+ *   f32  the C++ type float
+ *   f64  the C++ type double
+ *   c32  the C++ type complex<float>
+ *   c64  the C++ type complex<double>
+ * ------------------------------------------------------------------------
+ * </pre>
+ */
+
+//! true if \p x is any kind of uniform numeric vector
+bool pmt_is_uniform_vector(pmt_t x);  
+
+bool pmt_is_u8vector(pmt_t x);
+bool pmt_is_s8vector(pmt_t x);
+bool pmt_is_u16vector(pmt_t x);
+bool pmt_is_s16vector(pmt_t x);
+bool pmt_is_u32vector(pmt_t x);
+bool pmt_is_s32vector(pmt_t x);
+bool pmt_is_u64vector(pmt_t x);
+bool pmt_is_s64vector(pmt_t x);
+bool pmt_is_f32vector(pmt_t x);
+bool pmt_is_f64vector(pmt_t x);
+bool pmt_is_c32vector(pmt_t x);
+bool pmt_is_c64vector(pmt_t x);
+
+pmt_t pmt_make_u8vector(size_t k, uint8_t fill);
+pmt_t pmt_make_s8vector(size_t k, int8_t fill);
+pmt_t pmt_make_u16vector(size_t k, uint16_t fill);
+pmt_t pmt_make_s16vector(size_t k, int16_t fill);
+pmt_t pmt_make_u32vector(size_t k, uint32_t fill);
+pmt_t pmt_make_s32vector(size_t k, int32_t fill);
+pmt_t pmt_make_u64vector(size_t k, uint64_t fill);
+pmt_t pmt_make_s64vector(size_t k, int64_t fill);
+pmt_t pmt_make_f32vector(size_t k, float fill);
+pmt_t pmt_make_f64vector(size_t k, double fill);
+pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill);
+pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill);
+
+pmt_t pmt_init_u8vector(size_t k, const uint8_t *data);
+pmt_t pmt_init_s8vector(size_t k, const int8_t *data);
+pmt_t pmt_init_u16vector(size_t k, const uint16_t *data);
+pmt_t pmt_init_s16vector(size_t k, const int16_t *data);
+pmt_t pmt_init_u32vector(size_t k, const uint32_t *data);
+pmt_t pmt_init_s32vector(size_t k, const int32_t *data);
+pmt_t pmt_init_u64vector(size_t k, const uint64_t *data);
+pmt_t pmt_init_s64vector(size_t k, const int64_t *data);
+pmt_t pmt_init_f32vector(size_t k, const float *data);
+pmt_t pmt_init_f64vector(size_t k, const double *data);
+pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data);
+pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data);
+
+uint8_t  pmt_u8vector_ref(pmt_t v, size_t k);
+int8_t   pmt_s8vector_ref(pmt_t v, size_t k);
+uint16_t pmt_u16vector_ref(pmt_t v, size_t k);
+int16_t  pmt_s16vector_ref(pmt_t v, size_t k);
+uint32_t pmt_u32vector_ref(pmt_t v, size_t k);
+int32_t  pmt_s32vector_ref(pmt_t v, size_t k);
+uint64_t pmt_u64vector_ref(pmt_t v, size_t k);
+int64_t  pmt_s64vector_ref(pmt_t v, size_t k);
+float    pmt_f32vector_ref(pmt_t v, size_t k);
+double   pmt_f64vector_ref(pmt_t v, size_t k);
+std::complex<float>  pmt_c32vector_ref(pmt_t v, size_t k);
+std::complex<double> pmt_c64vector_ref(pmt_t v, size_t k);
+
+void pmt_u8vector_set(pmt_t v, size_t k, uint8_t x);  //< v[k] = x
+void pmt_s8vector_set(pmt_t v, size_t k, int8_t x);
+void pmt_u16vector_set(pmt_t v, size_t k, uint16_t x);
+void pmt_s16vector_set(pmt_t v, size_t k, int16_t x);
+void pmt_u32vector_set(pmt_t v, size_t k, uint32_t x);
+void pmt_s32vector_set(pmt_t v, size_t k, int32_t x);
+void pmt_u64vector_set(pmt_t v, size_t k, uint64_t x);
+void pmt_s64vector_set(pmt_t v, size_t k, int64_t x);
+void pmt_f32vector_set(pmt_t v, size_t k, float x);
+void pmt_f64vector_set(pmt_t v, size_t k, double x);
+void pmt_c32vector_set(pmt_t v, size_t k, std::complex<float> x);
+void pmt_c64vector_set(pmt_t v, size_t k, std::complex<double> x);
+
+// Return const pointers to the elements
+
+const void *pmt_uniform_vector_elements(pmt_t v, size_t &len);  //< works with any; len is in bytes
+
+const uint8_t  *pmt_u8vector_elements(pmt_t v, size_t &len);  //< len is in elements
+const int8_t   *pmt_s8vector_elements(pmt_t v, size_t &len);  //< len is in elements
+const uint16_t *pmt_u16vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int16_t  *pmt_s16vector_elements(pmt_t v, size_t &len); //< len is in elements
+const uint32_t *pmt_u32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int32_t  *pmt_s32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const uint64_t *pmt_u64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int64_t  *pmt_s64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const float    *pmt_f32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const double   *pmt_f64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const std::complex<float>  *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements
+
+// Return non-const pointers to the elements
+
+void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len);  //< works with any; len is in bytes
+
+uint8_t  *pmt_u8vector_writable_elements(pmt_t v, size_t &len);  //< len is in elements
+int8_t   *pmt_s8vector_writable_elements(pmt_t v, size_t &len);  //< len is in elements
+uint16_t *pmt_u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int16_t  *pmt_s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+uint32_t *pmt_u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int32_t  *pmt_s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+uint64_t *pmt_u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int64_t  *pmt_s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+float    *pmt_f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+double   *pmt_f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+std::complex<float>  *pmt_c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+
+/*
+ * ------------------------------------------------------------------------
+ *        Dictionary (a.k.a associative array, hash, map)
+ *
+ * This is a functional data structure that is persistent.  Updating a
+ * functional data structure does not destroy the existing version, but
+ * rather creates a new version that coexists with the old.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is a dictionary
+bool pmt_is_dict(const pmt_t &obj);
+
+//! Make an empty dictionary
+pmt_t pmt_make_dict();
+
+//! Return a new dictionary with \p key associated with \p value.
+pmt_t pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value);
+
+//! Return a new dictionary with \p key removed.
+pmt_t pmt_dict_delete(const pmt_t &dict, const pmt_t &key);
+
+//! Return true if \p key exists in \p dict
+bool  pmt_dict_has_key(const pmt_t &dict, const pmt_t &key);
+
+//! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
+pmt_t pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found);
+
+//! Return list of (key . value) pairs
+pmt_t pmt_dict_items(pmt_t dict);
+
+//! Return list of keys
+pmt_t pmt_dict_keys(pmt_t dict);
+
+//! Return list of values
+pmt_t pmt_dict_values(pmt_t dict);
+
+/*
+ * ------------------------------------------------------------------------
+ *   Any (wraps boost::any -- can be used to wrap pretty much anything)
+ *
+ * Cannot be serialized or used across process boundaries.
+ * See http://www.boost.org/doc/html/any.html
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is an any
+bool pmt_is_any(pmt_t obj);
+
+//! make an any
+pmt_t pmt_make_any(const boost::any &any);
+
+//! Return underlying boost::any
+boost::any pmt_any_ref(pmt_t obj);
+
+//! Store \p any in \p obj
+void pmt_any_set(pmt_t obj, const boost::any &any);
+
+
+/*
+ * ------------------------------------------------------------------------
+ *    msg_accepter -- pmt representation of gruel::msg_accepter
+ * ------------------------------------------------------------------------
+ */
+//! Return true if \p obj is a msg_accepter
+bool pmt_is_msg_accepter(const pmt_t &obj);
+
+//! make a msg_accepter
+pmt_t pmt_make_msg_accepter(boost::shared_ptr<gruel::msg_accepter> ma);
+
+//! Return underlying msg_accepter
+boost::shared_ptr<gruel::msg_accepter> pmt_msg_accepter_ref(const pmt_t &obj);
+
+/*
+ * ------------------------------------------------------------------------
+ *                       General functions
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if x and y are the same object; otherwise return false.
+bool pmt_eq(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * \brief Return true if x and y should normally be regarded as the same object, else false.
+ *
+ * <pre>
+ * eqv returns true if:
+ *   x and y are the same object.
+ *   x and y are both \#t or both \#f.
+ *   x and y are both symbols and their names are the same.
+ *   x and y are both numbers, and are numerically equal.
+ *   x and y are both the empty list (nil).
+ *   x and y are pairs or vectors that denote same location in store.
+ * </pre>
+ */
+bool pmt_eqv(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * pmt_equal recursively compares the contents of pairs and vectors,
+ * applying pmt_eqv on other objects such as numbers and symbols.  
+ * pmt_equal may fail to terminate if its arguments are circular data
+ * structures.
+ */
+bool pmt_equal(const pmt_t& x, const pmt_t& y);
+
+
+//! Return the number of elements in v
+size_t pmt_length(const pmt_t& v);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ *  and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs.  If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eq to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assq(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ *  and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs.  If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eqv to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assv(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ *  and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs.  If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_equal to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assoc(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Apply \p proc element-wise to the elements of list and returns
+ * a list of the results, in order.
+ *
+ * \p list must be a list.  The dynamic order in which \p proc is
+ * applied to the elements of \p list is unspecified.
+ */
+pmt_t pmt_map(pmt_t proc(const pmt_t&), pmt_t list);
+
+/*!
+ * \brief reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+pmt_t pmt_reverse(pmt_t list);
+
+/*!
+ * \brief destructively reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+pmt_t pmt_reverse_x(pmt_t list);
+
+/*!
+ * \brief (acons x y a) == (cons (cons x y) a)
+ */
+inline static pmt_t
+pmt_acons(pmt_t x, pmt_t y, pmt_t a)
+{
+  return pmt_cons(pmt_cons(x, y), a);
+}
+
+/*!
+ * \brief locates \p nth element of \n list where the car is the 'zeroth' element.
+ */
+pmt_t pmt_nth(size_t n, pmt_t list);
+
+/*!
+ * \brief returns the tail of \p list that would be obtained by calling
+ * cdr \p n times in succession.
+ */
+pmt_t pmt_nthcdr(size_t n, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memq use pmt_eq to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_memq(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memv use pmt_eqv to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_memv(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_member use pmt_equal to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_member(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return true if every element of \p list1 appears in \p list2, and false otherwise.
+ * Comparisons are done with pmt_eqv.
+ */
+bool pmt_subsetp(pmt_t list1, pmt_t list2);
+
+/*!
+ * \brief Return a list of length 1 containing \p x1
+ */
+pmt_t pmt_list1(const pmt_t& x1);
+
+/*!
+ * \brief Return a list of length 2 containing \p x1, \p x2
+ */
+pmt_t pmt_list2(const pmt_t& x1, const pmt_t& x2);
+
+/*!
+ * \brief Return a list of length 3 containing \p x1, \p x2, \p x3
+ */
+pmt_t pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3);
+
+/*!
+ * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4
+ */
+pmt_t pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4);
+
+/*!
+ * \brief Return a list of length 5 containing \p x1, \p x2, \p x3, \p x4, \p x5
+ */
+pmt_t pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5);
+
+/*!
+ * \brief Return a list of length 6 containing \p x1, \p x2, \p x3, \p x4, \p
+ * x5, \p x6
+ */
+pmt_t pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6);
+
+/*!
+ * \brief Return \p list with \p item added to it.
+ */
+pmt_t pmt_list_add(pmt_t list, const pmt_t& item);
+
+
+/*
+ * ------------------------------------------------------------------------
+ *                          read / write
+ * ------------------------------------------------------------------------
+ */
+extern const pmt_t PMT_EOF;    //< The end of file object
+
+//! return true if obj is the EOF object, otherwise return false.
+bool pmt_is_eof_object(pmt_t obj);
+
+/*!
+ * read converts external representations of pmt objects into the
+ * objects themselves.  Read returns the next object parsable from
+ * the given input port, updating port to point to the first
+ * character past the end of the external representation of the
+ * object.
+ *
+ * If an end of file is encountered in the input before any
+ * characters are found that can begin an object, then an end of file
+ * object is returned.   The port remains open, and further attempts
+ * to read will also return an end of file object.  If an end of file
+ * is encountered after the beginning of an object's external
+ * representation, but the external representation is incomplete and
+ * therefore not parsable, an error is signaled.
+ */
+pmt_t pmt_read(std::istream &port);
+
+/*!
+ * Write a written representation of \p obj to the given \p port.
+ */
+void pmt_write(pmt_t obj, std::ostream &port);
+
+/*!
+ * Return a string representation of \p obj.
+ * This is the same output as would be generated by pmt_write.
+ */
+std::string pmt_write_string(pmt_t obj);
+
+
+std::ostream& operator<<(std::ostream &os, pmt_t obj);
+
+
+/*
+ * ------------------------------------------------------------------------
+ *                   portable byte stream representation
+ * ------------------------------------------------------------------------
+ */
+/*!
+ * \brief Write portable byte-serial representation of \p obj to \p sink
+ */
+bool pmt_serialize(pmt_t obj, std::streambuf &sink);
+
+/*!
+ * \brief Create obj from portable byte-serial representation
+ */
+pmt_t pmt_deserialize(std::streambuf &source);
+
+
+void pmt_dump_sizeof();        // debugging
+
+} /* namespace pmt */
+
+
+#include <gruel/pmt_sugar.h>
+
+#endif /* INCLUDED_PMT_H */
diff --git a/gruel/src/include/gruel/pmt_pool.h b/gruel/src/include/gruel/pmt_pool.h
new file mode 100644 (file)
index 0000000..b792523
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_PMT_POOL_H
+#define INCLUDED_PMT_POOL_H
+
+#include <cstddef>
+#include <vector>
+#include <boost/thread.hpp>
+
+namespace pmt {
+
+/*!
+ * \brief very simple thread-safe fixed-size allocation pool
+ *
+ * FIXME may want to go to global allocation with per-thread free list.
+ * This would eliminate virtually all lock contention.
+ */
+class pmt_pool {
+
+  struct item {
+    struct item        *d_next;
+  };
+  
+  typedef boost::unique_lock<boost::mutex>  scoped_lock;
+  mutable boost::mutex                 d_mutex;
+  boost::condition_variable    d_cond;
+  
+  size_t             d_itemsize;
+  size_t             d_alignment;
+  size_t             d_allocation_size;
+  size_t             d_max_items;
+  size_t             d_n_items;
+  item              *d_freelist;
+  std::vector<char *> d_allocations;
+
+public:
+  /*!
+   * \param itemsize size in bytes of the items to be allocated.
+   * \param alignment alignment in bytes of all objects to be allocated (must be power-of-2).
+   * \param allocation_size number of bytes to allocate at a time from the underlying allocator.
+   * \param max_items is the maximum number of items to allocate.  If this number is exceeded,
+   *         the allocate blocks.  0 implies no limit.
+   */
+  pmt_pool(size_t itemsize, size_t alignment = 16,
+          size_t allocation_size = 4096, size_t max_items = 0);
+  ~pmt_pool();
+
+  void *malloc();
+  void free(void *p);
+};
+
+} /* namespace pmt */
+
+#endif /* INCLUDED_PMT_POOL_H */
diff --git a/gruel/src/include/gruel/pmt_sugar.h b/gruel/src/include/gruel/pmt_sugar.h
new file mode 100644 (file)
index 0000000..92bcb5f
--- /dev/null
@@ -0,0 +1,165 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_PMT_SUGAR_H
+#define INCLUDED_GRUEL_PMT_SUGAR_H
+
+/*!
+ * This file is included by pmt.h and contains pseudo-constructor
+ * shorthand for making pmt objects
+ */
+
+namespace pmt {
+
+  //! Make pmt symbol
+  static inline pmt_t
+  mp(const std::string &s)
+  {
+    return pmt_string_to_symbol(s);
+  }
+
+  //! Make pmt symbol
+  static inline pmt_t
+  mp(const char *s)
+  {
+    return pmt_string_to_symbol(s);
+  }
+
+  //! Make pmt long
+  static inline pmt_t
+  mp(long x){
+    return pmt_from_long(x);
+  }
+
+  //! Make pmt long
+  static inline pmt_t
+  mp(int x){
+    return pmt_from_long(x);
+  }
+
+  //! Make pmt double
+  static inline pmt_t
+  mp(double x){
+    return pmt_from_double(x);
+  }
+  
+  //! Make pmt complex
+  static inline pmt_t
+  mp(std::complex<double> z)
+  {
+    return pmt_make_rectangular(z.real(), z.imag());
+  }
+
+  //! Make pmt complex
+  static inline pmt_t
+  mp(std::complex<float> z)
+  {
+    return pmt_make_rectangular(z.real(), z.imag());
+  }
+
+  //! Make pmt msg_accepter
+  static inline pmt_t
+  mp(boost::shared_ptr<gruel::msg_accepter> ma)
+  {
+    return pmt_make_msg_accepter(ma);
+  }
+
+  //! Make pmt Binary Large Object (BLOB)
+  static inline pmt_t
+  mp(const void *data, size_t len_in_bytes)
+  {
+    return pmt_make_blob(data, len_in_bytes);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0)
+  {
+    return pmt_make_tuple(e0);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1)
+  {
+    return pmt_make_tuple(e0, e1);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2)
+  {
+    return pmt_make_tuple(e0, e1, e2);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4, e5);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8);
+  }
+
+  //! Make tuple
+  static inline pmt_t
+  mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9)
+  {
+    return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9);
+  }
+
+
+} /* namespace pmt */
+
+
+#endif /* INCLUDED_GRUEL_PMT_SUGAR_H */
diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h
new file mode 100644 (file)
index 0000000..d72e552
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_THREAD_H
+#define INCLUDED_THREAD_H
+
+#include <boost/thread.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace gruel {
+
+  typedef boost::thread                    thread;
+  typedef boost::mutex                     mutex;
+  typedef boost::unique_lock<boost::mutex> scoped_lock;
+  typedef boost::condition_variable        condition_variable;
+  typedef boost::posix_time::time_duration duration;
+
+  /*!
+   * Returns absolute time 'secs' into the future
+   */
+  boost::system_time get_new_timeout(double secs);
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_THREAD_H */
index 27dbbf7bbc4c68f3f4d0b6967d16ad60be4602b1..b024bfdaf93e8f59dedb8aaaf49cd63763f99669 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -21,7 +21,7 @@
 #ifndef INCLUDED_THREAD_BODY_WRAPPER_H
 #define INCLUDED_THREAD_BODY_WRAPPER_H
 
-#include <boost/thread.hpp>
+#include <gruel/thread.h>
 #include <exception>
 #include <iostream>
 
index ae9a4250bb70d2d9fb266fe86fef3fb2074ac9b4..0270746e4d16569bd59903554a42ebfca929dad3 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2001-2003 William E. Kempf
  * Copyright (C) 2007 Anthony Williams
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  *
  *  Distributed under the Boost Software License, Version 1.0. (See accompanying 
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -15,8 +15,8 @@
 #ifndef INCLUDED_GRUEL_THREAD_GROUP_H
 #define INCLUDED_GRUEL_THREAD_GROUP_H
 
+#include <gruel/thread.h>
 #include <boost/utility.hpp>
-#include <boost/thread.hpp>
 #include <boost/thread/shared_mutex.hpp>
 #include <boost/function.hpp>
 
diff --git a/gruel/src/lib/.gitignore b/gruel/src/lib/.gitignore
new file mode 100644 (file)
index 0000000..165e179
--- /dev/null
@@ -0,0 +1,5 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+test_gruel
index c2a008e48ac56cf160155583a223914541dc78a8..1bcd26e90717feed2d578c59dcddcb7519d77adc 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
 
 include $(top_srcdir)/Makefile.common
 
-AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
+SUBDIRS = pmt msg
+
+AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
+
+
+TESTS = test_gruel
+
+noinst_PROGRAMS = test_gruel
+
 
 lib_LTLIBRARIES = libgruel.la
 
 # magic flags
-libgruel_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) -version-info 0:0:0
+libgruel_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) $(LTVERSIONFLAGS)
+
+# ----------------------------------------------------------------
+
+PMT_LIB = pmt/libpmt.la
+MSG_LIB = msg/libmsg.la
 
 # These are the source files that go into the gruel shared library
-libgruel_la_SOURCES = \
-       realtime.cc \
-       sys_pri.cc \
-       thread_body_wrapper.cc \
+libgruel_la_SOURCES =                  \
+       realtime.cc                     \
+       sys_pri.cc                      \
+       thread.cc                       \
+       thread_body_wrapper.cc          \
        thread_group.cc
 
-libgruel_la_LIBADD = \
-       $(BOOST_THREAD_LIB)
+libgruel_la_LIBADD =                   \
+       $(BOOST_THREAD_LIB)             \
+       $(PMT_LIB)                      \
+       $(MSG_LIB)                      \
+       -lstdc++
+
+
+# ----------------------------------------------------------------
+
+test_gruel_SOURCES = test_gruel.cc
+test_gruel_LDADD   = pmt/libpmt-qa.la libgruel.la
 
-noinst_HEADERS =
diff --git a/gruel/src/lib/msg/.gitignore b/gruel/src/lib/msg/.gitignore
new file mode 100644 (file)
index 0000000..c026fd6
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
diff --git a/gruel/src/lib/msg/Makefile.am b/gruel/src/lib/msg/Makefile.am
new file mode 100644 (file)
index 0000000..13a6570
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
+
+noinst_LTLIBRARIES = libmsg.la
+
+libmsg_la_SOURCES = \
+       msg_accepter.cc \
+       msg_accepter_msgq.cc \
+       msg_queue.cc
+
diff --git a/gruel/src/lib/msg/msg_accepter.cc b/gruel/src/lib/msg/msg_accepter.cc
new file mode 100644 (file)
index 0000000..64878f7
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gruel/msg_accepter.h>
+
+namespace gruel {
+
+  msg_accepter::~msg_accepter()
+  {
+    // NOP, required as virtual destructor
+  }
+
+} /* namespace gruel */
diff --git a/gruel/src/lib/msg/msg_accepter_msgq.cc b/gruel/src/lib/msg/msg_accepter_msgq.cc
new file mode 100644 (file)
index 0000000..64fe501
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gruel/msg_accepter_msgq.h>
+
+using namespace pmt;
+
+namespace gruel {
+
+  msg_accepter_msgq::msg_accepter_msgq(msg_queue_sptr msgq)
+    : d_msg_queue(msgq)
+  {
+  }
+
+  msg_accepter_msgq::~msg_accepter_msgq()
+  {
+    // NOP, required as virtual destructor
+  }
+
+  void
+  msg_accepter_msgq::post(pmt_t msg)
+  {
+    d_msg_queue->insert_tail(msg);
+  }
+
+} /* namespace gruel */
diff --git a/gruel/src/lib/msg/msg_queue.cc b/gruel/src/lib/msg/msg_queue.cc
new file mode 100644 (file)
index 0000000..8d15f08
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gruel/msg_queue.h>
+#include <stdexcept>
+
+using namespace pmt;
+
+namespace gruel {
+
+  msg_queue_sptr
+  make_msg_queue(unsigned int limit)
+  {
+    return msg_queue_sptr(new msg_queue(limit));
+  }
+  
+  msg_queue::msg_queue(unsigned int limit)
+    : d_limit(limit)
+  {
+  }
+  
+  msg_queue::~msg_queue()
+  {
+    flush();
+  }
+
+  void
+  msg_queue::insert_tail(pmt_t msg)
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    while (full_p())
+      d_not_full.wait(guard);
+
+    d_msgs.push_back(msg);
+    d_not_empty.notify_one();
+  }
+
+  pmt_t
+  msg_queue::delete_head()
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    while (empty_p())
+      d_not_empty.wait(guard);
+
+    pmt_t m(d_msgs.front());
+    d_msgs.pop_front();
+
+    if (d_limit > 0)           // Unlimited length queues never block on write
+      d_not_full.notify_one();
+
+    return m;
+  }
+
+  pmt_t
+  msg_queue::delete_head_nowait()
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    if (empty_p())
+      return pmt_t();
+       
+    pmt_t m(d_msgs.front());
+    d_msgs.pop_front();
+
+    if (d_limit > 0)           // Unlimited length queues never block on write
+      d_not_full.notify_one();
+
+    return m;
+  }
+
+  void
+  msg_queue::flush()
+  {
+    while (delete_head_nowait() != pmt_t())
+      ;
+  }
+
+} /* namespace gruel */
diff --git a/gruel/src/lib/pmt/.gitignore b/gruel/src/lib/pmt/.gitignore
new file mode 100644 (file)
index 0000000..035c031
--- /dev/null
@@ -0,0 +1,10 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/test_pmt
+/qa_pmt_unv.cc
+/qa_pmt_unv.h
+/pmt_unv_int.h
+/pmt_unv.cc
+/stamp-sources-generate
diff --git a/gruel/src/lib/pmt/Makefile.am b/gruel/src/lib/pmt/Makefile.am
new file mode 100644 (file)
index 0000000..8750cbd
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Copyright 2008,2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
+
+
+noinst_LTLIBRARIES = libpmt.la
+
+# ----------------------------------------------------------------
+# these scripts generate code
+
+code_generator =                       \
+       generate_unv.py                 \
+       unv_template.h.t                \
+       unv_template.cc.t               \
+       unv_qa_template.cc.t            
+
+GENERATED_H =                          \
+       pmt_unv_int.h                   \
+       qa_pmt_unv.h                    
+
+GENERATED_CC =                         \
+       pmt_unv.cc                      \
+       qa_pmt_unv.cc                   
+
+python_built_sources = $(GENERATED_H) $(GENERATED_CC)
+
+PMT_SERIAL_TAGS_H = $(abs_top_builddir)/gruel/src/include/gruel/pmt_serial_tags.h
+BUILT_SOURCES = $(python_built_sources) $(PMT_SERIAL_TAGS_H)
+
+EXTRA_DIST = $(code_generator)
+
+# ----------------------------------------------------------------
+
+libpmt_la_SOURCES =                    \
+       pmt.cc                          \
+       pmt_io.cc                       \
+       pmt_pool.cc                     \
+       pmt_serialize.cc                \
+       pmt_unv.cc
+
+libpmt_la_LIBADD =                     \
+       $(BOOST_THREAD_LIB)             \
+       -lstdc++
+
+libpmt_la_LDFLAGS =                    \
+       $(BOOST_LDFLAGS)
+
+noinst_HEADERS = \
+       $(GENERATED_H)                  \
+       pmt_int.h                       \
+       qa_pmt.h                        \
+       qa_pmt_prims.h
+
+# Build the qa code into its own library
+
+noinst_LTLIBRARIES += libpmt-qa.la
+
+libpmt_qa_la_SOURCES =                 \
+       qa_pmt.cc                       \
+       qa_pmt_prims.cc                 \
+       qa_pmt_unv.cc                   
+
+# magic flags
+libpmt_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid version
+
+libpmt_qa_la_LIBADD =                  \
+       libpmt.la                       \
+       $(CPPUNIT_LIBS)                 \
+       -lstdc++                        
+
+
+# Do creation and inclusion of other Makefiles last
+
+# common way for generating sources from templates when using
+# BUILT_SOURCES, using parallel build protection.
+gen_sources = $(python_built_sources)
+gen_sources_deps = $(core_generator)
+par_gen_command = PYTHONPATH=$(top_srcdir)/gruel/src/lib/pmt srcdir=$(srcdir) $(PYTHON) $(srcdir)/generate_unv.py
+include $(top_srcdir)/Makefile.par.gen
+
+# Rule to create the build header file using GUILE
+# Doesn't need parallel protections because there is a single target
+$(PMT_SERIAL_TAGS_H): $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm
+       $(RUN_GUILE) $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm $(PMT_SERIAL_TAGS_H)
diff --git a/gruel/src/lib/pmt/generate_unv.py b/gruel/src/lib/pmt/generate_unv.py
new file mode 100755 (executable)
index 0000000..02aace2
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2009 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.
+# 
+
+"""
+Generate code for uniform numeric vectors
+"""
+
+import re, os, os.path
+
+
+unv_types = (
+    ('u8', 'uint8_t'),
+    ('s8', 'int8_t'),
+    ('u16', 'uint16_t'),
+    ('s16', 'int16_t'),
+    ('u32', 'uint32_t'),
+    ('s32', 'int32_t'),
+    ('u64', 'uint64_t'),
+    ('s64', 'int64_t'),
+    ('f32', 'float'),
+    ('f64', 'double'),
+    ('c32', 'std::complex<float>'),
+    ('c64', 'std::complex<double>')
+    )
+
+header = """\
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+"""
+
+guard_tail = """
+#endif
+"""
+
+includes = """
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+#include <gruel/pmt.h>
+#include "pmt_int.h"
+"""
+
+qa_includes = """
+#include <qa_pmt_unv.h>
+#include <cppunit/TestAssert.h>
+#include <gruel/pmt.h>
+#include <stdio.h>
+
+using namespace pmt;
+"""
+
+
+# set srcdir to the directory that contains Makefile.am
+try:
+    srcdir = os.environ['srcdir']
+except KeyError, e:
+    srcdir = "."
+srcdir = srcdir + '/'
+
+
+def open_src (name, mode):
+    global srcdir
+    return open(os.path.join (srcdir, name), mode)
+
+
+def guard_name(filename):
+    return 'INCLUDED_' + re.sub('\.', '_', filename.upper())
+
+def guard_head(filename):
+    guard = guard_name(filename)
+    return """
+#ifndef %s
+#define %s
+""" % (guard, guard)
+
+
+def do_substitution (d, input, out_file):
+    def repl (match_obj):
+        key = match_obj.group (1)
+        # print key
+        return d[key]
+    
+    out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, input)
+    out_file.write (out)
+
+
+def generate_h():
+    template = open_src('unv_template.h.t', 'r').read()
+    output_filename = 'pmt_unv_int.h'
+    output = open(output_filename, 'w')
+    output.write(header)
+    output.write(guard_head(output_filename))
+    for tag, typ in unv_types:
+        d = { 'TAG' : tag, 'TYPE' : typ }
+        do_substitution(d, template, output)
+    output.write(guard_tail)
+
+def generate_cc():
+    template = open_src('unv_template.cc.t', 'r').read()
+    output = open('pmt_unv.cc', 'w')
+    output.write(header)
+    output.write(includes)
+    for tag, typ in unv_types:
+        d = { 'TAG' : tag, 'TYPE' : typ }
+        do_substitution(d, template, output)
+
+
+def generate_qa_h():
+    output_filename = 'qa_pmt_unv.h'
+    output = open(output_filename, 'w')
+    output.write(header)
+    output.write(guard_head(output_filename))
+
+    output.write('''
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_pmt_unv : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_pmt_unv);
+''')
+    for tag, typ in unv_types:
+        output.write('  CPPUNIT_TEST(test_%svector);\n' % (tag,))
+    output.write('''\
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+''')     
+    for tag, typ in unv_types:
+        output.write('  void test_%svector();\n' % (tag,))
+    output.write('};\n')
+    output.write(guard_tail)
+
+def generate_qa_cc():
+    template = open_src('unv_qa_template.cc.t', 'r').read()
+    output = open('qa_pmt_unv.cc', 'w')
+    output.write(header)
+    output.write(qa_includes)
+    for tag, typ in unv_types:
+        d = { 'TAG' : tag, 'TYPE' : typ }
+        do_substitution(d, template, output)
+    
+
+def main():
+    generate_h()
+    generate_cc()
+    generate_qa_h()
+    generate_qa_cc()
+
+if __name__ == '__main__':
+    main()
diff --git a/gruel/src/lib/pmt/pmt.cc b/gruel/src/lib/pmt/pmt.cc
new file mode 100644 (file)
index 0000000..aa1688d
--- /dev/null
@@ -0,0 +1,1339 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+#include <gruel/pmt.h>
+#include "pmt_int.h"
+#include <gruel/msg_accepter.h>
+#include <gruel/pmt_pool.h>
+#include <stdio.h>
+#include <string.h>
+
+namespace pmt {
+
+static const int CACHE_LINE_SIZE = 64;         // good guess
+
+# if (PMT_LOCAL_ALLOCATOR)
+
+static pmt_pool global_pmt_pool(sizeof(pmt_pair), CACHE_LINE_SIZE);
+
+void *
+pmt_base::operator new(size_t size)
+{
+  void *p = global_pmt_pool.malloc();
+
+  // fprintf(stderr, "pmt_base::new p = %p\n", p);
+  assert((reinterpret_cast<intptr_t>(p) & (CACHE_LINE_SIZE - 1)) == 0);
+  return p;
+}
+
+void
+pmt_base::operator delete(void *p, size_t size)
+{
+  global_pmt_pool.free(p);
+}
+
+#endif
+
+void intrusive_ptr_add_ref(pmt_base* p) { ++(p->count_); }
+void intrusive_ptr_release(pmt_base* p) { if (--(p->count_) == 0 ) delete p; }
+
+pmt_base::~pmt_base()
+{
+  // nop -- out of line virtual destructor
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                         Exceptions
+////////////////////////////////////////////////////////////////////////////
+
+pmt_exception::pmt_exception(const std::string &msg, pmt_t obj)
+  : logic_error(msg + ": " + pmt_write_string(obj))
+{
+}
+
+pmt_wrong_type::pmt_wrong_type(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": wrong_type ", obj)
+{
+}
+
+pmt_out_of_range::pmt_out_of_range(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": out of range ", obj)
+{
+}
+
+pmt_notimplemented::pmt_notimplemented(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": notimplemented ", obj)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                          Dynamic Casts
+////////////////////////////////////////////////////////////////////////////
+
+static pmt_symbol *
+_symbol(pmt_t x)
+{
+  return dynamic_cast<pmt_symbol*>(x.get());
+}
+
+static pmt_integer *
+_integer(pmt_t x)
+{
+  return dynamic_cast<pmt_integer*>(x.get());
+}
+
+static pmt_real *
+_real(pmt_t x)
+{
+  return dynamic_cast<pmt_real*>(x.get());
+}
+
+static pmt_complex *
+_complex(pmt_t x)
+{
+  return dynamic_cast<pmt_complex*>(x.get());
+}
+
+static pmt_pair *
+_pair(pmt_t x)
+{
+  return dynamic_cast<pmt_pair*>(x.get());
+}
+
+static pmt_vector *
+_vector(pmt_t x)
+{
+  return dynamic_cast<pmt_vector*>(x.get());
+}
+
+static pmt_tuple *
+_tuple(pmt_t x)
+{
+  return dynamic_cast<pmt_tuple*>(x.get());
+}
+
+static pmt_uniform_vector *
+_uniform_vector(pmt_t x)
+{
+  return dynamic_cast<pmt_uniform_vector*>(x.get());
+}
+
+static pmt_any *
+_any(pmt_t x)
+{
+  return dynamic_cast<pmt_any*>(x.get());
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                           Globals
+////////////////////////////////////////////////////////////////////////////
+
+const pmt_t PMT_T = pmt_t(new pmt_bool());             // singleton
+const pmt_t PMT_F = pmt_t(new pmt_bool());             // singleton
+const pmt_t PMT_NIL = pmt_t(new pmt_null());           // singleton
+const pmt_t PMT_EOF = pmt_cons(PMT_NIL, PMT_NIL);      // singleton
+
+////////////////////////////////////////////////////////////////////////////
+//                           Booleans
+////////////////////////////////////////////////////////////////////////////
+
+pmt_bool::pmt_bool(){}
+
+bool
+pmt_is_true(pmt_t obj)
+{
+  return obj != PMT_F;
+}
+
+bool
+pmt_is_false(pmt_t obj)
+{
+  return obj == PMT_F;
+}
+
+bool
+pmt_is_bool(pmt_t obj)
+{
+  return obj->is_bool();
+}
+
+pmt_t
+pmt_from_bool(bool val)
+{
+  return val ? PMT_T : PMT_F;
+}
+
+bool
+pmt_to_bool(pmt_t val)
+{
+  if (val == PMT_T)
+    return true;
+  if (val == PMT_F)
+    return false;
+  throw pmt_wrong_type("pmt_to_bool", val);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                             Symbols
+////////////////////////////////////////////////////////////////////////////
+
+static const unsigned int SYMBOL_HASH_TABLE_SIZE = 701;
+static std::vector<pmt_t> s_symbol_hash_table(SYMBOL_HASH_TABLE_SIZE);
+
+pmt_symbol::pmt_symbol(const std::string &name) : d_name(name){}
+
+
+static unsigned int
+hash_string(const std::string &s)
+{
+  unsigned int h = 0;
+  unsigned int g = 0;
+
+  for (std::string::const_iterator p = s.begin(); p != s.end(); ++p){
+    h = (h << 4) + (*p & 0xff);
+    g = h & 0xf0000000;
+    if (g){
+      h = h ^ (g >> 24);
+      h = h ^ g;
+    }
+  }
+  return h;
+}
+
+bool 
+pmt_is_symbol(const pmt_t& obj)
+{
+  return obj->is_symbol();
+}
+
+pmt_t 
+pmt_string_to_symbol(const std::string &name)
+{
+  unsigned hash = hash_string(name) % SYMBOL_HASH_TABLE_SIZE;
+
+  // Does a symbol with this name already exist?
+  for (pmt_t sym = s_symbol_hash_table[hash]; sym; sym = _symbol(sym)->next()){
+    if (name == _symbol(sym)->name())
+      return sym;              // Yes.  Return it
+  }
+
+  // Nope.  Make a new one.
+  pmt_t sym = pmt_t(new pmt_symbol(name));
+  _symbol(sym)->set_next(s_symbol_hash_table[hash]);
+  s_symbol_hash_table[hash] = sym;
+  return sym;
+}
+
+// alias...
+pmt_t
+pmt_intern(const std::string &name)
+{
+  return pmt_string_to_symbol(name);
+}
+
+const std::string
+pmt_symbol_to_string(const pmt_t& sym)
+{
+  if (!sym->is_symbol())
+    throw pmt_wrong_type("pmt_symbol_to_string", sym);
+
+  return _symbol(sym)->name();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+//                             Number
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_is_number(pmt_t x)
+{
+  return x->is_number();
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                             Integer
+////////////////////////////////////////////////////////////////////////////
+
+pmt_integer::pmt_integer(long value) : d_value(value) {}
+
+bool
+pmt_is_integer(pmt_t x)
+{
+  return x->is_integer();
+}
+
+
+pmt_t
+pmt_from_long(long x)
+{
+  return pmt_t(new pmt_integer(x));
+}
+
+long
+pmt_to_long(pmt_t x)
+{
+  pmt_integer* i = dynamic_cast<pmt_integer*>(x.get());
+  if ( i )
+    return i->value();
+
+  throw pmt_wrong_type("pmt_to_long", x);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                              Real
+////////////////////////////////////////////////////////////////////////////
+
+pmt_real::pmt_real(double value) : d_value(value) {}
+
+bool 
+pmt_is_real(pmt_t x)
+{
+  return x->is_real();
+}
+
+pmt_t
+pmt_from_double(double x)
+{
+  return pmt_t(new pmt_real(x));
+}
+
+double
+pmt_to_double(pmt_t x)
+{
+  if (x->is_real())
+    return _real(x)->value();
+  if (x->is_integer())
+    return _integer(x)->value();
+
+  throw pmt_wrong_type("pmt_to_double", x);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                              Complex
+////////////////////////////////////////////////////////////////////////////
+
+pmt_complex::pmt_complex(std::complex<double> value) : d_value(value) {}
+
+bool 
+pmt_is_complex(pmt_t x)
+{
+  return x->is_complex();
+}
+
+pmt_t
+pmt_make_rectangular(double re, double im)
+{
+  return pmt_t(new pmt_complex(std::complex<double>(re, im)));
+}
+
+std::complex<double>
+pmt_to_complex(pmt_t x)
+{
+  if (x->is_complex())
+    return _complex(x)->value();
+  if (x->is_real())
+    return _real(x)->value();
+  if (x->is_integer())
+    return _integer(x)->value();
+
+  throw pmt_wrong_type("pmt_to_complex", x);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                              Pairs
+////////////////////////////////////////////////////////////////////////////
+
+pmt_null::pmt_null() {}
+pmt_pair::pmt_pair(const pmt_t& car, const pmt_t& cdr) : d_car(car), d_cdr(cdr) {}
+
+bool
+pmt_is_null(const pmt_t& x)
+{
+  return x == PMT_NIL;
+}
+
+bool
+pmt_is_pair(const pmt_t& obj)
+{
+  return obj->is_pair();
+}
+
+pmt_t
+pmt_cons(const pmt_t& x, const pmt_t& y)
+{
+  return pmt_t(new pmt_pair(x, y));
+}
+
+pmt_t
+pmt_car(const pmt_t& pair)
+{
+  pmt_pair* p = dynamic_cast<pmt_pair*>(pair.get());
+  if ( p )
+    return p->car();
+  
+  throw pmt_wrong_type("pmt_car", pair);
+}
+
+pmt_t
+pmt_cdr(const pmt_t& pair)
+{
+  pmt_pair* p = dynamic_cast<pmt_pair*>(pair.get());
+  if ( p )
+    return p->cdr();
+  
+  throw pmt_wrong_type("pmt_cdr", pair);
+}
+
+void
+pmt_set_car(pmt_t pair, pmt_t obj)
+{
+  if (pair->is_pair())
+    _pair(pair)->set_car(obj);
+  else
+    throw pmt_wrong_type("pmt_set_car", pair);
+}
+
+void
+pmt_set_cdr(pmt_t pair, pmt_t obj)
+{
+  if (pair->is_pair())
+    _pair(pair)->set_cdr(obj);
+  else
+    throw pmt_wrong_type("pmt_set_cdr", pair);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                             Vectors
+////////////////////////////////////////////////////////////////////////////
+
+pmt_vector::pmt_vector(size_t len, pmt_t fill)
+  : d_v(len)
+{
+  for (size_t i = 0; i < len; i++)
+    d_v[i] = fill;
+}
+
+pmt_t
+pmt_vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_vector_ref", pmt_from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_vector::set(size_t k, pmt_t obj)
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_vector_set", pmt_from_long(k));
+  d_v[k] = obj;
+}
+
+void
+pmt_vector::fill(pmt_t obj)
+{
+  for (size_t i = 0; i < length(); i++)
+    d_v[i] = obj;
+}
+
+bool
+pmt_is_vector(pmt_t obj)
+{
+  return obj->is_vector();
+}
+
+pmt_t
+pmt_make_vector(size_t k, pmt_t fill)
+{
+  return pmt_t(new pmt_vector(k, fill));
+}
+
+pmt_t
+pmt_vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_vector())
+    throw pmt_wrong_type("pmt_vector_ref", vector);
+  return _vector(vector)->ref(k);
+}
+
+void
+pmt_vector_set(pmt_t vector, size_t k, pmt_t obj)
+{
+  if (!vector->is_vector())
+    throw pmt_wrong_type("pmt_vector_set", vector);
+  _vector(vector)->set(k, obj);
+}
+
+void
+pmt_vector_fill(pmt_t vector, pmt_t obj)
+{
+  if (!vector->is_vector())
+    throw pmt_wrong_type("pmt_vector_set", vector);
+  _vector(vector)->fill(obj);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                             Tuples
+////////////////////////////////////////////////////////////////////////////
+
+pmt_tuple::pmt_tuple(size_t len)
+  : d_v(len)
+{
+}
+
+pmt_t
+pmt_tuple::ref(size_t k) const
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_tuple_ref", pmt_from_long(k));
+  return d_v[k];
+}
+
+bool
+pmt_is_tuple(pmt_t obj)
+{
+  return obj->is_tuple();
+}
+
+pmt_t
+pmt_tuple_ref(const pmt_t &tuple, size_t k)
+{
+  if (!tuple->is_tuple())
+    throw pmt_wrong_type("pmt_tuple_ref", tuple);
+  return _tuple(tuple)->ref(k);
+}
+
+// for (i=0; i < 10; i++)
+//   make_constructor()
+
+pmt_t
+pmt_make_tuple()
+{
+  return pmt_t(new pmt_tuple(0));
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0)
+{
+  pmt_tuple *t = new pmt_tuple(1);
+  t->_set(0, e0);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1)
+{
+  pmt_tuple *t = new pmt_tuple(2);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2)
+{
+  pmt_tuple *t = new pmt_tuple(3);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3)
+{
+  pmt_tuple *t = new pmt_tuple(4);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4)
+{
+  pmt_tuple *t = new pmt_tuple(5);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5)
+{
+  pmt_tuple *t = new pmt_tuple(6);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6)
+{
+  pmt_tuple *t = new pmt_tuple(7);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7)
+{
+  pmt_tuple *t = new pmt_tuple(8);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8)
+{
+  pmt_tuple *t = new pmt_tuple(9);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  t->_set(8, e8);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9)
+{
+  pmt_tuple *t = new pmt_tuple(10);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  t->_set(8, e8);
+  t->_set(9, e9);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_to_tuple(const pmt_t &x)
+{
+  if (x->is_tuple())           // already one
+    return x;
+
+  size_t len = pmt_length(x);
+  pmt_tuple *t = new pmt_tuple(len);
+  pmt_t r = pmt_t(t);
+
+  if (x->is_vector()){
+    for (size_t i = 0; i < len; i++)
+      t->_set(i, _vector(x)->ref(i));
+    return r;
+  }
+
+  if (x->is_pair()){
+    pmt_t y = x;
+    for (size_t i = 0; i < len; i++){
+      t->_set(i, pmt_car(y));
+      y = pmt_cdr(y);
+    }
+    return r;
+  }
+
+  throw pmt_wrong_type("pmt_to_tuple", x);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+//                       Uniform Numeric Vectors
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_is_uniform_vector(pmt_t x)
+{
+  return x->is_uniform_vector();
+}
+
+const void *
+pmt_uniform_vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_uniform_vector())
+    throw pmt_wrong_type("pmt_uniform_vector_elements", vector);
+  return _uniform_vector(vector)->uniform_elements(len);
+}
+
+void *
+pmt_uniform_vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_uniform_vector())
+    throw pmt_wrong_type("pmt_uniform_vector_writable_elements", vector);
+  return _uniform_vector(vector)->uniform_writable_elements(len);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                            Dictionaries
+////////////////////////////////////////////////////////////////////////////
+
+/*
+ * This is an a-list implementation.
+ *
+ * When we need better performance for large dictionaries, consider implementing
+ * persistent Red-Black trees as described in "Purely Functional Data Structures", 
+ * Chris Okasaki, 1998, section 3.3.
+ */
+
+bool
+pmt_is_dict(const pmt_t &obj)
+{
+  return pmt_is_null(obj) || pmt_is_pair(obj);
+}
+
+pmt_t
+pmt_make_dict()
+{
+  return PMT_NIL;
+}
+
+pmt_t
+pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value)
+{
+  if (pmt_is_null(dict))
+    return pmt_acons(key, value, PMT_NIL);
+
+  if (pmt_dict_has_key(dict, key))
+    return pmt_acons(key, value, pmt_dict_delete(dict, key));
+
+  return pmt_acons(key, value, dict);
+}
+
+pmt_t
+pmt_dict_delete(const pmt_t &dict, const pmt_t &key)
+{
+  if (pmt_is_null(dict))
+    return dict;
+
+  if (pmt_eqv(pmt_caar(dict), key))
+    return pmt_cdr(dict);
+  
+  return pmt_cons(pmt_car(dict), pmt_dict_delete(pmt_cdr(dict), key));
+}
+
+pmt_t
+pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found)
+{
+  pmt_t        p = pmt_assv(key, dict);        // look for (key . value) pair
+  if (pmt_is_pair(p))
+    return pmt_cdr(p);
+  else
+    return not_found;
+}
+
+bool
+pmt_dict_has_key(const pmt_t &dict, const pmt_t &key)
+{
+  return pmt_is_pair(pmt_assv(key, dict));
+}
+
+pmt_t
+pmt_dict_items(pmt_t dict)
+{
+  if (!pmt_is_dict(dict))
+    throw pmt_wrong_type("pmt_dict_values", dict);
+
+  return dict;         // equivalent to dict in the a-list case
+}
+
+pmt_t
+pmt_dict_keys(pmt_t dict)
+{
+  if (!pmt_is_dict(dict))
+    throw pmt_wrong_type("pmt_dict_keys", dict);
+
+  return pmt_map(pmt_car, dict);
+}
+
+pmt_t
+pmt_dict_values(pmt_t dict)
+{
+  if (!pmt_is_dict(dict))
+    throw pmt_wrong_type("pmt_dict_keys", dict);
+
+  return pmt_map(pmt_cdr, dict);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                                 Any
+////////////////////////////////////////////////////////////////////////////
+
+pmt_any::pmt_any(const boost::any &any) : d_any(any) {}
+
+bool
+pmt_is_any(pmt_t obj)
+{
+  return obj->is_any();
+}
+
+pmt_t
+pmt_make_any(const boost::any &any)
+{
+  return pmt_t(new pmt_any(any));
+}
+
+boost::any
+pmt_any_ref(pmt_t obj)
+{
+  if (!obj->is_any())
+    throw pmt_wrong_type("pmt_any_ref", obj);
+  return _any(obj)->ref();
+}
+
+void
+pmt_any_set(pmt_t obj, const boost::any &any)
+{
+  if (!obj->is_any())
+    throw pmt_wrong_type("pmt_any_set", obj);
+  _any(obj)->set(any);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//               msg_accepter -- built from "any"
+////////////////////////////////////////////////////////////////////////////
+
+bool 
+pmt_is_msg_accepter(const pmt_t &obj)
+{
+  if (!pmt_is_any(obj))
+    return false;
+
+  boost::any r = pmt_any_ref(obj);
+  return boost::any_cast<gruel::msg_accepter_sptr>(&r) != 0;
+}
+
+//! make a msg_accepter
+pmt_t
+pmt_make_msg_accepter(gruel::msg_accepter_sptr ma)
+{
+  return pmt_make_any(ma);
+}
+
+//! Return underlying msg_accepter
+gruel::msg_accepter_sptr
+pmt_msg_accepter_ref(const pmt_t &obj)
+{
+  try {
+    return boost::any_cast<gruel::msg_accepter_sptr>(pmt_any_ref(obj));
+  }
+  catch (boost::bad_any_cast &e){
+    throw pmt_wrong_type("pmt_msg_accepter_ref", obj);
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//             Binary Large Object -- currently a u8vector
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_is_blob(pmt_t x)
+{
+  // return pmt_is_u8vector(x);
+  return pmt_is_uniform_vector(x);
+}
+
+pmt_t
+pmt_make_blob(const void *buf, size_t len_in_bytes)
+{
+  return pmt_init_u8vector(len_in_bytes, (const uint8_t *) buf);
+}
+
+const void *
+pmt_blob_data(pmt_t blob)
+{
+  size_t len;
+  return pmt_uniform_vector_elements(blob, len);
+}
+
+size_t
+pmt_blob_length(pmt_t blob)
+{
+  size_t len;
+  pmt_uniform_vector_elements(blob, len);
+  return len;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//                          General Functions
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_eq(const pmt_t& x, const pmt_t& y)
+{
+  return x == y;
+}
+
+bool
+pmt_eqv(const pmt_t& x, const pmt_t& y)
+{
+  if (x == y)
+    return true;
+
+  if (x->is_integer() && y->is_integer())
+    return _integer(x)->value() == _integer(y)->value();
+
+  if (x->is_real() && y->is_real())
+    return _real(x)->value() == _real(y)->value();
+
+  if (x->is_complex() && y->is_complex())
+    return _complex(x)->value() == _complex(y)->value();
+
+  return false;
+}
+
+bool
+pmt_eqv_raw(pmt_base *x, pmt_base *y)
+{
+  if (x == y)
+    return true;
+
+  if (x->is_integer() && y->is_integer())
+    return _integer(x)->value() == _integer(y)->value();
+
+  if (x->is_real() && y->is_real())
+    return _real(x)->value() == _real(y)->value();
+
+  if (x->is_complex() && y->is_complex())
+    return _complex(x)->value() == _complex(y)->value();
+
+  return false;
+}
+
+bool
+pmt_equal(const pmt_t& x, const pmt_t& y)
+{
+  if (pmt_eqv(x, y))
+    return true;
+
+  if (x->is_pair() && y->is_pair())
+    return pmt_equal(pmt_car(x), pmt_car(y)) && pmt_equal(pmt_cdr(x), pmt_cdr(y));
+
+  if (x->is_vector() && y->is_vector()){
+    pmt_vector *xv = _vector(x);
+    pmt_vector *yv = _vector(y);
+    if (xv->length() != yv->length())
+      return false;
+
+    for (unsigned i = 0; i < xv->length(); i++)
+      if (!pmt_equal(xv->_ref(i), yv->_ref(i)))
+       return false;
+
+    return true;
+  }
+
+  if (x->is_tuple() && y->is_tuple()){
+    pmt_tuple *xv = _tuple(x);
+    pmt_tuple *yv = _tuple(y);
+    if (xv->length() != yv->length())
+      return false;
+
+    for (unsigned i = 0; i < xv->length(); i++)
+      if (!pmt_equal(xv->_ref(i), yv->_ref(i)))
+       return false;
+
+    return true;
+  }
+
+  if (x->is_uniform_vector() && y->is_uniform_vector()){
+    pmt_uniform_vector *xv = _uniform_vector(x);
+    pmt_uniform_vector *yv = _uniform_vector(y);
+    if (xv->length() != yv->length())
+      return false;
+
+    size_t len_x, len_y;
+    if (memcmp(xv->uniform_elements(len_x),
+              yv->uniform_elements(len_y),
+              len_x) == 0)
+      return true;
+
+    return true;
+  }
+
+  // FIXME add other cases here...
+
+  return false;
+}
+
+size_t
+pmt_length(const pmt_t& x)
+{
+  if (x->is_vector())
+    return _vector(x)->length();
+
+  if (x->is_uniform_vector())
+    return _uniform_vector(x)->length();
+
+  if (x->is_tuple())
+    return _tuple(x)->length();
+
+  if (x->is_null())
+    return 0;
+
+  if (x->is_pair()) {
+    size_t length=1;
+    pmt_t it = pmt_cdr(x);
+    while (pmt_is_pair(it)){
+      length++;
+      it = pmt_cdr(it);
+    }
+    if (pmt_is_null(it))
+      return length;
+
+    // not a proper list
+    throw pmt_wrong_type("pmt_length", x);
+  }
+
+  // FIXME dictionary length (number of entries)
+
+  throw pmt_wrong_type("pmt_length", x);
+}
+
+pmt_t
+pmt_assq(pmt_t obj, pmt_t alist)
+{
+  while (pmt_is_pair(alist)){
+    pmt_t p = pmt_car(alist);
+    if (!pmt_is_pair(p))       // malformed alist
+      return PMT_F;
+
+    if (pmt_eq(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_F;
+}
+
+/*
+ * This avoids a bunch of shared_pointer reference count manipulation.
+ */
+pmt_t
+pmt_assv_raw(pmt_base *obj, pmt_base *alist)
+{
+  while (alist->is_pair()){
+    pmt_base *p = ((pmt_pair *)alist)->d_car.get();
+    if (!p->is_pair())         // malformed alist
+      return PMT_F;
+
+    if (pmt_eqv_raw(obj, ((pmt_pair *)p)->d_car.get()))
+      return ((pmt_pair *)alist)->d_car;
+
+    alist = (((pmt_pair *)alist)->d_cdr).get();
+  }
+  return PMT_F;
+}
+
+#if 1
+
+pmt_t
+pmt_assv(pmt_t obj, pmt_t alist)
+{
+  return pmt_assv_raw(obj.get(), alist.get());
+}
+
+#else
+
+pmt_t
+pmt_assv(pmt_t obj, pmt_t alist)
+{
+  while (pmt_is_pair(alist)){
+    pmt_t p = pmt_car(alist);
+    if (!pmt_is_pair(p))       // malformed alist
+      return PMT_F;
+
+    if (pmt_eqv(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_F;
+}
+
+#endif
+
+
+pmt_t
+pmt_assoc(pmt_t obj, pmt_t alist)
+{
+  while (pmt_is_pair(alist)){
+    pmt_t p = pmt_car(alist);
+    if (!pmt_is_pair(p))       // malformed alist
+      return PMT_F;
+
+    if (pmt_equal(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_F;
+}
+
+pmt_t
+pmt_map(pmt_t proc(const pmt_t&), pmt_t list)
+{
+  pmt_t r = PMT_NIL;
+
+  while(pmt_is_pair(list)){
+    r = pmt_cons(proc(pmt_car(list)), r);
+    list = pmt_cdr(list);
+  }
+
+  return pmt_reverse_x(r);
+}
+
+pmt_t
+pmt_reverse(pmt_t listx)
+{
+  pmt_t list = listx;
+  pmt_t r = PMT_NIL;
+
+  while(pmt_is_pair(list)){
+    r = pmt_cons(pmt_car(list), r);
+    list = pmt_cdr(list);
+  }
+  if (pmt_is_null(list))
+    return r;
+  else
+    throw pmt_wrong_type("pmt_reverse", listx);
+}
+
+pmt_t
+pmt_reverse_x(pmt_t list)
+{
+  // FIXME do it destructively
+  return pmt_reverse(list);
+}
+
+pmt_t
+pmt_nth(size_t n, pmt_t list)
+{
+  pmt_t t = pmt_nthcdr(n, list);
+  if (pmt_is_pair(t))
+    return pmt_car(t);
+  else
+    return PMT_NIL;
+}
+
+pmt_t
+pmt_nthcdr(size_t n, pmt_t list)
+{
+  if (!(pmt_is_pair(list) || pmt_is_null(list)))
+    throw pmt_wrong_type("pmt_nthcdr", list);
+    
+  while (n > 0){
+    if (pmt_is_pair(list)){
+      list = pmt_cdr(list);
+      n--;
+      continue;
+    }
+    if (pmt_is_null(list))
+      return PMT_NIL;
+    else
+      throw pmt_wrong_type("pmt_nthcdr: not a LIST", list);
+  }
+  return list;
+}
+
+pmt_t
+pmt_memq(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_eq(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_F;
+}
+
+pmt_t
+pmt_memv(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_eqv(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_F;
+}
+
+pmt_t
+pmt_member(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_equal(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_F;
+}
+
+bool
+pmt_subsetp(pmt_t list1, pmt_t list2)
+{
+  while (pmt_is_pair(list1)){
+    pmt_t p = pmt_car(list1);
+    if (pmt_is_false(pmt_memv(p, list2)))
+      return false;
+    list1 = pmt_cdr(list1);
+  }
+  return true;
+}
+
+pmt_t
+pmt_list1(const pmt_t& x1)
+{
+  return pmt_cons(x1, PMT_NIL);
+}
+
+pmt_t
+pmt_list2(const pmt_t& x1, const pmt_t& x2)
+{
+  return pmt_cons(x1, pmt_cons(x2, PMT_NIL));
+}
+
+pmt_t
+pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, PMT_NIL)));
+}
+
+pmt_t
+pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, PMT_NIL))));
+}
+
+pmt_t
+pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, PMT_NIL)))));
+}
+
+pmt_t
+pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, pmt_cons(x6, PMT_NIL))))));
+}
+
+pmt_t
+pmt_list_add(pmt_t list, const pmt_t& item)
+{
+  return pmt_reverse(pmt_cons(item, pmt_reverse(list)));
+}
+
+pmt_t
+pmt_caar(pmt_t pair)
+{
+  return (pmt_car(pmt_car(pair)));
+}
+
+pmt_t
+pmt_cadr(pmt_t pair)
+{
+  return pmt_car(pmt_cdr(pair));
+}
+
+pmt_t
+pmt_cdar(pmt_t pair)
+{
+  return pmt_cdr(pmt_car(pair));
+}
+
+pmt_t
+pmt_cddr(pmt_t pair)
+{
+  return pmt_cdr(pmt_cdr(pair));
+}
+
+pmt_t
+pmt_caddr(pmt_t pair)
+{
+  return pmt_car(pmt_cdr(pmt_cdr(pair)));
+}
+
+pmt_t
+pmt_cadddr(pmt_t pair)
+{
+  return pmt_car(pmt_cdr(pmt_cdr(pmt_cdr(pair))));
+}
+  
+bool
+pmt_is_eof_object(pmt_t obj)
+{
+  return pmt_eq(obj, PMT_EOF);
+}
+
+void
+pmt_dump_sizeof()
+{
+  printf("sizeof(pmt_t)              = %3zd\n", sizeof(pmt_t));
+  printf("sizeof(pmt_base)           = %3zd\n", sizeof(pmt_base));
+  printf("sizeof(pmt_bool)           = %3zd\n", sizeof(pmt_bool));
+  printf("sizeof(pmt_symbol)         = %3zd\n", sizeof(pmt_symbol));
+  printf("sizeof(pmt_integer)        = %3zd\n", sizeof(pmt_integer));
+  printf("sizeof(pmt_real)           = %3zd\n", sizeof(pmt_real));
+  printf("sizeof(pmt_complex)        = %3zd\n", sizeof(pmt_complex));
+  printf("sizeof(pmt_null)           = %3zd\n", sizeof(pmt_null));
+  printf("sizeof(pmt_pair)           = %3zd\n", sizeof(pmt_pair));
+  printf("sizeof(pmt_vector)         = %3zd\n", sizeof(pmt_vector));
+  printf("sizeof(pmt_uniform_vector) = %3zd\n", sizeof(pmt_uniform_vector));
+}
+
+} /* namespace pmt */
diff --git a/gruel/src/lib/pmt/pmt_int.h b/gruel/src/lib/pmt/pmt_int.h
new file mode 100644 (file)
index 0000000..50683ff
--- /dev/null
@@ -0,0 +1,233 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+#ifndef INCLUDED_PMT_INT_H
+#define INCLUDED_PMT_INT_H
+
+#include <gruel/pmt.h>
+#include <boost/utility.hpp>
+#include <boost/detail/atomic_count.hpp>
+
+/*
+ * EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION!
+ *
+ * See pmt.h for the public interface
+ */
+
+#define PMT_LOCAL_ALLOCATOR 0          // define to 0 or 1
+namespace pmt {
+
+class pmt_base : boost::noncopyable {
+  mutable boost::detail::atomic_count count_;
+
+protected:
+  pmt_base() : count_(0) {};
+  virtual ~pmt_base();
+
+public:
+  virtual bool is_bool()    const { return false; }
+  virtual bool is_symbol()  const { return false; }
+  virtual bool is_number()  const { return false; }
+  virtual bool is_integer() const { return false; }
+  virtual bool is_real()    const { return false; }
+  virtual bool is_complex() const { return false; }
+  virtual bool is_null()    const { return false; }
+  virtual bool is_pair()    const { return false; }
+  virtual bool is_tuple()   const { return false; }
+  virtual bool is_vector()  const { return false; }
+  virtual bool is_dict()    const { return false; }
+  virtual bool is_any()     const { return false; }
+
+  virtual bool is_uniform_vector() const { return false; }
+  virtual bool is_u8vector()  const { return false; }
+  virtual bool is_s8vector()  const { return false; }
+  virtual bool is_u16vector() const { return false; }
+  virtual bool is_s16vector() const { return false; }
+  virtual bool is_u32vector() const { return false; }
+  virtual bool is_s32vector() const { return false; }
+  virtual bool is_u64vector() const { return false; }
+  virtual bool is_s64vector() const { return false; }
+  virtual bool is_f32vector() const { return false; }
+  virtual bool is_f64vector() const { return false; }
+  virtual bool is_c32vector() const { return false; }
+  virtual bool is_c64vector() const { return false; }
+
+  friend void intrusive_ptr_add_ref(pmt_base* p);
+  friend void intrusive_ptr_release(pmt_base* p);
+
+# if (PMT_LOCAL_ALLOCATOR)
+  void *operator new(size_t);
+  void operator delete(void *, size_t);
+#endif
+};
+
+class pmt_bool : public pmt_base
+{
+public:
+  pmt_bool();
+  //~pmt_bool(){}
+
+  bool is_bool() const { return true; }
+};
+
+
+class pmt_symbol : public pmt_base
+{
+  std::string  d_name;
+  pmt_t                d_next;
+  
+public:
+  pmt_symbol(const std::string &name);
+  //~pmt_symbol(){}
+
+  bool is_symbol() const { return true; }
+  const std::string name() { return d_name; }
+
+  pmt_t next() { return d_next; }              // symbol table link
+  void set_next(pmt_t next) { d_next = next; }
+};
+
+class pmt_integer : public pmt_base
+{
+public:
+  long         d_value;
+
+  pmt_integer(long value);
+  //~pmt_integer(){}
+
+  bool is_number()  const { return true; }
+  bool is_integer() const { return true; }
+  long value() const { return d_value; }
+};
+
+class pmt_real : public pmt_base
+{
+public:
+  double       d_value;
+
+  pmt_real(double value);
+  //~pmt_real(){}
+
+  bool is_number()  const { return true; }
+  bool is_real() const { return true; }
+  double value() const { return d_value; }
+};
+
+class pmt_complex : public pmt_base
+{
+public:
+  std::complex<double> d_value;
+
+  pmt_complex(std::complex<double> value);
+  //~pmt_complex(){}
+
+  bool is_number()  const { return true; }
+  bool is_complex() const { return true; }
+  std::complex<double> value() const { return d_value; }
+};
+
+class pmt_null  : public pmt_base
+{
+public:
+  pmt_null();
+  //~pmt_null(){}
+
+  bool is_null() const { return true; }
+};
+
+class pmt_pair : public pmt_base
+{
+public:
+  pmt_t                d_car;
+  pmt_t                d_cdr;
+
+  pmt_pair(const pmt_t& car, const pmt_t& cdr);
+  //~pmt_pair(){};
+
+  bool is_pair() const { return true; }
+  pmt_t car() const { return d_car; }
+  pmt_t cdr() const { return d_cdr; }
+
+  void set_car(pmt_t car) { d_car = car; }
+  void set_cdr(pmt_t cdr) { d_cdr = cdr; }
+};
+
+class pmt_vector : public pmt_base
+{
+  std::vector<pmt_t>   d_v;
+
+public:
+  pmt_vector(size_t len, pmt_t fill);
+  //~pmt_vector();
+
+  bool is_vector() const { return true; }
+  pmt_t ref(size_t k) const;
+  void  set(size_t k, pmt_t obj);
+  void  fill(pmt_t fill);
+  size_t length() const { return d_v.size(); }
+
+  pmt_t _ref(size_t k) const { return d_v[k]; }
+};
+
+class pmt_tuple : public pmt_base
+{
+  std::vector<pmt_t>   d_v;
+
+public:
+  pmt_tuple(size_t len);
+  //~pmt_tuple();
+
+  bool is_tuple() const { return true; }
+  pmt_t ref(size_t k) const;
+  size_t length() const { return d_v.size(); }
+
+  pmt_t _ref(size_t k) const { return d_v[k]; }
+  void _set(size_t k, pmt_t v) { d_v[k] = v; }
+};
+
+class pmt_any : public pmt_base
+{
+  boost::any   d_any;
+
+public:
+  pmt_any(const boost::any &any);
+  //~pmt_any();
+
+  bool is_any() const { return true; }
+  const boost::any &ref() const { return d_any; }
+  void  set(const boost::any &any) { d_any = any; }
+};
+
+
+class pmt_uniform_vector : public pmt_base
+{
+public:
+  bool is_uniform_vector() const { return true; }
+  virtual const void *uniform_elements(size_t &len) = 0;
+  virtual void *uniform_writable_elements(size_t &len) = 0;
+  virtual size_t length() const = 0;
+};
+
+#include "pmt_unv_int.h"
+
+} /* namespace pmt */
+
+#endif /* INCLUDED_PMT_INT_H */
diff --git a/gruel/src/lib/pmt/pmt_io.cc b/gruel/src/lib/pmt/pmt_io.cc
new file mode 100644 (file)
index 0000000..179e6b7
--- /dev/null
@@ -0,0 +1,156 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+#include <gruel/pmt.h>
+#include "pmt_int.h"
+#include <sstream>
+
+namespace pmt {
+
+static void
+pmt_write_list_tail(pmt_t obj, std::ostream &port)
+{
+  pmt_write(pmt_car(obj), port); // write the car
+  obj = pmt_cdr(obj);           // step to cdr
+
+  if (pmt_is_null(obj))                 // ()
+    port << ")";
+
+  else if (pmt_is_pair(obj)){   // normal list
+    port << " ";
+    pmt_write_list_tail(obj, port);
+  }
+  else {                        // dotted pair
+    port << " . ";
+    pmt_write(obj, port);
+    port << ")";
+  }
+}
+
+void
+pmt_write(pmt_t obj, std::ostream &port)
+{
+  if (pmt_is_bool(obj)){
+    if (pmt_is_true(obj))
+      port << "#t";
+    else
+      port << "#f";
+  }
+  else if (pmt_is_symbol(obj)){
+    port << pmt_symbol_to_string(obj);
+  }
+  else if (pmt_is_number(obj)){
+    if (pmt_is_integer(obj))
+      port << pmt_to_long(obj);
+    else if (pmt_is_real(obj))
+      port << pmt_to_double(obj);
+    else if (pmt_is_complex(obj)){
+      std::complex<double> c = pmt_to_complex(obj);
+      port << c.real() << '+' << c.imag() << 'i';
+    }
+    else
+      goto error;
+  }
+  else if (pmt_is_null(obj)){
+    port << "()";
+  }
+  else if (pmt_is_pair(obj)){
+    port << "(";
+    pmt_write_list_tail(obj, port);
+  }
+  else if (pmt_is_tuple(obj)){
+    port << "{";
+    size_t len = pmt_length(obj);
+    if (len > 0){
+      port << pmt_tuple_ref(obj, 0);
+      for (size_t i = 1; i < len; i++)
+       port << " " << pmt_tuple_ref(obj, i);
+    }
+    port << "}";
+  }
+  else if (pmt_is_vector(obj)){
+    port << "#(";
+    size_t len = pmt_length(obj);
+    if (len > 0){
+      port << pmt_vector_ref(obj, 0);
+      for (size_t i = 1; i < len; i++)
+       port << " " << pmt_vector_ref(obj, i);
+    }
+    port << ")";
+  }
+  else if (pmt_is_dict(obj)){
+    // FIXME
+    // port << "#<dict " << obj << ">";
+    port << "#<dict>";
+  }
+  else if (pmt_is_uniform_vector(obj)){
+    // FIXME
+    // port << "#<uniform-vector " << obj << ">";
+    port << "#<uniform-vector>";
+  }
+  else {
+  error:
+    // FIXME
+    // port << "#<" << obj << ">";
+    port << "#<unknown>";
+  }
+}
+
+std::ostream& operator<<(std::ostream &os, pmt_t obj)
+{
+  pmt_write(obj, os);
+  return os;
+}
+
+std::string 
+pmt_write_string(pmt_t obj)
+{
+  std::ostringstream s;
+  s << obj;
+  return s.str();
+}
+
+pmt_t
+pmt_read(std::istream &port)
+{
+  throw pmt_notimplemented("notimplemented: pmt_read", PMT_NIL);
+}
+
+void
+pmt_serialize(pmt_t obj, std::ostream &sink)
+{
+  throw pmt_notimplemented("notimplemented: pmt_serialize", obj);
+}
+
+/*!
+ * \brief Create obj from portable byte-serial representation
+ */
+pmt_t 
+pmt_deserialize(std::istream &source)
+{
+  throw pmt_notimplemented("notimplemented: pmt_deserialize", PMT_NIL);
+}
+
+} /* namespace pmt */
diff --git a/gruel/src/lib/pmt/pmt_pool.cc b/gruel/src/lib/pmt/pmt_pool.cc
new file mode 100644 (file)
index 0000000..731d28c
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gruel/pmt_pool.h>
+#include <algorithm>
+#include <stdint.h>
+
+namespace pmt {
+
+static inline size_t
+ROUNDUP(size_t x, size_t stride)
+{
+  return ((((x) + (stride) - 1)/(stride)) * (stride));
+}
+
+pmt_pool::pmt_pool(size_t itemsize, size_t alignment,
+                  size_t allocation_size, size_t max_items)
+  : d_itemsize(ROUNDUP(itemsize, alignment)),
+    d_alignment(alignment),
+    d_allocation_size(std::max(allocation_size, 16 * itemsize)),
+    d_max_items(max_items), d_n_items(0),
+    d_freelist(0)
+{
+}
+
+pmt_pool::~pmt_pool()
+{
+  for (unsigned int i = 0; i < d_allocations.size(); i++){
+    delete [] d_allocations[i];
+  }
+}
+
+void *
+pmt_pool::malloc()
+{
+  scoped_lock guard(d_mutex);
+  item *p;
+
+  if (d_max_items != 0){
+    while (d_n_items >= d_max_items)
+      d_cond.wait(guard);
+  }
+
+  if (d_freelist){     // got something?
+    p = d_freelist;
+    d_freelist = p->d_next;
+    d_n_items++;
+    return p;
+  }
+
+  // allocate a new chunk
+  char *alloc = new char[d_allocation_size + d_alignment - 1];
+  d_allocations.push_back(alloc);
+
+  // get the alignment we require
+  char *start = (char *)(((uintptr_t)alloc + d_alignment-1) & -d_alignment);
+  char *end = alloc + d_allocation_size + d_alignment - 1;
+  size_t n = (end - start) / d_itemsize;
+
+  // link the new items onto the free list.
+  p = (item *) start;
+  for (size_t i = 0; i < n; i++){
+    p->d_next = d_freelist;
+    d_freelist = p;
+    p = (item *)((char *) p + d_itemsize);
+  }
+
+  // now return the first one
+  p = d_freelist;
+  d_freelist = p->d_next;
+  d_n_items++;
+  return p;
+}
+
+void
+pmt_pool::free(void *foo)
+{
+  if (!foo)
+    return;
+
+  scoped_lock guard(d_mutex);
+
+  item *p = (item *) foo;
+  p->d_next = d_freelist;
+  d_freelist = p;
+  d_n_items--;
+  if (d_max_items != 0)
+    d_cond.notify_one();
+}
+
+} /* namespace pmt */
diff --git a/gruel/src/lib/pmt/pmt_serialize.cc b/gruel/src/lib/pmt/pmt_serialize.cc
new file mode 100644 (file)
index 0000000..937423a
--- /dev/null
@@ -0,0 +1,357 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+#include <gruel/pmt.h>
+#include "pmt_int.h"
+#include "gruel/pmt_serial_tags.h"
+
+namespace pmt {
+
+static pmt_t parse_pair(std::streambuf &sb);
+
+// ----------------------------------------------------------------
+// output primitives
+// ----------------------------------------------------------------
+
+static bool
+serialize_untagged_u8(unsigned int i, std::streambuf &sb)
+{
+  return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+
+// always writes big-endian
+static bool
+serialize_untagged_u16(unsigned int i, std::streambuf &sb)
+{
+  sb.sputc((i >> 8) & 0xff);
+  return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+
+// always writes big-endian
+static bool
+serialize_untagged_u32(unsigned int i, std::streambuf &sb)
+{
+  sb.sputc((i >> 24) & 0xff);
+  sb.sputc((i >> 16) & 0xff);
+  sb.sputc((i >>  8) & 0xff);
+  return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+
+#if 0
+// always writes big-endian
+static bool
+serialize_untagged_u64(uint64_t i, std::streambuf &sb)
+{
+  sb.sputc((i >> 56) & 0xff);
+  sb.sputc((i >> 48) & 0xff);
+  sb.sputc((i >> 40) & 0xff);
+  sb.sputc((i >> 32) & 0xff);
+  sb.sputc((i >> 24) & 0xff);
+  sb.sputc((i >> 16) & 0xff);
+  sb.sputc((i >>  8) & 0xff);
+  return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+#endif
+
+// ----------------------------------------------------------------
+// input primitives
+// ----------------------------------------------------------------
+
+
+// always reads big-endian
+static bool
+deserialize_untagged_u8(uint8_t *ip, std::streambuf &sb)
+{
+  std::streambuf::traits_type::int_type  t;
+  int i;
+
+  t = sb.sbumpc();
+  i = t & 0xff;
+
+  *ip = i;
+  return t != std::streambuf::traits_type::eof();
+}
+
+// always reads big-endian
+static bool
+deserialize_untagged_u16(uint16_t *ip, std::streambuf &sb)
+{
+  std::streambuf::traits_type::int_type  t;
+  int i;
+
+  t = sb.sbumpc();
+  i = t & 0xff;
+
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+
+  *ip = i;
+  return t != std::streambuf::traits_type::eof();
+}
+
+// always reads big-endian
+static bool
+deserialize_untagged_u32(uint32_t *ip, std::streambuf &sb)
+{
+  std::streambuf::traits_type::int_type  t;
+  int i;
+
+  t = sb.sbumpc();
+  i = t & 0xff;
+
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+
+  *ip = i;
+  return t != std::streambuf::traits_type::eof();
+}
+
+#if 0
+// always reads big-endian
+static bool
+deserialize_untagged_u64(uint64_t *ip, std::streambuf &sb)
+{
+  std::streambuf::traits_type::int_type  t;
+  uint64_t i;
+
+  t = sb.sbumpc();
+  i = t & 0xff;
+
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+  t = sb.sbumpc();
+  i = (i << 8) | (t & 0xff);
+
+  *ip = i;
+  return t != std::streambuf::traits_type::eof();
+}
+#endif
+
+/*
+ * Write portable byte-serial representation of \p obj to \p sb
+ *
+ * N.B., Circular structures cause infinite recursion.
+ */
+bool
+pmt_serialize(pmt_t obj, std::streambuf &sb)
+{
+  bool ok = true;
+
+ tail_recursion:
+
+  if (pmt_is_bool(obj)){
+    if (pmt_eq(obj, PMT_T))
+      return serialize_untagged_u8(PST_TRUE, sb);
+    else
+      return serialize_untagged_u8(PST_FALSE, sb);
+  }
+  
+  if (pmt_is_null(obj))
+    return serialize_untagged_u8(PST_NULL, sb);
+
+  if (pmt_is_symbol(obj)){
+    const std::string s = pmt_symbol_to_string(obj);
+    size_t len = s.size();
+    ok = serialize_untagged_u8(PST_SYMBOL, sb);
+    ok &= serialize_untagged_u16(len, sb);
+    for (size_t i = 0; i < len; i++)
+      ok &= serialize_untagged_u8(s[i], sb);
+    return ok;
+  }
+
+  if (pmt_is_pair(obj)){
+    ok = serialize_untagged_u8(PST_PAIR, sb);
+    ok &= pmt_serialize(pmt_car(obj), sb);
+    if (!ok)
+      return false;
+    obj = pmt_cdr(obj);
+    goto tail_recursion;
+  }
+
+  if (pmt_is_number(obj)){
+
+    if (pmt_is_integer(obj)){
+      long i = pmt_to_long(obj);
+      if (sizeof(long) > 4){
+       if (i < -2147483647 || i > 2147483647)
+         throw pmt_notimplemented("pmt_serialize (64-bit integers)", obj);
+      }
+      ok = serialize_untagged_u8(PST_INT32, sb);
+      ok &= serialize_untagged_u32(i, sb);
+      return ok;
+    }
+
+    if (pmt_is_real(obj))
+      throw pmt_notimplemented("pmt_serialize (real)", obj);
+
+    if (pmt_is_complex(obj))
+      throw pmt_notimplemented("pmt_serialize (complex)", obj);
+  }
+
+  if (pmt_is_vector(obj))
+    throw pmt_notimplemented("pmt_serialize (vector)", obj);
+
+  if (pmt_is_uniform_vector(obj))
+    throw pmt_notimplemented("pmt_serialize (uniform-vector)", obj);
+    
+  if (pmt_is_dict(obj))
+    throw pmt_notimplemented("pmt_serialize (dict)", obj);
+    
+
+  throw pmt_notimplemented("pmt_serialize (?)", obj);
+}
+
+/*
+ * Create obj from portable byte-serial representation
+ *
+ * Returns next obj from streambuf, or PMT_EOF at end of file.
+ * Throws exception on malformed input.
+ */
+pmt_t
+pmt_deserialize(std::streambuf &sb)
+{
+  uint8_t      tag;
+  //uint8_t    u8;
+  uint16_t     u16;
+  uint32_t     u32;
+  //uint32_t   u64;
+  static char   tmpbuf[1024];
+
+  if (!deserialize_untagged_u8(&tag, sb))
+    return PMT_EOF;
+
+  switch (tag){
+  case PST_TRUE:
+    return PMT_T;
+    
+  case PST_FALSE:
+    return PMT_F;
+
+  case PST_NULL:
+    return PMT_NIL;
+
+  case PST_SYMBOL:
+    if (!deserialize_untagged_u16(&u16, sb))
+      goto error;
+    if (u16 > sizeof(tmpbuf))
+      throw pmt_notimplemented("pmt_deserialize: very long symbol",
+                              PMT_F);
+    if (sb.sgetn(tmpbuf, u16) != u16)
+      goto error;
+    return pmt_intern(std::string(tmpbuf, u16));
+
+  case PST_INT32:
+    if (!deserialize_untagged_u32(&u32, sb))
+      goto error;
+    return pmt_from_long((int32_t) u32);
+
+  case PST_PAIR:
+    return parse_pair(sb);
+
+  case PST_DOUBLE:
+  case PST_COMPLEX:
+  case PST_VECTOR:
+  case PST_DICT:
+  case PST_UNIFORM_VECTOR:
+  case PST_COMMENT:
+    throw pmt_notimplemented("pmt_deserialize: tag value = ",
+                            pmt_from_long(tag));
+    
+  default:
+    throw pmt_exception("pmt_deserialize: malformed input stream, tag value = ",
+                       pmt_from_long(tag));
+  }
+
+ error:
+  throw pmt_exception("pmt_deserialize: malformed input stream", PMT_F);
+}
+
+/*
+ * This is a mostly non-recursive implementation that allows us to
+ * deserialize very long lists w/o exhausting the evaluation stack.
+ *
+ * On entry we've already eaten the PST_PAIR tag.
+ */
+pmt_t
+parse_pair(std::streambuf &sb)
+{
+  uint8_t tag;
+  pmt_t        val, expr, lastnptr, nptr;
+
+  //
+  // Keep appending nodes until we get a non-PAIR cdr.
+  //
+  lastnptr = PMT_NIL;
+  while (1){
+    expr = pmt_deserialize(sb);                // read the car
+
+    nptr = pmt_cons(expr, PMT_NIL);    // build new cell
+    if (pmt_is_null(lastnptr))
+      val = nptr;
+    else
+      pmt_set_cdr(lastnptr, nptr);
+    lastnptr = nptr;
+
+    if (!deserialize_untagged_u8(&tag, sb))  // get tag of cdr
+      throw pmt_exception("pmt_deserialize: malformed input stream", PMT_F);
+
+    if (tag == PST_PAIR)
+      continue;                        // keep on looping...
+
+    if (tag == PST_NULL){
+      expr = PMT_NIL;
+      break;
+    }
+
+    //
+    // default: push tag back and use pmt_deserialize to get the cdr
+    //
+    sb.sungetc();
+    expr = pmt_deserialize(sb);
+    break;
+  }
+
+  //
+  // At this point, expr contains the value of the final cdr in the list.
+  //
+  pmt_set_cdr(lastnptr, expr);
+  return val;
+}
+
+} /* namespace pmt */
diff --git a/gruel/src/lib/pmt/qa_pmt.cc b/gruel/src/lib/pmt/qa_pmt.cc
new file mode 100644 (file)
index 0000000..250befa
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * This class gathers together all the test cases for pmt into
+ * a single test suite.  As you create new test cases, add them here.
+ */
+
+#include <qa_pmt.h>
+#include <qa_pmt_prims.h>
+#include <qa_pmt_unv.h>
+
+CppUnit::TestSuite *
+qa_pmt::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("pmt");
+
+  s->addTest (qa_pmt_prims::suite ());
+  s->addTest (qa_pmt_unv::suite ());
+  
+  return s;
+}
diff --git a/gruel/src/lib/pmt/qa_pmt.h b/gruel/src/lib/pmt/qa_pmt.h
new file mode 100644 (file)
index 0000000..43a6dbf
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_QA_PMT_H
+#define INCLUDED_QA_PMT_H
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for pmt
+
+class qa_pmt {
+ public:
+  //! return suite of tests for all of pmt
+  static CppUnit::TestSuite *suite ();
+};
+
+#endif /* INCLUDED_QA_PMT_H */
diff --git a/gruel/src/lib/pmt/qa_pmt_prims.cc b/gruel/src/lib/pmt/qa_pmt_prims.cc
new file mode 100644 (file)
index 0000000..f2414c7
--- /dev/null
@@ -0,0 +1,578 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_pmt_prims.h>
+#include <cppunit/TestAssert.h>
+#include <gruel/msg_passing.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+
+using namespace pmt;
+
+void
+qa_pmt_prims::test_symbols()
+{
+  CPPUNIT_ASSERT(!pmt_is_symbol(PMT_T));
+  CPPUNIT_ASSERT(!pmt_is_symbol(PMT_F));
+  CPPUNIT_ASSERT_THROW(pmt_symbol_to_string(PMT_F), pmt_wrong_type);
+
+  pmt_t sym1 = mp("test");
+  CPPUNIT_ASSERT(pmt_is_symbol(sym1));
+  CPPUNIT_ASSERT_EQUAL(std::string("test"), pmt_symbol_to_string(sym1));
+  CPPUNIT_ASSERT(pmt_is_true(sym1));
+  CPPUNIT_ASSERT(!pmt_is_false(sym1));
+
+  pmt_t sym2 = mp("foo");
+  pmt_t sym3 = mp("test");
+  CPPUNIT_ASSERT_EQUAL(sym1, sym3);
+  CPPUNIT_ASSERT(sym1 != sym2);
+  CPPUNIT_ASSERT(sym1 == sym3);
+
+  static const int N = 2048;
+  std::vector<pmt_t> v1(N);
+  std::vector<pmt_t> v2(N);
+
+  // generate a bunch of symbols
+  for (int i = 0; i < N; i++){
+    char buf[100];
+    snprintf(buf, sizeof(buf), "test-%d", i);
+    v1[i] = mp(buf);
+  }
+
+  // confirm that they are all unique
+  for (int i = 0; i < N; i++)
+    for (int j = i + 1; j < N; j++)
+      CPPUNIT_ASSERT(v1[i] != v1[j]);
+
+  // generate the same symbols again
+  for (int i = 0; i < N; i++){
+    char buf[100];
+    snprintf(buf, sizeof(buf), "test-%d", i);
+    v2[i] = mp(buf);
+  }
+
+  // confirm that we get the same ones back
+  for (int i = 0; i < N; i++)
+    CPPUNIT_ASSERT(v1[i] == v2[i]);
+}
+
+void
+qa_pmt_prims::test_booleans()
+{
+  pmt_t sym = mp("test");
+  CPPUNIT_ASSERT(pmt_is_bool(PMT_T));
+  CPPUNIT_ASSERT(pmt_is_bool(PMT_F));
+  CPPUNIT_ASSERT(!pmt_is_bool(sym));
+  CPPUNIT_ASSERT_EQUAL(pmt_from_bool(false), PMT_F);
+  CPPUNIT_ASSERT_EQUAL(pmt_from_bool(true), PMT_T);
+  CPPUNIT_ASSERT_EQUAL(false, pmt_to_bool(PMT_F));
+  CPPUNIT_ASSERT_EQUAL(true, pmt_to_bool(PMT_T));
+  CPPUNIT_ASSERT_THROW(pmt_to_bool(sym), pmt_wrong_type);
+}
+
+void
+qa_pmt_prims::test_integers()
+{
+  pmt_t p1 = pmt_from_long(1);
+  pmt_t m1 = pmt_from_long(-1);
+  CPPUNIT_ASSERT(!pmt_is_integer(PMT_T));
+  CPPUNIT_ASSERT(pmt_is_integer(p1));
+  CPPUNIT_ASSERT(pmt_is_integer(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_long(PMT_T), pmt_wrong_type);
+  CPPUNIT_ASSERT_EQUAL(-1L, pmt_to_long(m1));
+  CPPUNIT_ASSERT_EQUAL(1L, pmt_to_long(p1));
+}
+
+void
+qa_pmt_prims::test_reals()
+{
+  pmt_t p1 = pmt_from_double(1);
+  pmt_t m1 = pmt_from_double(-1);
+  CPPUNIT_ASSERT(!pmt_is_real(PMT_T));
+  CPPUNIT_ASSERT(pmt_is_real(p1));
+  CPPUNIT_ASSERT(pmt_is_real(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_double(PMT_T), pmt_wrong_type);
+  CPPUNIT_ASSERT_EQUAL(-1.0, pmt_to_double(m1));
+  CPPUNIT_ASSERT_EQUAL(1.0, pmt_to_double(p1));
+  CPPUNIT_ASSERT_EQUAL(1.0, pmt_to_double(pmt_from_long(1)));
+}
+
+void
+qa_pmt_prims::test_complexes()
+{
+  pmt_t p1 = pmt_make_rectangular(2, -3);
+  pmt_t m1 = pmt_make_rectangular(-3, 2);
+  CPPUNIT_ASSERT(!pmt_is_complex(PMT_T));
+  CPPUNIT_ASSERT(pmt_is_complex(p1));
+  CPPUNIT_ASSERT(pmt_is_complex(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_complex(PMT_T), pmt_wrong_type);
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, -3), pmt_to_complex(p1));
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(-3, 2), pmt_to_complex(m1));
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_long(1)));
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_double(1.0)));
+}
+
+void
+qa_pmt_prims::test_pairs()
+{
+  CPPUNIT_ASSERT(pmt_is_null(PMT_NIL));
+  CPPUNIT_ASSERT(!pmt_is_pair(PMT_NIL));
+  pmt_t s1 = mp("s1");
+  pmt_t s2 = mp("s2");
+  pmt_t s3 = mp("s3");
+
+
+  CPPUNIT_ASSERT_EQUAL((size_t)0, pmt_length(PMT_NIL));
+  CPPUNIT_ASSERT_THROW(pmt_length(s1), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_length(pmt_from_double(42)), pmt_wrong_type);
+
+  pmt_t c1 = pmt_cons(s1, PMT_NIL);
+  CPPUNIT_ASSERT(pmt_is_pair(c1));
+  CPPUNIT_ASSERT(!pmt_is_pair(s1));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt_car(c1));
+  CPPUNIT_ASSERT_EQUAL(PMT_NIL, pmt_cdr(c1));
+  CPPUNIT_ASSERT_EQUAL((size_t) 1, pmt_length(c1));
+
+  pmt_t c3 = pmt_cons(s3, PMT_NIL);
+  pmt_t c2 = pmt_cons(s2, c3);
+  pmt_set_cdr(c1, c2);
+  CPPUNIT_ASSERT_EQUAL(c2, pmt_cdr(c1));
+  pmt_set_car(c1, s3);
+  CPPUNIT_ASSERT_EQUAL(s3, pmt_car(c1));
+  CPPUNIT_ASSERT_EQUAL((size_t)1, pmt_length(c3));
+  CPPUNIT_ASSERT_EQUAL((size_t)2, pmt_length(c2));
+  
+  CPPUNIT_ASSERT_THROW(pmt_cdr(PMT_NIL), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_car(PMT_NIL), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_set_car(s1, PMT_NIL), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_set_cdr(s1, PMT_NIL), pmt_wrong_type);
+}
+
+void
+qa_pmt_prims::test_vectors()
+{
+  static const size_t N = 3;
+  pmt_t v1 = pmt_make_vector(N, PMT_NIL);
+  CPPUNIT_ASSERT_EQUAL(N, pmt_length(v1));
+  pmt_t s0 = mp("s0");
+  pmt_t s1 = mp("s1");
+  pmt_t s2 = mp("s2");
+
+  pmt_vector_set(v1, 0, s0);
+  pmt_vector_set(v1, 1, s1);
+  pmt_vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt_vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt_vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt_vector_ref(v1, N), pmt_out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt_vector_set(v1, N, PMT_NIL), pmt_out_of_range);
+
+  pmt_vector_fill(v1, s0);
+  for (size_t i = 0; i < N; i++)
+    CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, i));
+}
+
+static void
+check_tuple(size_t len, const std::vector<pmt_t> &s, pmt_t t)
+{
+  CPPUNIT_ASSERT_EQUAL(true, pmt_is_tuple(t));
+  CPPUNIT_ASSERT_EQUAL(len, pmt_length(t));
+
+  for (size_t i = 0; i < len; i++)
+    CPPUNIT_ASSERT_EQUAL(s[i], pmt_tuple_ref(t, i));
+
+}
+
+void
+qa_pmt_prims::test_tuples()
+{
+  pmt_t v = pmt_make_vector(10, PMT_NIL);
+  std::vector<pmt_t> s(10);
+  for (size_t i = 0; i < 10; i++){
+    std::ostringstream os;
+    os << "s" << i;
+    s[i] = mp(os.str());
+    pmt_vector_set(v, i, s[i]);
+  }
+
+
+  pmt_t t;
+
+  t = pmt_make_tuple();
+  check_tuple(0, s, t);
+
+  t = pmt_make_tuple(s[0]);
+  check_tuple(1, s, t);
+
+  CPPUNIT_ASSERT(pmt_is_vector(v));
+  CPPUNIT_ASSERT(!pmt_is_tuple(v));
+  CPPUNIT_ASSERT(pmt_is_tuple(t));
+  CPPUNIT_ASSERT(!pmt_is_vector(t));
+
+  t = pmt_make_tuple(s[0], s[1]);
+  check_tuple(2, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  check_tuple(3, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3]);
+  check_tuple(4, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4]);
+  check_tuple(5, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5]);
+  check_tuple(6, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
+  check_tuple(7, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
+  check_tuple(8, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
+  check_tuple(9, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
+  check_tuple(10, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  CPPUNIT_ASSERT_THROW(pmt_tuple_ref(t, 3), pmt_out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt_vector_ref(t, 0), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_tuple_ref(v, 0), pmt_wrong_type);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
+  pmt_t t2 = pmt_to_tuple(v);
+  CPPUNIT_ASSERT_EQUAL(size_t(10), pmt_length(v));
+  CPPUNIT_ASSERT(pmt_equal(t, t2));
+  //std::cout << v << std::endl;
+  //std::cout << t2 << std::endl;
+
+  
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  pmt_t list0 = pmt_list3(s[0], s[1], s[2]);
+  CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(list0));
+  t2 = pmt_to_tuple(list0);
+  CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(t2));
+  CPPUNIT_ASSERT(pmt_equal(t, t2));
+}
+
+void
+qa_pmt_prims::test_equivalence()
+{
+  pmt_t s0 = mp("s0");
+  pmt_t s1 = mp("s1");
+  pmt_t s2 = mp("s2");
+  pmt_t list0 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
+  pmt_t list1 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
+  pmt_t i0 = pmt_from_long(42);
+  pmt_t i1 = pmt_from_long(42);
+  pmt_t r0 = pmt_from_double(42);
+  pmt_t r1 = pmt_from_double(42);
+  pmt_t r2 = pmt_from_double(43);
+
+  CPPUNIT_ASSERT(pmt_eq(s0, s0));
+  CPPUNIT_ASSERT(!pmt_eq(s0, s1));
+  CPPUNIT_ASSERT(pmt_eqv(s0, s0));
+  CPPUNIT_ASSERT(!pmt_eqv(s0, s1));
+
+  CPPUNIT_ASSERT(pmt_eqv(i0, i1));
+  CPPUNIT_ASSERT(pmt_eqv(r0, r1));
+  CPPUNIT_ASSERT(!pmt_eqv(r0, r2));
+  CPPUNIT_ASSERT(!pmt_eqv(i0, r0));
+
+  CPPUNIT_ASSERT(!pmt_eq(list0, list1));
+  CPPUNIT_ASSERT(!pmt_eqv(list0, list1));
+  CPPUNIT_ASSERT(pmt_equal(list0, list1));
+
+  pmt_t v0 = pmt_make_vector(3, s0);
+  pmt_t v1 = pmt_make_vector(3, s0);
+  pmt_t v2 = pmt_make_vector(4, s0);
+  CPPUNIT_ASSERT(!pmt_eqv(v0, v1));
+  CPPUNIT_ASSERT(pmt_equal(v0, v1));
+  CPPUNIT_ASSERT(!pmt_equal(v0, v2));
+
+  pmt_vector_set(v0, 0, list0);
+  pmt_vector_set(v0, 1, list0);
+  pmt_vector_set(v1, 0, list1);
+  pmt_vector_set(v1, 1, list1);
+  CPPUNIT_ASSERT(pmt_equal(v0, v1));
+}
+
+void
+qa_pmt_prims::test_misc()
+{
+  pmt_t k0 = mp("k0");
+  pmt_t k1 = mp("k1");
+  pmt_t k2 = mp("k2");
+  pmt_t k3 = mp("k3");
+  pmt_t v0 = mp("v0");
+  pmt_t v1 = mp("v1");
+  pmt_t v2 = mp("v2");
+  pmt_t p0 = pmt_cons(k0, v0);
+  pmt_t p1 = pmt_cons(k1, v1);
+  pmt_t p2 = pmt_cons(k2, v2);
+  
+  pmt_t alist = pmt_cons(p0, pmt_cons(p1, pmt_cons(p2, PMT_NIL)));
+  CPPUNIT_ASSERT(pmt_eq(p1, pmt_assv(k1, alist)));
+  CPPUNIT_ASSERT(pmt_eq(PMT_F, pmt_assv(k3, alist)));
+  
+  pmt_t keys = pmt_cons(k0, pmt_cons(k1, pmt_cons(k2, PMT_NIL)));
+  pmt_t vals = pmt_cons(v0, pmt_cons(v1, pmt_cons(v2, PMT_NIL)));
+  CPPUNIT_ASSERT(pmt_equal(keys, pmt_map(pmt_car, alist)));
+  CPPUNIT_ASSERT(pmt_equal(vals, pmt_map(pmt_cdr, alist)));
+}
+
+void
+qa_pmt_prims::test_dict()
+{
+  pmt_t dict = pmt_make_dict();
+  CPPUNIT_ASSERT(pmt_is_dict(dict));
+
+  pmt_t k0 = mp("k0");
+  pmt_t k1 = mp("k1");
+  pmt_t k2 = mp("k2");
+  pmt_t k3 = mp("k3");
+  pmt_t v0 = mp("v0");
+  pmt_t v1 = mp("v1");
+  pmt_t v2 = mp("v2");
+  pmt_t v3 = mp("v3");
+  pmt_t not_found = pmt_cons(PMT_NIL, PMT_NIL);
+  
+  CPPUNIT_ASSERT(!pmt_dict_has_key(dict, k0));
+  dict = pmt_dict_add(dict, k0, v0);
+  CPPUNIT_ASSERT(pmt_dict_has_key(dict, k0));
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k0, not_found), v0));
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), not_found));
+  dict = pmt_dict_add(dict, k1, v1);
+  dict = pmt_dict_add(dict, k2, v2);
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v1));
+  dict = pmt_dict_add(dict, k1, v3);
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v3));
+
+  pmt_t keys = pmt_list3(k1, k2, k0);
+  pmt_t vals = pmt_list3(v3, v2, v0);
+  //std::cout << "pmt_dict_keys:   " << pmt_dict_keys(dict) << std::endl;
+  //std::cout << "pmt_dict_values: " << pmt_dict_values(dict) << std::endl;
+  CPPUNIT_ASSERT(pmt_equal(keys, pmt_dict_keys(dict)));
+  CPPUNIT_ASSERT(pmt_equal(vals, pmt_dict_values(dict)));
+}
+
+void
+qa_pmt_prims::test_io()
+{
+  pmt_t k0 = mp("k0");
+  pmt_t k1 = mp("k1");
+  pmt_t k2 = mp("k2");
+  pmt_t k3 = mp("k3");
+
+  CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
+}
+
+void
+qa_pmt_prims::test_lists()
+{
+  pmt_t s0 = mp("s0");
+  pmt_t s1 = mp("s1");
+  pmt_t s2 = mp("s2");
+  pmt_t s3 = mp("s3");
+
+  pmt_t l1 = pmt_list4(s0, s1, s2, s3);
+  pmt_t l2 = pmt_list3(s0, s1, s2);
+  pmt_t l3 = pmt_list_add(l2, s3);
+  CPPUNIT_ASSERT(pmt_equal(l1, l3));
+}
+
+// ------------------------------------------------------------------------
+
+// class foo is used in test_any below.
+// It can't be declared in the scope of test_any because of template
+// namespace problems.
+
+class foo {
+public:
+  double       d_double;
+  int          d_int;
+  foo(double d=0, int i=0) : d_double(d), d_int(i) {}
+};
+
+bool operator==(const foo &a, const foo &b)
+{
+  return a.d_double == b.d_double && a.d_int == b.d_int;
+}
+
+std::ostream& operator<<(std::ostream &os, const foo obj)
+{
+  os << "<foo: " << obj.d_double << ", " << obj.d_int << ">";
+  return os;
+}
+
+void
+qa_pmt_prims::test_any()
+{
+  boost::any a0;
+  boost::any a1;
+  boost::any a2;
+
+  a0 = std::string("Hello!");
+  a1 = 42;
+  a2 = foo(3.250, 21);
+
+  pmt_t p0 = pmt_make_any(a0);
+  pmt_t p1 = pmt_make_any(a1);
+  pmt_t p2 = pmt_make_any(a2);
+
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello!"),
+                      boost::any_cast<std::string>(pmt_any_ref(p0)));
+
+  CPPUNIT_ASSERT_EQUAL(42,
+                      boost::any_cast<int>(pmt_any_ref(p1)));
+
+  CPPUNIT_ASSERT_EQUAL(foo(3.250, 21),
+                      boost::any_cast<foo>(pmt_any_ref(p2)));
+}
+
+// ------------------------------------------------------------------------
+
+class qa_pmt_msg_accepter_nop : public gruel::msg_accepter {
+public:
+  qa_pmt_msg_accepter_nop(){};
+  ~qa_pmt_msg_accepter_nop();
+  void post(pmt_t){};
+};
+
+qa_pmt_msg_accepter_nop::~qa_pmt_msg_accepter_nop(){}
+
+void
+qa_pmt_prims::test_msg_accepter()
+{
+  pmt_t sym = mp("my-symbol");
+
+  boost::any a0;
+  a0 = std::string("Hello!");
+  pmt_t p0 = pmt_make_any(a0);
+
+  gruel::msg_accepter_sptr ma0 = gruel::msg_accepter_sptr(new qa_pmt_msg_accepter_nop());
+  pmt_t p1 = pmt_make_msg_accepter(ma0);
+
+  CPPUNIT_ASSERT_EQUAL(ma0.get(), pmt_msg_accepter_ref(p1).get());
+
+  CPPUNIT_ASSERT_THROW(pmt_msg_accepter_ref(sym), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_msg_accepter_ref(p0),  pmt_wrong_type);
+
+  // just confirm interfaces on send are OK
+  gruel::send(ma0.get(), sym);
+  gruel::send(ma0, sym);
+  gruel::send(p1, sym);
+
+}
+
+// ------------------------------------------------------------------------
+
+void
+qa_pmt_prims::test_serialize()
+{
+  std::stringbuf sb;           // fake channel
+  pmt_t a = mp("a");
+  pmt_t b = mp("b");
+  pmt_t c = mp("c");
+
+  sb.str("");                  // reset channel to empty
+
+  // write stuff to channel
+
+  pmt_serialize(PMT_NIL, sb);
+  pmt_serialize(mp("foobarvia"), sb);
+  pmt_serialize(pmt_from_long(123456789), sb);
+  pmt_serialize(pmt_from_long(-123456789), sb);
+  pmt_serialize(pmt_cons(PMT_NIL, PMT_NIL), sb);
+  pmt_serialize(pmt_cons(a, b), sb);
+  pmt_serialize(pmt_list1(a), sb);
+  pmt_serialize(pmt_list2(a, b), sb);
+  pmt_serialize(pmt_list3(a, b, c), sb);
+  pmt_serialize(pmt_list3(a, pmt_list3(c, b, a), c), sb);
+  pmt_serialize(PMT_T, sb);
+  pmt_serialize(PMT_F, sb);
+
+  // read it back
+
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_NIL));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), mp("foobarvia")));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(123456789)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(-123456789)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(PMT_NIL, PMT_NIL)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(a, b)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list1(a)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list2(a, b)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, b, c)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, pmt_list3(c, b, a), c)));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_T));
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_F));
+
+  CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_EOF));     // last item
+
+
+  // FIXME add tests for real, complex, vector, uniform-vector, dict
+  // FIXME add tests for malformed input too.
+
+}
+
+void
+qa_pmt_prims::test_sets()
+{
+  pmt_t s1 = mp("s1");
+  pmt_t s2 = mp("s2");
+  pmt_t s3 = mp("s3");
+
+  pmt_t l1 = pmt_list1(s1);
+  pmt_t l2 = pmt_list2(s2,s3);
+  pmt_t l3 = pmt_list3(s1,s2,s3);
+
+  CPPUNIT_ASSERT(pmt_is_pair(pmt_memq(s1,l1)));
+  CPPUNIT_ASSERT(pmt_is_false(pmt_memq(s3,l1)));
+
+  CPPUNIT_ASSERT(pmt_subsetp(l1,l3));
+  CPPUNIT_ASSERT(pmt_subsetp(l2,l3));
+  CPPUNIT_ASSERT(!pmt_subsetp(l1,l2));
+  CPPUNIT_ASSERT(!pmt_subsetp(l2,l1));
+  CPPUNIT_ASSERT(!pmt_subsetp(l3,l2));
+}
+
+void
+qa_pmt_prims::test_sugar()
+{
+  CPPUNIT_ASSERT(pmt_is_symbol(mp("my-symbol")));
+  CPPUNIT_ASSERT_EQUAL((long) 10, pmt_to_long(mp(10)));
+  CPPUNIT_ASSERT_EQUAL((double) 1e6, pmt_to_double(mp(1e6)));
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, 3),
+                      pmt_to_complex(mp(std::complex<double>(2, 3))));
+
+  int buf[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  pmt_t blob = mp(buf, sizeof(buf));
+  const void *data = pmt_blob_data(blob);
+  size_t nbytes = pmt_blob_length(blob);
+  CPPUNIT_ASSERT_EQUAL(sizeof(buf), nbytes);
+  CPPUNIT_ASSERT(memcmp(buf, data, nbytes) == 0);
+}
diff --git a/gruel/src/lib/pmt/qa_pmt_prims.h b/gruel/src/lib/pmt/qa_pmt_prims.h
new file mode 100644 (file)
index 0000000..29ba02f
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_QA_PMT_PRIMS_H
+#define INCLUDED_QA_PMT_PRIMS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_pmt_prims : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_pmt_prims);
+  CPPUNIT_TEST(test_symbols);
+  CPPUNIT_TEST(test_booleans);
+  CPPUNIT_TEST(test_integers);
+  CPPUNIT_TEST(test_reals);
+  CPPUNIT_TEST(test_complexes);
+  CPPUNIT_TEST(test_pairs);
+  CPPUNIT_TEST(test_vectors);
+  CPPUNIT_TEST(test_tuples);
+  CPPUNIT_TEST(test_equivalence);
+  CPPUNIT_TEST(test_misc);
+  CPPUNIT_TEST(test_dict);
+  CPPUNIT_TEST(test_any);
+  CPPUNIT_TEST(test_msg_accepter);
+  CPPUNIT_TEST(test_io);
+  CPPUNIT_TEST(test_lists);
+  CPPUNIT_TEST(test_serialize);
+  CPPUNIT_TEST(test_sets);
+  CPPUNIT_TEST(test_sugar);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_symbols();
+  void test_booleans();
+  void test_integers();
+  void test_reals();
+  void test_complexes();
+  void test_pairs();
+  void test_vectors();
+  void test_tuples();
+  void test_equivalence();
+  void test_misc();
+  void test_dict();
+  void test_any();
+  void test_msg_accepter();
+  void test_io();
+  void test_lists();
+  void test_serialize();
+  void test_sets();
+  void test_sugar();
+};
+
+#endif /* INCLUDED_QA_PMT_PRIMS_H */
+
diff --git a/gruel/src/lib/pmt/unv_qa_template.cc.t b/gruel/src/lib/pmt/unv_qa_template.cc.t
new file mode 100644 (file)
index 0000000..1e2c8e8
--- /dev/null
@@ -0,0 +1,35 @@
+void
+qa_pmt_unv::test_@TAG@vector()
+{
+  static const size_t N = 3;
+  pmt_t v1 = pmt_make_@TAG@vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt_length(v1));
+  @TYPE@ s0 = @TYPE@(10);
+  @TYPE@ s1 = @TYPE@(20);
+  @TYPE@ s2 = @TYPE@(30);
+
+  pmt_@TAG@vector_set(v1, 0, s0);
+  pmt_@TAG@vector_set(v1, 1, s1);
+  pmt_@TAG@vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt_@TAG@vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt_@TAG@vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt_@TAG@vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt_@TAG@vector_ref(v1, N), pmt_out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt_@TAG@vector_set(v1, N, @TYPE@(0)), pmt_out_of_range);
+
+  size_t       len;
+  const @TYPE@ *rd = pmt_@TAG@vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  @TYPE@ *wr = pmt_@TAG@vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = @TYPE@(0);
+  CPPUNIT_ASSERT_EQUAL(@TYPE@(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
diff --git a/gruel/src/lib/pmt/unv_template.cc.t b/gruel/src/lib/pmt/unv_template.cc.t
new file mode 100644 (file)
index 0000000..148965c
--- /dev/null
@@ -0,0 +1,122 @@
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_@TAG@vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_@TAG@vector *
+_@TAG@vector(pmt_t x)
+{
+  return dynamic_cast<pmt_@TAG@vector*>(x.get());
+}
+
+
+pmt_@TAG@vector::pmt_@TAG@vector(size_t k, @TYPE@ fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_@TAG@vector::pmt_@TAG@vector(size_t k, const @TYPE@ *data)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = data[i];
+}
+
+@TYPE@
+pmt_@TAG@vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_@TAG@vector_ref", pmt_from_long(k));
+  return d_v[k];
+}
+
+void 
+pmt_@TAG@vector::set(size_t k, @TYPE@ x)
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_@TAG@vector_set", pmt_from_long(k));
+  d_v[k] = x;
+}
+
+const @TYPE@ *
+pmt_@TAG@vector::elements(size_t &len)
+{
+  len = length();
+  return &d_v[0];
+}
+
+@TYPE@ *
+pmt_@TAG@vector::writable_elements(size_t &len)
+{
+  len = length();
+  return &d_v[0];
+}
+
+const void*
+pmt_@TAG@vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(@TYPE@);
+  return &d_v[0];
+}
+
+void*
+pmt_@TAG@vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(@TYPE@);
+  return &d_v[0];
+}
+
+bool
+pmt_is_@TAG@vector(pmt_t obj)
+{
+  return obj->is_@TAG@vector();
+}
+
+pmt_t
+pmt_make_@TAG@vector(size_t k, @TYPE@ fill)
+{
+  return pmt_t(new pmt_@TAG@vector(k, fill));
+}
+
+pmt_t
+pmt_init_@TAG@vector(size_t k, const @TYPE@ *data)
+{
+  return pmt_t(new pmt_@TAG@vector(k, data));
+}
+
+@TYPE@
+pmt_@TAG@vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_@TAG@vector())
+    throw pmt_wrong_type("pmt_@TAG@vector_ref", vector);
+  return _@TAG@vector(vector)->ref(k);
+}
+
+void
+pmt_@TAG@vector_set(pmt_t vector, size_t k, @TYPE@ obj)
+{
+  if (!vector->is_@TAG@vector())
+    throw pmt_wrong_type("pmt_@TAG@vector_set", vector);
+  _@TAG@vector(vector)->set(k, obj);
+}
+
+const @TYPE@ *
+pmt_@TAG@vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_@TAG@vector())
+    throw pmt_wrong_type("pmt_@TAG@vector_elements", vector);
+  return _@TAG@vector(vector)->elements(len);
+}
+
+@TYPE@ *
+pmt_@TAG@vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_@TAG@vector())
+    throw pmt_wrong_type("pmt_@TAG@vector_writable_elements", vector);
+  return _@TAG@vector(vector)->writable_elements(len);
+}
+
+} /* namespace pmt */
diff --git a/gruel/src/lib/pmt/unv_template.h.t b/gruel/src/lib/pmt/unv_template.h.t
new file mode 100644 (file)
index 0000000..83ba0be
--- /dev/null
@@ -0,0 +1,23 @@
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_@TAG@vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_@TAG@vector : public pmt_uniform_vector
+{
+  std::vector< @TYPE@ >        d_v;
+
+public:
+  pmt_@TAG@vector(size_t k, @TYPE@ fill);
+  pmt_@TAG@vector(size_t k, const @TYPE@ *data);
+  // ~pmt_@TAG@vector();
+
+  bool is_@TAG@vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  @TYPE@ ref(size_t k) const;
+  void set(size_t k, @TYPE@ x);
+  const @TYPE@ *elements(size_t &len);
+  @TYPE@ *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+};
diff --git a/gruel/src/lib/test_gruel.cc b/gruel/src/lib/test_gruel.cc
new file mode 100644 (file)
index 0000000..6693034
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include "pmt/qa_pmt.h"
+
+int 
+main(int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest(qa_pmt::suite ());
+  
+  bool was_successful = runner.run("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc
new file mode 100644 (file)
index 0000000..d8f77b5
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gruel/thread.h>
+
+namespace gruel {
+
+  boost::system_time
+  get_new_timeout(double secs)
+  {
+    return boost::get_system_time() + boost::posix_time::milliseconds(long(secs*1e3));
+  }
+
+}
diff --git a/gruel/src/scheme/.gitignore b/gruel/src/scheme/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gruel/src/scheme/Makefile.am b/gruel/src/scheme/Makefile.am
new file mode 100644 (file)
index 0000000..4980063
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+SUBDIRS = gnuradio
diff --git a/gruel/src/scheme/gnuradio/.gitignore b/gruel/src/scheme/gnuradio/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/gruel/src/scheme/gnuradio/Makefile.am b/gruel/src/scheme/gnuradio/Makefile.am
new file mode 100644 (file)
index 0000000..0ce01f6
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Copyright 2007,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+#pkgdatadir = $(datadir)/gnuradio
+
+EXTRA_DIST =                           \
+       gen-serial-tags.scm
+
+# really scheme source files
+dist_pkgdata_DATA =                    \
+       pmt-serial-tags.scm             \
+       pmt-serialize.scm               \
+       macros-etc.scm
+
diff --git a/gruel/src/scheme/gnuradio/gen-serial-tags.scm b/gruel/src/scheme/gnuradio/gen-serial-tags.scm
new file mode 100755 (executable)
index 0000000..7b90872
--- /dev/null
@@ -0,0 +1,118 @@
+#!/usr/bin/guile \
+-e main -s
+!#
+;;; -*-scheme-*-
+;;;
+;;; 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 this program; if not, write to the Free Software Foundation, Inc.,
+;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;;;
+
+(use-modules (ice-9 format))
+
+(defmacro when (pred . body)
+  `(if ,pred (begin ,@body) #f))
+
+;; ----------------------------------------------------------------
+
+(define (main args)
+
+  (define (usage)
+    (format 0
+           "usage: ~a <pmt-serial-tags.scm> <pmt_serial_tags.h>~%"
+           (car args)))
+
+  (when (not (= (length args) 3))
+       (usage)
+       (format 0 "args: ~s~%" args)
+       (exit 1))
+      
+  (let ((i-file (open-input-file (cadr args)))
+       (h-file (open-output-file (caddr args))))
+
+      (write-header-comment h-file "// ")
+      (display "#ifndef INCLUDED_PMT_SERIAL_TAGS_H\n" h-file)
+      (display "#define INCLUDED_PMT_SERIAL_TAGS_H\n" h-file)
+      (newline h-file)
+      (display "enum pst_tags {\n" h-file)
+
+      (for-each-in-file i-file
+       (lambda (form)
+        (let* ((name (cadr form))
+               (c-name (string-upcase (c-ify name)))
+               (value (caddr form)))
+          ;;(format h-file   "static const int ~a\t= 0x~x;~%" c-name value)
+          (format h-file   "  ~a\t= 0x~x,~%" c-name value))))
+
+      (display "};\n" h-file)
+      (display "#endif\n" h-file)))
+
+(define (c-ify name)
+  (list->string (map (lambda (c)
+                      (if (eqv? c #\-) #\_ c))
+                    (string->list (symbol->string name)))))
+
+
+(define (write-header-comment o-port prefix)
+  (for-each (lambda (comment)
+             (format o-port "~a~a~%" prefix comment))
+           header-comment))
+
+(define header-comment
+  '(
+    ""
+    "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 this program; if not, write to the Free Software Foundation, Inc.,"
+    "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
+    ""
+    ""
+    "THIS FILE IS MACHINE GENERATED FROM pmt-serial-tags.scm. DO NOT EDIT BY HAND."
+    "See pmt-serial-tags.scm for additional commentary."
+    ""))
+
+
+
+(define (for-each-in-file file f)
+  (let ((port (if (port? file)
+                 file
+                 (open-input-file file))))
+    (letrec
+     ((loop
+       (lambda (port form)
+        (cond ((eof-object? form)
+               (when (not (eq? port file))
+                     (close-input-port port))
+               #t)
+              (else
+               (f form)
+               (set! form #f)          ; for GC
+               (loop port (read port)))))))
+     (loop port (read port)))))
diff --git a/gruel/src/scheme/gnuradio/macros-etc.scm b/gruel/src/scheme/gnuradio/macros-etc.scm
new file mode 100644 (file)
index 0000000..ac2a4a3
--- /dev/null
@@ -0,0 +1,50 @@
+;;; -*- scheme -*-
+;;;
+;;; 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 this program; if not, write to the Free Software Foundation, Inc.,
+;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;;;
+
+(define-module (gnuradio macros-etc)
+  :export (atom? when unless for-each-in-file))
+
+(define (atom? obj)
+  (not (pair? obj)))
+
+(defmacro when (pred . body)
+  `(if ,pred (begin ,@body) #f))
+
+(defmacro unless (pred . body)
+  `(if (not ,pred) (begin ,@body) #f))
+
+
+(define (for-each-in-file file f)
+  (let ((port (if (port? file)
+                 file
+                 (open-input-file file))))
+    (letrec
+     ((loop
+       (lambda (port form)
+        (cond ((eof-object? form)
+               (when (not (eq? port file))
+                     (close-input-port port))
+               #t)
+              (else
+               (f form)
+               (set! form #f)          ; for GC
+               (loop port (read port)))))))
+     (loop port (read port)))))
diff --git a/gruel/src/scheme/gnuradio/pmt-serial-tags.scm b/gruel/src/scheme/gnuradio/pmt-serial-tags.scm
new file mode 100644 (file)
index 0000000..646a751
--- /dev/null
@@ -0,0 +1,75 @@
+;;; -*-scheme-*-
+;;;
+;;; 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 (define 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 this program; if not, write to the Free Software Foundation, Inc.,
+;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;;;
+
+;;; definitions of tag values used for marshalling pmt data
+
+(define pst-true               #x00)
+(define pst-false              #x01)
+(define pst-symbol             #x02)   ; untagged-int16 n; followed by n bytes of symbol name
+(define pst-int32              #x03)
+(define pst-double             #x04)
+(define pst-complex            #x05)   ; complex<double>: real, imag
+(define pst-null               #x06)
+(define pst-pair               #x07)   ; followed by two objects
+(define pst-vector             #x08)   ; untagged-int32 n; followed by n objects
+(define pst-dict               #x09)   ; untagged-int32 n; followed by n key/value tuples
+
+(define pst-uniform-vector     #x0a)
+
+;; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c32, c64
+;;
+;;   untagged-uint8  tag
+;;   untagged-uint8  uvi (define uniform vector info, see below)
+;;   untagged-int32  n-items
+;;   untagged-uint8  npad
+;;   npad bytes of zeros to align binary data
+;;   n-items binary numeric items
+;;
+;; uvi:
+;; +-+-+-+-+-+-+-+-+
+;; |B|   subtype   |
+;; +-+-+-+-+-+-+-+-+
+;;
+;; B == 0, numeric data is little-endian.
+;; B == 1, numeric data is big-endian.
+
+    (define uvi-endian-mask     #x80)
+    (define uvi-subtype-mask    #x7f)
+
+    (define uvi-little-endian   #x00)
+    (define uvi-big-endian      #x80)
+
+    (define uvi-u8             #x00)
+    (define uvi-s8             #x01)
+    (define uvi-u16            #x02)
+    (define uvi-s16            #x03)
+    (define uvi-u32            #x04)
+    (define uvi-s32            #x05)
+    (define uvi-u64            #x06)
+    (define uvi-s64            #x07)
+    (define uvi-f32            #x08)
+    (define uvi-f64            #x09)
+    (define uvi-c32            #x0a)
+    (define uvi-c64            #x0b)
+
+
+(define pst-comment            #x3b)   ; ascii ';'
+(define pst-comment-end                #x0a)   ; ascii '\n'
diff --git a/gruel/src/scheme/gnuradio/pmt-serialize.scm b/gruel/src/scheme/gnuradio/pmt-serialize.scm
new file mode 100644 (file)
index 0000000..c1d32d7
--- /dev/null
@@ -0,0 +1,48 @@
+;;;
+;;; 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 this program; if not, write to the Free Software Foundation, Inc.,
+;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;;;
+
+;;; An implementation of pmt_serialize in scheme.
+;;; Currently handles only symbols and pairs.  They're all we need for now.
+
+(define-module (gnuradio pmt-serialize)
+  :export (pmt-serialize))
+
+(load-from-path "gnuradio/pmt-serial-tags")
+
+(define (pmt-serialize obj put-byte)
+  (define (put-u16 x)
+    (put-byte (logand (ash x -8) #xff))
+    (put-byte (logand x #xff)))
+    
+  (cond ((null? obj)
+        (put-byte pst-null))
+       ((symbol? obj)
+        (let* ((sym-as-bytes (map char->integer (string->list (symbol->string obj))))
+               (len (length sym-as-bytes)))
+          (put-byte pst-symbol)
+          (put-u16 len)
+          (for-each put-byte sym-as-bytes)))
+       
+       ((pair? obj)
+        (put-byte pst-pair)
+        (pmt-serialize (car obj) put-byte)
+        (pmt-serialize (cdr obj) put-byte))
+       (else
+        (throw 'not-implemented "pmt-serialize" obj))))
index 69fbe26dc0758c12fc39a7af13c4d797d2ec86df..1cb8e170adc361f5618a7a1957de934ad9173871 100644 (file)
@@ -13,14 +13,14 @@ abs_top_builddir=@abs_top_builddir@
 # current QA srcdir
 export srcdir=$3
 
-# Where to find my swig generated shared library
-mylibdir=$2/src:$2/src/.libs:$2/src/lib:$2/src/lib/.libs
+# Where to find my C++ and swig generated shared libraries
+mylibdir=$2/src:$2/src/.libs:$2/src/lib:$2/src/lib/.libs:$2/lib:$2/lib/.libs:$2/swig:$2/swig/.libs
 
 # Where to find my swig generated python module
 mysrcdir=$1/src:$1/src/lib
 
 # Where to find my hand written python modules
-mypydir=$1/src:$1/src/python
+mypydir=$1/src:$1/src/python:$1/python
 
 # Where to find core's swig generated shared libraries,
 # and hand generated swig glue
@@ -56,9 +56,6 @@ fi
 PYTHONPATH="$mylibdir:$mysrcdir:$mypydir:$PYTHONPATH"
 export PYTHONPATH
 
-# Where to find omnithread library files
-gromnidir=@omnithread_LIBDIRPATH@
-
 # Where to find gruel library files
 grueldir=@gruel_LIBDIRPATH@
 
@@ -68,7 +65,7 @@ grcoredir=@gnuradio_core_LIBDIRPATH@
 # Construct search path for python modules
 # Check each one to make sure it's not "" before adding
 grlibdir=""
-for dir in $gromnidir $grcoredir $grueldir
+for dir in $grcoredir $grueldir
 do
     if [ "$dir" != "" ]
     then
diff --git a/usrp/.gitignore b/usrp/.gitignore
new file mode 100644 (file)
index 0000000..4af69af
--- /dev/null
@@ -0,0 +1,31 @@
+/*.cache
+/*.la
+/*.lo
+/*.pc
+/.deps
+/.la
+/.libs
+/.lo
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/ltmain.sh
+/libtool
+/ltmain.sh
+/make.log
+/missing
+/missing
+/stamp-h
+/py-compile
+/stamp-h.in
+/stamp-h1
+/usrp.iss
diff --git a/usrp/doc/.gitignore b/usrp/doc/.gitignore
new file mode 100644 (file)
index 0000000..fdf7036
--- /dev/null
@@ -0,0 +1,14 @@
+/Makefile
+/Makefile.in
+/html
+/latex
+/man
+/Doxyfile
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/xml
+/usrp_guide.html
index 1c01e43fad450dd21e0e7269e130ef69076573eb..6099ebb72818caca0348320299b244760456e243 100644 (file)
@@ -25,7 +25,7 @@ include $(top_srcdir)/Makefile.common
 SUBDIRS = other
 
 man3dir = $(mandir)/man3
-usrp_docdir  = $(prefix)/share/doc/usrp-@VERSION@
+usrp_docdir  = $(prefix)/share/doc/usrp-$(DOCVER)
 
 EXTRA_DIST =                   \
        Doxyfile.in             \
diff --git a/usrp/doc/inband-signaling-gigethernet b/usrp/doc/inband-signaling-gigethernet
new file mode 100644 (file)
index 0000000..4ca7542
--- /dev/null
@@ -0,0 +1,34 @@
+Gigabit Ethernet Interconnect for the USRP2
+
+At this point, this is a place to summarize design requirements,
+possible solutions, point-counterpoint, etc.
+
+
+Requirements:
+
+(R1) High throughput and low latency between USRP h/w and user-space.
+One of the primary reasons for switching from USB to gigabit ethernet
+is to increase throughput.  Many users want to be be able to build
+WLAN type systems, and are thwarted by the relatively low throughput
+available over the USB.  Eric thinks we should shoot for at least
+100MB/s full-duplex into user space, using packets with payloads on
+the order of 256 to 512 bytes.  The small packet size is to reduce the
+latency.  This is important for many MACs that people want to build on
+the host side.
+
+(R2) Non-priviledged user programs should be able to access the USRP.
+This could be implemented by a priviledged daemon that actually handles the
+low level communication with the USRP2.  This daemon may be desirable
+for other reasons, including central point of control for
+arbitrating/muxing/demuxing between multiple concurrent users (e.g.,
+Tx, Rx, requests, replies, various logical channels).
+
+(R3) Some way to flow control the host to USRP2 stream.  This is
+required in case the user connects an unthrottled signal generator to
+the USRP. (This is not uncommon.)  The USRP2 to host direction
+shouldn't be a problem, since the USRP2 throughput is controlled by
+its configuration.  It is an error to configure the USRP2 to transmit
+data at a higher rate than the transport or host can consume.
+
+One solution to this requirement could be having the USRP2 emit GigE
+"pause" frames.  We'll need to confirm that this works.
diff --git a/usrp/doc/inband-signaling-usb b/usrp/doc/inband-signaling-usb
new file mode 100644 (file)
index 0000000..14f8347
--- /dev/null
@@ -0,0 +1,314 @@
+This file specifies the format of USB packets used for in-band data
+transmission and signaling on the USRP.  All packets are 512-byte long,
+and are transfered using USB "bulk" transfers.
+
+IN packets are sent towards the host.
+OUT packets are sent away from the host.
+
+The layout is 32-bits wide.  All data is transmitted in little-endian
+format across the USB.
+
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |O|U|D|S|E|   RSSI    |  Chan   | mbz |  Tag  |   Payload Len   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                           Timestamp                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   +                                                               +
+   |                            Payload                            |
+   .                                                               .
+   .                                                               .
+   .                                                               .
+   |                                                               |
+   +             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |      ...    |                                                 .
+   +-+-+-+-+-+-+-+                                                 .
+   .                                                               .
+   .                            Padding                            .
+   .                                                               .
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   
+
+  mbz   Must be Zero: these bits must be zero in both IN and OUT packets.
+
+  O     Overrun Flag: set in an IN packet if an overrun condition was
+        detected.  Must be zero in OUT packets.  Overrun occurs when
+        the FPGA has data to transmit to the host and there is no
+        buffer space available.  This generally indicates a problem on
+        the host.  Either it is not keeping up, or it has configured
+        the FPGA to transmit data at a higher rate than the transport
+        (USB) can support.
+
+  U     Underrun Flag: set in an IN packet if an underrun condition
+        was detected.  Must be zero in OUT packets.  Underrun occurs
+        when the FPGA runs out of samples, and it's not between
+        bursts.  See the "End of Burst flag" below.
+
+  D     Dropped Packet Flag: Set in an IN packet if the FPGA
+       discarded an OUT packet because its timestamp had already
+       passed.
+
+  S     Start of Burst Flag:  Set in an OUT packet if the data is the
+        first segment of what is logically a continuous burst of data.
+        Must be zero in IN packets.
+
+  E     End of Burst Flag:  Set in an OUT packet if the data is the
+        last segment of what is logically a continuous burst of data.
+        Must be zero in IN packets.  Underruns are not reported
+        when the FPGA runs out of samples between bursts.
+
+
+  RSSI  6-bit Received Strength Signal Indicator:  Must be zero in OUT
+        packets.  In IN packets, indicates RSSI as reported by front end.
+       FIXME The format and interpretation are to be determined.
+
+  Chan  5-bit logical channel number.  Channel number 0x1f is reserved
+        for control information.  See "Control Channel" below.  Other
+        channels are "data channels."  Each data channel is logically
+        independent of the others.  A data channel payload field
+        contains a sequence of homogeneous samples.  The format of the
+        samples is determined by the configuration associated with the
+        given channel.  It is often the case that the payload field
+        contains 32-bit complex samples, each containing 16-bit real
+        and imaginary components.
+
+  Tag   4-bit tag for matching IN packets with OUT packets.
+        [FIXME, write more...]
+
+  Payload Len: 9-bit field that specifies the length of the payload
+        field in bytes.  Must be in the range 0 to 504 inclusive.
+
+  Timestamp: 32-bit timestamp.
+       On IN packets, the timestamp indicates the time at which the
+       first sample of the packet was produced by the A/D converter(s)
+        for that channel.  On OUT packets, the timestamp specifies the
+        time at which the first sample in the packet should go out the
+        D/A converter(s) for that channel.  If a packet reaches the
+       head of the transmit queue, and the current time is later than
+       the timestamp, an error is assumed to have occurred and the
+       packet is discarded.  As a special case, the timestamp
+       0xffffffff is interpreted as "Now".
+
+       The time base is a free running 32-bit counter that is
+       incremented by the A/D sample-clock.
+
+  Payload: Variable length field.  Length is specified by the
+        Payload Len field.
+
+  Padding: This field is 504 - Payload Len bytes long, and its content
+        is unspecified.  This field pads the packet out to a constant
+        512 bytes.
+
+
+
+"Data Channel" payload format:
+-------------------------------
+
+If Chan != 0x1f, the packet is a "data packet" and the payload is a
+sequence of homogeneous samples.  The format of the samples is
+determined by the configuration associated with the given channel.  
+It is often the case that the payload field contains 32-bit complex
+samples, each containing 16-bit real and imaginary components.
+
+
+"Control Channel" payload format:
+---------------------------------
+
+If Chan == 0x1f, the packet is a "control packet".  The control channel
+payload consists of a sequence of 0 or more sub-packets.
+
+Each sub-packet starts on a 32-bit boundary, and consists of an 8-bit
+Opcode field, an 8-bit Length field, Length bytes of arguments, and 0,
+1, 2 or 3 bytes of padding to align the tail of the sub-packet to
+a 32-bit boundary.
+
+Control channel packets shall be processed at the head of the queue,
+and shall observe the timestamp semantics described above.
+
+
+General sub-packet format:
+--------------------------
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-//-+-+-+-+-+-+-+-+
+   |     Opcode    |    Length     |        <length bytes> ...    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-//-+-+-+-+-+-+-+-+
+
+
+Specific sub-packet formats:
+----------------------------
+
+  RID: 6-bit Request-ID. Copied from request sub-packet into corresponding
+       reply sub-packet.  RID allows the host to match requests and replies.
+
+  Reg Number: 10-bit Register Number.
+
+
+
+Ping Fixed Length:
+
+    Opcode:    OP_PING_FIXED
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |    RID    |     Ping Value    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Ping Fixed Length Reply:
+
+    Opcode:    OP_PING_FIXED_REPLY
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |    RID    |     Ping Value    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Write Register:
+
+    Opcode:    OP_WRITE_REG
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       6       |    mbz    |     Reg Number    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Register Value                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Write Register Masked:
+
+    Opcode:    OP_WRITE_REG_MASKED
+
+    REG[Num] = (REG[Num] & ~Mask) | (Value & Mask)
+
+    That is, only the register bits that correspond to 1's in the
+    mask are written with the new value.
+
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |      10       |    mbz    |     Reg Number    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Register Value                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                           Mask Value                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Read Register:
+
+    Opcode:    OP_READ_REG
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |    RID    |     Reg Number    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Read Register Reply:
+
+    Opcode:    OP_READ_REG_REPLY
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       6       |    RID    |     Reg Number    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Register Value                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+I2C Write:
+
+    Opcode:    OP_I2C_WRITE
+    I2C Addr:   7-bit I2C address
+    Data:      The bytes to write to the I2C bus
+    Length:     Length of Data + 2
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |    Length     |       mbz       |   I2C Addr  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+I2C Read:
+
+    Opcode:    OP_I2C_READ
+    I2C Addr:  7-bit I2C address
+    Nbytes:    Number of bytes to read from I2C bus
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       3       |    RID    | mbz |   I2C Addr  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Nbytes    |              unspecified padding              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+I2C Read Reply:
+
+    Opcode:    OP_I2C_READ_REPLY
+    I2C Addr:  7-bit I2C address
+    Data:      Length - 2 bytes of data read from I2C bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |     Length    |    RID    | mbz |   I2C Addr  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+SPI Write:
+
+    Opcode:          OP_SPI_WRITE
+    Enables:         Which SPI enables to assert (mask)
+    Format:          Specifies format of SPI data and Opt Header Bytes
+    Opt Header Bytes: 2-byte field containing optional Tx bytes; see Format
+    Data:            The bytes to write to the SPI bus
+    Length:          Length of Data + 6
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |    Length     |              mbz              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Enables    |    Format     |        Opt Header Bytes       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+SPI Read:
+
+    Opcode:          OP_SPI_READ
+    Enables:         Which SPI enables to assert (mask)
+    Format:          Specifies format of SPI data and Opt Header Bytes
+    Opt Header Bytes: 2-byte field containing optional Tx bytes; see Format
+    Nbytes:          Number of bytes to read from SPI bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       7       |    RID    |        mbz        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Enables    |    Format     |        Opt Header Bytes       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Nbytes    |              unspecified padding              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+SPI Read Reply:
+
+    Opcode:   OP_SPI_READ_REPLY
+    Data:     Length - 2 bytes of data read from SPI bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |     Length    |    RID    |        mbz        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Delay:
+
+    Opcode:    OP_DELAY
+    Ticks:     16-bit unsigned delay count
+
+    Delay Ticks clock ticks before executing next operation.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |            Ticks              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
diff --git a/usrp/doc/inband-signaling-usb-host b/usrp/doc/inband-signaling-usb-host
new file mode 100644 (file)
index 0000000..6bfdca9
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+
+See usrp/host/lib/inband/usrp_server.mbh for interface
+
diff --git a/usrp/doc/other/.gitignore b/usrp/doc/other/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp/doc/traffic-cop-dma b/usrp/doc/traffic-cop-dma
new file mode 100644 (file)
index 0000000..0b3c350
--- /dev/null
@@ -0,0 +1,137 @@
+Matt,
+
+Here's my idea on the interface to the traffic cop.  Basically I'm
+thinking about treating it as 4 separate DMA channels, one for each of
+the four possible "flows".  In the interest of simplicity, I think we can
+assign buffers 0,1 to channel 0;  2,3 to channel 1, etc...
+
+port assignments
+-----------------
+  0   SERDES
+  1   DSP pipeline
+  2   Gigabit ethernet MAC
+  3   RAM
+
+
+registers
+---------
+
+  MBZ == Must Be Zero
+
+     3                   2                   1
+   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 
+
+
+TC_DMA_SRC_{0,3} [WR] ("traffic cop DMA source, channel N")
+
+  (The {0,3} notation means there are four of these registers,
+   one for each channel, named TC_DMA_SRC_0, TC_DMA_SRC_1,
+   TC_DMA_SRC_2, TC_DMA_3.)
+
+  Specifies where the writing port adapter writes info the buffer, and
+  the maximum number of lines to write.
+
+       5             9                  9                9  
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |0|  src  |      start      |     end (max)   |       step      |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  src:   source port number.  E.g., 2 = ethernet MAC (the buffer writer)
+  start: starting line number for transfer (32-bit lines)
+  end:   index of last line to write.  I.e., start = 0, end = 0, xfers 1 line.
+  step:  normally 1.
+
+
+TC_DMA_DST_{0,3} [WR]
+
+  Specifies the range of lines that the reading port adapter accesses.
+  The number of lines to be transferred is controlled by the source.
+
+       5             9                  9                9  
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |0|  dst  |      start      |    end (max)    |       step      |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  dst:   destination port number.  E.g., 1 = DSP pipeline (the buffer reader)
+  start: starting line number tranfer (32-bit lines)
+  end:   Must be zero, unless a TC_DMA_CMD_SEND_0 or TC_DMA_CMD_SEND_1
+         cmd is written to TC_DMA_CTRL_{0,3} in which case this
+         specifies the index of the last line to send to the destination.
+  step:  normally 1.
+
+
+TC_DMA_CTRL_{0,3} [WR]
+
+                            27                           1    4
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                         MBZ                         |A|  cmd  |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+  A:    Set if "Host Approval" is required before beginning xfer to dst.
+        Used to allow processor to inspect packet for s/w dispatch.  If set,
+       traffic cop sets PENDING_APPROVAL bit (and causes interrupt?) after the
+       2nd line has been written into the buffer.   Reader is held off
+       until hosts APPROVES or DROPS the buffer.
+
+
+  cmd:  command
+
+    TC_DMA_CMD_RESET        0  // abort active tranfers now; reset to idle state
+    TC_DMA_CMD_START        1  // begin transfers according
+    TC_DMA_CMD_STOP         2  // stop transfers at completion of current buffer
+    TC_DMA_CMD_APPROVE_0     3  // host approves xfer on even buffer, continue
+    TC_DMA_CMD_APPROVE_1     4  // host approves xfer on odd buffer, continue
+    TC_DMA_CMD_DROP_0       5  // host naks xfer on even buffer, drop buffer and continue
+    TC_DMA_CMD_DROP_1       6  // host naks xfer on even buffer, drop buffer and continue
+    TC_DMA_CMD_SEND_0       7  // copy buffer 0 to destination (processor init'd buffer)
+    TC_DMA_CMD_SEND_1       8  // copy buffer 1 to destination (processor init'd buffer)
+
+
+TC_DMA_STATUS_{0,3} [RD]
+
+           10                  10
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |    nwritten even  |   nwritten odd    |     state?    | flags |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  nwritten even:  number of lines written into even buffer
+  nwritten odd:   number of lines written into odd buffer
+
+  flag bits:
+
+    bmTCDS_PENDING_APPROVAL_0  (1 << 0)   // pending host approval on even buffer
+    bmTCDS_PENDING_APPROVAL_1  (1 << 1)   // pending host approval on odd buffer
+    bmTCDS_WRITE_DONE_0                (1 << 2)   // the even buffer write is complete
+    bmTCDS_WRITE_DONE_1                (1 << 3)   // the odd buffer write is complete
+
+I think the combination of the "host approval" and WRITE_DONE bits
+will allow us to handle the cases where the host looks and doesn't
+care, and the case where the host looks, cares, and needs to wait
+until it sees the whole packet.
+
+WRITE_DONE_* should be cleared when the corresponding buffer is
+selected to be written into (e.g., when swapping buffers, and at init)
+prior to writing the first line.  WRITE_DONE_* is set when the
+requested number of lines have been written into the buffer.
+
+
+
+I also want a "global status register" that pulls the N flag bits
+from each of the 4 status registers into a single word.  This should
+allow me to read a single word to figure out what to do.
+
+
+TC_DMA_STATUS_GLOBAL [RD]
+
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |     flags3    |     flags2    |     flags1    |     flags0    |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+// some kind of registers to enable and ack interrupts
+
+TC_DMA_INTR_EN  [WR]     // enable particular interrupts
+TC_DMA_INTR_CLR [WR]     // clear particular pending interrupts
+
diff --git a/usrp/doc/usrp_rfx_diagrams.odp b/usrp/doc/usrp_rfx_diagrams.odp
new file mode 100644 (file)
index 0000000..4521f71
Binary files /dev/null and b/usrp/doc/usrp_rfx_diagrams.odp differ
diff --git a/usrp/firmware/.gitignore b/usrp/firmware/.gitignore
new file mode 100644 (file)
index 0000000..75bb241
--- /dev/null
@@ -0,0 +1,25 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/usrp.pc
diff --git a/usrp/firmware/include/.gitignore b/usrp/firmware/include/.gitignore
new file mode 100644 (file)
index 0000000..75bb241
--- /dev/null
@@ -0,0 +1,25 @@
+/Makefile
+/Makefile.in
+/aclocal.m4
+/configure
+/config.h.in
+/stamp-h.in
+/libtool
+/config.log
+/config.h
+/config.cache
+/config.status
+/missing
+/stamp-h
+/stamp-h1
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/missing
+/make.log
+/usrp.pc
index 97ca60bf21ed40cd776680e659a8e9cb98bc6f52..e17726c07baa7a15111744ceadd7ed71b33f7a57 100644 (file)
@@ -19,7 +19,9 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-include_HEADERS =              \
+usrpincludedir = $(includedir)/usrp
+
+usrpinclude_HEADERS =          \
        usrp_i2c_addr.h         \
        usrp_spi_defs.h         \
        fpga_regs_common.h      \
index fae7bdf3576a05a17d4eb33a3e4b1aa4f69769cc..2f210f5674f4cfd9934a05f6bba6d5ad5d16e104 100644 (file)
@@ -26,8 +26,8 @@
 //   Contents:   EZ-USB FX2 register declarations and bit mask definitions.
 //
 // $Archive: /USB/Target/Inc/fx2regs.h $
-// $Date: 2007-07-20 20:44:38 -0700 (Fri, 20 Jul 2007) $
-// $Revision: 6044 $
+// $Date$
+// $Revision$
 //
 //
 //   Copyright (c) 2000 Cypress Semiconductor, All rights reserved
index 4f9ac4f9d9593cc5af115f8f8c9b45dc8987fae7..46a06943498f251c67f5bf29ecc3e43561b525bb 100644 (file)
@@ -54,6 +54,9 @@
 #define USB_PID_FSF_BDALE_7            0x0011    // Bdale Garbee <bdale@gag.com>
 #define USB_PID_FSF_BDALE_8            0x0012    // Bdale Garbee <bdale@gag.com>
 #define USB_PID_FSF_BDALE_9            0x0013    // Bdale Garbee <bdale@gag.com>
+#define USB_PID_FSF_HPSDR_HERMES       0x0014    // HPSDR Hermes
+#define USB_PID_FSF_THINKRF            0x0015    // Catalin Patulea <catalin.patulea@thinkrf.com>
+#define USB_PID_FSF_MSA                        0x0016    // Hans de Bok <hdbok@dionaea.demon.nl> Scotty's Modular Spectrum Analyzer
 
 #define USB_PID_FSF_LBNL_UXO            0x0018    // http://recycle.lbl.gov/~ldoolitt/uxo/
 
diff --git a/usrp/firmware/lib/.gitignore b/usrp/firmware/lib/.gitignore
new file mode 100644 (file)
index 0000000..04f2532
--- /dev/null
@@ -0,0 +1,18 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/*.lib
+/Makefile
+/Makefile.in
diff --git a/usrp/firmware/lib/i2c-compiler-bug.c b/usrp/firmware/lib/i2c-compiler-bug.c
new file mode 100644 (file)
index 0000000..360b779
--- /dev/null
@@ -0,0 +1,129 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c.h"
+#include "fx2regs.h"
+#include <string.h>
+
+
+// issue a stop bus cycle and wait for completion
+
+
+// returns non-zero if successful, else 0
+unsigned char
+i2c_read (unsigned char addr, xdata unsigned char *buf, unsigned char len)
+{
+  volatile unsigned char       junk;
+  
+  if (len == 0)                        // reading zero bytes always works
+    return 1;
+  
+  // memset (buf, 0, len);             // FIXME, remove
+
+  while (I2CS & bmSTOP)                // wait for stop to clear
+    ;
+
+
+  I2CS = bmSTART;
+  I2DAT = (addr << 1) | 1;     // write address and direction (1's the read bit)
+
+  while ((I2CS & bmDONE) == 0)
+    ;
+
+  if ((I2CS & bmBERR) || (I2CS & bmACK) == 0)  // no device answered...
+    goto fail;
+
+  if (len == 1)
+    I2CS |= bmLASTRD;          
+
+  junk = I2DAT;                        // trigger the first read cycle
+
+#if 1
+  while (len != 1){
+    while ((I2CS & bmDONE) == 0)
+      ;
+
+    if (I2CS & bmBERR)
+      goto fail;
+
+    len--;
+    if (len == 1)
+      I2CS |= bmLASTRD;
+    
+    *buf++ = I2DAT;            // get data, trigger another read
+  }
+#endif
+
+  // wait for final byte
+  
+  while ((I2CS & bmDONE) == 0)
+    ;
+  
+  if (I2CS & bmBERR)
+    goto fail;
+
+  I2CS |= bmSTOP;
+  *buf = I2DAT;
+
+  return 1;
+
+ fail:
+  I2CS |= bmSTOP;
+  return 0;
+}
+
+
+
+// returns non-zero if successful, else 0
+unsigned char
+i2c_write (unsigned char addr, xdata const unsigned char *buf, unsigned char len)
+{
+  while (I2CS & bmSTOP)                // wait for stop to clear
+    ;
+
+  I2CS = bmSTART;
+  I2DAT = (addr << 1) | 0;     // write address and direction (0's the write bit)
+
+  while ((I2CS & bmDONE) == 0)
+    ;
+
+  if ((I2CS & bmBERR) || (I2CS & bmACK) == 0)  // no device answered...
+    goto fail;
+
+  while (len > 0){
+    I2DAT = *buf++;
+    len--;
+
+    while ((I2CS & bmDONE) == 0)
+      ;
+
+    if ((I2CS & bmBERR) || (I2CS & bmACK) == 0)        // no device answered...
+      goto fail;
+  }
+
+  I2CS |= bmSTOP;
+  return 1;
+
+ fail:
+  I2CS |= bmSTOP;
+  return 0;
+}
diff --git a/usrp/firmware/src/.gitignore b/usrp/firmware/src/.gitignore
new file mode 100644 (file)
index 0000000..d46c52c
--- /dev/null
@@ -0,0 +1,17 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile
+/Makefile.in
diff --git a/usrp/firmware/src/common/.gitignore b/usrp/firmware/src/common/.gitignore
new file mode 100644 (file)
index 0000000..d46c52c
--- /dev/null
@@ -0,0 +1,17 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile
+/Makefile.in
diff --git a/usrp/firmware/src/common/_startup.a51.brittle b/usrp/firmware/src/common/_startup.a51.brittle
new file mode 100644 (file)
index 0000000..2996275
--- /dev/null
@@ -0,0 +1,78 @@
+;;; -*- asm -*-
+;;;
+;;; Copyright 2003 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.
+
+    
+;;; The default external memory initialization provided by sdcc is not
+;;; appropriate to the FX2.  This is derived from the sdcc code, but uses 
+;;; the FX2 specific _MPAGE sfr.
+
+
+       .area XISEG   (XDATA)   ; the initialized external data area
+       .area XINIT   (CODE)    ; the code space consts to init XISEG
+       .area XSEG    (XDATA)   ; zero initialized xdata
+       .area USBDESCSEG (XDATA); usb descriptors
+
+       
+       ;; BIG TIME KLUDGE!
+       ;; Look at usrp_main.rst and count the bytes from our
+       ;; "normal return location" to the first instruction following
+       ;; the comment: "_mcs51_getRAMCLEAR () start"
+       
+       INSTRUCTION_BYTES_TO_SKIP = 0x29         ; valid for sdcc 2.4.0 
+       
+
+       .area CSEG    (CODE)
+
+       ;; sfr that sets upper address byte of MOVX using @r0 or @r1
+       _MPAGE  =       0x0092
+
+__sdcc_external_startup::
+;      _mcs51_genXINIT() start
+       mov     r1,#l_XINIT
+       mov     a,r1
+       orl     a,#(l_XINIT >> 8)
+       jz      00003$
+       mov     r2,#((l_XINIT+255) >> 8)
+       mov     dptr,#s_XINIT
+       mov     r0,#s_XISEG
+       mov     _MPAGE,#(s_XISEG >> 8)
+00001$:        clr     a
+       movc    a,@a+dptr
+       movx    @r0,a
+       inc     dptr
+       inc     r0
+       cjne    r0,#0,00002$
+       inc     _MPAGE
+00002$:        djnz    r1,00001$
+       djnz    r2,00001$
+       mov     _MPAGE,#0xFF
+00003$:
+
+       ;; Danger! Total KLUDGE!
+       ;; We pop the return address, add a magic number to it
+       ;; then jump to that address.  Believe it or not, this
+       ;; looks like the least kludgy way to handle this,
+       ;; short of patching the compiler...
+
+       pop     dph
+       pop     dpl
+       mov     a,#INSTRUCTION_BYTES_TO_SKIP
+       jmp     @a+dptr
index 023c4b3f5797ba79b9144684f856f53f82144f71..00c2e3414138ace2c51870ad1a9d0bc733c373a0 100755 (executable)
@@ -140,13 +140,13 @@ def build_eeprom_image (filename, rev):
     assert (len (image) <= 256)
     return image
 
-def build_shell_script (out, ihx_filename, rev):
+def build_shell_script (out, ihx_filename, rev, prefix):
 
     image = build_eeprom_image (ihx_filename, rev)
 
     out.write ('#!/bin/sh\n')
-    out.write ('usrper -x load_firmware /usr/local/share/usrp/rev%d/std.ihx\n' % rev)
-    out.write ('sleep 1\n')
+    out.write ('usrper -x load_firmware ' + prefix + '/share/usrp/rev%d/std.ihx\n' % rev)
+    out.write ('sleep 2\n')
     
     # print "len(image) =", len(image)
     
@@ -161,11 +161,13 @@ def build_shell_script (out, ihx_filename, rev):
                    (i2c_addr, rom_addr, ''.join (hex_image[0:l])))
         hex_image = hex_image[l:]
         rom_addr = rom_addr + l
-        out.write ('sleep 1\n')
+        out.write ('sleep 2\n')
 
 if __name__ == '__main__':
-    usage = "usage: %prog -r REV [options] bootfile.ihx"
+    usage = "usage: %prog -p PREFIX -r REV [options] bootfile.ihx"
     parser = OptionParser (usage=usage)
+    parser.add_option ("-p", "--prefix", type="string", default="",
+                       help="Specify install prefix from configure")
     parser.add_option ("-r", "--rev", type="int", default=-1,
                        help="Specify USRP revision number REV (2 or 4)")
     (options, args) = parser.parse_args ()
@@ -176,7 +178,11 @@ if __name__ == '__main__':
         sys.stderr.write (
             "You must specify the USRP revision number (2 or 4) with -r REV\n")
         sys.exit (1)
+    if options.prefix == "":
+        sys.stderr.write (
+            "You must specify the install prefix with -p PREFIX\n")
+        sys.exit (1)
 
     ihx_filename = args[0]
 
-    build_shell_script (sys.stdout, ihx_filename, options.rev)
+    build_shell_script (sys.stdout, ihx_filename, options.rev, options.prefix)
diff --git a/usrp/firmware/src/usrp2/.gitignore b/usrp/firmware/src/usrp2/.gitignore
new file mode 100644 (file)
index 0000000..54a9e94
--- /dev/null
@@ -0,0 +1,20 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/Makefile
+/Makefile.in
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile.in
+/burn-usrp2-eeprom
+/burn-usrp4-eeprom
index e380b19074b41782ba211fd9f0fb62aff43b52c0..4402cd6365901e4cba936a26f7d3d41448e63b42 100644 (file)
@@ -108,11 +108,11 @@ eeprom_boot.ihx: $(EEPROM_BOOT_OBJS) $(LIBDEP)
        $(XCC) $(LINKOPTS) -o $@ $(EEPROM_BOOT_OBJS)
 
 burn-usrp2-eeprom: eeprom_boot.ihx
-       $(PYTHON) $(srcdir)/../common/build_eeprom.py -r2 eeprom_boot.ihx > $@
+       $(PYTHON) $(srcdir)/../common/build_eeprom.py -p$(prefix) -r2 eeprom_boot.ihx > $@
        chmod +x $@
 
 burn-usrp4-eeprom: eeprom_boot.ihx
-       $(PYTHON) $(srcdir)/../common/build_eeprom.py -r4 eeprom_boot.ihx > $@
+       $(PYTHON) $(srcdir)/../common/build_eeprom.py -p$(prefix) -r4 eeprom_boot.ihx > $@
        chmod +x $@
 
 
diff --git a/usrp/firmware/src/usrp2/gpif.gpf b/usrp/firmware/src/usrp2/gpif.gpf
new file mode 100755 (executable)
index 0000000..854e253
Binary files /dev/null and b/usrp/firmware/src/usrp2/gpif.gpf differ
diff --git a/usrp/fpga/.gitignore b/usrp/fpga/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 8721af4a796fa58748729107872e99c3a1a874bb..901a66f0fd9e03ae5f1f40045706561ba2c6d40b 100644 (file)
@@ -20,5 +20,3 @@
 # 
 
 SUBDIRS = rbf
-
-include Makefile.extra
diff --git a/usrp/fpga/README b/usrp/fpga/README
new file mode 100644 (file)
index 0000000..3d1e7ad
--- /dev/null
@@ -0,0 +1,3 @@
+The FPGA source content that used to be here is now hosted at:
+
+git://ettus.sourcerepo.com/ettus/fpga.git
diff --git a/usrp/fpga/rbf/.gitignore b/usrp/fpga/rbf/.gitignore
new file mode 100644 (file)
index 0000000..eb58a95
--- /dev/null
@@ -0,0 +1,4 @@
+/Makefile
+/Makefile.in
+/usrp_fpga_rev1.rbf
+/usrp_fpga_rev2.rbf
diff --git a/usrp/fpga/rbf/rev2/.gitignore b/usrp/fpga/rbf/rev2/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp/fpga/rbf/rev2/multi_4rx_0tx.rbf b/usrp/fpga/rbf/rev2/multi_4rx_0tx.rbf
new file mode 100755 (executable)
index 0000000..b7e4eb3
Binary files /dev/null and b/usrp/fpga/rbf/rev2/multi_4rx_0tx.rbf differ
diff --git a/usrp/fpga/rbf/rev4/.gitignore b/usrp/fpga/rbf/rev4/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp/fpga/rbf/rev4/multi_4rx_0tx.rbf b/usrp/fpga/rbf/rev4/multi_4rx_0tx.rbf
new file mode 100755 (executable)
index 0000000..b7e4eb3
Binary files /dev/null and b/usrp/fpga/rbf/rev4/multi_4rx_0tx.rbf differ
diff --git a/usrp/host/.gitignore b/usrp/host/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
index ac9fd1a4290a86f1e549a832f11bba3da2d62223..aa94fbd6ec31cece1a4d84d949c516c352245735 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2007 Free Software Foundation, Inc.
+# Copyright 2001,2007,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -19,4 +19,8 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-SUBDIRS = misc lib swig apps
+SUBDIRS = misc lib include apps
+
+if PYTHON
+SUBDIRS += swig
+endif 
diff --git a/usrp/host/apps/.gitignore b/usrp/host/apps/.gitignore
new file mode 100644 (file)
index 0000000..16fdf27
--- /dev/null
@@ -0,0 +1,27 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.dat
+/usrper
+/usrper2
+/test_input
+/test_fusb
+/test_usrp
+/test_usrp0
+/test_usrp_standard_rx
+/test_usrp_standard_tx
+/test_usrp_inband_timestamps
+/test_usrp_inband_registers
+/test_usrp_inband_rx
+/test_usrp_inband_tx
+/test_usrp_basic_rx
+/check_order_quickly
+/usrp_cal_dc_offset
+/test_usrp_inband_cs
+/read_packets
+/test_usrp_inband_ping
index b0c21d55fee6941f69f1776a23e808f511312c21..8aa361b22fcb397cbe7f173e9437f9d89bacde29 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2003,2006,2008 Free Software Foundation, Inc.
+# Copyright 2003,2006,2008,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -22,7 +22,7 @@
 include $(top_srcdir)/Makefile.common
 
 AM_CPPFLAGS = $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \
-          $(WITH_INCLUDES)
+          $(USB_INCLUDES) $(WITH_INCLUDES)
 
 bin_PROGRAMS =                         \
        usrper                          \
index e9ff9f5bc61c6e6f6cbfb657dc28e6f5924a8895..8fb9143eb7a25fcfbea75cbd3c5f4a03d2d9cf88 100755 (executable)
@@ -1,24 +1,24 @@
 #!/usr/bin/env python
 #
-# Copyright 2005,2007 Free Software Foundation, Inc.
-# 
+# Copyright 2005,2007,2009 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 usrpm.usrp_prims import *
 from optparse import OptionParser
@@ -36,6 +36,9 @@ daughterboards = {
     'tvrx'            : (None,                      (TV_RX, 0x0000)),
     'tvrx2'           : (None,                      (TV_RX_REV_2, 0x0000)),
     'tvrx3'           : (None,                      (TV_RX_REV_3, 0x0000)),
+    'tvrx_mimo'       : (None,                      (TV_RX_MIMO, 0x0000)),
+    'tvrx2_mimo'      : (None,                      (TV_RX_REV_2_MIMO, 0x0000)),
+    'tvrx3_mimo'      : (None,                      (TV_RX_REV_3_MIMO, 0x0000)),
     'dtt754'          : (None,                      (DTT754, 0x0000)),
     'dtt768'          : (None,                      (DTT768, 0x0000)),
     'rfx400'          : ((FLEX_400_TX, 0x0000),     (FLEX_400_RX, 0x0000)),
@@ -66,7 +69,9 @@ daughterboards = {
     'lftx'            : ((LF_TX, 0x0000),           None),
     'lfrx'            : (None,                      (LF_RX, 0x0000)),
     'wbx_lo'          : ((WBX_LO_TX, 0x0000),       (WBX_LO_RX, 0x0000)),
+    'wbx_ng'          : ((WBX_NG_TX, 0x0000),       (WBX_NG_RX, 0x0000)),
     'xcvr2450'        : ((XCVR2450_TX, 0x0000),       (XCVR2450_RX, 0x0000)),
+    'bitshark_rx'     : (None,                      (BITSHARK_RX, 0x0000)),
     'experimental_tx' : ((EXPERIMENTAL_TX, 0x0000), None),
     'experimental_rx' : (None,                      (EXPERIMENTAL_RX, 0x0000)),
     }
@@ -101,11 +106,11 @@ def init_eeprom(u, slot_name, force, dbid, oe):
     if not e:
         print "%s: no d'board, skipped" % (slot_name,)
         return True
-    
+
     if not force and (sum (map (ord, e)) & 0xff) == 0 and ord (e[0]) == 0xDB:
         print "%s: already initialized, skipped" % (slot_name,)
         return True
-        
+
     if not write_dboard_eeprom (u, i2c_addr, dbid, oe):
         print "%s: failed to write d'board EEPROM" % (slot_name,)
         return False
@@ -165,4 +170,4 @@ and at least one side using -A and/or -B."""
 
 if __name__ == "__main__":
     main ()
-    
+
diff --git a/usrp/host/apps/check_order b/usrp/host/apps/check_order
new file mode 100755 (executable)
index 0000000..56e1927
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# -*- Python -*-
+
+import sys
+import fileinput
+
+skip_count = 4096
+lineno = 0
+last_error = 0
+
+for line in fileinput.input ():
+    lineno += 1
+    if lineno < skip_count:
+        continue
+    (offset, dec_val, hex_val) = line.split ()
+    if lineno == skip_count:
+        expected_val = int (dec_val)
+    int_dec_val = int (dec_val)
+    int_hex_val = int (hex_val, 16)
+    if int_dec_val != expected_val:
+        print "line %6d, delta %4d, expected %6d, got %6d" % (lineno,
+                                                              lineno - last_error,
+                                                              expected_val,
+                                                              int_dec_val)
+        last_error = lineno
+    elif ((int_hex_val >> 12) & 0xf) != (int_hex_val & 0xf):
+        print "line %6d, delta %4d, invalid high bits %04x" % (lineno,
+                                                               lineno - last_error,
+                                                               int_hex_val)
+        last_error = lineno
+        
+    # expected_val = (expected_val + 1) & 0xffff
+    expected_val = (expected_val + 1) & 0x0fff
+    
+
+        
+    
+
+    
diff --git a/usrp/host/apps/dump_12bit_shorts b/usrp/host/apps/dump_12bit_shorts
new file mode 100755 (executable)
index 0000000..a896f2d
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# -*- Python -*-
+
+import sys, errno
+
+counter = 0
+
+try:
+    while 1:
+        x = sys.stdin.read (2)
+        if not x:
+            break
+
+        v = (ord(x[1]) << 8) | ord(x[0])
+        sys.stdout.write ("0x%08x  %6d  0x%04x\n" % (counter, v & 0x0fff, v))
+        counter += 1
+except IOError, e:
+    if e.errno == errno.EPIPE:
+        sys.exit (0)
+    
+  
+  
+
diff --git a/usrp/host/apps/dump_shorts b/usrp/host/apps/dump_shorts
new file mode 100755 (executable)
index 0000000..6104ea0
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# -*- Python -*-
+
+import sys, errno
+
+counter = 0
+
+try:
+    while 1:
+        x = sys.stdin.read (2)
+        if not x:
+            break
+
+        v = (ord(x[1]) << 8) | ord(x[0])
+        sys.stdout.write ("0x%08x  %6d  0x%04x\n" % (counter, v, v))
+        counter += 1
+except IOError, e:
+    if e.errno == errno.EPIPE:
+        sys.exit (0)
+    
+  
+  
+
diff --git a/usrp/host/apps/run b/usrp/host/apps/run
new file mode 100755 (executable)
index 0000000..5b13336
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+./test_usrp_standard_rx -D 8 -o rx.bin
+./dump_12bit_shorts <rx.bin | head -100000 >rx.ascii
+./check_order rx.ascii
+#./dump_12bit_shorts <rx.bin | ./check_order
diff --git a/usrp/host/apps/run2 b/usrp/host/apps/run2
new file mode 100755 (executable)
index 0000000..5fcf154
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+./test_usrp_standard_rx -D 8 -o rx.bin
+./check_order_quickly <rx.bin
diff --git a/usrp/host/apps/run_input b/usrp/host/apps/run_input
new file mode 100755 (executable)
index 0000000..b8afae6
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test_usrp_standard_rx -D 8 -o rx.bin "$@"
+./dump_shorts <rx.bin | head -50000 >rx.ascii
+
index 4a47daa95b1d2c8630b6411ba12c8e5c8eb7fe45..4098decda43cdbab4a42fd7c0fe40af365963e3e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2006,2008 Free Software Foundation, Inc.
+ * Copyright 2003,2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <usb.h>                       /* needed for usb functions */
 #include <getopt.h>
 #include <assert.h>
 #include <math.h>
 #include "time_stuff.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 #include "fpga_regs_common.h"
 #include "fpga_regs_standard.h"
 
index 3cc20c4472a7e4988bc3663c1cbd45c02f4338e1..cc9f9edfccf984129f29e9f5cf59fbb54ec1520b 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <usb.h>                       /* needed for usb functions */
 #include <getopt.h>
 #include <assert.h>
 #include <math.h>
 #include "time_stuff.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 #include <boost/program_options.hpp>
 
 enum {
index 5ebac12a367b9bb973c5ee28d2a5e08b3dea2bb3..5f708d672c01d1abc359fc2152d7e7cfec57d5f6 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2008 Free Software Foundation, Inc.
+ * Copyright 2005,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <usb.h>                       /* needed for usb functions */
 #include <getopt.h>
 #include <assert.h>
 #include <math.h>
 #include <boost/scoped_ptr.hpp>
-#include "usrp_local_sighandler.h"
-#include "usrp_standard.h"
-#include "usrp_bytesex.h"
+#include <usrp/usrp_local_sighandler.h>
+#include <usrp/usrp_standard.h>
+#include <usrp/usrp_bytesex.h>
 
 char *prog_name;
 
index 3740022e0ace1342840bc7d4aa5889755445c86f..593cd7921e1e5694690d45b151f34eeb970117bb 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * USRP - Universal Software Radio Peripheral
  *
- * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2004,2009 Free Software Foundation, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <usb.h>                       /* needed for usb functions */
 #include <getopt.h>
 #include <assert.h>
 #include <errno.h>
 
-#include "usrp_prims.h"
+#include "usrp/usrp_prims.h"
 #include "usrp_spi_defs.h"
-#include <string.h>
 
 char *prog_name;
 
-
 static void
 set_progname (char *path)
 {
@@ -194,7 +195,7 @@ main (int argc, char **argv)
   usrp_one_time_init ();
 
   
-  struct usb_device *udev = usrp_find_device (which_board, fx2_ok_p);
+  libusb_device *udev = usrp_find_device (which_board, fx2_ok_p);
   if (udev == 0){
     fprintf (stderr, "%s: failed to find usrp[%d]\n", prog_name, which_board);
     exit (1);
@@ -208,7 +209,7 @@ main (int argc, char **argv)
     fprintf (stderr, "%s: found unconfigured FX2; needs firmware.\n", prog_name);
   }
 
-  struct usb_dev_handle *udh = usrp_open_cmd_interface (udev);
+  libusb_device_handle *udh = usrp_open_cmd_interface (udev);
   if (udh == 0){
     fprintf (stderr, "%s: failed to open_cmd_interface\n", prog_name);
     exit (1);
diff --git a/usrp/host/include/.gitignore b/usrp/host/include/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp/host/include/Makefile.am b/usrp/host/include/Makefile.am
new file mode 100644 (file)
index 0000000..5de5fe5
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Copyright 2009 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 = usrp
+
diff --git a/usrp/host/include/usrp/.gitignore b/usrp/host/include/usrp/.gitignore
new file mode 100644 (file)
index 0000000..0f068a1
--- /dev/null
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+
+# Generated files
+/libusb_types.h
+/usrp_dbid.h
diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am
new file mode 100644 (file)
index 0000000..2aaf66a
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+usrpincludedir = $(includedir)/usrp
+
+usrpinclude_HEADERS = \
+       db_base.h \
+       db_basic.h \
+       db_bitshark_rx.h \
+       db_dbs_rx.h \
+       db_dtt754.h \
+       db_dtt768.h \
+       db_flexrf.h \
+       db_flexrf_mimo.h \
+       db_tv_rx.h \
+       db_tv_rx_mimo.h \
+       db_wbxng.h \
+       db_xcvr2450.h \
+       libusb_types.h \
+       usrp_basic.h \
+       usrp_bytesex.h \
+       usrp_dbid.h \
+       usrp_local_sighandler.h \
+       usrp_prims.h \
+       usrp_slots.h \
+       usrp_standard.h \
+       usrp_subdev_spec.h \
+       usrp_tune_result.h
+
+EXTRA_DIST = \
+       libusb_types.h.in
+
+if PYTHON
+swiginclude_HEADERS = \
+       db_base.i
+endif
diff --git a/usrp/host/include/usrp/db_base.h b/usrp/host/include/usrp/db_base.h
new file mode 100644 (file)
index 0000000..3547089
--- /dev/null
@@ -0,0 +1,119 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+//
+
+#ifndef INCLUDED_DB_BASE_H
+#define INCLUDED_DB_BASE_H
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <iosfwd>
+
+class db_base;
+typedef boost::shared_ptr<db_base> db_base_sptr;
+
+class usrp_basic;
+typedef boost::shared_ptr<usrp_basic> usrp_basic_sptr;
+
+struct freq_result_t
+{
+  bool  ok;
+  double baseband_freq;
+};
+
+/******************************************************************************/
+
+/*!
+ * \brief Abstract base class for all USRP daughterboards
+ * \ingroup usrp
+ */
+class db_base
+{
+ protected:
+  bool                         d_is_shutdown;
+  usrp_basic                  *d_raw_usrp;
+  int                          d_which;
+  double                       d_lo_offset;
+
+  void _enable_refclk(bool enable);
+  virtual double _refclk_freq();
+  virtual int _refclk_divisor();
+
+  usrp_basic *usrp(){
+    return d_raw_usrp;
+  }
+
+ public:
+  db_base(boost::shared_ptr<usrp_basic> usrp, int which);
+  virtual ~db_base();
+
+  int dbid();
+  std::string name();
+  std::string side_and_name();
+  int which() { return d_which; }
+
+  bool bypass_adc_buffers(bool bypass);
+  bool set_atr_mask(int v);
+  bool set_atr_txval(int v);
+  bool set_atr_rxval(int v);
+  bool set_atr_tx_delay(int v);
+  bool set_atr_rx_delay(int v);
+  bool set_lo_offset(double offset);
+  double lo_offset() { return d_lo_offset; }
+
+
+  ////////////////////////////////////////////////////////
+  // derived classes should override the following methods
+
+protected:
+  friend class usrp_basic;
+
+  /*!
+   * Called to shutdown daughterboard.  Called from dtor and usrp_basic dtor.
+   *
+   * N.B., any class that overrides shutdown MUST call shutdown in its destructor.
+   */
+  virtual void shutdown();
+
+
+public:
+  virtual float gain_min() = 0;
+  virtual float gain_max() = 0;
+  virtual float gain_db_per_step() = 0;
+  virtual double freq_min() = 0;
+  virtual double freq_max() = 0;
+  virtual struct freq_result_t set_freq(double target_freq) = 0;
+  virtual bool set_gain(float gain) = 0;
+  virtual bool is_quadrature() = 0;
+  virtual bool i_and_q_swapped();
+  virtual bool spectrum_inverted();
+  virtual bool set_enable(bool on);
+  virtual bool set_auto_tr(bool on);
+  virtual bool select_rx_antenna(int which_antenna);
+  virtual bool select_rx_antenna(const std::string &which_antenna);
+  virtual bool set_bw(float bw);
+};
+
+
+std::ostream & operator<<(std::ostream &os, db_base &x);
+
+#endif /* INCLUDED_DB_BASE_H */
diff --git a/usrp/host/include/usrp/db_base.i b/usrp/host/include/usrp/db_base.i
new file mode 100644 (file)
index 0000000..78c72b8
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3, or (at your option)
+// any later version.
+// 
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+//
+
+
+%{
+#include <usrp/db_base.h>
+%}
+
+%include <gr_shared_ptr.i>
+
+class usrp_tune_result
+{
+public:  
+  usrp_tune_result(double baseband=0, double dxc=0, 
+                  double residual=0, bool inv=0);
+  ~usrp_tune_result();
+
+  double baseband_freq;
+  double dxc_freq;
+  double residual_freq;
+  bool  inverted;
+};
+
+struct freq_result_t
+{
+  bool  ok;
+  double baseband_freq;
+};
+
+class db_base
+{
+ private:
+  db_base(boost::shared_ptr<usrp_basic> usrp, int which);
+
+ public:
+  virtual ~db_base();
+
+  int dbid();
+  std::string name();
+  std::string side_and_name();
+  int which() { return d_which; }
+
+  bool bypass_adc_buffers(bool bypass);
+  bool set_atr_mask(int v);
+  bool set_atr_txval(int v);
+  bool set_atr_rxval(int v);
+  bool set_atr_tx_delay(int v);
+  bool set_atr_rx_delay(int v);
+  bool set_lo_offset(double offset);
+  double lo_offset() { return d_lo_offset; }
+
+  virtual float gain_min() = 0;
+  virtual float gain_max() = 0;
+  virtual float gain_db_per_step() = 0;
+  virtual double freq_min() = 0;
+  virtual double freq_max() = 0;
+  virtual struct freq_result_t set_freq(double target_freq) = 0;
+  virtual bool set_gain(float gain) = 0;
+  virtual bool is_quadrature() = 0;
+  virtual bool i_and_q_swapped();
+  virtual bool spectrum_inverted();
+  virtual bool set_enable(bool on);
+  virtual bool set_auto_tr(bool on);
+  virtual bool select_rx_antenna(int which_antenna);
+  virtual bool select_rx_antenna(const std::string &antenna);
+  virtual bool set_bw(float bw);
+};
+
+// Create templates for db's, vectors of db's, and vector of vectors of db's
+typedef boost::shared_ptr<db_base> db_base_sptr;
+%template(db_base_sptr) boost::shared_ptr<db_base>;
+%template(db_base_sptr_vector) std::vector<db_base_sptr>;
+%template(db_base_sptr_vector_vector) std::vector<std::vector<db_base_sptr> >;
+
+// Set better class name in Python
+// Enable freq_range and gain_range from public methods of class not implemented in C++
+// And create a dummy wrapper for backwards compatability with some of the example code
+%pythoncode %{
+  db_base_sptr.__repr__ = lambda self: "<db_base::%s>" % (self.name(),)
+  db_base_sptr.freq_range = lambda self: (self.freq_min(), self.freq_max(), 1)
+  db_base_sptr.gain_range = lambda self: (self.gain_min(), self.gain_max(), self.gain_db_per_step())
+
+%}
diff --git a/usrp/host/include/usrp/db_basic.h b/usrp/host/include/usrp/db_basic.h
new file mode 100644 (file)
index 0000000..7f81733
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_BASIC_H
+#define DB_BASIC_H
+
+#include <usrp/db_base.h>
+
+
+/******************************************************************************/
+
+
+class db_basic_tx : public db_base
+{
+public:
+  db_basic_tx(usrp_basic_sptr usrp, int which);
+  ~db_basic_tx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double target_freq);
+  bool  set_gain(float gain);
+  bool  is_quadrature();
+};
+
+
+/******************************************************************************/
+
+
+class db_basic_rx : public db_base
+{
+ public:
+  db_basic_rx(usrp_basic_sptr usrp, int which, int subdev);
+  ~db_basic_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double target_freq);
+  bool set_gain(float gain);
+  bool is_quadrature();
+
+private:
+  int d_subdev;
+};
+
+
+/******************************************************************************/
+
+
+class db_lf_rx : public db_basic_rx
+{
+ public:
+  db_lf_rx(usrp_basic_sptr usrp, int which, int subdev);
+  ~db_lf_rx();
+  
+  double freq_min();
+  double freq_max();
+};
+
+
+/******************************************************************************/
+
+
+class db_lf_tx : public db_basic_tx
+{ 
+ public:
+  db_lf_tx(usrp_basic_sptr usrp, int which);
+  ~db_lf_tx();
+  
+  double freq_min();
+  double freq_max();
+};
+
+
+#endif
diff --git a/usrp/host/include/usrp/db_bitshark_rx.h b/usrp/host/include/usrp/db_bitshark_rx.h
new file mode 100644 (file)
index 0000000..f81877d
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+//
+// Copyright 2010 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 asversion 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.
+
+#ifndef DB_BITSHARK_RX_H
+#define DB_BITSHARK_RX_H
+
+#include <usrp/db_base.h>
+#include <vector>
+#include <stdint.h>
+
+class db_bitshark_rx : public db_base
+{
+private:
+    int d_i2c_addr;
+    // Internal function for interfacing to the card
+    void _set_pga(int pga_gain);
+    
+protected:
+    void shutdown();
+    
+public:
+    db_bitshark_rx(usrp_basic_sptr usrp, int which);
+    ~db_bitshark_rx();
+    
+    float gain_min();
+    float gain_max();
+    float gain_db_per_step();
+    double freq_min();
+    double freq_max();
+    struct freq_result_t set_freq(double freq);
+    bool  set_gain(float gain);
+    bool  set_bw(float bw);
+    bool  set_clock_scheme(uint8_t clock_scheme, uint32_t ref_clock_freq);
+    bool  is_quadrature();
+    bool  i_and_q_swapped();
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_dbs_rx.h b/usrp/host/include/usrp/db_dbs_rx.h
new file mode 100644 (file)
index 0000000..7f86963
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_DBS_RX_H
+#define DB_DBS_RX_H
+
+#include <usrp/db_base.h>
+#include <vector>
+
+#if 0
+struct bw_t {
+  int m;
+  int fdac;
+  float div;
+};
+#endif
+
+class db_dbs_rx : public db_base
+{
+private:
+  int d_osc, d_cp, d_n, d_div2, d_r, d_r_int;
+  int d_fdac, d_m, d_dl, d_ade, d_adl, d_gc1, d_gc2, d_diag;
+  int d_i2c_addr;
+  
+  // Internal gain functions
+  void _write_reg(int regno, int v);
+  void _write_regs(int starting_regno, const std::vector<int> &vals);
+  std::vector<int> _read_status();
+  void _send_reg(int regno);
+  void _set_m(int m);
+  void _set_fdac(int fdac);
+  void _set_dl(int dl);
+  void _set_gc2(int gc2);
+  void _set_gc1(int gc1);
+  void _set_pga(int pga_gain);
+
+  // Internal frequency function
+  void _set_osc(int osc);
+  void _set_cp(int cp);
+  void _set_n(int n);
+  void _set_div2(int div2);
+  void _set_r(int r);
+  void _set_ade(int ade);
+
+  int _refclk_divisor();
+
+protected:
+  void shutdown();
+
+public:
+  db_dbs_rx(usrp_basic_sptr usrp, int which);
+  ~db_dbs_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double freq);
+  bool  set_gain(float gain);
+  bool  is_quadrature();
+  bool  set_bw(float bw);
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_dtt754.h b/usrp/host/include/usrp/db_dtt754.h
new file mode 100644 (file)
index 0000000..4fb9528
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_DTT754_H
+#define DB_DTT754_H
+
+#include <usrp/db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class db_dtt754 : public db_base
+{
+public:
+  db_dtt754(usrp_basic_sptr usrp, int which);
+  ~db_dtt754();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double target_freq);
+  
+  bool is_quadrature();
+  bool spectrum_inverted();
+  bool set_bw(float bw);
+
+private:
+  void _set_rfagc(float gain);
+  void _set_ifagc(float gain);
+  void _set_pga(float pga_gain);
+
+  int d_i2c_addr;
+  float d_bw, d_freq, d_IF, d_f_ref;
+  bool d_inverted;
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_dtt768.h b/usrp/host/include/usrp/db_dtt768.h
new file mode 100644 (file)
index 0000000..78e157e
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_DTT768_H
+#define DB_DTT768_H
+
+#include <usrp/db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class db_dtt768 : public db_base
+{
+public:
+  db_dtt768(usrp_basic_sptr usrp, int which);
+  ~db_dtt768();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double target_freq);
+  
+  bool is_quadrature();
+  bool spectrum_inverted();
+  bool set_bw(float bw);
+
+private:
+  void _set_rfagc(float gain);
+  void _set_ifagc(float gain);
+  void _set_pga(float pga_gain);
+
+  int d_i2c_addr;
+  float d_bw, d_freq, d_IF, d_f_ref;
+  bool d_inverted;
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_flexrf.h b/usrp/host/include/usrp/db_flexrf.h
new file mode 100644 (file)
index 0000000..0c83440
--- /dev/null
@@ -0,0 +1,354 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_FLEXRF_H
+#define DB_FLEXRF_H
+
+#include <usrp/db_base.h>
+#include <cmath>
+
+//debug_using_gui = true                // Must be set to True or False
+#define debug_using_gui false           // Must be set to True or False
+
+class _AD4360_common;
+
+class flexrf_base : public db_base
+{
+public:
+  flexrf_base(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~flexrf_base();
+
+  struct freq_result_t set_freq(double freq);
+
+  bool  is_quadrature();
+  double freq_min();
+  double freq_max();
+
+protected:
+  void _write_all(int R, int control, int N);
+  void _write_control(int control);
+  void _write_R(int R);
+  void _write_N(int N);
+  void _write_it(int v);
+  bool _lock_detect();
+
+  virtual bool _compute_regs(double freq, int &retR, int &retcontrol, 
+                            int &retN, double &retfreq);
+  int  _compute_control_reg();
+  int _refclk_divisor();
+
+  bool _set_pga(float pga_gain);
+
+  int power_on() { return d_power_on; }
+  int power_off() { return 0; }
+
+  bool d_first;
+  int  d_spi_format;
+  int  d_spi_enable;
+  int  d_power_on;
+  int  d_PD;
+
+  _AD4360_common *d_common;
+};
+
+// ----------------------------------------------------------------
+
+class flexrf_base_tx : public flexrf_base
+{
+protected:
+  void shutdown();
+
+public:
+  flexrf_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~flexrf_base_tx();
+
+  // All RFX tx d'boards have fixed gain
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+
+  bool set_auto_tr(bool on);
+  bool set_enable(bool on);
+  bool set_gain(float gain);
+};
+
+class flexrf_base_rx : public flexrf_base
+{
+protected:
+  void shutdown();
+
+public:
+  flexrf_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~flexrf_base_rx();
+    
+  bool set_auto_tr(bool on);
+  bool select_rx_antenna(int which_antenna);
+  bool select_rx_antenna(const std::string &which_antenna);
+  bool set_gain(float gain);
+
+};
+
+// ----------------------------------------------------------------
+
+
+class _AD4360_common
+{
+public:
+  _AD4360_common();
+  virtual ~_AD4360_common();
+
+  virtual double freq_min() = 0;
+  virtual double freq_max() = 0;
+
+  bool _compute_regs(double refclk_freq, double freq, int &retR, 
+                    int &retcontrol, int &retN, double &retfreq);
+  int _compute_control_reg();
+  virtual int _refclk_divisor();
+  int _prescaler();
+
+  void R_DIV(int div) { d_R_DIV = div; }
+
+protected:
+  int d_R_RSV, d_BSC, d_TEST, d_LDP, d_ABP, d_N_RSV, d_PL, d_MTLD;
+  int d_CPG, d_CP3S, d_PDP, d_MUXOUT, d_CR, d_PC;
+
+  // FIXME: d_PD might cause conflict from flexrf_base
+  int d_A_DIV, d_B_DIV, d_R_DIV, d_P, d_PD, d_CP2, d_CP1, d_DIVSEL;
+  int d_DIV2, d_CPGAIN, d_freq_mult;
+
+};
+
+//----------------------------------------------------------------------
+
+class _2400_common : public _AD4360_common
+{
+ public:
+  _2400_common();
+  ~_2400_common() {}
+  double freq_min();
+  double freq_max();
+};
+
+//----------------------------------------------------------------------
+
+class _1200_common : public _AD4360_common
+{
+public:
+  _1200_common();
+  ~_1200_common() {}
+
+  double freq_min();
+  double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _1800_common : public _AD4360_common
+{
+ public:
+  _1800_common();
+  ~_1800_common() {}
+
+  double freq_min();
+  double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _900_common : public _AD4360_common
+{
+public:
+  _900_common();
+  ~_900_common() {}
+  
+  double freq_min();
+  double freq_max();
+};
+
+//-------------------------------------------------------------------------
+
+class _400_common : public _AD4360_common
+{
+public:
+  _400_common();
+  ~_400_common() {}
+
+  double freq_min();
+  double freq_max();
+};
+
+class _400_tx : public _400_common
+{
+public:
+  _400_tx();
+  ~_400_tx() {}
+};
+
+class _400_rx : public _400_common
+{
+public:
+  _400_rx();
+  ~_400_rx() {}
+};
+
+//------------------------------------------------------------    
+
+class db_flexrf_2400_tx : public flexrf_base_tx
+{
+ public:
+  db_flexrf_2400_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_2400_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_2400_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_2400_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_2400_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+//------------------------------------------------------------    
+
+class db_flexrf_1200_tx : public flexrf_base_tx
+{
+public:
+  db_flexrf_1200_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_1200_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_1200_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_1200_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_1200_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+//------------------------------------------------------------    
+
+class db_flexrf_1800_tx : public flexrf_base_tx
+{
+ public:
+  db_flexrf_1800_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_1800_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_1800_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_1800_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_1800_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+//------------------------------------------------------------    
+
+class db_flexrf_900_tx : public flexrf_base_tx
+{
+ public:
+  db_flexrf_900_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_900_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_900_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_900_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_900_rx();
+  
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+
+//------------------------------------------------------------    
+
+class db_flexrf_400_tx : public flexrf_base_tx
+{
+ public:
+  db_flexrf_400_tx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_400_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+class db_flexrf_400_rx : public flexrf_base_rx
+{
+public:
+  db_flexrf_400_rx(usrp_basic_sptr usrp, int which);
+  ~db_flexrf_400_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_flexrf_mimo.h b/usrp/host/include/usrp/db_flexrf_mimo.h
new file mode 100644 (file)
index 0000000..771f3b2
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */ 
+
+#include <usrp/db_flexrf.h>
+
+class db_flexrf_2400_tx_mimo_a : public db_flexrf_2400_tx
+{
+ public:
+  db_flexrf_2400_tx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_2400_rx_mimo_a : public db_flexrf_2400_rx
+{
+ public:
+  db_flexrf_2400_rx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+      
+class db_flexrf_2400_tx_mimo_b : public db_flexrf_2400_tx
+{
+ public:
+  db_flexrf_2400_tx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_2400_rx_mimo_b : public db_flexrf_2400_rx
+{
+ public:
+  db_flexrf_2400_rx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+
+class db_flexrf_1800_tx_mimo_a : public db_flexrf_1800_tx
+{
+ public:
+  db_flexrf_1800_tx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1800_rx_mimo_a : public db_flexrf_1800_rx
+{
+ public:
+  db_flexrf_1800_rx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1800_tx_mimo_b : public db_flexrf_1800_tx
+{
+ public:
+  db_flexrf_1800_tx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1800_rx_mimo_b : public db_flexrf_1800_rx
+{
+ public:
+  db_flexrf_1800_rx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1200_tx_mimo_a : public db_flexrf_1200_tx
+{
+ public:
+  db_flexrf_1200_tx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1200_rx_mimo_a : public db_flexrf_1200_rx
+{
+ public:
+  db_flexrf_1200_rx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1200_tx_mimo_b : public db_flexrf_1200_tx
+{
+ public:
+  db_flexrf_1200_tx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_1200_rx_mimo_b : public db_flexrf_1200_rx
+{
+ public:
+  db_flexrf_1200_rx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_900_tx_mimo_a : public db_flexrf_900_tx
+{
+ public:
+  db_flexrf_900_tx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_900_rx_mimo_a : public db_flexrf_900_rx
+{
+ public:
+  db_flexrf_900_rx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_900_tx_mimo_b : public db_flexrf_900_tx
+{
+ public:
+  db_flexrf_900_tx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_900_rx_mimo_b : public db_flexrf_900_rx
+{
+ public:
+  db_flexrf_900_rx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_400_tx_mimo_a : public db_flexrf_400_tx
+{
+ public:
+  db_flexrf_400_tx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_400_rx_mimo_a : public db_flexrf_400_rx
+{
+ public:
+  db_flexrf_400_rx_mimo_a(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_400_tx_mimo_b : public db_flexrf_400_tx
+{
+ public:
+  db_flexrf_400_tx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
+
+class db_flexrf_400_rx_mimo_b : public db_flexrf_400_rx
+{
+ public:
+  db_flexrf_400_rx_mimo_b(usrp_basic_sptr usrp, int which);
+  int _refclk_divisor();
+};
diff --git a/usrp/host/include/usrp/db_tv_rx.h b/usrp/host/include/usrp/db_tv_rx.h
new file mode 100644 (file)
index 0000000..ee3ed2b
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_TV_RX_H
+#define DB_TV_RX_H
+
+#include <usrp/db_base.h>
+
+class db_tv_rx : public db_base
+{
+private:
+  void _set_rfagc(float gain);
+  void _set_ifagc(float gain);
+  void _set_pga(float pga_gain);
+
+  int d_i2c_addr;
+  double d_first_IF, d_second_IF;
+  int d_reference_divisor;
+  bool d_fast_tuning;
+  bool d_inverted;
+
+public:
+  db_tv_rx(usrp_basic_sptr usrp, int which, 
+          double first_IF, double second_IF);
+  ~db_tv_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  double freq_min();
+  double freq_max();
+  struct freq_result_t set_freq(double target_freq);
+  bool  set_gain(float gain);
+  bool  is_quadrature();
+  bool  spectrum_inverted();
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_tv_rx_mimo.h b/usrp/host/include/usrp/db_tv_rx_mimo.h
new file mode 100644 (file)
index 0000000..0a9bb48
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+//
+// Copyright 2009 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 asversion 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.
+
+#ifndef DB_TV_RX_MIMO_H
+#define DB_TV_RX_MIMO_H
+
+#include <usrp/db_tv_rx.h>
+
+class db_tv_rx_mimo : public db_tv_rx
+{
+ public:
+  db_tv_rx_mimo(usrp_basic_sptr usrp, int which,double first_IF, double second_IF);
+  int _refclk_divisor();
+};
+
+#endif
diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
new file mode 100644 (file)
index 0000000..8611d47
--- /dev/null
@@ -0,0 +1,115 @@
+/* -*- c++ -*- */
+//
+// Copyright 2009 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 asversion 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.
+
+#ifndef INCLUDED_DB_WBXNG_H
+#define INCLUDED_DB_WBXNG_H
+
+#include <usrp/db_base.h>
+#include <cmath>
+
+class adf4350;
+
+class wbxng_base : public db_base
+{
+public:
+  wbxng_base(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base();
+
+  struct freq_result_t set_freq(double freq);
+
+  bool  is_quadrature();
+  double freq_min();
+  double freq_max();
+
+protected:
+  bool _lock_detect();
+  bool _set_pga(float pga_gain);
+
+  int power_on() { return d_power_on; }
+  int power_off() { return 0; }
+
+  bool d_first;
+  int  d_spi_format;
+  int  d_spi_enable;
+  int  d_power_on;
+  int  d_PD;
+
+  adf4350 *d_common;
+};
+
+// ----------------------------------------------------------------
+
+class wbxng_base_tx : public wbxng_base
+{
+protected:
+  void shutdown();
+
+public:
+  wbxng_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base_tx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+
+  bool set_auto_tr(bool on);
+  bool set_enable(bool on);
+  bool set_gain(float gain);
+};
+
+class wbxng_base_rx : public wbxng_base
+{
+protected:
+  void shutdown();
+  bool _set_attn(float attn);
+
+public:
+  wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base_rx();
+
+  bool set_auto_tr(bool on);
+  bool select_rx_antenna(int which_antenna);
+  bool select_rx_antenna(const std::string &which_antenna);
+  bool set_gain(float gain);
+};
+
+// ----------------------------------------------------------------
+
+class db_wbxng_tx : public wbxng_base_tx
+{
+ public:
+  db_wbxng_tx(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_tx();
+};
+
+class db_wbxng_rx : public wbxng_base_rx
+{
+public:
+  db_wbxng_rx(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool i_and_q_swapped();
+};
+
+#endif /* INCLUDED_DB_WBXNG_H */
diff --git a/usrp/host/include/usrp/db_xcvr2450.h b/usrp/host/include/usrp/db_xcvr2450.h
new file mode 100644 (file)
index 0000000..305c60d
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifndef DB_XCVR2450_H
+#define DB_XCVR2450_H
+
+#include <usrp/db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class xcvr2450;
+typedef boost::shared_ptr<xcvr2450> xcvr2450_sptr;
+
+
+/******************************************************************************/
+
+
+class db_xcvr2450_base: public db_base
+{
+  /*
+   * Abstract base class for all xcvr2450 boards.
+   * 
+   * Derive board specific subclasses from db_xcvr2450_base_{tx,rx}
+   */
+public:
+  db_xcvr2450_base(usrp_basic_sptr usrp, int which);
+  ~db_xcvr2450_base();
+  struct freq_result_t set_freq(double target_freq);
+  bool is_quadrature();
+  double freq_min();
+  double freq_max();
+
+protected:
+  xcvr2450_sptr d_xcvr;
+  void shutdown_common();
+};
+
+
+/******************************************************************************/
+
+
+class db_xcvr2450_tx : public db_xcvr2450_base
+{
+protected:
+  void shutdown();
+
+public:
+  db_xcvr2450_tx(usrp_basic_sptr usrp, int which);
+  ~db_xcvr2450_tx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+  bool  i_and_q_swapped();
+};
+
+class db_xcvr2450_rx : public db_xcvr2450_base
+{
+protected:
+  void shutdown();
+
+public:
+  db_xcvr2450_rx(usrp_basic_sptr usrp, int which);
+  ~db_xcvr2450_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+};
+
+
+
+#endif
diff --git a/usrp/host/include/usrp/libusb_types.h.in b/usrp/host/include/usrp/libusb_types.h.in
new file mode 100644 (file)
index 0000000..cf10e33
--- /dev/null
@@ -0,0 +1,38 @@
+/*  -*- Mode: C++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef _LIBUSB_TYPES_H_
+#define _LIBUSB_TYPES_H_
+
+#if @USE_LIBUSB1@
+#include <libusb-1.0/libusb.h>
+struct libusb_device;
+struct libusb_device_handle;
+struct libusb_device_descriptor;
+#else
+#include <usb.h>
+typedef struct usb_device libusb_device;
+typedef struct usb_dev_handle libusb_device_handle;
+typedef struct usb_device_descriptor libusb_device_descriptor;
+#endif
+
+#endif /* _LIBUSB_TYPES_H_ */
diff --git a/usrp/host/include/usrp/usrp_basic.h b/usrp/host/include/usrp/usrp_basic.h
new file mode 100644 (file)
index 0000000..c24630e
--- /dev/null
@@ -0,0 +1,993 @@
+/*  -*- c++ -*- */
+/*
+ * Copyright 2005,2009 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.
+ */
+
+#ifndef INCLUDED_USRP_BASIC_H
+#define INCLUDED_USRP_BASIC_H
+
+#include <usrp/db_base.h>
+#include <usrp/usrp_slots.h>
+#include <usrp/usrp_subdev_spec.h>
+#include <usrp/libusb_types.h>
+#include <string>
+#include <vector>
+#include <boost/utility.hpp>
+
+class  fusb_devhandle;
+class  fusb_ephandle;
+
+enum txrx_t {
+  C_RX = 0,
+  C_TX = 1
+};
+
+/*
+ * ----------------------------------------------------------------------
+ * Mid level interface to the Universal Software Radio Peripheral (Rev 1)
+ *
+ * These classes implement the basic functionality for talking to the
+ * USRP.  They try to be as independent of the signal processing code
+ * in FPGA as possible.  They implement access to the low level
+ * peripherals on the board, provide a common way for reading and
+ * writing registers in the FPGA, and provide the high speed interface
+ * to streaming data across the USB.
+ *
+ * It is expected that subclasses will be derived that provide
+ * access to the functionality to a particular FPGA configuration.
+ * ----------------------------------------------------------------------
+ */
+
+
+/*!
+ * \brief abstract base class for usrp operations
+ * \ingroup usrp
+ */
+class usrp_basic : boost::noncopyable
+{
+protected:
+  void shutdown_daughterboards();
+
+protected:
+  libusb_device_handle         *d_udh;
+  struct libusb_context                *d_ctx;
+  int                           d_usb_data_rate;       // bytes/sec
+  int                           d_bytes_per_poll;      // how often to poll for overruns
+  bool                          d_verbose;
+  long                          d_fpga_master_clock_freq;
+
+  static const int              MAX_REGS = 128;
+  unsigned int                  d_fpga_shadows[MAX_REGS];
+
+  int                           d_dbid[2];             // daughterboard ID's (side A, side B)
+
+  /*!
+   * Shared pointers to subclasses of db_base.
+   *
+   * The outer vector is of length 2 (0 = side A, 1 = side B).  The
+   * inner vectors are of length 1, 2 or 3 depending on the number of
+   * subdevices implemented by the daugherboard.  At this time, only
+   * the Basic Rx and LF Rx implement more than 1 subdevice.
+   */
+  std::vector< std::vector<db_base_sptr> > d_db;
+
+  //! One time call, made only only from usrp_standard_*::make after shared_ptr is created.
+  void init_db(usrp_basic_sptr u);
+
+
+  usrp_basic (int which_board,
+             libusb_device_handle *open_interface (libusb_device *dev),
+             const std::string fpga_filename = "",
+             const std::string firmware_filename = "");
+
+  /*!
+   * \brief advise usrp_basic of usb data rate (bytes/sec)
+   *
+   * N.B., this doesn't tweak any hardware.  Derived classes
+   * should call this to inform us of the data rate whenever it's
+   * first set or if it changes.
+   *
+   * \param usb_data_rate      bytes/sec
+   */
+  void set_usb_data_rate (int usb_data_rate);
+  
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param slot       Which Tx or Rx slot to write.
+   *                   N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+   *                   SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+   * \param which_dac  [0,3] RX slots must use only 0 and 1.  TX slots must use only 2 and 3.
+   * \param value      [0,4095]
+   * \returns true iff successful
+   */
+  bool _write_aux_dac (int slot, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param slot       2-bit slot number. E.g., SLOT_TX_A
+   * \param which_adc  [0,1]
+   * \param value      return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  bool _read_aux_adc (int slot, int which_adc, int *value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param slot       2-bit slot number. E.g., SLOT_TX_A
+   * \param which_adc  [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int _read_aux_adc (int slot, int which_adc);
+
+
+public:
+  virtual ~usrp_basic ();
+
+
+  /*!
+   * Return a vector of vectors that contain shared pointers
+   * to the daughterboard instance(s) associated with the specified side.
+   *
+   * It is an error to use the returned objects after the usrp_basic
+   * object has been destroyed.
+   */
+  std::vector<std::vector<db_base_sptr> > db() const { return d_db; }
+
+  /*!
+   * Return a vector of size >= 1 that contains shared pointers
+   * to the daughterboard instance(s) associated with the specified side.
+   *
+   * \param which_side [0,1] which daughterboard
+   *
+   * It is an error to use the returned objects after the usrp_basic
+   * object has been destroyed.
+   */
+  std::vector<db_base_sptr> db(int which_side);
+  /*!
+   * \brief is the subdev_spec valid?
+   */
+  bool is_valid(const usrp_subdev_spec &ss);
+
+  /*!
+   * \brief given a subdev_spec, return the corresponding daughterboard object.
+   * \throws std::invalid_ argument if ss is invalid.
+   *
+   * \param ss specifies the side and subdevice
+   */
+  db_base_sptr selected_subdev(const usrp_subdev_spec &ss);
+
+  /*!
+   * \brief return frequency of master oscillator on USRP
+   */
+  long fpga_master_clock_freq () const { return d_fpga_master_clock_freq; }
+
+  /*!
+   * Tell API that the master oscillator on the USRP is operating at a non-standard 
+   * fixed frequency. This is only needed for custom USRP hardware modified to 
+   * operate at a different frequency from the default factory configuration. This
+   * function must be called prior to any other API function.
+   * \param master_clock USRP2 FPGA master clock frequency in Hz (10..64 MHz)
+   */
+  void set_fpga_master_clock_freq (long master_clock) { d_fpga_master_clock_freq = master_clock; }
+
+  /*!
+   * \returns usb data rate in bytes/sec
+   */
+  int usb_data_rate () const { return d_usb_data_rate; }
+
+  void set_verbose (bool on) { d_verbose = on; }
+
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+
+  /*!
+   * \brief Write EEPROM on motherboard or any daughterboard.
+   * \param i2c_addr           I2C bus address of EEPROM
+   * \param eeprom_offset      byte offset in EEPROM to begin writing
+   * \param buf                        the data to write
+   * \returns true iff sucessful
+   */
+  bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
+
+  /*!
+   * \brief Read EEPROM on motherboard or any daughterboard.
+   * \param i2c_addr           I2C bus address of EEPROM
+   * \param eeprom_offset      byte offset in EEPROM to begin reading
+   * \param len                        number of bytes to read
+   * \returns the data read if successful, else a zero length string.
+   */
+  std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
+
+  /*!
+   * \brief Write to I2C peripheral
+   * \param i2c_addr           I2C bus address (7-bits)
+   * \param buf                        the data to write
+   * \returns true iff successful
+   * Writes are limited to a maximum of of 64 bytes.
+   */
+  bool write_i2c (int i2c_addr, const std::string buf);
+
+  /*!
+   * \brief Read from I2C peripheral
+   * \param i2c_addr           I2C bus address (7-bits)
+   * \param len                        number of bytes to read
+   * \returns the data read if successful, else a zero length string.
+   * Reads are limited to a maximum of 64 bytes.
+   */
+  std::string read_i2c (int i2c_addr, int len);
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which_adc  which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
+   * \param offset     16-bit value to subtract from raw ADC input.
+   */
+  bool set_adc_offset (int which_adc, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which_dac  which DAC[0,3]: 0 = TX_A I, 1 = TX_A Q...
+   * \param offset     10-bit offset value (ambiguous format:  See AD9862 datasheet).
+   * \param offset_pin 1-bit value.  If 0 offset applied to -ve differential pin;
+   *                                  If 1 offset applied to +ve differential pin.
+   */
+  bool set_dac_offset (int which_dac, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which_adc  which ADC[0,3]
+   * \param bypass     if non-zero, bypass input buffer and connect input
+   *                   directly to switched cap SHA input of RxPGA.
+   */
+  bool set_adc_buffer_bypass (int which_adc, bool bypass);
+
+  /*!
+   * \brief Enable/disable automatic DC offset removal control loop in FPGA
+   *
+   * \param bits  which control loops to enable
+   * \param mask  which \p bits to pay attention to
+   *
+   * If the corresponding bit is set, enable the automatic DC
+   * offset correction control loop.
+   *
+   * <pre>
+   * The 4 low bits are significant:
+   *
+   *   ADC0 = (1 << 0)
+   *   ADC1 = (1 << 1)
+   *   ADC2 = (1 << 2)
+   *   ADC3 = (1 << 3)
+   * </pre>
+   *
+   * By default the control loop is enabled on all ADC's.
+   */
+  bool set_dc_offset_cl_enable(int bits, int mask);
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  /*!
+   * \brief Return daughterboard ID for given side [0,1].
+   *
+   * \param which_side [0,1] which daughterboard
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  virtual int daughterboard_id (int which_side) const = 0;
+
+  /*!
+   * \brief Clock ticks to delay rising of T/R signal
+   * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+   */
+  bool write_atr_tx_delay(int value);
+
+  /*!
+   * \brief Clock ticks to delay falling edge of T/R signal
+   * \sa write_atr_mask, write_atr_txval, write_atr_rxval
+   */
+  bool write_atr_rx_delay(int value);
+
+
+\f  // ================================================================
+  // Routines to access and control daughterboard specific i/o
+  //
+  // Those with a common_ prefix access either the Tx or Rx side depending
+  // on the txrx parameter.  Those without the common_ prefix are virtual
+  // and are overriden in usrp_basic_rx and usrp_basic_tx to access the
+  // the Rx or Tx sides automatically.  We provide the common_ versions
+  // for those daughterboards such as the WBX and XCVR2450 that share
+  // h/w resources (such as the LO) between the Tx and Rx sides.
+
+  // ----------------------------------------------------------------
+  // BEGIN common_  daughterboard control functions
+
+  /*!
+   * \brief Set Programmable Gain Amplifier(PGA)
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_amp  which amp [0,3]
+   * \param gain_in_db gain value(linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool common_set_pga(txrx_t txrx, int which_amp, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_amp  which amp [0,3]
+   */
+  double common_pga(txrx_t txrx, int which_amp) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   * \param txrx       Tx or Rx?
+   */
+  double common_pga_min(txrx_t txrx) const;
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   * \param txrx       Tx or Rx?
+   */
+  double common_pga_max(txrx_t txrx) const;
+
+  /*!
+   * \brief Return hardware step size of PGA(linear in dB).
+   * \param txrx       Tx or Rx?
+   */
+  double common_pga_db_per_step(txrx_t txrx) const;
+
+  /*!
+   * \brief Write direction register(output enables) for pins that go to daughterboard.
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which size
+   * \param value      value to write into register
+   * \param mask       which bits of value to write into reg
+   *
+   * Each d'board has 16-bits of general purpose i/o.
+   * Setting the bit makes it an output from the FPGA to the d'board.
+   *
+   * This register is initialized based on a value stored in the
+   * d'board EEPROM.  In general, you shouldn't be using this routine
+   * without a very good reason.  Using this method incorrectly will
+   * kill your USRP motherboard and/or daughterboard.
+   */
+  bool _common_write_oe(txrx_t txrx, int which_side, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \param value      value to write into register
+   * \param mask       which bits of value to write into reg
+   */
+  bool common_write_io(txrx_t txrx, int which_side, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \param value      output
+   */
+  bool common_read_io(txrx_t txrx, int which_side, int *value);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int common_read_io(txrx_t txrx, int which_side);
+
+  /*!
+   * \brief Write daughterboard refclk config register
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \param value      value to write into register, see below
+   *
+   * <pre>
+   * Control whether a reference clock is sent to the daughterboards,
+   * and what frequency.  The refclk is sent on d'board i/o pin 0.
+   * 
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-----------------------------------------------+-+------------+
+   *  |             Reserved (Must be zero)           |E|   DIVISOR  |
+   *  +-----------------------------------------------+-+------------+
+   * 
+   *  Bit 7  -- 1 turns on refclk, 0 allows IO use
+   *  Bits 6:0 Divider value
+   * </pre>
+   */
+  bool common_write_refclk(txrx_t txrx, int which_side, int value);
+
+  /*!
+   * \brief Automatic Transmit/Receive switching
+   * <pre>
+   *
+   * If automatic transmit/receive (ATR) switching is enabled in the
+   * FR_ATR_CTL register, the presence or absence of data in the FPGA
+   * transmit fifo selects between two sets of values for each of the 4
+   * banks of daughterboard i/o pins.
+   *
+   * Each daughterboard slot has 3 16-bit registers associated with it:
+   *   FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
+   *
+   * FR_ATR_MASK_{0,1,2,3}: 
+   *
+   *   These registers determine which of the daugherboard i/o pins are
+   *   affected by ATR switching.  If a bit in the mask is set, the
+   *   corresponding i/o bit is controlled by ATR, else it's output
+   *   value comes from the normal i/o pin output register:
+   *   FR_IO_{0,1,2,3}.
+   *
+   * FR_ATR_TXVAL_{0,1,2,3}:
+   * FR_ATR_RXVAL_{0,1,2,3}:
+   *
+   *   If the Tx fifo contains data, then the bits from TXVAL that are
+   *   selected by MASK are output.  Otherwise, the bits from RXVAL that
+   *   are selected by MASK are output.
+   * </pre>
+   */
+  bool common_write_atr_mask(txrx_t txrx, int which_side, int value);
+  bool common_write_atr_txval(txrx_t txrx, int which_side, int value);
+  bool common_write_atr_rxval(txrx_t txrx, int which_side, int value);
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   *                   N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+   *                   SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+   * \param which_dac  [2,3] TX slots must use only 2 and 3.
+   * \param value      [0,4095]
+   * \returns true iff successful
+   */
+  bool common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \param which_adc  [0,1]
+   * \param value      return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  bool common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param txrx       Tx or Rx?
+   * \param which_side [0,1] which d'board
+   * \param which_adc  [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int common_read_aux_adc(txrx_t txrx, int which_side, int which_adc);
+
+  // END common_ daughterboard control functions\f
+  // ----------------------------------------------------------------
+  // BEGIN virtual daughterboard control functions
+
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which_amp  which amp [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  virtual bool set_pga (int which_amp, double gain_in_db) = 0;
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param which_amp  which amp [0,3]
+   */
+  virtual double pga (int which_amp) const = 0;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  virtual double pga_min () const = 0;
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  virtual double pga_max () const = 0;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  virtual double pga_db_per_step () const = 0;
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_side [0,1] which size
+   * \param value      value to write into register
+   * \param mask       which bits of value to write into reg
+   *
+   * Each d'board has 16-bits of general purpose i/o.
+   * Setting the bit makes it an output from the FPGA to the d'board.
+   *
+   * This register is initialized based on a value stored in the
+   * d'board EEPROM.  In general, you shouldn't be using this routine
+   * without a very good reason.  Using this method incorrectly will
+   * kill your USRP motherboard and/or daughterboard.
+   */
+  virtual bool _write_oe (int which_side, int value, int mask) = 0;
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_side [0,1] which d'board
+   * \param value      value to write into register
+   * \param mask       which bits of value to write into reg
+   */
+  virtual bool write_io (int which_side, int value, int mask) = 0;
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_side [0,1] which d'board
+   * \param value      output
+   */
+  virtual bool read_io (int which_side, int *value) = 0;
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_side [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  virtual int read_io (int which_side) = 0;
+
+  /*!
+   * \brief Write daughterboard refclk config register
+   *
+   * \param which_side [0,1] which d'board
+   * \param value      value to write into register, see below
+   *
+   * <pre>
+   * Control whether a reference clock is sent to the daughterboards,
+   * and what frequency.  The refclk is sent on d'board i/o pin 0.
+   * 
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-----------------------------------------------+-+------------+
+   *  |             Reserved (Must be zero)           |E|   DIVISOR  |
+   *  +-----------------------------------------------+-+------------+
+   * 
+   *  Bit 7  -- 1 turns on refclk, 0 allows IO use
+   *  Bits 6:0 Divider value
+   * </pre>
+   */
+  virtual bool write_refclk(int which_side, int value) = 0;
+
+  virtual bool write_atr_mask(int which_side, int value) = 0;
+  virtual bool write_atr_txval(int which_side, int value) = 0;
+  virtual bool write_atr_rxval(int which_side, int value) = 0;
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param which_side [0,1] which d'board
+   *                   N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
+   *                   SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
+   * \param which_dac  [2,3] TX slots must use only 2 and 3.
+   * \param value      [0,4095]
+   * \returns true iff successful
+   */
+  virtual bool write_aux_dac (int which_side, int which_dac, int value) = 0;
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_side [0,1] which d'board
+   * \param which_adc  [0,1]
+   * \param value      return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  virtual bool read_aux_adc (int which_side, int which_adc, int *value) = 0;
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_side [0,1] which d'board
+   * \param which_adc  [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  virtual int read_aux_adc (int which_side, int which_adc) = 0;
+
+  /*!
+   * \brief returns current fusb block size
+   */
+  virtual int block_size() const = 0;
+
+  /*!
+   * \brief returns A/D or D/A converter rate in Hz
+   */
+  virtual long converter_rate() const = 0;
+
+  // END virtual daughterboard control functions\f
+
+  // ----------------------------------------------------------------
+  // Low level implementation routines.
+  // You probably shouldn't be using these...
+  //
+
+  bool _set_led (int which_led, bool on);
+
+  /*!
+   * \brief Write FPGA register.
+   * \param regno      7-bit register number
+   * \param value      32-bit value
+   * \returns true iff successful
+   */
+  bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
+
+  /*!
+   * \brief Read FPGA register.
+   * \param regno      7-bit register number
+   * \param value      32-bit value
+   * \returns true iff successful
+   */
+  bool _read_fpga_reg (int regno, int *value); //< 7-bit regno, 32-bit value
+
+  /*!
+   * \brief Read FPGA register.
+   * \param regno      7-bit register number
+   * \returns register value if successful, else READ_FAILED
+   */
+  int  _read_fpga_reg (int regno);
+
+  /*!
+   * \brief Write FPGA register with mask.
+   * \param regno      7-bit register number
+   * \param value      16-bit value
+   * \param mask       16-bit value
+   * \returns true if successful
+   * Only use this for registers who actually implement a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
+   */
+  bool _write_fpga_reg_masked (int regno, int value, int mask);
+
+  /*!
+   * \brief Write AD9862 register.
+   * \param which_codec 0 or 1
+   * \param regno      6-bit register number
+   * \param value      8-bit value
+   * \returns true iff successful
+   */
+  bool _write_9862 (int which_codec, int regno, unsigned char value);
+
+  /*!
+   * \brief Read AD9862 register.
+   * \param which_codec 0 or 1
+   * \param regno      6-bit register number
+   * \param value      8-bit value
+   * \returns true iff successful
+   */
+  bool _read_9862 (int which_codec, int regno, unsigned char *value) const;
+
+  /*!
+   * \brief Read AD9862 register.
+   * \param which_codec 0 or 1
+   * \param regno      6-bit register number
+   * \returns register value if successful, else READ_FAILED
+   */
+  int  _read_9862 (int which_codec, int regno) const;
+
+  /*!
+   * \brief Write data to SPI bus peripheral.
+   *
+   * \param optional_header    0,1 or 2 bytes to write before buf.
+   * \param enables            bitmask of peripherals to write. See usrp_spi_defs.h
+   * \param format             transaction format.  See usrp_spi_defs.h SPI_FMT_*
+   * \param buf                        the data to write
+   * \returns true iff successful
+   * Writes are limited to a maximum of 64 bytes.
+   *
+   * If \p format specifies that optional_header bytes are present, they are
+   * written to the peripheral immediately prior to writing \p buf.
+   */
+  bool _write_spi (int optional_header, int enables, int format, std::string buf);
+
+  /*
+   * \brief Read data from SPI bus peripheral.
+   *
+   * \param optional_header    0,1 or 2 bytes to write before buf.
+   * \param enables            bitmask of peripheral to read. See usrp_spi_defs.h
+   * \param format             transaction format.  See usrp_spi_defs.h SPI_FMT_*
+   * \param len                        number of bytes to read.  Must be in [0,64].
+   * \returns the data read if sucessful, else a zero length string.
+   *
+   * Reads are limited to a maximum of 64 bytes.
+   *
+   * If \p format specifies that optional_header bytes are present, they
+   * are written to the peripheral first.  Then \p len bytes are read from
+   * the peripheral and returned.
+   */
+  std::string _read_spi (int optional_header, int enables, int format, int len);
+
+  /*!
+   * \brief Start data transfers.
+   * Called in base class to derived class order.
+   */
+  bool start ();
+
+  /*!
+   * \brief Stop data transfers.
+   * Called in base class to derived class order.
+   */
+  bool stop ();
+};
+
+\f/*!
+ * \brief class for accessing the receive side of the USRP
+ * \ingroup usrp
+ */
+class usrp_basic_rx : public usrp_basic 
+{
+private:
+  fusb_devhandle       *d_devhandle;
+  fusb_ephandle                *d_ephandle;
+  int                   d_bytes_seen;          // how many bytes we've seen
+  bool                  d_first_read;
+  bool                  d_rx_enable;
+
+protected:
+  /*!
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
+   * \param fpga_filename    name of the rbf file to load
+   * \param firmware_filename name of ihx file to load
+   */
+  usrp_basic_rx (int which_board,
+                int fusb_block_size=0,
+                int fusb_nblocks=0,
+                const std::string fpga_filename = "",
+                const std::string firmware_filename = ""
+                );  // throws if trouble
+
+  bool set_rx_enable (bool on);
+  bool rx_enable () const { return d_rx_enable; }
+
+  bool disable_rx ();          // conditional disable, return prev state
+  void restore_rx (bool on);   // conditional set
+
+  void probe_rx_slots (bool verbose);
+
+public:
+  ~usrp_basic_rx ();
+
+  /*!
+   * \brief invokes constructor, returns instance or 0 if trouble
+   *
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
+   * \param fpga_filename    name of file that contains image to load into FPGA
+   * \param firmware_filename  name of file that contains image to load into FX2
+   */
+  static usrp_basic_rx *make (int which_board,
+                             int fusb_block_size=0,
+                             int fusb_nblocks=0,
+                             const std::string fpga_filename = "",
+                             const std::string firmware_filename = ""
+                             );
+
+  /*!
+   * \brief tell the fpga the rate rx samples are coming from the A/D's
+   *
+   * div = fpga_master_clock_freq () / sample_rate
+   *
+   * sample_rate is determined by a myriad of registers
+   * in the 9862.  That's why you have to tell us, so
+   * we can tell the fpga.
+   */
+  bool set_fpga_rx_sample_rate_divisor (unsigned int div);
+
+  /*!
+   * \brief read data from the D/A's via the FPGA.
+   * \p len must be a multiple of 512 bytes.
+   *
+   * \returns the number of bytes read, or -1 on error.
+   *
+   * If overrun is non-NULL it will be set true iff an RX overrun is detected.
+   */
+  int read (void *buf, int len, bool *overrun);
+
+
+  //! sampling rate of A/D converter
+  virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
+  long adc_rate() const { return converter_rate(); }
+  int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
+
+  bool set_pga (int which_amp, double gain_in_db);
+  double pga (int which_amp) const;
+  double pga_min () const;
+  double pga_max () const;
+  double pga_db_per_step () const;
+
+  bool _write_oe (int which_side, int value, int mask);
+  bool write_io (int which_side, int value, int mask);
+  bool read_io (int which_side, int *value);
+  int read_io (int which_side);
+  bool write_refclk(int which_side, int value);
+  bool write_atr_mask(int which_side, int value);
+  bool write_atr_txval(int which_side, int value);
+  bool write_atr_rxval(int which_side, int value);
+
+  bool write_aux_dac (int which_side, int which_dac, int value);
+  bool read_aux_adc (int which_side, int which_adc, int *value);
+  int  read_aux_adc (int which_side, int which_adc);
+
+  int block_size() const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+\f/*!
+ * \brief class for accessing the transmit side of the USRP
+ * \ingroup usrp
+ */
+class usrp_basic_tx : public usrp_basic 
+{
+private:
+  fusb_devhandle       *d_devhandle;
+  fusb_ephandle                *d_ephandle;
+  int                   d_bytes_seen;          // how many bytes we've seen
+  bool                  d_first_write;
+  bool                  d_tx_enable;
+
+ protected:
+  /*!
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512.
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default.
+   * \param fpga_filename    name of file that contains image to load into FPGA
+   * \param firmware_filename  name of file that contains image to load into FX2
+   */
+  usrp_basic_tx (int which_board,
+                int fusb_block_size=0,
+                int fusb_nblocks=0,
+                const std::string fpga_filename = "",
+                const std::string firmware_filename = ""
+                );             // throws if trouble
+
+  bool set_tx_enable (bool on);
+  bool tx_enable () const { return d_tx_enable; }
+
+  bool disable_tx ();          // conditional disable, return prev state
+  void restore_tx (bool on);   // conditional set
+
+  void probe_tx_slots (bool verbose);
+
+public:
+
+  ~usrp_basic_tx ();
+
+  /*!
+   * \brief invokes constructor, returns instance or 0 if trouble
+   *
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
+   * \param fpga_filename    name of file that contains image to load into FPGA
+   * \param firmware_filename  name of file that contains image to load into FX2
+   */
+  static usrp_basic_tx *make (int which_board, int fusb_block_size=0, int fusb_nblocks=0,
+                             const std::string fpga_filename = "",
+                             const std::string firmware_filename = ""
+                             );
+
+  /*!
+   * \brief tell the fpga the rate tx samples are going to the D/A's
+   *
+   * div = fpga_master_clock_freq () * 2
+   *
+   * sample_rate is determined by a myriad of registers
+   * in the 9862.  That's why you have to tell us, so
+   * we can tell the fpga.
+   */
+  bool set_fpga_tx_sample_rate_divisor (unsigned int div);
+
+  /*!
+   * \brief Write data to the A/D's via the FPGA.
+   *
+   * \p len must be a multiple of 512 bytes.
+   * \returns number of bytes written or -1 on error.
+   *
+   * if \p underrun is non-NULL, it will be set to true iff
+   * a transmit underrun condition is detected.
+   */
+  int write (const void *buf, int len, bool *underrun);
+
+  /*
+   * Block until all outstanding writes have completed.
+   * This is typically used to assist with benchmarking
+   */
+  void wait_for_completion ();
+
+  //! sampling rate of D/A converter
+  virtual long converter_rate() const { return fpga_master_clock_freq () * 2; } // 128M
+  long dac_rate() const { return converter_rate(); }
+  int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
+
+  bool set_pga (int which_amp, double gain_in_db);
+  double pga (int which_amp) const;
+  double pga_min () const;
+  double pga_max () const;
+  double pga_db_per_step () const;
+
+  bool _write_oe (int which_side, int value, int mask);
+  bool write_io (int which_side, int value, int mask);
+  bool read_io (int which_side, int *value);
+  int read_io (int which_side);
+  bool write_refclk(int which_side, int value);
+  bool write_atr_mask(int which_side, int value);
+  bool write_atr_txval(int which_side, int value);
+  bool write_atr_rxval(int which_side, int value);
+
+  bool write_aux_dac (int which_side, int which_dac, int value);
+  bool read_aux_adc (int which_side, int which_adc, int *value);
+  int read_aux_adc (int which_side, int which_adc);
+
+  int block_size() const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+#endif /* INCLUDED_USRP_BASIC_H */
diff --git a/usrp/host/include/usrp/usrp_bytesex.h b/usrp/host/include/usrp/usrp_bytesex.h
new file mode 100644 (file)
index 0000000..331db31
--- /dev/null
@@ -0,0 +1,108 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+#ifndef INCLUDED_USRP_BYTESEX_H
+#define INCLUDED_USRP_BYTESEX_H
+
+/*!
+ * \brief routines for convertering between host and usrp byte order
+ *
+ * Prior to including this file, the user must include "config.h"
+ * which will or won't define WORDS_BIGENDIAN based on the
+ * result of the AC_C_BIGENDIAN autoconf test.
+ */
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+
+#warning Using non-portable code (likely wrong other than ILP32).
+
+static inline unsigned short int
+bswap_16 (unsigned short int x)
+{
+  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
+}
+
+static inline unsigned int
+bswap_32 (unsigned int x)
+{
+  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
+        | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
+}
+#endif
+
+
+#ifdef WORDS_BIGENDIAN
+
+static inline unsigned int
+host_to_usrp_u32 (unsigned int x)
+{
+  return bswap_32(x);
+}
+
+static inline unsigned int
+usrp_to_host_u32 (unsigned int x)
+{
+  return bswap_32(x);
+}
+
+static inline short int
+host_to_usrp_short (short int x)
+{
+  return bswap_16 (x);
+}
+
+static inline short int
+usrp_to_host_short (short int x)
+{
+  return bswap_16 (x);
+}
+
+#else
+
+static inline unsigned int
+host_to_usrp_u32 (unsigned int x)
+{
+  return x;
+}
+
+static inline unsigned int
+usrp_to_host_u32 (unsigned int x)
+{
+  return x;
+}
+
+static inline short int
+host_to_usrp_short (short int x)
+{
+  return x;
+}
+
+static inline short int
+usrp_to_host_short (unsigned short int x)
+{
+  return x;
+}
+
+#endif
+
+#endif /* INCLUDED_USRP_BYTESEX_H */
diff --git a/usrp/host/include/usrp/usrp_local_sighandler.h b/usrp/host/include/usrp/usrp_local_sighandler.h
new file mode 100644 (file)
index 0000000..ee33675
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_USRP_LOCAL_SIGHANDLER_H
+#define INCLUDED_USRP_LOCAL_SIGHANDLER_H
+
+#include <signal.h>
+#include <string>
+
+/*!
+ * \brief Representation of signal.
+ */
+class usrp_signal
+{
+  int  d_signum;
+public:
+  usrp_signal (int signum) : d_signum (signum) {}
+  int signal () const { return d_signum; }
+  std::string name () const;
+};
+
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class usrp_local_sighandler {
+  int                  d_signum;
+#ifdef HAVE_SIGACTION
+  struct sigaction     d_old_action;
+#endif
+public:
+  usrp_local_sighandler (int signum, void (*new_handler)(int));
+  ~usrp_local_sighandler ();
+
+  /* throw usrp_signal (signum) */
+  static void throw_signal (int signum) throw (usrp_signal);
+};
+
+#endif /* INCLUDED_USRP_LOCAL_SIGHANDLER_H */
diff --git a/usrp/host/include/usrp/usrp_prims.h b/usrp/host/include/usrp/usrp_prims.h
new file mode 100644 (file)
index 0000000..4780d00
--- /dev/null
@@ -0,0 +1,307 @@
+/*  -*- c++ -*- */
+/*
+ * Copyright 2005,2009 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.
+ */
+
+#ifndef INCLUDED_USRP_PRIMS_H
+#define INCLUDED_USRP_PRIMS_H
+
+#include <usrp/usrp_slots.h>
+#include <usrp/libusb_types.h>
+#include <string>
+
+struct libusb_context;
+
+static const int USRP_HASH_SIZE = 16;
+
+enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED };
+
+/*!
+ * \brief initialize libusb; Behavior differs depending on libusb version
+ *
+ * libusb-0.12
+ *
+ * Probe busses and devices. The argument is ignored and defaults to NULL.
+ * Safe to call more than once.
+ *
+ * libusb-1.0
+ *
+ * If an location to a libusb_context is passed in, create and write in the new
+ * context. If no argument is provided, initialize libusb with the default
+ * (NULL) context.
+ *
+ * Generally _not_ safe to call more than once with non-NULL argument since a
+ * new context will be created each time.
+ */
+
+void usrp_one_time_init (libusb_context **ctx = NULL);
+
+/*!
+ * \brief deinitialize libusb
+ *
+ * libusb-0.1: No effect
+ *
+ * libusb-1.0: Deinitialize context ctx 
+ */
+void usrp_deinit (libusb_context *ctx);
+
+/*
+ * force a rescan of the buses and devices
+ */
+void usrp_rescan ();
+
+/*!
+ * \brief locate Nth (zero based) USRP device in system.
+ * Return pointer or 0 if not found.
+ *
+ * The following kinds of devices are considered USRPs:
+ *
+ *   unconfigured USRP (no firwmare loaded)
+ *   configured USRP (firmware loaded)
+ *   unconfigured Cypress FX2 (only if fx2_ok_p is true)
+ */
+libusb_device *usrp_find_device (int nth, bool fx2_ok_p = false, libusb_context *ctx = NULL);
+
+bool usrp_usrp_p (libusb_device *q);           //< is this a USRP
+bool usrp_usrp0_p (libusb_device *q);          //< is this a USRP Rev 0
+bool usrp_usrp1_p (libusb_device *q);          //< is this a USRP Rev 1
+bool usrp_usrp2_p (libusb_device *q);          //< is this a USRP Rev 2
+int  usrp_hw_rev (libusb_device *q);           //< return h/w rev code
+
+bool usrp_fx2_p (libusb_device *q);                    //< is this an unconfigured Cypress FX2
+
+bool usrp_unconfigured_usrp_p (libusb_device *q);      //< some kind of unconfigured USRP
+bool usrp_configured_usrp_p (libusb_device *q);        //< some kind of configured USRP
+
+/*!
+ * \brief given a libusb_device return an instance of the appropriate libusb_device_handle
+ *
+ * These routines claim the specified interface and select the
+ * correct alternate interface.  (USB nomenclature is totally screwed!)
+ *
+ * If interface can't be opened, or is already claimed by some other
+ * process, 0 is returned.
+ */
+libusb_device_handle *usrp_open_cmd_interface (libusb_device *dev);
+libusb_device_handle *usrp_open_rx_interface (libusb_device *dev);
+libusb_device_handle *usrp_open_tx_interface (libusb_device *dev);
+
+/*!
+ * \brief close interface.
+ */
+bool usrp_close_interface (libusb_device_handle *udh);
+
+/*!
+ * \brief load intel hex format file into USRP/Cypress FX2 (8051).
+ *
+ * The filename extension is typically *.ihx
+ *
+ * Note that loading firmware may cause the device to renumerate.  I.e.,
+ * change its configuration, invalidating the current device handle.
+ */
+
+usrp_load_status_t 
+usrp_load_firmware (libusb_device_handle *udh, const char *filename, bool force);
+
+/*!
+ * \brief load intel hex format file into USRP FX2 (8051).
+ *
+ * The filename extension is typically *.ihx
+ *
+ * Note that loading firmware may cause the device to renumerate.  I.e.,
+ * change its configuration, invalidating the current device handle.
+ * If the result is ULS_OK, usrp_load_firmware_nth delays 1 second
+ * then rescans the busses and devices.
+ */
+usrp_load_status_t
+usrp_load_firmware_nth (int nth, const char *filename, bool force, libusb_context *ctx = NULL);
+
+/*!
+ * \brief load fpga configuration bitstream
+ */
+usrp_load_status_t
+usrp_load_fpga (libusb_device_handle *udh, const char *filename, bool force);
+
+/*!
+ * \brief load the regular firmware and fpga bitstream in the Nth USRP.
+ *
+ * This is the normal starting point...
+ */
+bool usrp_load_standard_bits (int nth, bool force,
+                             const std::string fpga_filename = "",
+                             const std::string firmware_filename = "",
+                             libusb_context *ctx = NULL);
+
+/*!
+ * \brief copy the given \p hash into the USRP hash slot \p which.
+ * The usrp implements two hash slots, 0 and 1.
+ */
+bool usrp_set_hash (libusb_device_handle *udh, int which,
+                   const unsigned char hash[USRP_HASH_SIZE]);
+
+/*!
+ * \brief retrieve the \p hash from the USRP hash slot \p which.
+ * The usrp implements two hash slots, 0 and 1.
+ */
+bool usrp_get_hash (libusb_device_handle *udh, int which,
+                   unsigned char hash[USRP_HASH_SIZE]);
+
+bool usrp_write_fpga_reg (libusb_device_handle *udh, int reg, int value);
+bool usrp_read_fpga_reg (libusb_device_handle *udh, int reg, int *value);
+bool usrp_set_fpga_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_tx_enable (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_rx_enable (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_tx_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_rx_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_led (libusb_device_handle *udh, int which, bool on);
+
+bool usrp_check_rx_overrun (libusb_device_handle *udh, bool *overrun_p);
+bool usrp_check_tx_underrun (libusb_device_handle *udh, bool *underrun_p);
+
+// i2c_read and i2c_write are limited to a maximum len of 64 bytes.
+
+bool usrp_i2c_write (libusb_device_handle *udh, int i2c_addr,
+                    const void *buf, int len);
+
+bool usrp_i2c_read (libusb_device_handle *udh, int i2c_addr,
+                   void *buf, int len);
+
+// spi_read and spi_write are limited to a maximum of 64 bytes
+// See usrp_spi_defs.h for more info
+
+bool usrp_spi_write (libusb_device_handle *udh,
+                    int optional_header, int enables, int format,
+                    const void *buf, int len);
+
+bool usrp_spi_read (libusb_device_handle *udh,
+                    int optional_header, int enables, int format,
+                    void *buf, int len);
+
+
+bool usrp_9862_write (libusb_device_handle *udh,
+                     int which_codec,                  // [0,  1]
+                     int regno,                        // [0, 63]
+                     int value);                       // [0, 255]     
+
+bool usrp_9862_read (libusb_device_handle *udh,
+                    int which_codec,                   // [0,  1]
+                    int regno,                         // [0, 63]
+                    unsigned char *value);             // [0, 255]
+
+/*!
+ * \brief Write multiple 9862 regs at once.
+ *
+ * \p buf contains alternating register_number, register_value pairs.
+ * \p len must be even and is the length of buf in bytes.
+ */
+bool usrp_9862_write_many (libusb_device_handle *udh, int which_codec,
+                          const unsigned char *buf, int len);
+                          
+
+/*!
+ * \brief write specified regs to all 9862's in the system
+ */
+bool usrp_9862_write_many_all (libusb_device_handle *udh,
+                              const unsigned char *buf, int len);
+                          
+
+// Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
+// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
+
+bool usrp_eeprom_write (libusb_device_handle *udh, int i2c_addr,
+                       int eeprom_offset, const void *buf, int len);
+
+
+// Read 24LC024 / 24LC025 EEPROM on motherboard or daughterboard.
+// Which EEPROM is determined by i2c_addr.  See i2c_addr.h
+
+bool usrp_eeprom_read (libusb_device_handle *udh, int i2c_addr,
+                      int eeprom_offset, void *buf, int len);
+
+
+// Slot specific i/o routines
+
+/*!
+ * \brief write to the specified aux dac.
+ *
+ * \p slot: which Tx or Rx slot to write.
+ *    N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's
+ *          SLOT_TX_B and SLOT_RX_B share the same AUX DAC's
+ *
+ * \p which_dac: [0,3]  RX slots must use only 0 and 1.
+ *                     TX slots must use only 2 and 3.
+ *
+ * AUX DAC 3 is really the 9862 sigma delta output.
+ *
+ * \p value to write to aux dac.  All dacs take straight
+ * binary values.  Although dacs 0, 1 and 2 are 8-bit and dac 3 is 12-bit,
+ * the interface is in terms of 12-bit values [0,4095]
+ */
+bool usrp_write_aux_dac (libusb_device_handle *uhd, int slot,
+                        int which_dac, int value);
+
+/*!
+ * \brief Read the specified aux adc
+ *
+ * \p slot: which Tx or Rx slot to read aux dac
+ * \p which_adc: [0,1]  which of the two adcs to read
+ * \p *value: return value, 12-bit straight binary.
+ */
+bool usrp_read_aux_adc (libusb_device_handle *udh, int slot,
+                       int which_adc, int *value);
+
+
+/*!
+ * \brief usrp daughterboard id to name mapping
+ */
+const std::string usrp_dbid_to_string (int dbid);
+
+
+enum usrp_dbeeprom_status_t { UDBE_OK, UDBE_BAD_SLOT, UDBE_NO_EEPROM, UDBE_INVALID_EEPROM };
+
+struct usrp_dboard_eeprom {
+  unsigned short       id;             // d'board identifier code
+  unsigned short       oe;             // fpga output enables:
+                                       //   If bit set, i/o pin is an output from FPGA.
+  short                        offset[2];      // ADC/DAC offset correction
+};
+
+/*!
+ * \brief Read and return parsed daughterboard eeprom
+ */
+usrp_dbeeprom_status_t
+usrp_read_dboard_eeprom (libusb_device_handle *udh,
+                        int slot_id, usrp_dboard_eeprom *eeprom);
+
+/*!
+ * \brief write ADC/DAC offset calibration constants to d'board eeprom
+ */
+bool usrp_write_dboard_offsets (libusb_device_handle *udh, int slot_id,
+                               short offset0, short offset1);
+
+/*!
+ * \brief return a usrp's serial number.
+ *
+ * Note that this only works on a configured usrp.
+ * \returns non-zero length string iff successful.
+ */
+std::string usrp_serial_number(libusb_device_handle *udh);
+
+#endif /* INCLUDED_USRP_PRIMS_H */
diff --git a/usrp/host/include/usrp/usrp_slots.h b/usrp/host/include/usrp/usrp_slots.h
new file mode 100644 (file)
index 0000000..d2c50fc
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_USRP_SLOTS_H
+#define INCLUDED_USRP_SLOTS_H
+
+// daughterboard slot numbers used in some calls
+
+static const int SLOT_TX_A = 0;
+static const int SLOT_RX_A = 1;
+static const int SLOT_TX_B = 2;
+static const int SLOT_RX_B = 3;
+
+#endif /* INCLUDED_USRP_SLOTS_H */
diff --git a/usrp/host/include/usrp/usrp_standard.h b/usrp/host/include/usrp/usrp_standard.h
new file mode 100644 (file)
index 0000000..a631f8b
--- /dev/null
@@ -0,0 +1,452 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 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.
+ */
+
+#ifndef INCLUDED_USRP_STANDARD_H
+#define INCLUDED_USRP_STANDARD_H
+
+#include <usrp/usrp_basic.h>
+#include <boost/shared_ptr.hpp>
+#include <usrp/usrp_tune_result.h>
+
+class usrp_standard_tx;
+class usrp_standard_rx;
+
+typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr;
+typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr;
+
+/*!
+ * \ingroup usrp
+ */
+class usrp_standard_common
+{
+  int  d_fpga_caps;            // capability register val
+
+protected:
+  usrp_standard_common(usrp_basic *parent);
+
+public:
+  /*!
+   *\brief does the FPGA implement the final Rx half-band filter?
+   * If it doesn't, the maximum decimation factor with proper gain 
+   * is 1/2 of what it would otherwise be.
+   */
+  bool has_rx_halfband() const;
+
+  /*!
+   * \brief number of digital downconverters implemented in the FPGA
+   * This will be 0, 1, 2 or 4.
+   */
+  int nddcs() const;
+
+  /*!
+   *\brief does the FPGA implement the initial Tx half-band filter?
+   */
+  bool has_tx_halfband() const;
+
+  /*!
+   * \brief number of digital upconverters implemented in the FPGA
+   * This will be 0, 1, or 2.
+   */
+  int nducs() const;
+
+  /*!
+   * \brief Calculate the frequency to use for setting the digital up or down converter.
+   *
+   * \param target_freq is the desired RF frequency (Hz).
+   * \param baseband_freq is the RF frequency that corresponds to DC in the IF coming from the d'board.
+   * \param  fs is the sampling frequency.
+   * \param[out] dxc_freq the frequency to program into the DDC (or DUC).
+   * \param[out] inverted is true if we're operating in an inverted Nyquist zone.
+   */
+  static void calc_dxc_freq(double target_freq, double baseband_freq, double fs,
+                           double *dxc_freq, bool *inverted);
+};
+
+/*!
+ * \brief The C++ interface the receive side of the USRP
+ * \ingroup usrp
+ *
+ * This is the recommended interface to USRP receive functionality
+ * for applications that use the USRP but not GNU Radio.
+ */
+class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common
+{
+ private:
+  static const int     MAX_CHAN = 4;
+  unsigned int         d_decim_rate;
+  int                  d_nchan;
+  int                  d_sw_mux;
+  int                  d_hw_mux;
+  double               d_rx_freq[MAX_CHAN];
+
+ protected:
+  usrp_standard_rx (int which_board,
+                   unsigned int decim_rate,
+                   int nchan = 1,
+                   int mux = -1,
+                   int mode = 0,
+                   int fusb_block_size = 0,
+                   int fusb_nblocks = 0,
+                   const std::string fpga_filename = "",
+                   const std::string firmware_filename = ""
+                   );  // throws if trouble
+
+  bool write_hw_mux_reg ();
+
+ public:
+
+  enum {
+    FPGA_MODE_NORMAL     = 0x00,
+    FPGA_MODE_LOOPBACK   = 0x01,
+    FPGA_MODE_COUNTING   = 0x02,
+    FPGA_MODE_COUNTING_32BIT   = 0x04
+  };
+
+  ~usrp_standard_rx ();
+
+  /*!
+   * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
+   *
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param decim_rate      decimation factor
+   * \param nchan           number of channels
+   * \param mux                     Rx mux setting, \sa set_mux
+   * \param mode            mode
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
+   * \param fpga_filename    Name of rbf file to load
+   * \param firmware_filename Name of ihx file to load
+   */
+  static usrp_standard_rx_sptr make(int which_board,
+                                   unsigned int decim_rate,
+                                   int nchan = 1,
+                                   int mux = -1,
+                                   int mode = 0,
+                                   int fusb_block_size = 0,
+                                   int fusb_nblocks = 0,
+                                   const std::string fpga_filename = "",
+                                   const std::string firmware_filename = ""
+                                   );
+  /*!
+   * \brief Set decimator rate.  \p rate MUST BE EVEN and in [8, 256].
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate () * nchannels ()
+   */
+  bool set_decim_rate  (unsigned int rate);
+
+  /*!
+   * \brief Set number of active channels.  \p nchannels must be 1, 2 or 4.
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate () * nchannels ()
+   */
+  bool set_nchannels (int nchannels);
+
+  /*!
+   * \brief Set input mux configuration.
+   *
+   * This determines which ADC (or constant zero) is connected to 
+   * each DDC input.  There are 4 DDCs.  Each has two inputs.
+   *
+   * <pre>
+   * Mux value:
+   *
+   *    3                   2                   1                       
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   * |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   *
+   * Each 4-bit I field is either 0,1,2,3
+   * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
+   * All Q's must be 0xf or none of them may be 0xf
+   * </pre>
+   */
+  bool set_mux  (int mux);
+
+  /*!
+   * Determine the appropriate Rx mux value as a function of the subdevice choosen
+   * and the characteristics of the respective daughterboard.
+   */
+  int determine_rx_mux_value(const usrp_subdev_spec &ss);
+  int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
+
+  /*!
+   * \brief set the frequency of the digital down converter.
+   *
+   * \p channel must be in the range [0,3].  \p freq is the center
+   * frequency in Hz.  \p freq may be either negative or postive.
+   * The frequency specified is quantized.  Use rx_freq to retrieve
+   * the actual value used.
+   */
+  bool set_rx_freq (int channel, double freq);  
+
+  /*!
+   * \brief set fpga mode
+   */
+  bool set_fpga_mode (int mode);
+
+  /*!
+   * \brief Set the digital down converter phase register.
+   *
+   * \param channel    which ddc channel [0, 3]
+   * \param phase      32-bit integer phase value.
+   */
+  bool set_ddc_phase(int channel, int phase);
+
+  /*!
+   * \brief Specify Rx data format.
+   *
+   * \param format     format specifier
+   *
+   * Rx data format control register
+   *
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-----------------------------------------+-+-+---------+-------+
+   *  |          Reserved (Must be zero)        |B|Q|  WIDTH  | SHIFT |
+   *  +-----------------------------------------+-+-+---------+-------+
+   *
+   *  SHIFT specifies arithmetic right shift [0, 15]
+   *  WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
+   *  Q     if set deliver both I & Q, else just I
+   *  B     if set bypass half-band filter.
+   *
+   * Right now the acceptable values are:
+   *
+   *   B  Q  WIDTH  SHIFT
+   *   0  1    16     0
+   *   0  1     8     8
+   *
+   * More valid combos to come.
+   *
+   * Default value is 0x00000300  16-bits, 0 shift, deliver both I & Q.
+   */
+  bool set_format(unsigned int format);
+
+  static unsigned int make_format(int width=16, int shift=0,
+                                 bool want_q=true, bool bypass_halfband=false);
+  static int format_width(unsigned int format);
+  static int format_shift(unsigned int format);
+  static bool format_want_q(unsigned int format);
+  static bool format_bypass_halfband(unsigned int format);
+
+  /*!
+   * \brief High-level "tune" method.  Works for the single channel case.
+   *
+   * This method adjusts both the daughterboard LO and the DDC so that
+   * target_freq ends up at DC in the complex baseband samples.
+   *
+   * \param chan  which DDC channel we're controlling (almost always 0).
+   * \param db    the daughterboard we're controlling.
+   * \param target_freq the RF frequency we want at DC in the complex baseband.
+   * \param[out] result details how the hardware was configured.
+   *
+   * \returns true iff everything was successful.
+   */
+  bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+  
+
+  // ACCESSORS
+  unsigned int decim_rate () const;
+  double rx_freq (int channel) const;
+  int nchannels () const;
+  int mux () const;
+  unsigned int format () const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+// ----------------------------------------------------------------
+
+/*!
+ * \brief The C++ interface the transmit side of the USRP
+ * \ingroup usrp
+ *
+ * This is the recommended interface to USRP transmit functionality
+ * for applications that use the USRP but not GNU Radio.
+ *
+ * Uses digital upconverter (coarse & fine modulators) in AD9862...
+ */
+class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common
+{
+ public:
+  enum coarse_mod_t {
+    CM_NEG_FDAC_OVER_4,                // -32 MHz
+    CM_NEG_FDAC_OVER_8,                // -16 MHz
+    CM_OFF,
+    CM_POS_FDAC_OVER_8,                // +16 MHz
+    CM_POS_FDAC_OVER_4         // +32 MHz
+  };
+
+ protected:
+  static const int     MAX_CHAN = 2;
+  unsigned int         d_interp_rate;
+  int                  d_nchan;
+  int                  d_sw_mux;
+  int                  d_hw_mux;
+  double               d_tx_freq[MAX_CHAN];
+  coarse_mod_t         d_coarse_mod[MAX_CHAN];
+  unsigned char                d_tx_modulator_shadow[MAX_CHAN];
+
+  virtual bool set_coarse_modulator (int channel, coarse_mod_t cm);
+  usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const;
+
+ protected:
+  usrp_standard_tx (int which_board,
+                   unsigned int interp_rate,
+                   int nchan = 1,
+                   int mux = -1,
+                   int fusb_block_size = 0,
+                   int fusb_nblocks = 0,
+                   const std::string fpga_filename = "",
+                   const std::string firmware_filename = ""
+                   );  // throws if trouble
+
+  bool write_hw_mux_reg ();
+
+ public:
+  ~usrp_standard_tx ();
+
+  /*!
+   * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
+   *
+   * \param which_board             Which USRP board on usb (not particularly useful; use 0)
+   * \param interp_rate             interpolation factor
+   * \param nchan           number of channels
+   * \param mux                     Tx mux setting, \sa set_mux
+   * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
+   *                         Use zero for a reasonable default.
+   * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
+   * \param fpga_filename    Name of rbf file to load
+   * \param firmware_filename Name of ihx file to load
+   */
+  static usrp_standard_tx_sptr make(int which_board,
+                                   unsigned int interp_rate,
+                                   int nchan = 1,
+                                   int mux = -1,
+                                   int fusb_block_size = 0,
+                                   int fusb_nblocks = 0,
+                                   const std::string fpga_filename = "",
+                                   const std::string firmware_filename = ""
+                                   );
+
+  /*!
+   * \brief Set interpolator rate.  \p rate must be in [4, 512] and a multiple of 4.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () / interp_rate () * nchannels ()
+   */
+  virtual bool set_interp_rate (unsigned int rate);
+
+  /*!
+   * \brief Set number of active channels.  \p nchannels must be 1 or 2.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () / decim_rate () * nchannels ()
+   */
+  bool set_nchannels  (int nchannels);
+
+  /*!
+   * \brief Set output mux configuration.
+   *
+   * <pre>
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-------------------------------+-------+-------+-------+-------+
+   *  |                               | DAC3  | DAC2  | DAC1  |  DAC0 |
+   *  +-------------------------------+-------+-------+-------+-------+
+   * 
+   *  There are two interpolators with complex inputs and outputs.
+   *  There are four DACs.
+   * 
+   *  Each 4-bit DACx field specifies the source for the DAC and
+   *  whether or not that DAC is enabled.  Each subfield is coded
+   *  like this: 
+   * 
+   *     3 2 1 0
+   *    +-+-----+
+   *    |E|  N  |
+   *    +-+-----+
+   * 
+   *  Where E is set if the DAC is enabled, and N specifies which
+   *  interpolator output is connected to this DAC.
+   * 
+   *   N   which interp output
+   *  ---  -------------------
+   *   0   chan 0 I
+   *   1   chan 0 Q
+   *   2   chan 1 I
+   *   3   chan 1 Q
+   * </pre>
+   */
+  bool set_mux  (int mux);
+
+  /*!
+   * Determine the appropriate Tx mux value as a function of the subdevice choosen
+   * and the characteristics of the respective daughterboard.
+   */
+  int determine_tx_mux_value(const usrp_subdev_spec &ss);
+  int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
+
+  /*!
+   * \brief set the frequency of the digital up converter.
+   *
+   * \p channel must be in the range [0,1].  \p freq is the center
+   * frequency in Hz.  It must be in the range [-44M, 44M].
+   * The frequency specified is quantized.  Use tx_freq to retrieve
+   * the actual value used.
+   */
+  virtual bool set_tx_freq (int channel, double freq);  // chan: [0,1]
+
+  // ACCESSORS
+  unsigned int interp_rate () const;
+  double tx_freq (int channel) const;
+  int nchannels () const;
+  int mux () const;
+
+  /*!
+   * \brief High-level "tune" method.  Works for the single channel case.
+   *
+   * This method adjusts both the daughterboard LO and the DUC so that
+   * DC in the complex baseband samples ends up at RF target_freq.
+   *
+   * \param chan  which DUC channel we're controlling (usually == which_side).
+   * \param db    the daughterboard we're controlling.
+   * \param target_freq the RF frequency we want our baseband translated to.
+   * \param[out] result details how the hardware was configured.
+   *
+   * \returns true iff everything was successful.
+   */
+  bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
+
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+#endif /* INCLUDED_USRP_STANDARD_H */
diff --git a/usrp/host/include/usrp/usrp_subdev_spec.h b/usrp/host/include/usrp/usrp_subdev_spec.h
new file mode 100644 (file)
index 0000000..e841ff8
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_USRP_SUBDEV_SPEC_H
+#define INCLUDED_USRP_SUBDEV_SPEC_H
+
+/*!
+ * \brief specify a daughterboard and subdevice on a daughterboard.
+ *
+ * In the USRP1, there are two sides, A and B.
+ *
+ * A daughterboard generally implements a single subdevice, but may in
+ * general implement any number of subdevices.  At this time, all daughterboards
+ * with the exception of the Basic Rx and LF Rx implement a single subdevice.
+ *
+ * The Basic Rx and LF Rx implement 2 subdevices (soon 3).  Subdevice
+ * 0 routes input RX-A to the DDC I input and routes a constant zero
+ * to the DDC Q input.  Similarly, subdevice 1 routes input RX-B to
+ * the DDC I input and routes a constant zero to the DDC Q
+ * input.  Subdevice 2 (when implemented) will route RX-A to the DDC I
+ * input and RX-B to the DDC Q input.
+ */
+
+struct usrp_subdev_spec {
+  unsigned int side;           // 0 -> A; 1 -> B
+  unsigned int subdev;         // which subdevice (usually zero)
+
+  usrp_subdev_spec(unsigned int _side = 0, unsigned int _subdev = 0)
+    : side(_side), subdev(_subdev) {}
+};
+
+#endif /* INCLUDED_USRP_SUBDEV_SPEC_H */
diff --git a/usrp/host/include/usrp/usrp_tune_result.h b/usrp/host/include/usrp/usrp_tune_result.h
new file mode 100644 (file)
index 0000000..200541a
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_USRP_TUNE_RESULT_H
+#define INCLUDED_USRP_TUNE_RESULT_H
+
+class usrp_tune_result
+{
+public:
+  // RF frequency that corresponds to DC in the IF
+  double baseband_freq;
+
+  // frequency programmed into the DDC/DUC
+  double dxc_freq;
+
+  // residual frequency (typically < 0.01 Hz)
+  double residual_freq;
+
+  // is the spectrum inverted?
+  bool inverted;
+
+  usrp_tune_result(double baseband=0, double dxc=0, double residual=0, bool _inverted=false)
+    : baseband_freq(baseband), dxc_freq(dxc),
+      residual_freq(residual), inverted(_inverted) {}
+};
+
+#endif /* INCLUDED_USRP_TUNE_RESULT_H */
diff --git a/usrp/host/lib/.gitignore b/usrp/host/lib/.gitignore
new file mode 100644 (file)
index 0000000..e0e4208
--- /dev/null
@@ -0,0 +1,14 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/test_fusb
+/std_paths.h
+/usrp_dbid.py
+/usrp_dbid.h
+/usrp_dbid.cc
+/stamp-*
index b6696b880f25e92de683af22ae874c868061cc82..23889fc85a25822b313dcb62883c0f08a684c028 100644 (file)
 #
 #  USRP - Universal Software Radio Peripheral
-# 
-#  Copyright (C) 2003,2004,2006,2007 Free Software Foundation, Inc.
-# 
+#
+#  Copyright (C) 2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+#
 #  This program 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 of the License, or
 #  (at your option) any later version.
-# 
+#
 #  This program is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
-# 
+#
 #  You should have received a copy of the GNU General Public License
 #  along with this program; if not, write to the Free Software
 #  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
-# 
+#
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = legacy
+common_INCLUDES = $(USRP_INCLUDES) $(USB_INCLUDES)
+
+lib_LTLIBRARIES = libusrp.la
+
+libusrp_la_common_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) $(BOOST_LDFLAGS)
+
+libusrp_la_common_LIBADD =             \
+       $(USB_LIBS)                     \
+       $(BOOST_THREAD_LIB)             \
+       ../misc/libmisc.la
+
+# darwin fusb requires gruel (for threading)
+if FUSB_TECH_darwin
+AM_CPPFLAGS = $(common_INCLUDES) $(GRUEL_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
+libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(GRUEL_LA)
+libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS) -framework CoreFoundation
+else
+AM_CPPFLAGS = $(common_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
+libusrp_la_LIBADD = $(libusrp_la_common_LIBADD)
+libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS)
+endif
+
+EXTRA_DIST =                           \
+       std_paths.h.in                  \
+       usrp_dbid.dat
+
+BUILT_SOURCES = $(abs_top_builddir)/usrp/host/include/usrp/usrp_dbid.h
+
+BUILT_SOURCES += usrp_dbid.cc \
+                usrp_dbid.py
+
+# ----------------------------------------------------------------
+# FUSB_TECH is set at configure time by way of
+#   usrp/config/usrp_fusb_tech.m4.
+#   It indicates which fast usb strategy we should be building.
+#   We currently implement "generic", "darwin", "win32" and "linux"
+
+
+generic_CODE =                                 \
+       fusb_generic.cc                 \
+       fusb_sysconfig_generic.cc       \
+       usrp_prims_libusb0.cc           
+
+darwin_CODE =                          \
+       fusb_darwin.cc                  \
+       fusb_sysconfig_darwin.cc        \
+       README_OSX                      \
+       circular_buffer.h               \
+       circular_linked_list.h          \
+       darwin_libusb.h                 \
+       usrp_prims_libusb0.cc           
+
+
+win32_CODE =                           \
+       fusb_win32.cc                   \
+       fusb_sysconfig_win32.cc         \
+       usrp_prims_libusb0.cc           
+
+
+linux_CODE =                           \
+       fusb_linux.cc                   \
+       fusb_sysconfig_linux.cc         \
+       usrp_prims_libusb0.cc           
+
+ra_wb_CODE =                           \
+       fusb_ra_wb.cc                   \
+       fusb_sysconfig_ra_wb.cc         \
+       usrp_prims_libusb0.cc           
+
+libusb1_CODE =                         \
+       fusb_libusb1.cc                 \
+       fusb_sysconfig_libusb1.cc       \
+       usrp_prims_libusb1.cc           
+
+#
+# include each <foo>_CODE entry here...
+#
+EXTRA_libusrp_la_SOURCES =             \
+       $(generic_CODE)                 \
+       $(darwin_CODE)                  \
+       $(win32_CODE)                   \
+       $(linux_CODE)                   \
+       $(ra_wb_CODE)                   \
+       $(libusb1_CODE)
+
+# work around automake deficiency
+libusrp_la_common_SOURCES =            \
+       fusb.cc                         \
+       md5.c                           \
+       usrp_basic.cc                   \
+       usrp_config.cc                  \
+       usrp_dbid.cc                    \
+       usrp_local_sighandler.cc        \
+       usrp_prims_common.cc            \
+       usrp_standard.cc                \
+       db_wbxng_adf4350.cc             \
+       db_wbxng_adf4350_regs.cc        \
+       db_boards.cc                    \
+       db_base.cc                      \
+       db_basic.cc                     \
+       db_bitshark_rx.cc               \
+       db_tv_rx.cc                     \
+       db_tv_rx_mimo.cc                \
+       db_flexrf.cc                    \
+       db_flexrf_mimo.cc               \
+       db_dbs_rx.cc                    \
+       db_wbxng.cc                     \
+       db_xcvr2450.cc                  \
+       db_dtt754.cc                    \
+       db_dtt768.cc                    \
+       db_util.cc
+
+if FUSB_TECH_generic
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(generic_CODE)
+endif
+
+if FUSB_TECH_darwin
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(darwin_CODE)
+endif
+
+if FUSB_TECH_win32
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(win32_CODE)
+endif
+
+if FUSB_TECH_linux
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(linux_CODE)
+endif
+
+if FUSB_TECH_ra_wb
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(ra_wb_CODE)
+endif
+
+if FUSB_TECH_libusb1
+libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(libusb1_CODE)
+endif
+
+
+noinst_HEADERS =                       \
+       ad9862.h                        \
+       db_base_impl.h                  \
+       db_boards.h                     \
+       db_util.h                       \
+       db_wbxng_adf4350.h              \
+       db_wbxng_adf4350_regs.h         \
+       fusb.h                          \
+       fusb_darwin.h                   \
+       fusb_generic.h                  \
+       fusb_linux.h                    \
+       fusb_libusb1.h                  \
+       fusb_ra_wb.h                    \
+       fusb_win32.h                    \
+       md5.h                           \
+       rate_to_regval.h                \
+       usrp_config.h                   \
+       usrp_primsi.h
+
+if PYTHON
+usrppython_PYTHON =                    \
+       usrp_dbid.py                    
+
+noinst_PYTHON =                                \
+       gen_usrp_dbid.py                \
+       check_data.py                   \
+       dump_data.py
+endif
+
+# common way for generating sources from templates when using
+# BUILT_SOURCES, using parallel build protection.
+gen_sources = $(BUILT_SOURCES)
+gen_sources_deps = gen_usrp_dbid.py usrp_dbid.dat
+par_gen_command = PYTHONPATH=$(top_srcdir)/usrp/src srcdir=$(srcdir) $(PYTHON) $(srcdir)/gen_usrp_dbid.py $(srcdir)/usrp_dbid.dat
+include $(top_srcdir)/Makefile.par.gen
diff --git a/usrp/host/lib/README_OSX b/usrp/host/lib/README_OSX
new file mode 100644 (file)
index 0000000..37026f2
--- /dev/null
@@ -0,0 +1,63 @@
+USRP Darwin Fast USB Changes
+Version 0.2 of 2006-04-27
+Michael Dickens <mdickens @at@ nd .dot. edu>
+
+The files included in this archive are:
+
+circular_buffer.h
+circular_linked_list.h
+darwin_libusb.h
+fusb_darwin.cc
+fusb_darwin.h
+mld_threads.h
+
+These files allow GNURadio code for Darwin / MaxOS X to talk to the
+USRP via USB 2.0 at rates up to around 30 Mega-Bytes/sec (MBps), up
+from 4-8 MBps without the changes.
+
+I implemented the buffering myself; there are probably GR buffers
+available which would do the work but as this is "beta" software it's
+a good place to start.  Speed improvements are made by porting
+LIBUSB's non-true async bulk read and write functions into USRP's
+"fusb", and upgrading them to handle -true- async transfers.
+Unfortunately, the easiest way to do this is to spawn a thread or 2 to
+handle the "async" part of the transfers.  This implementation uses
+Darwin's pthreads to do the work for mutexes, conditions, and threads.
+Previous implementations (0.1 and before) used "omni_threads" as
+provided by gnuradio-core, which caused issues with compiling and
+execution ... I'm glad that this is no longer the case.
+
+As far as I have tested, there is no way to improve the throughput to
+32+ MBps without moving into Darwin's "port"s ... a kernel-level data
+transport method with a user/application layer for USB-specific
+functions.  Unfortunately, Apple's documentation for these "port"s is
+minimal; I have learned more from reading the Darwin source code
+< http://darwinsource.opendarwin.org/ > than by reading Apple's
+documents!  This would also require -not- using LIBUSB, of which the
+removal from the rest of the USRP code would be potentially tedious.
+
+If you run into issues either compiling or testing the USRP on
+OSX, please send me a note.
+
+(1) Go through the bootstrap, configure, compile, and install as
+usual (e.g. see < http://www.nd.edu/~mdickens/GNURadio/ > for my
+usual).
+
+(2) from .../usrp/host/apps :  run the scripts
+++++++++++++++++
+./test_usrp_standard_tx
+./test_usrp_standard_rx
+++++++++++++++++
+
+For -all- systems I've tested on thus far, both of these return
+exactly 41 overruns / underruns, and -most- systems start out with a
+stalled pipe.  This stall comes in a usb_control function call to
+LIBUSB; one would have to change the LIBUSB code to handle this issue.
+
+(3) from gr-build/gnuradio-examples/python/usrp :
+++++++++++++++++
+./benchmark_usb.py
+++++++++++++++++
+
+(4) If you get to here, the try doing the FM receiver (gui or not).
+If that sounds correct, then the USB is working.  Yay!
\ No newline at end of file
diff --git a/usrp/host/lib/ad9862.h b/usrp/host/lib/ad9862.h
new file mode 100644 (file)
index 0000000..4375d93
--- /dev/null
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_AD9862_H
+#define INCLUDED_AD9862_H
+
+/*
+ * Analog Devices AD9862 registers and some fields
+ */
+
+#define BEGIN_AD9862   namespace ad9862 {
+#define        END_AD962       }
+#define        DEF static const int
+
+BEGIN_AD9862;
+
+DEF REG_GENERAL                =  0;
+DEF REG_RX_PWR_DN      =  1;
+DEF    RX_PWR_DN_VREF_DIFF             = (1 << 7);
+DEF    RX_PWR_DN_VREF                  = (1 << 6);
+DEF    RX_PWR_DN_RX_DIGIGAL            = (1 << 5);
+DEF    RX_PWR_DN_RX_B                  = (1 << 4);
+DEF    RX_PWR_DN_RX_A                  = (1 << 3);
+DEF    RX_PWR_DN_BUF_B                 = (1 << 2);
+DEF    RX_PWR_DN_BUF_A                 = (1 << 1);
+DEF    RX_PWR_DN_ALL                   = (1 << 0);
+
+DEF REG_RX_A           =  2;   // bypass input buffer / RxPGA
+DEF REG_RX_B           =  3;   // pypass input buffer / RxPGA
+DEF    RX_X_BYPASS_INPUT_BUFFER        = (1 << 7);
+
+DEF REG_RX_MISC                =  4;
+DEF    RX_MISC_HS_DUTY_CYCLE           = (1 << 2);
+DEF    RX_MISC_SHARED_REF              = (1 << 1);
+DEF    RX_MISC_CLK_DUTY                = (1 << 0);
+
+DEF REG_RX_IF          =  5;
+DEF    RX_IF_THREE_STATE               = (1 << 4);
+DEF    RX_IF_USE_CLKOUT1               = (0 << 3);     
+DEF    RX_IF_USE_CLKOUT2               = (1 << 3);     // aka Rx Retime
+DEF    RX_IF_2S_COMP                   = (1 << 2);
+DEF    RX_IF_INV_RX_SYNC               = (1 << 1);
+DEF    RX_IF_MUX_OUT                   = (1 << 0);
+
+DEF REG_RX_DIGITAL     =  6;
+DEF    RX_DIGITAL_2_CHAN               = (1 << 3);
+DEF    RX_DIGITAL_KEEP_MINUS_VE        = (1 << 2);
+DEF    RX_DIGITAL_HILBERT              = (1 << 1);
+DEF    RX_DIGITAL_DECIMATE             = (1 << 0);
+
+DEF REG_RESERVED_7     =  7;
+
+DEF REG_TX_PWR_DN      =  8;
+DEF    TX_PWR_DN_ALT_TIMING_MODE       = (1 << 5);
+DEF    TX_PWR_DN_TX_OFF_ENABLE         = (1 << 4);
+DEF    TX_PWR_DN_TX_DIGITAL            = (1 << 3);
+DEF    TX_PWR_DN_TX_ANALOG_B           = 0x4;
+DEF    TX_PWR_DN_TX_ANALOG_A           = 0x2;
+DEF    TX_PWR_DN_TX_ANALOG_BOTH        = 0x7;
+
+DEF REG_RESERVED_9     =  9;
+
+DEF REG_TX_A_OFFSET_LO = 10;
+DEF REG_TX_A_OFFSET_HI = 11;
+DEF REG_TX_B_OFFSET_LO = 12;
+DEF REG_TX_B_OFFSET_HI = 13;
+
+DEF REG_TX_A_GAIN      = 14;   // fine trim for matching
+DEF REG_TX_B_GAIN      = 15;   // fine trim for matching
+DEF    TX_X_GAIN_COARSE_FULL           = (3 << 6);
+DEF    TX_X_GAIN_COARSE_1_HALF         = (1 << 6);
+DEF    TX_X_GAIN_COARSE_1_ELEVENTH     = (0 << 6);
+
+DEF REG_TX_PGA         = 16;   // 20 dB continuous gain in 0.1 dB steps
+                               // 0x00 = min gain (-20 dB)
+                               // 0xff = max gain (  0 dB)
+
+DEF REG_TX_MISC                = 17;
+DEF    TX_MISC_SLAVE_ENABLE            = (1 << 1);
+DEF    TX_MISC_TX_PGA_FAST             = (1 << 0);
+
+DEF REG_TX_IF          = 18;
+DEF    TX_IF_USE_CLKOUT2               = (0 << 6);
+DEF    TX_IF_USE_CLKOUT1               = (1 << 6);     // aka Tx Retime
+DEF    TX_IF_I_FIRST                   = (0 << 5);
+DEF    TX_IF_Q_FIRST                   = (1 << 5);
+DEF    TX_IF_INV_TX_SYNC               = (1 << 4);
+DEF    TX_IF_2S_COMP                   = (1 << 3);
+DEF    TX_IF_INVERSE_SAMPLE            = (1 << 2);
+DEF    TX_IF_TWO_EDGES                 = (1 << 1);
+DEF    TX_IF_INTERLEAVED               = (1 << 0);
+
+DEF REG_TX_DIGITAL     = 19;
+DEF    TX_DIGITAL_2_DATA_PATHS         = (1 << 4);
+DEF    TX_DIGITAL_KEEP_NEGATIVE        = (1 << 3);
+DEF    TX_DIGITAL_HILBERT              = (1 << 2);
+DEF    TX_DIGITAL_INTERPOLATE_NONE     = 0x0;
+DEF    TX_DIGITAL_INTERPOLATE_2X       = 0x1;
+DEF    TX_DIGITAL_INTERPOLATE_4X       = 0x2;
+
+DEF REG_TX_MODULATOR   = 20;
+DEF    TX_MODULATOR_NEG_FINE_TUNE      = (1 << 5);
+DEF    TX_MODULATOR_DISABLE_NCO        = (0 << 4);
+DEF    TX_MODULATOR_ENABLE_NCO         = (1 << 4);     // aka Fine Mode
+DEF    TX_MODULATOR_REAL_MIX_MODE      = (1 << 3);
+DEF    TX_MODULATOR_NEG_COARSE_TUNE    = (1 << 2);
+DEF    TX_MODULATOR_COARSE_MODULATION_NONE     = 0x0;
+DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_4 = 0x1;
+DEF    TX_MODULATOR_COARSE_MODULATION_F_OVER_8 = 0x2;
+DEF    TX_MODULATOR_CM_MASK                    = 0x7;
+
+
+DEF REG_TX_NCO_FTW_7_0 = 21;
+DEF REG_TX_NCO_FTW_15_8        = 22;
+DEF REG_TX_NCO_FTW_23_16= 23;
+
+DEF REG_DLL            = 24;
+DEF    DLL_DISABLE_INTERNAL_XTAL_OSC   = (1 << 6);     // aka Input Clock Ctrl
+DEF    DLL_ADC_DIV2                    = (1 << 5);
+DEF    DLL_MULT_1X                     = (0 << 3);
+DEF    DLL_MULT_2X                     = (1 << 3);
+DEF    DLL_MULT_4X                     = (2 << 3);
+DEF    DLL_PWR_DN                      = (1 << 2);
+// undefined bit                       = (1 << 1);
+DEF    DLL_FAST                        = (1 << 0);
+
+DEF REG_CLKOUT         = 25;
+DEF    CLKOUT2_EQ_DLL                  = (0 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_2           = (1 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_4           = (2 << 6);
+DEF    CLKOUT2_EQ_DLL_OVER_8           = (3 << 6);
+DEF    CLKOUT_INVERT_CLKOUT2           = (1 << 5);
+DEF    CLKOUT_DISABLE_CLKOUT2          = (1 << 4);
+// undefined bit                       = (1 << 3);
+// undefined bit                       = (1 << 2);
+DEF    CLKOUT_INVERT_CLKOUT1           = (1 << 1);
+DEF    CLKOUT_DISABLE_CLKOUT1          = (1 << 0);
+
+DEF REG_AUX_ADC_A2_LO  = 26;
+DEF REG_AUX_ADC_A2_HI  = 27;
+DEF REG_AUX_ADC_A1_LO  = 28;
+DEF REG_AUX_ADC_A1_HI  = 29;
+DEF REG_AUX_ADC_B2_LO  = 30;
+DEF REG_AUX_ADC_B2_HI  = 31;
+DEF REG_AUX_ADC_B1_LO  = 32;
+DEF REG_AUX_ADC_B1_HI  = 33;
+
+DEF REG_AUX_ADC_CTRL   = 34;
+DEF    AUX_ADC_CTRL_AUX_SPI            = (1 << 7);
+DEF    AUX_ADC_CTRL_SELBNOTA           = (1 << 6);
+DEF    AUX_ADC_CTRL_REFSEL_B           = (1 << 5);
+DEF    AUX_ADC_CTRL_SELECT_B2          = (0 << 4);
+DEF    AUX_ADC_CTRL_SELECT_B1          = (1 << 4);
+DEF    AUX_ADC_CTRL_START_B            = (1 << 3);
+DEF    AUX_ADC_CTRL_REFSEL_A           = (1 << 2);
+DEF    AUX_ADC_CTRL_SELECT_A2          = (0 << 1);
+DEF    AUX_ADC_CTRL_SELECT_A1          = (1 << 1);
+DEF    AUX_ADC_CTRL_START_A            = (1 << 0);
+
+DEF REG_AUX_ADC_CLK    = 35;
+DEF    AUX_ADC_CLK_CLK_OVER_4          = (1 << 0);
+
+DEF REG_AUX_DAC_A      = 36;
+DEF REG_AUX_DAC_B      = 37;
+DEF REG_AUX_DAC_C      = 38;
+
+DEF REG_AUX_DAC_UPDATE = 39;
+DEF    AUX_DAC_UPDATE_SLAVE_ENABLE     = (1 << 7);
+DEF    AUX_DAC_UPDATE_C                = (1 << 2);
+DEF    AUX_DAC_UPDATE_B                = (1 << 1);
+DEF    AUX_DAC_UPDATE_A                = (1 << 0);
+
+DEF REG_AUX_DAC_PWR_DN = 40;
+DEF    AUX_DAC_PWR_DN_C                = (1 << 2);
+DEF    AUX_DAC_PWR_DN_B                = (1 << 1);
+DEF    AUX_DAC_PWR_DN_A                = (1 << 0);
+
+DEF REG_AUX_DAC_CTRL   = 41;
+DEF    AUX_DAC_CTRL_INV_C              = (1 << 4);
+DEF    AUX_DAC_CTRL_INV_B              = (1 << 2);
+DEF    AUX_DAC_CTRL_INV_A              = (1 << 0);
+
+DEF REG_SIGDELT_LO     = 42;
+DEF REG_SIGDELT_HI     = 43;
+
+// 44 to 48 reserved
+
+DEF REG_ADC_LOW_PWR_LO = 49;
+DEF REG_ADC_LOW_PWR_HI = 50;
+
+// 51 to 62 reserved
+
+DEF REG_CHIP_ID                = 63;
+
+
+END_AD962;
+
+#undef DEF
+#undef BEGIN_AD9862
+#undef END_AD962
+
+#endif /* INCLUDED_AD9862_H */
diff --git a/usrp/host/lib/check_data.py b/usrp/host/lib/check_data.py
new file mode 100755 (executable)
index 0000000..100f0f6
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+import sys
+import struct
+
+fin = sys.stdin
+
+count = 0
+expected = 0
+last_correction = 0
+
+while 1:
+    s = fin.read(2)
+    if not s or len(s) != 2:
+        break
+
+    v, = struct.unpack ('H', s)
+    iv = int(v) & 0xffff
+    # print "%8d  %6d  0x%04x" % (count, iv, iv)
+    if count & 0x1:                     # only counting on the Q channel
+        if (expected & 0xffff) != iv:
+            print "%8d  (%6d) %6d  0x%04x" % (count, count - last_correction, iv, iv)
+            expected = iv               # reset expected sequence
+            last_correction = count
+        expected = (expected + 1) & 0xffff 
+        
+    count += 1
+
+    
+
+
diff --git a/usrp/host/lib/circular_buffer.h b/usrp/host/lib/circular_buffer.h
new file mode 100644 (file)
index 0000000..48758bf
--- /dev/null
@@ -0,0 +1,315 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifndef _CIRCULAR_BUFFER_H_
+#define _CIRCULAR_BUFFER_H_
+
+#include <gruel/thread.h>
+#include <iostream>
+#include <stdexcept>
+
+#ifndef DO_DEBUG
+#define DO_DEBUG 0
+#endif
+
+#if DO_DEBUG
+#define DEBUG(X) do{X} while(0);
+#else
+#define DEBUG(X) do{} while(0);
+#endif
+
+template <class T>
+class circular_buffer
+{
+private:
+// the buffer to use
+  T* d_buffer;
+
+// the following are in Items (type T)
+  size_t d_bufLen_I, d_readNdx_I, d_writeNdx_I;
+  size_t d_n_avail_write_I, d_n_avail_read_I;
+
+// stuff to control access to class internals
+  gruel::mutex* d_internal;
+  gruel::condition_variable* d_readBlock;
+  gruel::condition_variable* d_writeBlock;
+
+// booleans to decide how to control reading, writing, and aborting
+  bool d_doWriteBlock, d_doFullRead, d_doAbort;
+
+  void delete_mutex_cond () {
+    if (d_internal) {
+      delete d_internal;
+      d_internal = NULL;
+    }
+    if (d_readBlock) {
+      delete d_readBlock;
+      d_readBlock = NULL;
+    }
+    if (d_writeBlock) {
+      delete d_writeBlock;
+      d_writeBlock = NULL;
+    }
+  };
+
+public:
+  circular_buffer (size_t bufLen_I,
+                  bool doWriteBlock = true, bool doFullRead = false) {
+    if (bufLen_I == 0)
+      throw std::runtime_error ("circular_buffer(): "
+                               "Number of items to buffer must be > 0.\n");
+    d_bufLen_I = bufLen_I;
+    d_buffer = (T*) new T[d_bufLen_I];
+    d_doWriteBlock = doWriteBlock;
+    d_doFullRead = doFullRead;
+    d_internal = NULL;
+    d_readBlock = d_writeBlock = NULL;
+    reset ();
+    DEBUG (std::cerr << "c_b(): buf len (items) = " << d_bufLen_
+          << ", doWriteBlock = " << (d_doWriteBlock ? "true" : "false")
+          << ", doFullRead = " << (d_doFullRead ? "true" : "false")
+          << std::endl);
+  };
+
+  ~circular_buffer () {
+    delete_mutex_cond ();
+    delete [] d_buffer;
+  };
+
+  inline size_t n_avail_write_items () {
+    gruel::scoped_lock l (*d_internal);
+    size_t retVal = d_n_avail_write_I;
+    return (retVal);
+  };
+
+  inline size_t n_avail_read_items () {
+    gruel::scoped_lock l (*d_internal);
+    size_t retVal = d_n_avail_read_I;
+    return (retVal);
+  };
+
+  inline size_t buffer_length_items () {return (d_bufLen_I);};
+  inline bool do_write_block () {return (d_doWriteBlock);};
+  inline bool do_full_read () {return (d_doFullRead);};
+
+  void reset () {
+    d_doAbort = false;
+    bzero (d_buffer, d_bufLen_I * sizeof (T));
+    d_readNdx_I = d_writeNdx_I = d_n_avail_read_I = 0;
+    d_n_avail_write_I = d_bufLen_I;
+    delete_mutex_cond ();
+    // create a mutex to handle contention of shared resources;
+    // any routine needed access to shared resources uses lock()
+    // before doing anything, then unlock() when finished.
+    d_internal = new gruel::mutex ();
+    // link the internal mutex to the read and write conditions;
+    // when wait() is called, the internal mutex will automatically
+    // be unlock()'ed.  Upon return (from a notify_one() to the condition),
+    // the internal mutex will be lock()'ed.
+    d_readBlock = new gruel::condition_variable ();
+    d_writeBlock = new gruel::condition_variable ();
+  };
+
+/*
+ * enqueue: add the given buffer of item-length to the queue,
+ *     first-in-first-out (FIFO).
+ *
+ * inputs:
+ *     buf: a pointer to the buffer holding the data
+ *
+ *     bufLen_I: the buffer length in items (of the instantiated type)
+ *
+ * returns:
+ *    -1: on overflow (write is not blocking, and data is being
+ *                     written faster than it is being read)
+ *     0: if nothing to do (0 length buffer)
+ *     1: if success
+ *     2: in the process of aborting, do doing nothing
+ *
+ * will throw runtime errors if inputs are improper:
+ *     buffer pointer is NULL
+ *     buffer length is larger than the instantiated buffer length
+ */
+
+  int enqueue (T* buf, size_t bufLen_I) {
+    DEBUG (std::cerr << "enqueue: buf = " << (void*) buf
+          << ", bufLen = " << bufLen_I
+          << ", #av_wr = " << d_n_avail_write_I
+          << ", #av_rd = " << d_n_avail_read_I << std::endl);
+    if (bufLen_I > d_bufLen_I) {
+      std::cerr << "ERROR: cannot add buffer longer ("
+               << bufLen_I << ") than instantiated length ("
+               << d_bufLen_I << ")." << std::endl;
+      throw std::runtime_error ("circular_buffer::enqueue()");
+    }
+
+    if (bufLen_I == 0)
+      return (0);
+    if (!buf)
+      throw std::runtime_error ("circular_buffer::enqueue(): "
+                               "input buffer is NULL.\n");
+    gruel::scoped_lock l (*d_internal);
+    if (d_doAbort) {
+      return (2);
+    }
+    // set the return value to 1: success; change if needed
+    int retval = 1;
+    if (bufLen_I > d_n_avail_write_I) {
+      if (d_doWriteBlock) {
+       while (bufLen_I > d_n_avail_write_I) {
+         DEBUG (std::cerr << "enqueue: #len > #a, waiting." << std::endl);
+         // wait; will automatically unlock() the internal mutex via
+         // the scoped lock
+         d_writeBlock->wait (l);
+         // and auto re-lock() it here.
+         if (d_doAbort) {
+           DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl);
+           return (2);
+         }
+         DEBUG (std::cerr << "enqueue: #len > #a, done waiting." << std::endl);
+       }
+      } else {
+       d_n_avail_read_I = d_bufLen_I - bufLen_I;
+       d_n_avail_write_I = bufLen_I;
+       DEBUG (std::cerr << "circular_buffer::enqueue: overflow" << std::endl);
+       retval = -1;
+      }
+    }
+    size_t n_now_I = d_bufLen_I - d_writeNdx_I, n_start_I = 0;
+    if (n_now_I > bufLen_I)
+      n_now_I = bufLen_I;
+    else if (n_now_I < bufLen_I)
+      n_start_I = bufLen_I - n_now_I;
+    bcopy (buf, &(d_buffer[d_writeNdx_I]), n_now_I * sizeof (T));
+    if (n_start_I) {
+      bcopy (&(buf[n_now_I]), d_buffer, n_start_I * sizeof (T));
+      d_writeNdx_I = n_start_I;
+    } else
+      d_writeNdx_I += n_now_I;
+    d_n_avail_read_I += bufLen_I;
+    d_n_avail_write_I -= bufLen_I;
+    d_readBlock->notify_one ();
+    return (retval);
+  };
+
+/*
+ * dequeue: removes from the queue the number of items requested, or
+ *     available, into the given buffer on a FIFO basis.
+ *
+ * inputs:
+ *     buf: a pointer to the buffer into which to copy the data
+ *
+ *     bufLen_I: pointer to the number of items to remove in items
+ *         (of the instantiated type)
+ *
+ * returns:
+ *     0: if nothing to do (0 length buffer)
+ *     1: if success
+ *     2: in the process of aborting, do doing nothing
+ *
+ * will throw runtime errors if inputs are improper:
+ *     buffer pointer is NULL
+ *     buffer length pointer is NULL
+ *     buffer length is larger than the instantiated buffer length
+ */
+
+  int dequeue (T* buf, size_t* bufLen_I) {
+    DEBUG (std::cerr << "dequeue: buf = " << ((void*) buf)
+          << ", *bufLen = " << (*bufLen_I)
+          << ", #av_wr = " <<  d_n_avail_write_I
+          << ", #av_rd = " << d_n_avail_read_I << std::endl);
+    if (!bufLen_I)
+      throw std::runtime_error ("circular_buffer::dequeue(): "
+                               "input bufLen pointer is NULL.\n");
+    if (!buf)
+      throw std::runtime_error ("circular_buffer::dequeue(): "
+                               "input buffer pointer is NULL.\n");
+    size_t l_bufLen_I = *bufLen_I;
+    if (l_bufLen_I == 0)
+      return (0);
+    if (l_bufLen_I > d_bufLen_I) {
+      std::cerr << "ERROR: cannot remove buffer longer ("
+               << l_bufLen_I << ") than instantiated length ("
+               << d_bufLen_I << ")." << std::endl;
+      throw std::runtime_error ("circular_buffer::dequeue()");
+    }
+
+    gruel::scoped_lock l (*d_internal);
+    if (d_doAbort) {
+      return (2);
+    }
+    if (d_doFullRead) {
+      while (d_n_avail_read_I < l_bufLen_I) {
+       DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl);
+       // wait; will automatically unlock() the internal mutex via
+       // the scoped lock
+       d_readBlock->wait (l);
+       // and re-lock() it here.
+       if (d_doAbort) {
+         DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl);
+         return (2);
+       }
+       DEBUG (std::cerr << "dequeue: #a < #len, done waiting." << std::endl);
+     }
+    } else {
+      while (d_n_avail_read_I == 0) {
+       DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl);
+       // wait; will automatically unlock() the internal mutex via
+       // the scoped lock
+       d_readBlock->wait (l);
+       // and re-lock() it here.
+       if (d_doAbort) {
+         DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl);
+         return (2);
+       }
+       DEBUG (std::cerr << "dequeue: #a == 0, done waiting." << std::endl);
+      }
+    }
+    if (l_bufLen_I > d_n_avail_read_I)
+      l_bufLen_I = d_n_avail_read_I;
+    size_t n_now_I = d_bufLen_I - d_readNdx_I, n_start_I = 0;
+    if (n_now_I > l_bufLen_I)
+      n_now_I = l_bufLen_I;
+    else if (n_now_I < l_bufLen_I)
+      n_start_I = l_bufLen_I - n_now_I;
+    bcopy (&(d_buffer[d_readNdx_I]), buf, n_now_I * sizeof (T));
+    if (n_start_I) {
+      bcopy (d_buffer, &(buf[n_now_I]), n_start_I * sizeof (T));
+      d_readNdx_I = n_start_I;
+    } else
+      d_readNdx_I += n_now_I;
+    *bufLen_I = l_bufLen_I;
+    d_n_avail_read_I -= l_bufLen_I;
+    d_n_avail_write_I += l_bufLen_I;
+    d_writeBlock->notify_one ();
+    return (1);
+  };
+
+  void abort () {
+    gruel::scoped_lock l (*d_internal);
+    d_doAbort = true;
+    d_writeBlock->notify_one ();
+    d_readBlock->notify_one ();
+  };
+};
+
+#endif /* _CIRCULAR_BUFFER_H_ */
diff --git a/usrp/host/lib/circular_linked_list.h b/usrp/host/lib/circular_linked_list.h
new file mode 100644 (file)
index 0000000..bbed5e4
--- /dev/null
@@ -0,0 +1,278 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifndef _CIRCULAR_LINKED_LIST_H_
+#define _CIRCULAR_LINKED_LIST_H_
+
+#include <gruel/thread.h>
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+#ifndef DO_DEBUG
+#define DO_DEBUG 0
+#endif
+
+#if DO_DEBUG
+#define DEBUG(X) do{X} while(0);
+#else
+#define DEBUG(X) do{} while(0);
+#endif
+
+template <class T> class s_both;
+
+template <class T> class s_node
+{
+  typedef s_node<T>* s_node_ptr;
+
+private:
+  T d_object;
+  bool d_available;
+  s_node_ptr d_prev, d_next;
+  s_both<T>* d_both;
+
+public:
+  s_node (T l_object,
+         s_node_ptr l_prev = NULL,
+         s_node_ptr l_next = NULL)
+    : d_object (l_object), d_available (TRUE), d_prev (l_prev),
+    d_next (l_next), d_both (0) {};
+
+  __INLINE__ s_node (s_node_ptr l_prev, s_node_ptr l_next = NULL) {
+    s_node ((T) NULL, l_prev, l_next); };
+  __INLINE__ s_node () { s_node (NULL, NULL, NULL); };
+  __INLINE__ ~s_node () {};
+
+  void remove () {
+    d_prev->next (d_next);
+    d_next->prev (d_prev);
+    d_prev = d_next = this;
+  };
+
+  void insert_before (s_node_ptr l_next) {
+    if (l_next) {
+      s_node_ptr l_prev = l_next->prev ();
+      d_next = l_next;
+      d_prev = l_prev;
+      l_prev->next (this);
+      l_next->prev (this);
+    } else
+      d_next = d_prev = this;
+  };
+
+  void insert_after (s_node_ptr l_prev) {
+    if (l_prev) {
+      s_node_ptr l_next = l_prev->next ();
+      d_prev = l_prev;
+      d_next = l_next;
+      l_next->prev (this);
+      l_prev->next (this);
+    } else
+      d_prev = d_next = this;
+  };
+
+  __INLINE__ T object () { return (d_object); };
+  __INLINE__ void object (T l_object) { d_object = l_object; };
+  __INLINE__ bool available () { return (d_available); };
+  __INLINE__ void set_available () { d_available = TRUE; };
+  __INLINE__ void set_available (bool l_avail) { d_available = l_avail; };
+  __INLINE__ void set_not_available () { d_available = FALSE; };
+  __INLINE__ s_node_ptr next () { return (d_next); };
+  __INLINE__ s_node_ptr prev () { return (d_prev); };
+  __INLINE__ s_both<T>* both () { return (d_both); };
+  __INLINE__ void next (s_node_ptr l_next) { d_next = l_next; };
+  __INLINE__ void prev (s_node_ptr l_prev) { d_prev = l_prev; };
+  __INLINE__ void both (s_both<T>* l_both) { d_both = l_both; };
+};
+
+template <class T> class circular_linked_list {
+  typedef s_node<T>* s_node_ptr;
+
+private:
+  s_node_ptr d_current, d_iterate, d_available, d_inUse;
+  size_t d_n_nodes, d_n_used;
+  gruel::mutex* d_internal;
+  gruel::condition_variable* d_ioBlock;
+
+public:
+  circular_linked_list (size_t n_nodes) {
+    if (n_nodes == 0)
+      throw std::runtime_error ("circular_linked_list(): n_nodes == 0");
+
+    d_iterate = NULL;
+    d_n_nodes = n_nodes;
+    d_n_used = 0;
+    s_node_ptr l_prev, l_next;
+    d_inUse = d_current = l_next = l_prev = NULL;
+
+    l_prev = new s_node<T> ();
+    l_prev->set_available ();
+    l_prev->next (l_prev);
+    l_prev->prev (l_prev);
+    if (n_nodes > 1) {
+      l_next = new s_node<T> (l_prev, l_prev);
+      l_next->set_available ();
+      l_next->next (l_prev);
+      l_next->prev (l_prev);
+      l_prev->next (l_next);
+      l_prev->prev (l_next);
+      if (n_nodes > 2) {
+       size_t n = n_nodes - 2;
+       while (n-- > 0) {
+         d_current = new s_node<T> (l_prev, l_next);
+         d_current->set_available ();
+         d_current->prev (l_prev);
+         d_current->next (l_next);
+         l_prev->next (d_current);
+         l_next->prev (d_current);
+         l_next = d_current;
+         d_current = NULL;
+       }
+      }
+    }
+    d_available = d_current = l_prev;
+    d_ioBlock = new gruel::condition_variable ();
+    d_internal = new gruel::mutex ();
+  };
+
+  ~circular_linked_list () {
+    iterate_start ();
+    s_node_ptr l_node = iterate_next ();
+    while (l_node) {
+      delete l_node;
+      l_node = iterate_next ();
+    }
+    delete d_ioBlock;
+    d_ioBlock = NULL;
+    delete d_internal;
+    d_internal = NULL;
+    d_available = d_inUse = d_iterate = d_current = NULL;
+    d_n_used = d_n_nodes = 0;
+  };
+
+  s_node_ptr find_next_available_node () {
+    gruel::scoped_lock l (*d_internal);
+// find an available node
+    s_node_ptr l_node = d_available; 
+    DEBUG (std::cerr << "w ");
+    while (! l_node) {
+      DEBUG (std::cerr << "x" << std::endl);
+      // the ioBlock condition will automatically unlock() d_internal
+      d_ioBlock->wait (l);
+      // and lock() is here
+      DEBUG (std::cerr << "y" << std::endl);
+      l_node = d_available;
+    }
+    DEBUG (std::cerr << "::f_n_a_n: #u = " << num_used()
+          << ", node = " << l_node << std::endl);
+// remove this one from the current available list
+    if (num_available () == 1) {
+// last one, just set available to NULL
+      d_available = NULL;
+    } else
+      d_available = l_node->next ();
+    l_node->remove ();
+// add is to the inUse list
+    if (! d_inUse)
+      d_inUse = l_node;
+    else
+      l_node->insert_before (d_inUse);
+    d_n_used++;
+    l_node->set_not_available ();
+    return (l_node);
+  };
+
+  void make_node_available (s_node_ptr l_node) {
+    if (!l_node) return;
+    gruel::scoped_lock l (*d_internal);
+    DEBUG (std::cerr << "::m_n_a: #u = " << num_used()
+          << ", node = " << l_node << std::endl);
+// remove this node from the inUse list
+    if (num_used () == 1) {
+// last one, just set inUse to NULL
+      d_inUse = NULL;
+    } else
+      d_inUse = l_node->next ();
+    l_node->remove ();
+// add this node to the available list
+    if (! d_available)
+      d_available = l_node;
+    else
+      l_node->insert_before (d_available);
+    d_n_used--;
+
+    DEBUG (std::cerr << "s" << d_n_used);
+// signal the condition when new data arrives
+    d_ioBlock->notify_one ();
+    DEBUG (std::cerr << "t ");
+  };
+
+  __INLINE__ void iterate_start () { d_iterate = d_current; };
+
+  s_node_ptr iterate_next () {
+#if 0
+// lock the mutex for thread safety
+    gruel::scoped_lock l (*d_internal);
+#endif
+    s_node_ptr l_this = NULL;
+    if (d_iterate) {
+      l_this = d_iterate;
+      d_iterate = d_iterate->next ();
+      if (d_iterate == d_current)
+       d_iterate = NULL;
+    }
+    return (l_this);
+  };
+
+  __INLINE__ T object () { return (d_current->d_object); };
+  __INLINE__ void object (T l_object) { d_current->d_object = l_object; };
+  __INLINE__ size_t num_nodes () { return (d_n_nodes); };
+  __INLINE__ size_t num_used () { return (d_n_used); };
+  __INLINE__ void num_used (size_t l_n_used) { d_n_used = l_n_used; };
+  __INLINE__ size_t num_available () { return (d_n_nodes - d_n_used); };
+  __INLINE__ void num_used_inc (void) {
+    if (d_n_used < d_n_nodes) ++d_n_used;
+  };
+  __INLINE__ void num_used_dec (void) {
+    if (d_n_used != 0) --d_n_used;
+// signal the condition that new data has arrived
+    d_ioBlock->notify_one ();
+  };
+  __INLINE__ bool in_use () { return (d_n_used != 0); };
+};
+
+template <class T> class s_both
+{
+private:
+  s_node<T>* d_node;
+  void* d_this;
+public:
+  __INLINE__ s_both (s_node<T>* l_node, void* l_this)
+    : d_node (l_node), d_this (l_this) {};
+  __INLINE__ ~s_both () {};
+  __INLINE__ s_node<T>* node () { return (d_node); };
+  __INLINE__ void* This () { return (d_this); };
+  __INLINE__ void set (s_node<T>* l_node, void* l_this) {
+    d_node = l_node; d_this = l_this;};
+};
+
+#endif /* _CIRCULAR_LINKED_LIST_H_ */
diff --git a/usrp/host/lib/darwin_libusb.h b/usrp/host/lib/darwin_libusb.h
new file mode 100644 (file)
index 0000000..8446f04
--- /dev/null
@@ -0,0 +1,227 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 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.
+ */
+
+/*
+ * The following code was taken from LIBUSB verion 0.1.10a,
+ * and makes the fusb_darwin codes do-able in the current GR
+ * programming framework.  Parts and pieces were taken from
+ * usbi.h, darwin.c, and error.h .
+ *
+ * LIBUSB version 0.1.10a is covered by the LGPL, version 2;
+ * These codes are used with permission from:
+ *   (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
+ *   (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
+ * All rights reserved.
+ */
+
+#ifndef __DARWIN_LIBUSB_H__
+#define __DARWIN_LIBUSB_H__
+
+#include <IOKit/IOCFBundle.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <IOKit/IOKitLib.h>
+
+extern "C" {
+
+static const char* darwin_error_strings[] = {
+  "no error",
+  "device not opened for exclusive access",
+  "no connection to an IOService",
+  "no asyc port has been opened for interface",
+  "another process has device opened for exclusive access",
+  "pipe is stalled",
+  "could not establish a connection to Darin kernel",
+  "invalid argument",
+  "unknown error"
+};
+
+static const char *
+darwin_error_str (int result)
+{
+  switch (result) {
+  case kIOReturnSuccess:
+    return (darwin_error_strings[0]);
+  case kIOReturnNotOpen:
+    return (darwin_error_strings[1]);
+  case kIOReturnNoDevice:
+    return (darwin_error_strings[2]);
+  case kIOUSBNoAsyncPortErr:
+    return (darwin_error_strings[3]);
+  case kIOReturnExclusiveAccess:
+    return (darwin_error_strings[4]);
+  case kIOUSBPipeStalled:
+    return (darwin_error_strings[5]);
+  case kIOReturnError:
+    return (darwin_error_strings[6]);
+  case kIOReturnBadArgument:
+    return (darwin_error_strings[7]);
+  default:
+    return (darwin_error_strings[8]);
+  }
+}
+
+/* not a valid errorno outside darwin.c */
+#define LUSBDARWINSTALL (ELAST+1)
+
+static int
+darwin_to_errno (int result)
+{
+  switch (result) {
+  case kIOReturnSuccess:
+    return 0;
+  case kIOReturnNotOpen:
+    return EBADF;
+  case kIOReturnNoDevice:
+  case kIOUSBNoAsyncPortErr:
+    return ENXIO;
+  case kIOReturnExclusiveAccess:
+    return EBUSY;
+  case kIOUSBPipeStalled:
+    return LUSBDARWINSTALL;
+  case kIOReturnBadArgument:
+    return EINVAL;
+  case kIOReturnError:
+  default:
+    return 1;
+  }
+}
+
+typedef enum {
+  USB_ERROR_TYPE_NONE = 0,
+  USB_ERROR_TYPE_STRING,
+  USB_ERROR_TYPE_ERRNO,
+} usb_error_type_t;
+
+extern char usb_error_str[1024];
+extern int usb_error_errno;
+extern usb_error_type_t usb_error_type;
+
+#define USB_ERROR(r, x)                                 \
+  do {                                          \
+    usb_error_type = USB_ERROR_TYPE_ERRNO;      \
+    usb_error_errno = x;                        \
+    return (r);                                         \
+  } while (0)
+
+#define USB_ERROR_STR(r, x, format, args...)                           \
+  do {                                                                 \
+    usb_error_type = USB_ERROR_TYPE_STRING;                            \
+    snprintf (usb_error_str, sizeof (usb_error_str) - 1,               \
+             format, ## args);                                         \
+    if (usb_debug) {                                                   \
+      std::cerr << "USB error: " << usb_error_str << std::cerr;                \
+    }                                                                  \
+    return (r);                                                                \
+  } while (0)
+
+#define USB_ERROR_STR_ORIG(x, format, args...)                         \
+  do {                                                                 \
+    usb_error_type = USB_ERROR_TYPE_STRING;                            \
+    snprintf (usb_error_str, sizeof (usb_error_str) - 1,               \
+             format, ## args);                                         \
+    if (usb_debug) {                                                   \
+      std::cerr << "USB error: " << usb_error_str << std::endl;                \
+    }                                                                  \
+    return (x);                                                                \
+  } while (0)
+
+#define USB_ERROR_STR_NO_RET(x, format, args...)                       \
+  do {                                                                 \
+    usb_error_type = USB_ERROR_TYPE_STRING;                            \
+    snprintf (usb_error_str, sizeof (usb_error_str) - 1,               \
+             format, ## args);                                         \
+    if (usb_debug) {                                                   \
+      std::cerr << "USB error: " << usb_error_str << std::endl;                \
+    }                                                                  \
+  } while (0)
+
+/*
+ * simple function that figures out what pipeRef
+ * is associated with an endpoint
+ */
+static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
+{
+  io_return_t ret;
+  UInt8 numep, direction, number;
+  UInt8 dont_care1, dont_care3;
+  UInt16 dont_care2;
+  int i;
+
+  if (usb_debug > 3) {
+    std::cerr << "Converting ep address to pipeRef." << std::endl;
+  }
+
+  /* retrieve the total number of endpoints on this interface */
+  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
+  if ( ret ) {
+    if ( usb_debug > 3 ) {
+      std::cerr << "ep_to_pipeRef: interface is "
+               << device->interface << std::endl;
+    }
+    USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of "
+                        "endpoints for interface" );
+  }
+
+  /* iterate through the pipeRefs until we find the correct one */
+  for (i = 1 ; i <= numep ; i++) {
+    ret = (*(device->interface))->GetPipeProperties
+      (device->interface, i, &direction, &number,
+       &dont_care1, &dont_care2, &dont_care3);
+
+    if (ret != kIOReturnSuccess) {
+      std::cerr << "ep_to_pipeRef: an error occurred getting "
+               << "pipe information on pipe " << i << std::endl;
+
+      USB_ERROR_STR_ORIG (-darwin_to_errno(ret),
+                         "ep_to_pipeRef(GetPipeProperties): %s",
+                         darwin_error_str(ret));
+    }
+
+    if (usb_debug > 3) {
+      std::cerr << "ep_to_pipeRef: Pipe " << i << ": DIR: "
+               << direction << " number: " << number << std::endl;
+    }
+
+    /* calculate the endpoint of the pipe and check it versus
+       the requested endpoint */
+    if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) |
+         (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
+      if (usb_debug > 3) {
+       std::cerr << "ep_to_pipeRef: pipeRef for ep address "
+                 << ep << " found: " << i << std::endl;
+      }
+      return (i);
+    }
+  }
+
+  if (usb_debug > 3) {
+    std::cerr << "ep_to_pipeRef: No pipeRef found with endpoint address "
+             << ep << std::endl;
+  }
+
+  /* none of the found pipes match the requested endpoint */
+  return (-1);
+}
+
+}
+#endif /* __DARWIN_LIBUSB_H__ */
diff --git a/usrp/host/lib/db_base.cc b/usrp/host/lib/db_base.cc
new file mode 100644 (file)
index 0000000..1cb4634
--- /dev/null
@@ -0,0 +1,256 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_base.h>
+#include <db_base_impl.h>
+
+#if 0
+tune_result::tune_result(double baseband, double dxc, double residual, bool inv)
+  : ok(false), baseband_freq(baseband), dxc_freq(dxc), 
+    residual_freq(residual), inverted(inv)
+{
+}
+
+tune_result::~tune_result()
+{ 
+}
+#endif
+
+
+/*****************************************************************************/
+
+db_base::db_base(usrp_basic_sptr usrp, int which)
+  : d_is_shutdown(false), d_raw_usrp(usrp.get()), d_which(which), d_lo_offset(0.0)
+{
+}
+
+db_base::~db_base()
+{
+  shutdown();
+}
+
+void
+db_base::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+  }
+}
+
+int 
+db_base::dbid()
+{
+  return usrp()->daughterboard_id(d_which);
+}
+
+std::string 
+db_base::name()
+{
+  return usrp_dbid_to_string(dbid());
+}
+
+std::string 
+db_base::side_and_name()
+{
+  if(d_which == 0)
+    return "A: " + name();
+  else
+    return "B: " + name();
+}
+
+// Function to bypass ADC buffers. Any board which is DC-coupled
+// should bypass the buffers
+
+bool
+db_base::bypass_adc_buffers(bool bypass)
+{
+  //if(d_tx) {
+  //  throw  std::runtime_error("TX Board has no adc buffers\n");
+  //}
+
+  bool ok = true;
+  if(d_which==0) {
+    ok &= usrp()->set_adc_buffer_bypass(0, bypass);
+    ok &= usrp()->set_adc_buffer_bypass(1, bypass);
+  }
+  else {
+    ok &= usrp()->set_adc_buffer_bypass(2, bypass);
+    ok &= usrp()->set_adc_buffer_bypass(3, bypass);
+  }
+  return ok;
+}
+
+bool 
+db_base::set_atr_mask(int v)
+{
+  // Set Auto T/R mask.
+  return usrp()->write_atr_mask(d_which, v);
+}
+
+bool 
+db_base::set_atr_txval(int v)
+{
+  // Set Auto T/R register value to be used when transmitting.
+  return usrp()->write_atr_txval(d_which, v);
+}
+  
+bool 
+db_base::set_atr_rxval(int v)
+{
+  // Set Auto T/R register value to be used when receiving.
+  return usrp()->write_atr_rxval(d_which, v);
+}
+  
+bool 
+db_base::set_atr_tx_delay(int v)
+{
+  // Set Auto T/R delay (in clock ticks) from when Tx fifo gets data to 
+  // when T/R switches.
+  return usrp()->write_atr_tx_delay(v);
+}
+
+bool 
+db_base::set_atr_rx_delay(int v)
+{
+  // Set Auto T/R delay (in clock ticks) from when Tx fifo goes empty to 
+  // when T/R switches.
+  return usrp()->write_atr_rx_delay(v);
+}
+
+bool
+db_base::i_and_q_swapped()
+{
+  // Return True if this is a quadrature device and (for RX) ADC 0 is Q
+  // or (for TX) DAC 0 is Q
+  return false;
+}
+
+bool 
+db_base::spectrum_inverted()
+{
+  // Return True if the dboard gives an inverted spectrum
+  
+  return false;
+}
+
+bool
+db_base::set_enable(bool on)
+{
+  // For tx daughterboards, this controls the transmitter enable.
+
+  return true; // default is nop
+}
+
+bool
+db_base::set_auto_tr(bool on)
+{
+  // Enable automatic Transmit/Receive switching (ATR).
+  // 
+  // Should be overridden in subclasses that care.  This will typically
+  // set the atr_mask, txval and rxval.
+
+  return true;
+}
+
+bool
+db_base::set_lo_offset(double offset)
+{
+  // Set how much LO is offset from requested frequency
+
+  d_lo_offset = offset;
+  return true;
+}
+
+bool
+db_base::select_rx_antenna(int which_antenna)
+{
+  // Specify which antenna port to use for reception.
+  // Should be overriden by daughterboards that care.
+
+  return which_antenna == 0;
+}
+
+bool
+db_base::select_rx_antenna(const std::string &which_antenna)
+{
+  // Specify which antenna port to use for reception.
+  // Should be overriden by daughterboards that care.
+
+  return which_antenna == "";
+}
+
+
+// Reference Clock section
+//
+// Control whether a reference clock is sent to the daughterboards,
+// and what frequency
+//
+// Bit 7  -- 1 turns on refclk, 0 allows IO use
+// Bits 6:0 Divider value
+//
+    
+double
+db_base::_refclk_freq() 
+{
+  return usrp()->fpga_master_clock_freq() / _refclk_divisor();
+}
+
+void 
+db_base::_enable_refclk(bool enable)
+{
+  int CLOCK_OUT = 1;   // Clock is on lowest bit
+  int REFCLK_ENABLE = 0x80;
+  int REFCLK_DIVISOR_MASK = 0x7f;
+
+  if(enable) {
+    usrp()->_write_oe(d_which, CLOCK_OUT, CLOCK_OUT); // output enable
+    usrp()->write_refclk(d_which, (_refclk_divisor() & REFCLK_DIVISOR_MASK) | REFCLK_ENABLE);
+  }
+  else {
+    usrp()->write_refclk(d_which, 0);
+  }
+}
+
+int 
+db_base::_refclk_divisor()
+{
+  // Return value to stick in REFCLK_DIVISOR register
+  throw std::runtime_error("_reflck_divisor() called from base class\n");;
+}
+
+bool
+db_base::set_bw(float bw)
+{
+  // Set baseband bandwidth (board specific)
+  // Should be overriden by boards that implement variable IF filtering (e.g., DBSRX)
+  return false;
+}
+
+std::ostream &operator<<(std::ostream &os, db_base &x)
+{
+  os << x.side_and_name();
+  return os;
+}
diff --git a/usrp/host/lib/db_base_impl.h b/usrp/host/lib/db_base_impl.h
new file mode 100644 (file)
index 0000000..9d5ca43
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DB_BASE_IMPL_H
+#define INCLUDED_DB_BASE_IMPL_H
+
+#include <usrp/db_base.h>
+#include <db_util.h>
+#include <usrp/usrp_basic.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp/usrp_prims.h>
+#include <usrp_spi_defs.h>
+#include <stdexcept>
+
+#endif /* INCLUDED_DB_BASE_IMPL_H */
diff --git a/usrp/host/lib/db_basic.cc b/usrp/host/lib/db_basic.cc
new file mode 100644 (file)
index 0000000..1694d6a
--- /dev/null
@@ -0,0 +1,266 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_basic.h>
+#include <db_base_impl.h>
+
+db_basic_tx::db_basic_tx(boost::shared_ptr<usrp_basic> usrp, int which)
+  : db_base(usrp, which)
+{
+  // Handler for Basic Tx daughterboards.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0 or 1 corresponding to TX_A or TX_B respectively
+
+  set_gain((gain_min() + gain_max()) / 2);         // initialize gain
+}
+
+db_basic_tx::~db_basic_tx()
+{
+}
+
+double 
+db_basic_tx::freq_min() 
+{
+  return -90e9;
+}
+
+double 
+db_basic_tx::freq_max() 
+{
+  return 90e9;
+}
+
+struct freq_result_t 
+db_basic_tx::set_freq(double target_freq)
+{
+  // Set the frequency.
+  // 
+  // @param freq:  target RF frequency in Hz
+  // @type freq:   double
+  // 
+  // @returns (ok, actual_baseband_freq) where:
+  //   ok is True or False and indicates success or failure,
+  //   actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+  
+  struct freq_result_t args = {false, 0};
+  args.ok = true;
+  args.baseband_freq = 0.0;
+  return args;
+}
+
+float
+db_basic_tx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_basic_tx::gain_max()
+{
+  return usrp()->pga_max();
+}
+
+float
+db_basic_tx::gain_db_per_step()
+{
+  return usrp()->pga_db_per_step();
+}
+
+bool 
+db_basic_tx::set_gain(float gain)
+{
+  // Set the gain.
+  // 
+  // @param gain:  gain in decibels
+  // @returns True/False
+
+  bool ok = usrp()->set_pga(d_which * 2 + 0, gain);
+  ok = ok && usrp()->set_pga(d_which * 2 + 1, gain);
+  return ok;
+}
+
+bool 
+db_basic_tx::is_quadrature()
+{
+  // Return True if this board requires both I & Q analog channels.
+  
+  return true;
+}
+
+
+/******************************************************************************/
+
+
+db_basic_rx::db_basic_rx(usrp_basic_sptr usrp, int which, int subdev)
+  : db_base(usrp, which)
+{
+  // Handler for Basic Rx daughterboards.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0 or 1 corresponding to TX_A or TX_B respectively
+  // @param subdev: which analog i/o channel: 0 or 1
+  // @type subdev: int
+  
+  d_subdev = subdev;
+    
+  bypass_adc_buffers(true);
+
+  if(0) {       // Doing this would give us a different default than the historical values...
+    set_gain(float(gain_min() + gain_max()) / 2.0);       // initialize gain
+  }
+}
+
+db_basic_rx::~db_basic_rx()
+{
+}
+
+double
+db_basic_rx::freq_min() 
+{
+  return -90e9;
+}
+
+double
+db_basic_rx::freq_max()
+{
+  return 90e9;
+}
+
+struct freq_result_t 
+db_basic_rx::set_freq(double target_freq)
+{
+  // Set the frequency.
+  // 
+  // @param freq:  target RF frequency in Hz
+  // @type freq:   double
+  // 
+  // @returns (ok, actual_baseband_freq) where:
+  //   ok is True or False and indicates success or failure,
+  //   actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+  
+  struct freq_result_t args = {true, 0.0};
+  return args;
+}
+
+float
+db_basic_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_basic_rx::gain_max()
+{
+  return usrp()->pga_max();
+}
+
+float
+db_basic_rx::gain_db_per_step()
+{
+  return usrp()->pga_db_per_step();
+}
+
+bool 
+db_basic_rx::set_gain(float gain)
+{
+  // Set the gain.
+  // 
+  // @param gain:  gain in decibels
+  // @returns True/False
+  
+  return usrp()->set_pga(d_which * 2 + d_subdev, gain);
+}
+
+bool 
+db_basic_rx::is_quadrature()
+{
+  // Return True if this board requires both I & Q analog channels.
+
+  // This bit of info is useful when setting up the USRP Rx mux register.
+  
+  return (d_subdev == 2);
+}
+
+
+
+/******************************************************************************/
+
+
+db_lf_tx::db_lf_tx(usrp_basic_sptr usrp, int which)
+  : db_basic_tx(usrp, which)
+{
+  // Handler for Low Freq Tx daughterboards.
+  //
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+}
+
+db_lf_tx::~db_lf_tx()
+{
+}
+
+double 
+db_lf_tx::freq_min() 
+{
+  return -32e6;
+}
+
+double 
+db_lf_tx::freq_max()
+{
+  return 32e6;
+}
+
+/******************************************************************************/
+
+
+db_lf_rx::db_lf_rx(usrp_basic_sptr usrp, int which, int subdev)
+  : db_basic_rx(usrp, which, subdev)
+{
+  // Handler for Low Freq Rx daughterboards.
+  //
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+  // @param subdev: which analog i/o channel: 0 or 1
+  // @type subdev: int
+}
+
+db_lf_rx::~db_lf_rx()
+{
+}
+
+double
+db_lf_rx::freq_min() 
+{
+  return 0.0;
+}
+
+double
+db_lf_rx::freq_max() 
+{
+  return 32e6;
+}
+
+
diff --git a/usrp/host/lib/db_bitshark_rx.cc b/usrp/host/lib/db_bitshark_rx.cc
new file mode 100644 (file)
index 0000000..5368866
--- /dev/null
@@ -0,0 +1,417 @@
+//
+// Copyright 2010 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_bitshark_rx.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <cstdio>
+#include <string.h>
+#include <stdint.h>
+
+/* Note: Thie general structure of this file is based on the db_dbsrx.cc 
+   codebase for the dbsrx daughterboard. */
+
+/* The following defines specify the address map provided by the
+   Bitshark card. These registers are all accessed over I2C. */
+#define RF_CENTER_FREQ_REG 0x00
+#define RF_CHAN_FILTER_BW_REG 0x01
+#define RF_GAIN_REG 0x02
+#define BB_GAIN_REG 0x03
+#define ADF4350_REG 0x10
+#define SKY73202_REG 0x11
+#define CLOCK_SCHEME_REG 0x20
+
+/* The following table lists the registers provided by the BURX board that
+   are accessible over I2C:
+   --------------------------------------------------------
+   |RegAddr: 0x00-RF Center Freq register |
+       |4-bytes 0x00|
+       |4-byte unsigned RF center freq (in KHz)|
+   |RegAddr: 0x01-RF channel filter bandwidth register |
+       |4-bytes 0x00|
+       |4-byte unsigned RF channel filter bw (in KHz)|
+   |RegAddr: 0x02-RF gain register |
+       |7-bytes 0x00|
+       |1-byte signed RF gain (in dB)|
+   |RegAddr: 0x03-Baseband gain register |
+       |4-bytes 0x00|
+       |4-byte signed baseband filter gain (in dB)|
+   |RegAddr: 0x10-ADF4350 register |
+       |4-bytes 0x00|
+       |4-byte ADF4350 register value (actual ADF4350 reg addr embedded 
+        within 4-byte value)|
+   |RegAddr: 0x11-SKY73202 register |
+       |5-bytes 0x00|
+       |1-byte reg 0 of SKY73202 |
+       |1-byte reg 1 of SKY73202 |
+       |1-byte reg 2 of SKY73202 |
+   |RegAddr: 0x20-Clock Scheme |
+       |3-bytes 0x00|
+       |1-byte indicating clocking scheme:
+        -0x00 -> BURX local TCXO off, BURX accepts ref clock from
+                USRP (freq of USRP's ref clock specified in bytes 2-5)
+       -0x01 -> BURX local TCXO on, BURX uses its local TCXO as its ref
+                clock, TCXO signal output for use by USRP |
+       |4-byte USRP ref clock freq in hz (only needed if byte 1 set to 0x00) |
+       
+  ---------------------------------------------------------------------------
+   
+   As an example, lets say the client wants to set an RF center freq of
+   1000 MHz.  In KHz, this translates to 1000000 (resolution is only down to
+   steps of 1 KHz), which is 0x000F4240 in hex.  So the complete 9-byte I2C 
+   sequence that the client should send is as follows:
+   byte 0: 0x00-register 0x00 is the target of the write operation
+   bytes 1-4: 0x00 (padding)
+   byte 5: 0x40 (LSB of the 1000000 KHz value, in hex)
+   byte 6: 0x42
+   byte 7: 0x0F
+   byte 8: 0x00 (MSB of the 1000000 KHz value, in hex)
+
+   If using the usrper cmd-line application on a PC, this sequence would
+   be sent as follows (assuming that the BURX is in slot A):
+   
+   # usrper i2c_write 0x47 000000000040420F00
+   
+   How about another example...lets say the client wants to setup the clock
+   scheme to use scheme #1 where the 26 MHz TCXO on the BURX board is enabled,
+   and is provided to the USRP.  26 MHz (i.e. 26 million), in hex, is 0x18CBA80.
+   So the complete 9-byte I2C sequence that the client should send is as follows:
+   byte 0: 0x20-register 0x20 is the target of the write operation
+   bytes 1-3: 0x00 (padding)
+   byte 4: 0x01 (indicating that clock scheme #1 is wanted)
+   byte 5: 0x80 (LSB of the BURX ref clk freq)
+   byte 6: 0xBA
+   byte 7: 0x8C
+   byte 8: 0x01 (MSB of the BURX ref clk freq)
+   
+   To enable the BURX local ref clk, which will also make it available on the
+   on-board U.FL connector as a source for the USRP, a user can also use
+   the usrper cmd-line application on a PC.  The following sequence would
+   be sent (assuming that the BURX is in slot A):
+   
+   # usrper i2c_write 0x47 200000000180BA8C01
+
+*/
+
+#define NUM_BYTES_IN_I2C_CMD 9   
+
+/*****************************************************************************/
+
+db_bitshark_rx::db_bitshark_rx(usrp_basic_sptr _usrp, int which)
+  : db_base(_usrp, which)
+{
+    // Control Bitshark receiver USRP daughterboard.
+    // 
+    // @param usrp: instance of usrp.source_c
+    // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+    // turn off all outputs
+    usrp()->_write_oe(d_which, 0, 0xffff);
+
+    if (which == 0) 
+    {
+       d_i2c_addr = 0x47;
+    }
+    else 
+    {
+       d_i2c_addr = 0x45;
+    }
+
+    // initialize gain
+    set_gain((gain_min() + gain_max()) / 2.0);
+
+    // by default, assume we're using the USRPs clock as the ref clk,
+    // so setup the clock scheme and frequency.  If the user wants
+    // to use the Bitshark's TCXO, the clock scheme should be set
+    // to 1, the freq should be set to 26000000, and a top-level
+    // 'make' and 'make install' needs to be executed.  In addition, 
+    // a U.FL to SMA cable needs to connect J6 on the Bitshark to 
+    // the external clk input on the USRP
+    set_clock_scheme(0,64000000);
+
+    set_bw(8e6); // Default IF bandwidth to match USRP1 max host bandwidth
+
+    bypass_adc_buffers(true);
+}
+
+db_bitshark_rx::~db_bitshark_rx()
+{
+    shutdown();
+}
+
+/************ Private Functions **********************/
+
+void
+db_bitshark_rx::_set_pga(int pga_gain)
+{
+    assert(pga_gain>=0 && pga_gain<=20);
+    if(d_which == 0) 
+    {
+       usrp()->set_pga (0, pga_gain);
+       usrp()->set_pga (1, pga_gain);
+    }
+    else 
+    {
+       usrp()->set_pga (2, pga_gain);
+       usrp()->set_pga (3, pga_gain);
+    }
+}
+
+/************ Public Functions **********************/
+void
+db_bitshark_rx::shutdown()
+{
+    if (!d_is_shutdown)
+    {
+       d_is_shutdown = true;
+    }
+}
+
+bool
+db_bitshark_rx::set_bw (float bw)
+{
+    std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0);
+    uint16_t rf_bw_in_khz = (uint16_t)(bw/1000.0);
+    char val[4];
+    bool result = false;
+    uint8_t try_count = 0;
+    
+    memset(val,0x00,4);
+    if (rf_bw_in_khz < 660  || rf_bw_in_khz > 56000) 
+    {
+       fprintf(stderr, "db_bitshark_rx::set_bw: bw (=%d) must be between 660 KHz and 56 MHz inclusive\n", rf_bw_in_khz);
+       return false;
+    }
+    //fprintf(stdout,"Setting bw: requested bw in khz is %d\r\n",rf_bw_in_khz);
+    memcpy(val,&rf_bw_in_khz,4);
+    args[0] = RF_CHAN_FILTER_BW_REG;
+    args[5] = val[0];
+    args[6] = val[1];
+    args[7] = val[2];
+    args[8] = val[3];
+    while ((result != true) && (try_count < 3))
+    {
+       result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+       try_count++;
+    }
+
+    if (result == false)
+    {
+       fprintf(stderr, "db_bitshark_rx:set_bw: giving up after 3 tries without success\n");
+    }
+    
+    return result;
+}
+
+/* The gain referenced below is RF gain only.  There are two independent
+   gain settings at RF: a digital step attenuator (providing 0, -6, -12, and
+   -18 dB of attenuation), and a second LNA (LNA2) that provides ~25 dB of
+   gain (roughly...it actually depends on the RF freq).  So combining these
+   two stages can provide an overall gain range from 0 (which is mapped
+   to -18 dB on the step attenuator + LNA2 turned off) to 42 (which is
+   mapped to 0 dB on the step attenuator + LNA2 turned on).  
+   
+   There could be better ways to map these, but this is sufficient for
+   now. */
+float
+db_bitshark_rx::gain_min()
+{
+    return 0;
+}
+
+float
+db_bitshark_rx::gain_max()
+{
+    return 42;
+}
+
+float
+db_bitshark_rx::gain_db_per_step()
+{
+    return 6;
+}
+
+bool 
+db_bitshark_rx::set_gain(float gain)
+{
+    // Set the gain.
+    // 
+    // @param gain:  RF gain in decibels, range of 0-42
+    // @returns True/False
+    
+    std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0);
+    bool result = false;
+    uint8_t try_count = 0;
+        
+    if (gain < gain_min() || gain > gain_max()) 
+    {
+       fprintf(stderr,"db_bitshark_rx::set_gain: gain (=%f) must be between %f and %f inclusive\n", gain,gain_min(),gain_max());
+       return false;
+    }
+    //fprintf(stdout,"db_bitshark_rx::set_gain: requested gain of %f\r\n",gain);
+    args[0] = RF_GAIN_REG;
+    args[5] = (int)gain;
+
+    while ((result != true) && (try_count < 3))
+    {
+       result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+       try_count++;
+    }
+
+    if (result == false)
+    {
+       fprintf(stderr, "db_bitshark_rx:set_gain: giving up after 3 tries without success\n");
+    }
+    
+    return result;
+}
+
+
+bool 
+db_bitshark_rx::set_clock_scheme(uint8_t clock_scheme, uint32_t ref_clk_freq)
+{
+    // Set the clock scheme for determining how the BURX
+    // dboard receives its clock.  Note: Ideally, the constructor for the
+    // BURX board could simply call this method to set how it wants the
+    // clock scheme configured.  However, depending on the application
+    // using the daughterboard, the constructor may run _after_ some
+    // other portion of the application needs the FPGA.  And if the
+    // the clock source for the FPGA was the BURX's 26 MHz TCXO, we're in
+    // a chicken-before-the-egg dilemna.  So the solution is to leave
+    // this function here for reference in case an app wants to use it,
+    // and also give the user the ability to set the clock scheme through
+    // the usrper cmd-line application (see example at the top of this
+    // file).
+    // 
+    // @param clock_scheme
+    // @param ref_clk_freq in Hz
+    // @returns True/False
+    
+    std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0);
+    bool result = false;
+    uint8_t try_count = 0;
+    char val[4];
+        
+    if (clock_scheme > 1) 
+    {
+       fprintf(stderr,"db_bitshark_rx::set_clock_scheme: invalid scheme %d\n",clock_scheme);
+       return false;
+    }
+    //fprintf(stdout,"db_bitshark_rx::set_clock_scheme: requested clock schem of %d with freq %d Hz \n",clock_scheme,ref_clk_freq);
+    memcpy(val,&ref_clk_freq,4);
+    args[0] = CLOCK_SCHEME_REG;
+    args[4] = (int)clock_scheme;
+    args[5] = val[0];
+    args[6] = val[1];
+    args[7] = val[2];
+    args[8] = val[3];
+
+    while ((result != true) && (try_count < 3))
+    {
+       result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+       try_count++;
+    }
+
+    if (result == false)
+    {
+       fprintf(stderr, "db_bitshark_rx:set_clock_scheme: giving up after 3 tries without success\n");
+    }
+    return result;
+}
+
+double
+db_bitshark_rx::freq_min()
+{    
+    return 300e6;
+}
+
+double
+db_bitshark_rx::freq_max()
+{    
+    return 4e9;
+}
+
+struct freq_result_t
+db_bitshark_rx::set_freq(double freq)
+{
+    // Set the frequency.
+    // 
+    // @param freq:  target RF frequency in Hz
+    // @type freq:   double
+    // 
+    // @returns (ok, actual_baseband_freq) where:
+    //   ok is True or False and indicates success or failure,
+    //   actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+    
+    std::vector<int> args(NUM_BYTES_IN_I2C_CMD,0);
+    std::vector<int> bytes(2);
+    char val[4];
+    freq_result_t act_freq = {false, 0};
+    uint32_t freq_in_khz = (uint32_t)(freq/1000.0);
+    bool result = false;
+    uint8_t try_count = 0;
+        
+    memset(val,0x00,4);
+    if(!(freq>=freq_min() && freq<=freq_max())) 
+    {
+       return act_freq;
+    }
+    
+    //fprintf(stdout,"db_bitshark_rx::set_freq: requested freq is %d KHz\n",freq_in_khz);
+    memcpy(val,&freq_in_khz,4);
+    args[0] = RF_CENTER_FREQ_REG;
+    args[5] = val[0];
+    args[6] = val[1];
+    args[7] = val[2];
+    args[8] = val[3];
+
+    while ((result != true) && (try_count < 3))
+    {
+       result=usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+       try_count++;
+    }
+
+    if (result == false)
+    {
+       fprintf(stderr, "db_bitshark_rx:set_freq: giving up after 3 tries without success\n");
+    }
+        
+    act_freq.ok = result;
+    act_freq.baseband_freq = (double)freq;
+    return act_freq;
+}
+
+bool 
+db_bitshark_rx::is_quadrature()
+{    
+    // Return True if this board requires both I & Q analog channels.  
+    return true;
+}
+
+bool
+db_bitshark_rx::i_and_q_swapped()
+{
+    // Returns True since our I and Q channels are swapped
+    return true;
+}
diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc
new file mode 100644 (file)
index 0000000..9324d58
--- /dev/null
@@ -0,0 +1,244 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <db_boards.h>
+#include <usrp/usrp_dbid.h>
+#include <usrp/db_basic.h>
+#include <usrp/db_tv_rx.h>
+#include <usrp/db_tv_rx_mimo.h>
+#include <usrp/db_dbs_rx.h>
+#include <usrp/db_flexrf.h>
+#include <usrp/db_flexrf_mimo.h>
+#include <usrp/db_wbxng.h>
+#include <usrp/db_xcvr2450.h>
+#include <usrp/db_dtt754.h>
+#include <usrp/db_dtt768.h>
+#include <usrp/db_bitshark_rx.h>
+#include <cstdio>
+
+std::vector<db_base_sptr>
+instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
+{
+  std::vector<db_base_sptr> db;
+
+  switch(dbid) {
+
+  case(USRP_DBID_BASIC_TX):
+    db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_BASIC_RX):
+    db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+    db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+    db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 2)));
+    break;
+
+  case(USRP_DBID_LF_TX):
+    db.push_back(db_base_sptr(new db_lf_tx(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_LF_RX):
+    db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 0)));
+    db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 1)));
+    db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 2)));
+    break;
+
+  case(USRP_DBID_DBS_RX):
+    db.push_back(db_base_sptr(new db_dbs_rx(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_TV_RX):
+    db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 43.75e6, 5.75e6)));
+    break;
+  case(USRP_DBID_TV_RX_REV_2):
+    db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 44e6, 20e6)));
+    break;
+  case(USRP_DBID_TV_RX_REV_3):
+    db.push_back(db_base_sptr(new db_tv_rx(usrp, which_side, 44e6, 20e6)));
+    break;
+  case(USRP_DBID_TV_RX_MIMO):
+    db.push_back(db_base_sptr(new db_tv_rx_mimo(usrp, which_side, 43.75e6, 5.75e6)));
+    break;
+  case(USRP_DBID_TV_RX_REV_2_MIMO):
+    db.push_back(db_base_sptr(new db_tv_rx_mimo(usrp, which_side, 44e6, 20e6)));
+    break;
+  case(USRP_DBID_TV_RX_REV_3_MIMO):
+    db.push_back(db_base_sptr(new db_tv_rx_mimo(usrp, which_side, 44e6, 20e6)));
+    break;
+
+  case(USRP_DBID_FLEX_2400_TX):
+    db.push_back(db_base_sptr(new db_flexrf_2400_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_2400_RX):
+    db.push_back(db_base_sptr(new db_flexrf_2400_rx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_TX):
+    db.push_back(db_base_sptr(new db_flexrf_1200_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_RX):
+    db.push_back(db_base_sptr(new db_flexrf_1200_rx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_TX):
+    db.push_back(db_base_sptr(new db_flexrf_1800_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_RX):
+    db.push_back(db_base_sptr(new db_flexrf_1800_rx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_TX):
+    db.push_back(db_base_sptr(new db_flexrf_900_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_RX):
+    db.push_back(db_base_sptr(new db_flexrf_900_rx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_TX):
+    db.push_back(db_base_sptr(new db_flexrf_400_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_RX):
+    db.push_back(db_base_sptr(new db_flexrf_400_rx(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_2400_TX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_2400_tx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_2400_RX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_2400_rx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_TX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_1800_tx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_RX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_1800_rx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_TX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_1200_tx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_RX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_1200_rx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_TX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_900_tx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_RX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_900_rx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_TX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_400_tx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_RX_MIMO_A):
+    db.push_back(db_base_sptr(new db_flexrf_400_rx_mimo_a(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_2400_TX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_2400_tx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_2400_RX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_2400_rx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_TX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_1800_tx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1800_RX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_1800_rx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_TX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_1200_tx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_1200_RX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_1200_rx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_TX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_900_tx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_900_RX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_900_rx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_TX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_400_tx_mimo_b(usrp, which_side)));
+    break;
+  case(USRP_DBID_FLEX_400_RX_MIMO_B):
+    db.push_back(db_base_sptr(new db_flexrf_400_rx_mimo_b(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_XCVR2450_TX):
+    db.push_back(db_base_sptr(new db_xcvr2450_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_XCVR2450_RX):
+    db.push_back(db_base_sptr(new db_xcvr2450_rx(usrp, which_side)));
+    break;
+
+#if 0  // FIXME wbx doesn't compile
+  case(USRP_DBID_WBX_LO_TX):
+    db.push_back(db_base_sptr(new db_wbx_lo_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_WBX_LO_RX):
+    db.push_back(db_base_sptr(new db_wbx_lo_rx(usrp, which_side)));
+    break;
+#endif
+
+  case(USRP_DBID_WBX_NG_TX):
+    db.push_back(db_base_sptr(new db_wbxng_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_WBX_NG_RX):
+    db.push_back(db_base_sptr(new db_wbxng_rx(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_DTT754):
+    db.push_back(db_base_sptr(new db_dtt754(usrp, which_side)));
+    break;
+  case(USRP_DBID_DTT768):
+    db.push_back(db_base_sptr(new db_dtt768(usrp, which_side)));
+    break;
+
+  case(USRP_DBID_BITSHARK_RX):
+    db.push_back(db_base_sptr(new db_bitshark_rx(usrp, which_side)));
+    break;
+
+  case(-1):
+    if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){
+      db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+    }
+    else {
+      db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+      db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+    }
+    break;
+
+  case(-2):
+  default:
+    if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){
+      fprintf(stderr, "\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a \"Basic Tx.\"\n");
+      fprintf(stderr, "Warning: This is almost certainly wrong...  Use appropriate burn-*-eeprom utility.\n\n");
+      db.push_back(db_base_sptr(new db_basic_tx(usrp, which_side)));
+    }
+    else {
+      fprintf(stderr, "\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a \"Basic Rx.\"\n");
+      fprintf(stderr, "Warning: This is almost certainly wrong...  Use appropriate burn-*-eeprom utility.\n\n");
+      db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 0)));
+      db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
+    }
+    break;
+  }
+
+  return db;
+}
diff --git a/usrp/host/lib/db_boards.h b/usrp/host/lib/db_boards.h
new file mode 100644 (file)
index 0000000..136091c
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+//
+
+#ifndef DB_BOARDS_H
+#define DB_BOARDS_H
+
+#include <usrp/db_base.h>
+#include <usrp/usrp_basic.h>
+
+std::vector<db_base_sptr> instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side);
+
+#endif 
+
+
diff --git a/usrp/host/lib/db_dbs_rx.cc b/usrp/host/lib/db_dbs_rx.cc
new file mode 100644 (file)
index 0000000..7fe8c49
--- /dev/null
@@ -0,0 +1,501 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_dbs_rx.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <cstdio>
+
+
+/*****************************************************************************/
+
+
+db_dbs_rx::db_dbs_rx(usrp_basic_sptr _usrp, int which)
+  : db_base(_usrp, which)
+{
+  // Control DBS receiver based USRP daughterboard.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+  usrp()->_write_oe(d_which, 0x0001, 0x0001);
+  if(which == 0) {
+    d_i2c_addr = 0x67;
+  }
+  else {
+    d_i2c_addr = 0x65;
+  }
+
+  d_n = 950;
+  d_div2 = 0;
+  d_osc = 5;
+  d_cp = 3;
+  d_r = 4;
+  d_r_int = 1;
+  d_fdac = 127;
+  d_m = 2;
+  d_dl = 0;
+  d_ade = 0;
+  d_adl = 0;
+  d_gc1 = 0;
+  d_gc2 = 31;
+  d_diag = 0;
+  
+  _enable_refclk(true);
+  
+  set_gain((gain_min() + gain_max()) / 2.0);       // initialize gain
+
+  bypass_adc_buffers(true);
+}
+
+db_dbs_rx::~db_dbs_rx()
+{
+  shutdown();
+}
+
+void
+db_dbs_rx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown orderly
+    _enable_refclk(false);
+  }
+}
+
+void
+db_dbs_rx::_write_reg (int regno, int v)
+{
+  //regno is in [0,5], v is value to write to register"""
+  assert (0 <= regno && regno <= 5);
+  std::vector<int> args(2);
+  args[0] = regno;
+  args[1] = v;
+  usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+
+void
+db_dbs_rx::_write_regs (int starting_regno, const std::vector<int> &vals)
+{
+  // starting_regno is in [0,5],
+  // vals is a seq of integers to write to consecutive registers"""
+
+  //FIXME
+  std::vector<int> args;
+  args.push_back(starting_regno);
+  args.insert(args.end(), vals.begin(), vals.end());
+  usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args));
+}
+        
+std::vector<int>
+db_dbs_rx::_read_status ()
+{
+  //If successful, return list of two ints: [status_info, filter_DAC]"""
+  std::string s = usrp()->read_i2c (d_i2c_addr, 2);
+  if(s.size() != 2) {
+    std::vector<int> ret(0);
+    return ret;
+  }
+  return str_to_int_seq (s);
+}
+
+void
+db_dbs_rx::_send_reg(int regno)
+{
+  assert(0 <= regno && regno <= 5);
+  if(regno == 0)
+    _write_reg(0,(d_div2<<7) + (d_n>>8));
+  if(regno == 1)
+    _write_reg(1,d_n & 255);
+  if(regno == 2)
+    _write_reg(2,d_osc + (d_cp<<3) + (d_r_int<<5));
+  if(regno == 3)
+    _write_reg(3,d_fdac);
+  if(regno == 4)
+    _write_reg(4,d_m + (d_dl<<5) + (d_ade<<6) + (d_adl<<7));
+  if(regno == 5)
+    _write_reg(5,d_gc2 + (d_diag<<5));
+}
+
+// BW setting
+void
+db_dbs_rx::_set_m(int m)
+{
+  assert(m>0 && m<32);
+  d_m = m;
+  _send_reg(4);
+}
+  
+void
+db_dbs_rx::_set_fdac(int fdac)
+{
+  assert(fdac>=0 && fdac<128);
+  d_fdac = fdac;
+  _send_reg(3);
+}
+
+bool
+db_dbs_rx::set_bw (float bw)
+{
+  if (bw < 1e6 || bw > 33e6) {
+    fprintf(stderr, "db_dbs_rx::set_bw: bw (=%f) must be between 1e6 and 33e6 inclusive\n", bw);
+    return false;
+  }
+
+  // struct bw_t ret = {0, 0, 0};
+  int m_max, m_min, m_test, fdac_test;
+  if(bw >= 4e6)
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/1e6)));
+  else if(bw >= 2e6)      // Outside of Specs!
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/.5e6)));
+  else      // Way outside of Specs!
+    m_max = int(std::min(31, (int)floor(_refclk_freq()/.25e6)));
+  
+  m_min = int(ceil(_refclk_freq()/2.5e6));
+  m_test = m_max;
+  while(m_test >= m_min) {
+    fdac_test = static_cast<int>(round(((bw * m_test / _refclk_freq())-4)/.145));
+    if(fdac_test > 127)
+      m_test = m_test - 1;
+    else
+      break;
+  }
+
+  if(m_test>=m_min && fdac_test>=0) {
+    _set_m(m_test);
+    _set_fdac(fdac_test);
+
+    //ret.m = d_m;
+    //ret.fdac = d_fdac;
+    //ret.div = _refclk_freq()/d_m*(4+0.145*d_fdac);
+  }
+  else {
+    fprintf(stderr, "db_dbs_rx::set_bw: failed\n");
+    return false;
+  }
+
+  return true;
+}
+
+// Gain setting
+void
+db_dbs_rx::_set_dl(int dl)
+{
+  assert(dl == 0 || dl == 1);
+  d_dl = dl;
+  _send_reg(4);
+}
+
+void
+db_dbs_rx::_set_gc2(int gc2)
+{
+  assert(gc2<32 && gc2>=0);
+  d_gc2 = gc2;
+  _send_reg(5);
+}
+
+void
+db_dbs_rx::_set_gc1(int gc1)
+{
+  assert(gc1>=0 && gc1<4096);
+  d_gc1 = gc1;
+  usrp()->write_aux_dac(d_which, 0, gc1);
+}
+
+void
+db_dbs_rx::_set_pga(int pga_gain)
+{
+  assert(pga_gain>=0 && pga_gain<=20);
+  if(d_which == 0) {
+    usrp()->set_pga (0, pga_gain);
+    usrp()->set_pga (1, pga_gain);
+  }
+  else {
+    usrp()->set_pga (2, pga_gain);
+    usrp()->set_pga (3, pga_gain);
+  }
+}
+
+float
+db_dbs_rx::gain_min()
+{
+  return 0;
+}
+
+float
+db_dbs_rx::gain_max()
+{
+  return 104;
+}
+
+float
+db_dbs_rx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool 
+db_dbs_rx::set_gain(float gain)
+{
+  // Set the gain.
+  // 
+  // @param gain:  gain in decibels
+  // @returns True/False
+
+  if(!(gain>=0 && gain<105)) {
+    throw std::runtime_error("gain out of range\n");
+  }
+
+  int gc1=0, gc2=0, dl=0, pga=0;
+
+  if(gain < 56) {
+    gc1 = int((-gain*1.85/56.0 + 2.6)*4096.0/3.3);
+    gain = 0;
+  }
+  else {
+    gc1 = 0;
+    gain -= 56;
+  }
+   
+  if(gain < 24) {
+    gc2 = static_cast<int>(round(31.0 * (1-gain/24.0)));
+    gain = 0;
+  }
+  else {
+    gc2 = 0;
+    gain -=24;
+  }
+  
+  if(gain >= 4.58) {
+    dl = 1;
+    gain -= 4.58;
+  }
+
+  pga = gain;
+  _set_gc1(gc1);
+  _set_gc2(gc2);
+  _set_dl(dl);
+  _set_pga(pga);
+
+  return true;
+}
+
+// Frequency setting
+void
+db_dbs_rx::_set_osc(int osc)
+{
+  assert(osc>=0 && osc<8);
+  d_osc = osc;
+  _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_cp(int cp)
+{
+  assert(cp>=0 && cp<4);
+  d_cp = cp;
+  _send_reg(2);
+}
+
+void
+db_dbs_rx::_set_n(int n)
+{
+  assert(n>256 && n<32768);
+  d_n = n;
+  _send_reg(0);
+  _send_reg(1);
+}
+
+void
+db_dbs_rx::_set_div2(int div2)
+{
+  assert(div2 == 0 || div2 == 1);
+  d_div2 = div2;
+  _send_reg(0);
+}
+
+void
+db_dbs_rx::_set_r(int r)
+{
+  assert(r>=0 && r<128);
+  d_r = r;
+  d_r_int = static_cast<int>(round(log10(r)/log10(2)) - 1);
+  _send_reg(2);
+}
+
+// FIXME  How do we handle ADE and ADL properly?
+void
+db_dbs_rx::_set_ade(int ade)
+{
+  assert(ade == 0 || ade == 1);
+  d_ade = ade;
+  _send_reg(4);
+}
+
+double
+db_dbs_rx::freq_min()
+{
+  return 500e6;
+}
+
+double
+db_dbs_rx::freq_max()
+{
+  return 2.6e9;
+}
+
+struct freq_result_t
+db_dbs_rx::set_freq(double freq)
+{
+  // Set the frequency.
+  // 
+  // @param freq:  target RF frequency in Hz
+  // @type freq:   double
+  // 
+  // @returns (ok, actual_baseband_freq) where:
+  //   ok is True or False and indicates success or failure,
+  //   actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+  
+  freq_result_t args = {false, 0};
+  
+  if(!(freq>=freq_min() && freq<=freq_max())) {
+    return args;
+  }
+  
+  double vcofreq;
+  if(freq<1150e6) {
+    _set_div2(0);
+    vcofreq = 4 * freq;
+  }
+  else {
+    _set_div2(1);
+    vcofreq = 2 * freq;
+  }
+  
+  _set_ade(1);
+  int rmin = std::max(2, (int)(_refclk_freq()/2e6));
+  int rmax = std::min(128, (int)(_refclk_freq()/500e3));
+  int r = 2;
+  int n = 0;
+  int best_r = 2;
+  int best_n = 0;
+  int best_delta = 10e6;
+  int delta;
+  
+  while(r <= rmax) {
+    n = static_cast<int>(round(freq/(_refclk_freq()/r)));
+    if(r<rmin || n<256) {
+      r = r * 2;
+      continue;
+    }
+    delta = (int)fabs(n*_refclk_freq()/r - freq);
+    if(delta < 75e3) {
+      best_r = r;
+      best_n = n;
+      break;
+    }
+    if(delta < best_delta*0.9) {
+      best_r = r;
+      best_n = n;
+      best_delta = delta;
+    }
+    r = r * 2;
+  }
+  _set_r(best_r);
+
+  _set_n(static_cast<int>(round(best_n)));
+  int vco;
+  if(vcofreq < 2433e6)
+    vco = 0;
+  else if(vcofreq < 2711e6)
+    vco=1;
+  else if(vcofreq < 3025e6)
+    vco=2;
+  else if(vcofreq < 3341e6)
+    vco=3;
+  else if(vcofreq < 3727e6)
+    vco=4;
+  else if(vcofreq < 4143e6)
+    vco=5;
+  else if(vcofreq < 4493e6)
+    vco=6;
+  else
+    vco=7;
+  
+  _set_osc(vco);
+  
+  // Set CP current
+  int adc_val = 0;
+  std::vector<int> bytes(2);
+  while(adc_val == 0 || adc_val == 7) {
+    bytes = _read_status();
+    adc_val = bytes[0] >> 2;
+    if(adc_val == 0) {
+      if(vco <= 0) {
+       return args;
+      }
+      else {
+       vco = vco - 1;
+      }
+    }
+    else if(adc_val == 7) {
+      if(vco >= 7) {
+       return args;
+      }
+      else {
+       vco = vco + 1;
+      }
+    }
+    _set_osc(vco);
+  }
+  
+  if(adc_val == 1 || adc_val == 2) {
+    _set_cp(1);
+  }
+  else if(adc_val == 3 || adc_val == 4) {
+    _set_cp(2);
+  }
+  else {
+    _set_cp(3);
+  }
+  
+  args.ok = true;
+  args.baseband_freq = d_n * _refclk_freq() / d_r;
+  return args;
+}
+
+int
+db_dbs_rx::_refclk_divisor()
+{
+  //Return value to stick in REFCLK_DIVISOR register
+  return 16;
+}
+
+bool 
+db_dbs_rx::is_quadrature()
+{
+  // Return True if this board requires both I & Q analog channels.  
+  return true;
+}
diff --git a/usrp/host/lib/db_dtt754.cc b/usrp/host/lib/db_dtt754.cc
new file mode 100644 (file)
index 0000000..9ced705
--- /dev/null
@@ -0,0 +1,327 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_dtt754.h>
+#include <db_base_impl.h>
+
+int
+control_byte_1()
+{
+  int RS = 0;  // 0 = 166.66kHz reference
+  int ATP = 7; // Disable internal AGC
+  return (0x80 | ATP<<3 | RS);
+}
+
+int
+control_byte_2()
+{
+  int STBY = 0;  // powered on
+  int XTO = 1;   // turn off xtal out, which we don't have
+  int ATC = 0;   // not clear exactly, possibly speeds up or slows down AGC, which we are not using
+  
+  int c = 0xc2 | ATC<<5 | STBY<<4 | XTO;
+  return c;
+}
+
+int
+bandswitch_byte(float freq, float bw)
+{
+  int P5, CP, BS;
+
+  if(bw>7.5e6) {
+    P5 = 1;
+  }
+  else {
+    P5 = 0;
+  }
+
+  if(freq < 121e6) {
+    CP = 0;
+    BS = 1;
+  }
+  else if(freq < 141e6) {
+    CP = 1;
+    BS = 1;
+  }
+  else if(freq < 166e6) {
+    CP = 2;
+    BS = 1;
+  }
+  else if(freq < 182e6) {
+    CP = 3;
+    BS = 1;
+  }
+  else if(freq < 286e6) {
+    CP = 0;
+    BS = 2;
+  }
+  else if(freq < 386e6) {
+    CP = 1;
+    BS = 2;
+  }
+  else if(freq < 446e6) {
+    CP = 2;
+    BS = 2;
+  }
+  else if(freq < 466e6) {
+    CP = 3;
+    BS = 2;
+  }
+  else if(freq < 506e6) {
+    CP = 0;
+    BS = 8;
+  }
+  else if(freq < 761e6) {
+    CP = 1;
+    BS = 8;
+  }
+  else if(freq < 846e6) {
+    CP = 2;
+    BS = 8;
+  }
+  else { // limit is ~905 MHz
+    CP = 3;
+    BS = 8;
+  }
+  return (CP<<6 | P5 << 4 | BS);
+}
+
+db_dtt754::db_dtt754(usrp_basic_sptr _usrp, int which)
+  : db_base(_usrp, which)
+{
+  /*
+   * Control custom DTT75403-based daughterboard.
+   * 
+   * @param usrp: instance of usrp.source_c
+   * @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+   * @type which: int
+   */
+
+  // FIXME: DTT754 and DTT768 can probably inherit from a DTT class
+  
+  if(d_which == 0) {
+    d_i2c_addr = 0x60;
+  }
+  else {
+    d_i2c_addr = 0x62;
+  }
+
+  d_bw = 7e6;
+  d_IF = 36e6;
+        
+  d_f_ref = 166.6666e3;
+  d_inverted = false;
+
+  set_gain((gain_min() + gain_max()) / 2.0);
+
+  bypass_adc_buffers(false);
+}
+
+db_dtt754::~db_dtt754()
+{
+}
+  
+float
+db_dtt754::gain_min()
+{
+  return 0;
+}
+
+float
+db_dtt754::gain_max()
+{
+  return 115;
+}
+
+float
+db_dtt754::gain_db_per_step()
+{
+  return 1;
+}
+
+bool
+db_dtt754::set_gain(float gain)
+{
+  assert(gain>=0 && gain<=115);
+
+  float rfgain, ifgain, pgagain;
+  if(gain > 60) {
+    rfgain = 60;
+    gain = gain - 60;
+  }
+  else {
+    rfgain = gain;
+    gain = 0;
+  }
+  
+  if(gain > 35) {
+    ifgain = 35;
+    gain = gain - 35;
+  }
+  else {
+    ifgain = gain;
+    gain = 0;
+  }
+  pgagain = gain;
+  
+  _set_rfagc(rfgain);
+  _set_ifagc(ifgain);
+  _set_pga(pgagain);
+
+  return true; // can't fail with the assert in place
+}
+
+double
+db_dtt754::freq_min()
+{
+  return 44e6;
+}
+
+double
+db_dtt754::freq_max()
+{
+  return 900e6;
+}
+
+struct freq_result_t
+db_dtt754::set_freq(double target_freq)
+{
+  /*
+   * @returns (ok, actual_baseband_freq) where:
+   * ok is True or False and indicates success or failure,
+   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+   */
+  
+  freq_result_t ret = {false, 0.0};
+
+  if(target_freq < freq_min() || target_freq > freq_max()) {
+    return ret;
+  }
+        
+  double target_lo_freq = target_freq + d_IF;  // High side mixing
+
+  int divisor = (int)(0.5+(target_lo_freq / d_f_ref));
+  double actual_lo_freq = d_f_ref*divisor;
+  
+  if((divisor & ~0x7fff) != 0) {               // must be 15-bits or less
+    return ret;
+  }
+  
+  // build i2c command string
+  std::vector<int> buf(5);
+  buf[0] = (divisor >> 8) & 0xff;          // DB1
+  buf[1] = divisor & 0xff;                 // DB2
+  buf[2] = control_byte_1();
+  buf[3] = bandswitch_byte(actual_lo_freq, d_bw);
+  buf[4] = control_byte_2();
+
+  bool ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+
+  d_freq = actual_lo_freq - d_IF;
+        
+  ret.ok = ok;
+  ret.baseband_freq = actual_lo_freq;
+
+  return ret;
+
+}
+  
+bool
+db_dtt754::is_quadrature()
+{
+  /*
+   * Return True if this board requires both I & Q analog channels.
+   * 
+   * This bit of info is useful when setting up the USRP Rx mux register.
+   */
+     
+  return false;
+}
+
+bool
+db_dtt754::spectrum_inverted()
+{
+  /*
+   * The 43.75 MHz version is inverted
+   */
+  
+  return d_inverted;
+}
+
+bool
+db_dtt754::set_bw(float bw)
+{
+  /*
+   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+   */
+
+  d_bw = bw;
+  set_freq(d_freq);
+
+  return true; // FIXME: propagate set_freq result
+}
+
+void
+db_dtt754::_set_rfagc(float gain)
+{
+  assert(gain <= 60 && gain >= 0);
+  // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+  // Why are there two cases instead of a single linear case?
+  float voltage;
+  if(gain == 60) {
+    voltage = 4;
+  }
+  else {
+    voltage = gain/60.0 * 2.25 + 1.25;
+  }
+  
+  int dacword = (int)(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+    
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_dtt754::_set_ifagc(float gain)
+{
+  assert(gain <= 35 && gain >= 0);
+  float voltage = gain/35.0 * 2.1 + 1.4;
+  int dacword = (int)(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_dtt754::_set_pga(float pga_gain)
+{
+  assert(pga_gain >=0 && pga_gain <=20);
+  if(d_which == 0) {
+    usrp()->set_pga (0, pga_gain);
+  }
+  else {
+    usrp()->set_pga (2, pga_gain);
+  }
+}
diff --git a/usrp/host/lib/db_dtt768.cc b/usrp/host/lib/db_dtt768.cc
new file mode 100644 (file)
index 0000000..0dfe1a8
--- /dev/null
@@ -0,0 +1,300 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_dtt768.h>
+#include <db_base_impl.h>
+
+int
+control_byte_4()
+{
+  int C = 0;   // Charge Pump Current, no info on how to choose
+  int R = 4;   // 125 kHz fref
+  
+  // int ATP = 7; // Disable internal AGC
+  return (0x80 | C<<5 | R);
+}
+
+int
+control_byte_5(float freq, int agcmode = 1)
+{
+  if(agcmode) {
+    if(freq < 150e6) {
+      return 0x3B;
+    }
+    else if(freq < 420e6) {
+      return 0x7E;
+    }
+    else {
+      return 0xB7;
+    }
+  }
+  else {
+    if(freq < 150e6) {
+      return 0x39;
+    }
+    else if(freq < 420e6) {
+      return 0x7C;
+    }
+    else {
+      return 0xB5;
+    }
+  }
+}
+        
+int
+control_byte_6()
+{
+  int ATC = 0;   // AGC time constant = 100ms, 1 = 3S
+  int IFE = 1;   // IF AGC amplifier enable
+  int AT = 0;    // AGC control, ???
+  
+  return (ATC << 5 | IFE << 4 | AT);
+}
+
+int
+control_byte_7()
+{
+  int SAS = 1;  // SAW Digital mode
+  int AGD = 1;  // AGC disable
+  int ADS = 0;  // AGC detector into ADC converter
+  int T = 0;    // Test mode, undocumented
+  return (SAS << 7 | AGD << 5 | ADS << 4 | T);
+}
+
+db_dtt768::db_dtt768(usrp_basic_sptr _usrp, int which)
+  : db_base(_usrp, which)
+{
+  /*
+   * Control custom DTT76803-based daughterboard.
+   * 
+   * @param usrp: instance of usrp.source_c
+   * @param which: which side: 0 or 1 corresponding to RX_A or RX_B respectively
+   * @type which: int
+   */
+  
+  if(d_which == 0) {
+    d_i2c_addr = 0x60;
+  }
+  else {
+    d_i2c_addr = 0x62;
+  }
+
+  d_IF = 44e6;
+        
+  d_f_ref = 125e3;
+  d_inverted = false;
+
+  set_gain((gain_min() + gain_max()) / 2.0);
+
+  bypass_adc_buffers(false);
+}
+
+db_dtt768::~db_dtt768()
+{
+}
+  
+float
+db_dtt768::gain_min()
+{
+  return 0;
+}
+
+float
+db_dtt768::gain_max()
+{
+  return 115;
+}
+
+float
+db_dtt768::gain_db_per_step()
+{
+  return 1;
+}
+
+bool
+db_dtt768::set_gain(float gain)
+{
+  assert(gain>=0 && gain<=115);
+
+  float rfgain, ifgain, pgagain;
+  if(gain > 60) {
+    rfgain = 60;
+    gain = gain - 60;
+  }
+  else {
+    rfgain = gain;
+    gain = 0;
+  }
+  
+  if(gain > 35) {
+    ifgain = 35;
+    gain = gain - 35;
+  }
+  else {
+    ifgain = gain;
+    gain = 0;
+  }
+  pgagain = gain;
+  
+  _set_rfagc(rfgain);
+  _set_ifagc(ifgain);
+  _set_pga(pgagain);
+
+  return true;
+}
+
+double
+db_dtt768::freq_min()
+{
+  return 44e6;
+}
+
+double
+db_dtt768::freq_max()
+{
+  return 900e6;
+}
+
+struct freq_result_t
+db_dtt768::set_freq(double target_freq)
+{
+  /*
+   * @returns (ok, actual_baseband_freq) where:
+   * ok is True or False and indicates success or failure,
+   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+   */
+  
+  freq_result_t ret = {false, 0.0};
+
+  if(target_freq < freq_min() || target_freq > freq_max()) {
+    return ret;
+  }
+        
+  double target_lo_freq = target_freq + d_IF;  // High side mixing
+
+  int divisor = (int)(0.5+(target_lo_freq / d_f_ref));
+  double actual_lo_freq = d_f_ref*divisor;
+  
+  if((divisor & ~0x7fff) != 0) {               // must be 15-bits or less
+    return ret;
+  }
+  
+  // build i2c command string
+  std::vector<int> buf(6);
+  buf[0] = (divisor >> 8) & 0xff;          // DB1
+  buf[1] = divisor & 0xff;                 // DB2
+  buf[2] = control_byte_4();
+  buf[3] = control_byte_5(target_freq);
+  buf[4] = control_byte_6();
+  buf[5] = control_byte_7();
+
+  bool ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+
+  d_freq = actual_lo_freq - d_IF;
+  
+  ret.ok = ok;
+  ret.baseband_freq = actual_lo_freq;
+
+  return ret;
+
+}
+  
+bool
+db_dtt768::is_quadrature()
+{
+  /*
+   * Return True if this board requires both I & Q analog channels.
+   * 
+   * This bit of info is useful when setting up the USRP Rx mux register.
+   */
+     
+  return false;
+}
+
+bool
+db_dtt768::spectrum_inverted()
+{
+  /*
+   * The 43.75 MHz version is inverted
+   */
+  
+  return d_inverted;
+}
+
+bool
+db_dtt768::set_bw(float bw)
+{
+  /*
+   * Choose the SAW filter bandwidth, either 7MHz or 8MHz)
+   */
+
+  d_bw = bw;
+  set_freq(d_freq);
+
+  return true; // FIXME: propagate set_freq result
+}
+
+void
+db_dtt768::_set_rfagc(float gain)
+{
+  assert(gain <= 60 && gain >= 0);
+  // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+  // Why are there two cases instead of a single linear case?
+  float voltage;
+  if(gain == 60) {
+    voltage = 4;
+  }
+  else {
+    voltage = gain/60.0 * 2.25 + 1.25;
+  }
+  
+  int dacword = (int)(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+    
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_dtt768::_set_ifagc(float gain)
+{
+  assert(gain <= 35 && gain >= 0);
+  float voltage = gain/35.0 * 2.1 + 1.4;
+  int dacword = (int)(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_dtt768::_set_pga(float pga_gain)
+{
+  assert(pga_gain >=0 && pga_gain <=20);
+  if(d_which == 0) {
+    usrp()->set_pga (0, pga_gain);
+  }
+  else {
+    usrp()->set_pga (2, pga_gain);
+  }
+}
diff --git a/usrp/host/lib/db_flexrf.cc b/usrp/host/lib/db_flexrf.cc
new file mode 100644 (file)
index 0000000..07ac2be
--- /dev/null
@@ -0,0 +1,1146 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_flexrf.h>
+#include <db_base_impl.h>
+
+// d'board i/o pin defs
+// Tx and Rx have shared defs, but different i/o regs
+#define AUX_RXAGC (1 << 8)
+#define POWER_UP  (1 << 7)         // enables power supply
+#define RX_TXN    (1 << 6)         // Tx only: T/R antenna switch for TX/RX port
+#define RX2_RX1N  (1 << 6)         // Rx only: antenna switch between RX2 and TX/RX port
+#define ENABLE    (1 << 5)         // enables mixer
+#define AUX_SEN   (1 << 4)
+#define AUX_SCLK  (1 << 3)
+#define PLL_LOCK_DETECT (1 << 2)
+#define AUX_SDO   (1 << 1)
+#define CLOCK_OUT (1 << 0)
+
+flexrf_base::flexrf_base(usrp_basic_sptr _usrp, int which, int _power_on)
+  : db_base(_usrp, which), d_power_on(_power_on)
+{
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: which side: 0 or 1 corresponding to side A or B respectively
+    @type which: int
+  */
+
+  d_first = true;
+  d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+  usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
+  _enable_refclk(false);                // disable refclk
+
+  set_auto_tr(false);
+}
+
+flexrf_base::~flexrf_base()
+{
+  delete d_common;
+}
+
+void
+flexrf_base::_write_all(int R, int control, int N)
+{
+  /*
+    Write R counter latch, control latch and N counter latch to VCO.
+    
+    Adds 10ms delay between writing control and N if this is first call.
+    This is the required power-up sequence.
+    
+    @param R: 24-bit R counter latch
+    @type R: int
+    @param control: 24-bit control latch
+    @type control: int
+    @param N: 24-bit N counter latch
+    @type N: int
+  */
+  timespec t;
+  t.tv_sec = 0;
+  t.tv_nsec = 10000000;
+
+  _write_R(R);
+  _write_control(control);
+  if(d_first) {
+    //time.sleep(0.010);
+    nanosleep(&t, NULL);
+    d_first = false;
+  }
+  _write_N(N);
+}
+
+void
+flexrf_base::_write_control(int control)
+{
+  _write_it((control & ~0x3) | 0);
+}
+
+void
+flexrf_base::_write_R(int R)
+{
+  _write_it((R & ~0x3) | 1);
+}
+
+void
+flexrf_base::_write_N(int N)
+{
+  _write_it((N & ~0x3) | 2);
+}
+
+void
+flexrf_base::_write_it(int v)
+{
+  char s[3];
+  s[0] = (char)((v >> 16) & 0xff);
+  s[1] = (char)((v >>  8) & 0xff);
+  s[2] = (char)(v & 0xff);
+  std::string str(s, 3);
+  usrp()->_write_spi(0, d_spi_enable, d_spi_format, str);
+}
+        
+bool
+flexrf_base::_lock_detect()
+{
+  /*
+    @returns: the value of the VCO/PLL lock detect bit.
+    @rtype: 0 or 1
+  */
+  if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+    return true;
+  }
+  else {      // Give it a second chance
+    // FIXME: make portable sleep
+    timespec t;
+    t.tv_sec = 0;
+    t.tv_nsec = 100000000;
+    nanosleep(&t, NULL);
+    
+    if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+}
+
+bool
+flexrf_base::_compute_regs(double freq, int &retR, int &retcontrol,
+                          int &retN, double &retfreq)
+{
+  /*
+    Determine values of R, control, and N registers, along with actual freq.
+    
+    @param freq: target frequency in Hz
+    @type freq: float
+    @returns: (R, control, N, actual_freq)
+    @rtype: tuple(int, int, int, float)
+    
+    Override this in derived classes.
+  */
+  
+  //raise NotImplementedError;
+  throw std::runtime_error("_compute_regs called from flexrf_base\n");
+}
+
+int
+flexrf_base::_compute_control_reg()
+{
+  return d_common->_compute_control_reg();
+}
+
+int
+flexrf_base::_refclk_divisor()
+{
+  return d_common->_refclk_divisor();
+}
+
+struct freq_result_t
+flexrf_base::set_freq(double freq)
+{
+  /*
+    @returns (ok, actual_baseband_freq) where:
+    ok is True or False and indicates success or failure,
+    actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+  */
+
+  struct freq_result_t args = {false, 0};
+
+  // Offsetting the LO helps get the Tx carrier leakage out of the way.
+  // This also ensures that on Rx, we're not getting hosed by the
+  // FPGA's DC removal loop's time constant.  We were seeing a
+  // problem when running with discontinuous transmission.
+  // Offsetting the LO made the problem go away.
+  freq += d_lo_offset;
+  
+  int R, control, N;
+  double actual_freq;
+  _compute_regs(freq, R, control, N, actual_freq);
+
+  if(R==0) {
+    return args;
+  }
+   
+  _write_all(R, control, N);
+  args.ok = _lock_detect();
+  args.baseband_freq = actual_freq;
+  return args;
+}
+
+bool
+flexrf_base::_set_pga(float pga_gain)
+{
+  if(d_which == 0) {
+    usrp()->set_pga(0, pga_gain);
+    usrp()->set_pga(1, pga_gain);
+  }
+  else {
+    usrp()->set_pga(2, pga_gain);
+    usrp()->set_pga(3, pga_gain);
+  }
+  return true;
+}
+
+bool
+flexrf_base::is_quadrature()
+{
+  /*
+    Return True if this board requires both I & Q analog channels.
+    
+    This bit of info is useful when setting up the USRP Rx mux register.
+  */
+  return true;
+}
+
+double
+flexrf_base::freq_min()
+{
+  return d_common->freq_min();
+}
+
+double
+flexrf_base::freq_max()
+{
+  return d_common->freq_max();
+}
+
+// ----------------------------------------------------------------
+
+flexrf_base_tx::flexrf_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : flexrf_base(_usrp, which, _power_on)
+{
+  /*
+    @param usrp: instance of usrp.sink_c
+    @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+  */
+  
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_TX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_TX_B;
+  }
+  
+  // power up the transmit side, but don't enable the mixer
+  usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
+  usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+  set_lo_offset(4e6);
+
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+flexrf_base_tx::~flexrf_base_tx()
+{
+  shutdown();
+}
+
+
+void
+flexrf_base_tx::shutdown()
+{
+  // fprintf(stderr, "flexrf_base_tx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
+
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+
+    // Power down and leave the T/R switch in the R position
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+
+    // Power down VCO/PLL
+    d_PD = 3;
+  
+    _write_control(_compute_control_reg());
+    _enable_refclk(false);                       // turn off refclk
+    set_auto_tr(false);
+  }
+}
+
+bool
+flexrf_base_tx::set_auto_tr(bool on)
+{
+  bool ok = true;
+  if(on) {
+    ok &= set_atr_mask (RX_TXN | ENABLE);
+    ok &= set_atr_txval(0      | ENABLE);
+    ok &= set_atr_rxval(RX_TXN | 0);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  return ok;
+}
+
+bool
+flexrf_base_tx::set_enable(bool on)
+{
+  /*
+    Enable transmitter if on is true
+  */
+
+  int v;
+  int mask = RX_TXN | ENABLE;
+  if(on) {
+    v = ENABLE;
+  }
+  else {
+    v = RX_TXN;
+  }
+  return usrp()->write_io(d_which, v, mask);
+}
+
+float
+flexrf_base_tx::gain_min()
+{
+  return usrp()->pga_max();
+}
+
+float
+flexrf_base_tx::gain_max()
+{
+  return usrp()->pga_max();
+}
+
+float
+flexrf_base_tx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool
+flexrf_base_tx::set_gain(float gain)
+{
+  /*
+    Set the gain.
+    
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+  return _set_pga(usrp()->pga_max());
+}
+
+
+/**************************************************************************/
+
+
+flexrf_base_rx::flexrf_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : flexrf_base(_usrp, which, _power_on)
+{
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+  */
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE), 
+                  (POWER_UP|RX2_RX1N|ENABLE));
+  
+  // set up for RX on TX/RX port
+  select_rx_antenna("TX/RX");
+  
+  bypass_adc_buffers(true);
+
+  set_lo_offset(-4e6);
+}
+
+flexrf_base_rx::~flexrf_base_rx()
+{
+  shutdown();
+}
+
+void
+flexrf_base_rx::shutdown()
+{
+  // fprintf(stderr, "flexrf_base_rx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
+
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+
+    // Power down
+    usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
+
+    // Power down VCO/PLL
+    d_PD = 3;
+  
+
+    // fprintf(stderr, "flexrf_base_rx::shutdown  before _write_control\n");
+    _write_control(_compute_control_reg());
+
+    // fprintf(stderr, "flexrf_base_rx::shutdown  before _enable_refclk\n");
+    _enable_refclk(false);                       // turn off refclk
+
+    // fprintf(stderr, "flexrf_base_rx::shutdown  before set_auto_tr\n");
+    set_auto_tr(false);
+
+    // fprintf(stderr, "flexrf_base_rx::shutdown  after set_auto_tr\n");
+  }
+}
+
+bool
+flexrf_base_rx::set_auto_tr(bool on)
+{
+  bool ok = true;
+  if(on) {
+    ok &= set_atr_mask (ENABLE);
+    ok &= set_atr_txval(     0);
+    ok &= set_atr_rxval(ENABLE);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  return true;
+}
+
+bool
+flexrf_base_rx::select_rx_antenna(int which_antenna)
+{
+  /*
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  */
+
+  if(which_antenna == 0) {
+    usrp()->write_io(d_which, 0,RX2_RX1N);
+  }
+  else if(which_antenna == 1) {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    return false;
+    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+  }
+  return true;
+}
+
+bool
+flexrf_base_rx::select_rx_antenna(const std::string &which_antenna)
+{
+  /*
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  */
+
+  if(which_antenna == "TX/RX") {
+    usrp()->write_io(d_which, 0, RX2_RX1N);
+  }
+  else if(which_antenna == "RX2") {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+    return false;
+  }
+  return true;
+}
+
+bool
+flexrf_base_rx::set_gain(float gain)
+{
+  /*
+    Set the gain.
+    
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+  
+  // clamp gain
+  gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+  float pga_gain, agc_gain;
+  float V_maxgain, V_mingain, V_fullscale, dac_value;
+
+  float maxgain = gain_max() - usrp()->pga_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    pga_gain = gain-maxgain;
+    assert(pga_gain <= usrp()->pga_max());
+    agc_gain = maxgain;
+  }
+  else {
+    pga_gain = 0;
+    agc_gain = gain;
+  }
+  
+  V_maxgain = .2;
+  V_mingain = 1.2;
+  V_fullscale = 3.3;
+  dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  assert(dac_value>=0 && dac_value<4096);
+
+  return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
+         && _set_pga(int(pga_gain)));
+}
+
+// ----------------------------------------------------------------
+
+
+_AD4360_common::_AD4360_common()
+{
+  // R-Register Common Values
+  d_R_RSV = 0;  // bits 23,22
+  d_BSC   = 3;  // bits 21,20 Div by 8 to be safe
+  d_TEST  = 0;  // bit 19
+  d_LDP   = 1;  // bit 18
+  d_ABP   = 0;  // bit 17,16   3ns
+
+  // N-Register Common Values
+  d_N_RSV = 0;  // bit 7
+        
+  // Control Register Common Values
+  d_PD    = 0;  // bits 21,20   Normal operation
+  d_PL    = 0;  // bits 13,12   11mA
+  d_MTLD  = 1;  // bit 11       enabled
+  d_CPG   = 0;  // bit 10       CP setting 1
+  d_CP3S  = 0;  // bit 9        Normal
+  d_PDP   = 1;  // bit 8        Positive
+  d_MUXOUT = 1; // bits 7:5     Digital Lock Detect
+  d_CR    = 0;  // bit 4        Normal
+  d_PC    = 1;  // bits 3,2     Core power 10mA
+}
+
+_AD4360_common::~_AD4360_common()
+{
+}
+
+bool
+_AD4360_common::_compute_regs(double refclk_freq, double freq, int &retR, 
+                             int &retcontrol, int &retN, double &retfreq)
+{
+  /*
+    Determine values of R, control, and N registers, along with actual freq.
+    
+    @param freq: target frequency in Hz
+    @type freq: float
+    @returns: (R, control, N, actual_freq)
+    @rtype: tuple(int, int, int, float)
+  */
+  
+  //  Band-specific N-Register Values
+  //float phdet_freq = _refclk_freq()/d_R_DIV;
+  double phdet_freq = refclk_freq/d_R_DIV;
+  double desired_n = round(freq*d_freq_mult/phdet_freq);
+  double actual_freq = desired_n * phdet_freq;
+  int B = floor(desired_n/_prescaler());
+  int A = desired_n - _prescaler()*B;
+  d_B_DIV = int(B);    // bits 20:8
+  d_A_DIV = int(A);    // bit 6:2
+
+  //assert db_B_DIV >= db_A_DIV
+  if(d_B_DIV < d_A_DIV) {
+    retR = 0;
+    retcontrol = 0;
+    retN = 0;
+    retfreq = 0;
+    return false;
+  }
+
+  int R = (d_R_RSV<<22) | (d_BSC<<20) | (d_TEST<<19) | 
+    (d_LDP<<18) | (d_ABP<<16) | (d_R_DIV<<2);
+  
+  int control = _compute_control_reg();
+
+  int N = (d_DIVSEL<<23) | (d_DIV2<<22) | (d_CPGAIN<<21) | 
+    (d_B_DIV<<8) | (d_N_RSV<<7) | (d_A_DIV<<2);
+
+  retR = R;
+  retcontrol = control;
+  retN = N;
+  retfreq = actual_freq/d_freq_mult;
+  return true;
+}
+
+int
+_AD4360_common::_compute_control_reg()
+{
+  int control = (d_P<<22) | (d_PD<<20) | (d_CP2<<17) | (d_CP1<<14)
+    | (d_PL<<12) | (d_MTLD<<11) | (d_CPG<<10) | (d_CP3S<<9) | (d_PDP<<8)
+    | (d_MUXOUT<<5) | (d_CR<<4) | (d_PC<<2);
+  
+  return control;
+}
+
+int
+_AD4360_common::_refclk_divisor()
+{
+  /*
+    Return value to stick in REFCLK_DIVISOR register
+  */
+  return 1;
+}
+    
+int
+_AD4360_common::_prescaler()
+{
+  if(d_P == 0) {
+    return 8;
+  }
+  else if(d_P == 1) {
+    return 16;
+  }
+  else {
+    return 32;
+  }
+}
+
+//----------------------------------------------------------------------
+
+_2400_common::_2400_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;  // bits 15:2
+   
+  // Band-specific C-Register values
+  d_P = 1;        // bits 23,22   Div by 16/17
+  d_CP2 = 7;      // bits 19:17
+  d_CP1 = 7;      // bits 16:14
+
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 0;     // bit 22
+  d_CPGAIN = 0;   // bit 21
+  d_freq_mult = 1;
+}
+
+double
+_2400_common::freq_min()
+{
+  return 2300e6;
+}
+
+double
+_2400_common::freq_max()
+{
+  return 2900e6;
+}
+
+//----------------------------------------------------------------------
+
+_1200_common::_1200_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+   
+  // Band-specific C-Register values
+  d_P = 1;        // bits 23,22   Div by 16/17
+  d_CP2 = 7;      // bits 19:17   1.25 mA
+  d_CP1 = 7;      // bits 16:14   1.25 mA
+  
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 1;     // bit 22
+  d_CPGAIN = 0;   // bit 21
+  d_freq_mult = 2;
+}
+
+double 
+_1200_common::freq_min()
+{
+  return 1150e6;
+}
+
+double 
+_1200_common::freq_max()
+{
+  return 1450e6;
+}
+
+//-------------------------------------------------------------------------
+
+_1800_common::_1800_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+    
+  // Band-specific C-Register values
+  d_P = 1;        // bits 23,22   Div by 16/17
+  d_CP2 = 7;      // bits 19:17   1.25 mA
+  d_CP1 = 7;      // bits 16:14   1.25 mA
+  
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 0;     // bit 22
+  d_freq_mult = 1;
+  d_CPGAIN = 0;   // bit 21
+}
+
+double 
+_1800_common::freq_min()
+{
+  return 1500e6;
+}
+
+double 
+_1800_common::freq_max()
+{
+  return 2100e6;
+}
+
+//-------------------------------------------------------------------------
+
+_900_common::_900_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+   
+  // Band-specific C-Register values
+  d_P = 1;        // bits 23,22   Div by 16/17
+  d_CP2 = 7;      // bits 19:17   1.25 mA
+  d_CP1 = 7;      // bits 16:14   1.25 mA
+  
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 1;     // bit 22
+  d_freq_mult = 2;
+  d_CPGAIN = 0;   // bit 21
+}
+
+double
+_900_common::freq_min()
+{
+  return 750e6;
+}
+
+double
+_900_common::freq_max()
+{
+  return 1050e6;
+}
+
+//-------------------------------------------------------------------------
+
+_400_common::_400_common()
+  : _AD4360_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 16;   // bits 15:2 
+   
+  // Band-specific C-Register values
+  d_P = 0;        // bits 23,22   Div by 8/9
+  d_CP2 = 7;      // bits 19:17   1.25 mA
+  d_CP1 = 7;      // bits 16:14   1.25 mA
+  
+  // Band specifc N-Register Values  These are different for TX/RX
+  d_DIVSEL = 0;   // bit 23
+  d_freq_mult = 2;
+  
+  d_CPGAIN = 0;   // bit 21
+}
+
+double 
+_400_common::freq_min()
+{
+  return 400e6;
+}  
+
+double 
+_400_common::freq_max()
+{
+  return 500e6;
+}  
+
+_400_tx::_400_tx()
+  : _400_common()
+{
+  d_DIV2 = 1;     // bit 22
+}
+
+_400_rx::_400_rx()
+  : _400_common()
+{
+  d_DIV2 = 0;    // bit 22   // RX side has built-in DIV2 in AD8348
+}
+
+//------------------------------------------------------------    
+
+db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which)
+{
+  d_common = new _2400_common();
+}
+
+db_flexrf_2400_tx::~db_flexrf_2400_tx()
+{
+}
+
+bool
+db_flexrf_2400_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+
+db_flexrf_2400_rx::db_flexrf_2400_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which)
+{
+  d_common = new _2400_common();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_2400_rx::~db_flexrf_2400_rx()
+{
+}
+
+float
+db_flexrf_2400_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_2400_rx::gain_max()
+{
+  return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_2400_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+
+bool
+db_flexrf_2400_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_2400_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+//------------------------------------------------------------    
+
+
+db_flexrf_1200_tx::db_flexrf_1200_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which)
+{
+  d_common = new _1200_common();
+}
+
+db_flexrf_1200_tx::~db_flexrf_1200_tx()
+{
+}
+
+bool
+db_flexrf_1200_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+
+
+db_flexrf_1200_rx::db_flexrf_1200_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which)
+{
+  d_common = new _1200_common();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_1200_rx::~db_flexrf_1200_rx()
+{
+}
+
+float
+db_flexrf_1200_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_1200_rx::gain_max()
+{
+  return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_1200_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+bool
+db_flexrf_1200_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_1200_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+//------------------------------------------------------------    
+
+
+db_flexrf_1800_tx::db_flexrf_1800_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which)
+{
+  d_common = new _1800_common();
+}
+
+db_flexrf_1800_tx::~db_flexrf_1800_tx()
+{
+}
+
+bool
+db_flexrf_1800_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+
+db_flexrf_1800_rx::db_flexrf_1800_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which)
+{
+  d_common = new _1800_common();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_1800_rx::~db_flexrf_1800_rx()
+{
+}
+
+
+float
+db_flexrf_1800_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_1800_rx::gain_max()
+{
+  return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_1800_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+bool
+db_flexrf_1800_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_1800_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                                int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+//------------------------------------------------------------    
+
+
+db_flexrf_900_tx::db_flexrf_900_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which)
+{
+  d_common = new _900_common();
+}
+
+db_flexrf_900_tx::~db_flexrf_900_tx()
+{
+}
+
+bool
+db_flexrf_900_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                               int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+db_flexrf_900_rx::db_flexrf_900_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which)
+{
+  d_common = new _900_common();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_900_rx::~db_flexrf_900_rx()
+{
+}
+
+float
+db_flexrf_900_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_900_rx::gain_max()
+{
+  return usrp()->pga_max()+70;
+}
+
+float
+db_flexrf_900_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+bool
+db_flexrf_900_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_900_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                               int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+//------------------------------------------------------------    
+
+
+db_flexrf_400_tx::db_flexrf_400_tx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_tx(usrp, which, POWER_UP)
+{
+  d_common = new _400_tx();
+}
+
+db_flexrf_400_tx::~db_flexrf_400_tx()
+{
+}
+
+bool
+db_flexrf_400_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+                               int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
+
+
+db_flexrf_400_rx::db_flexrf_400_rx(usrp_basic_sptr usrp, int which)
+  : flexrf_base_rx(usrp, which, POWER_UP)
+{
+  d_common = new _400_rx();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_flexrf_400_rx::~db_flexrf_400_rx()
+{
+}
+
+float
+db_flexrf_400_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_flexrf_400_rx::gain_max()
+{
+  return usrp()->pga_max()+45;
+}
+
+float
+
+db_flexrf_400_rx::gain_db_per_step()
+{
+  return 0.035;
+}
+
+
+bool
+db_flexrf_400_rx::i_and_q_swapped()
+{
+  return true;
+}
+
+bool
+db_flexrf_400_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+                               int &retN, double &retfreq)
+{
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+                                retcontrol, retN, retfreq);
+}
+
diff --git a/usrp/host/lib/db_flexrf_mimo.cc b/usrp/host/lib/db_flexrf_mimo.cc
new file mode 100644 (file)
index 0000000..29bbbd5
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2008,2009 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.
+ */ 
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_flexrf_mimo.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp/usrp_prims.h>
+#include <usrp_spi_defs.h>
+
+
+db_flexrf_2400_tx_mimo_a::db_flexrf_2400_tx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_2400_tx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_2400_tx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+
+db_flexrf_2400_rx_mimo_a::db_flexrf_2400_rx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_2400_rx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_2400_rx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+      
+db_flexrf_2400_tx_mimo_b::db_flexrf_2400_tx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_2400_tx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_2400_tx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_2400_rx_mimo_b::db_flexrf_2400_rx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_2400_rx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_2400_rx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_1800_tx_mimo_a::db_flexrf_1800_tx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1800_tx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_1800_tx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+
+db_flexrf_1800_rx_mimo_a::db_flexrf_1800_rx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1800_rx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_1800_rx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+    
+db_flexrf_1800_tx_mimo_b::db_flexrf_1800_tx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1800_tx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_1800_tx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_1800_rx_mimo_b::db_flexrf_1800_rx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1800_rx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_1800_rx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_1200_tx_mimo_a::db_flexrf_1200_tx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1200_tx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_1200_tx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+
+db_flexrf_1200_rx_mimo_a::db_flexrf_1200_rx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1200_rx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_1200_rx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+    
+db_flexrf_1200_tx_mimo_b::db_flexrf_1200_tx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1200_tx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_1200_tx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_1200_rx_mimo_b::db_flexrf_1200_rx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_1200_rx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_1200_rx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_900_tx_mimo_a::db_flexrf_900_tx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_900_tx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_900_tx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+
+db_flexrf_900_rx_mimo_a::db_flexrf_900_rx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_900_rx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_900_rx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+    
+db_flexrf_900_tx_mimo_b::db_flexrf_900_tx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_900_tx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_900_tx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_900_rx_mimo_b::db_flexrf_900_rx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_900_rx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int db_flexrf_900_rx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+
+db_flexrf_400_tx_mimo_a::db_flexrf_400_tx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_400_tx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_400_tx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+    
+db_flexrf_400_rx_mimo_a::db_flexrf_400_rx_mimo_a(usrp_basic_sptr usrp, int which)
+  : db_flexrf_400_rx(usrp, which)
+{
+  _enable_refclk(true);
+  d_common->R_DIV(1);
+}
+
+int 
+db_flexrf_400_rx_mimo_a::_refclk_divisor()
+{
+  return 16;
+}
+    
+db_flexrf_400_tx_mimo_b::db_flexrf_400_tx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_400_tx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_400_tx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
+    
+db_flexrf_400_rx_mimo_b::db_flexrf_400_rx_mimo_b(usrp_basic_sptr usrp, int which)
+  : db_flexrf_400_rx(usrp, which)
+{
+  d_common->R_DIV(16);
+}
+
+int 
+db_flexrf_400_rx_mimo_b::_refclk_divisor()
+{
+  return 1;
+}
diff --git a/usrp/host/lib/db_tv_rx.cc b/usrp/host/lib/db_tv_rx.cc
new file mode 100644 (file)
index 0000000..1822479
--- /dev/null
@@ -0,0 +1,278 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_tv_rx.h>
+#include <db_base_impl.h>
+
+/*****************************************************************************/
+
+int
+control_byte_1(bool fast_tuning_p, int reference_divisor)
+{
+  int c = 0x88;
+  if(fast_tuning_p) {
+    c |= 0x40;
+  }
+
+  if(reference_divisor == 512) {
+    c |= 0x3 << 1;
+  }
+  else if(reference_divisor == 640) {
+    c |= 0x0 << 1;
+  }
+  else if(reference_divisor == 1024) {
+    c |= 0x1 << 1;
+  }
+  else {
+    assert(0);
+  }
+
+  return c;
+}
+
+int
+control_byte_2(double target_freq, bool shutdown_tx_PGA)
+{
+  int c;
+  if(target_freq < 158e6) {        // VHF low
+    c = 0xa0;
+  }
+  else if(target_freq < 464e6) {   // VHF high
+    c = 0x90;
+  }
+  else {                           // UHF
+    c = 0x30;
+  }
+
+  if(shutdown_tx_PGA) {
+    c |= 0x08;
+  }
+
+  return c;
+}
+
+
+/*****************************************************************************/
+
+
+db_tv_rx::db_tv_rx(usrp_basic_sptr usrp, int which,
+                  double first_IF, double second_IF)
+  : db_base(usrp, which)
+{
+  // Handler for Tv Rx daughterboards.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+  if(which == 0) {
+    d_i2c_addr = 0x60;
+  }
+  else {
+    d_i2c_addr = 0x61;
+  }
+
+  d_first_IF = first_IF;
+  d_second_IF = second_IF;
+  d_reference_divisor = 640;
+  d_fast_tuning = false;
+  d_inverted = false;                     // FIXME get rid of this
+  
+  set_gain((gain_min() + gain_max()) / 2.0);       // initialize gain
+
+  bypass_adc_buffers(false);
+}
+
+db_tv_rx::~db_tv_rx()
+{
+}
+
+// Gain setting
+void
+db_tv_rx::_set_rfagc(float gain)
+{
+  float voltage;
+
+  assert(gain <= 60 && gain >= 0);
+  // FIXME this has a 0.5V step between gain = 60 and gain = 59.
+  // Why are there two cases instead of a single linear case?
+  if(gain == 60) {
+    voltage = 4;
+  }
+  else {
+    voltage = gain/60.0 * 2.25 + 1.25;
+  }
+  int dacword = int(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 1, dacword);
+}
+
+void
+db_tv_rx::_set_ifagc(float gain)
+{
+  float voltage;
+
+  assert(gain <= 35 && gain >= 0);
+  voltage = gain/35.0 * 2.1 + 1.4;
+  int dacword = int(4096*voltage/1.22/3.3);    // 1.22 = opamp gain
+  
+  assert(dacword>=0 && dacword<4096);
+  usrp()->write_aux_dac(d_which, 0, dacword);
+}
+
+void
+db_tv_rx::_set_pga(float pga_gain)
+{
+  assert(pga_gain >=0 && pga_gain <=20);
+  if(d_which == 0) {
+    usrp()->set_pga(0, pga_gain);
+  }
+  else {
+    usrp()->set_pga (2, pga_gain);
+  }
+}           
+
+double
+db_tv_rx::freq_min()
+{
+  return 50e6;
+}
+
+double
+db_tv_rx::freq_max()
+{
+  return 860e6;
+}
+
+struct freq_result_t
+db_tv_rx::set_freq(double target_freq)
+{
+  // Set the frequency.
+  // 
+  // @param freq:  target RF frequency in Hz
+  // @type freq:   double
+  // 
+  // @returns (ok, actual_baseband_freq) where:
+  //   ok is True or False and indicates success or failure,
+  //   actual_baseband_freq is RF frequency that corresponds to DC in the IF.
+  
+  freq_result_t args = {false, 0};
+
+  double fmin = freq_min();
+  double fmax = freq_max();
+  if((target_freq < fmin) || (target_freq > fmax)) {
+    return args;
+  }
+  
+  double target_lo_freq = target_freq + d_first_IF;    // High side mixing
+  double f_ref = 4.0e6 / (double)(d_reference_divisor); // frequency steps
+
+  int divisor = int((target_lo_freq + (f_ref * 4)) / (f_ref * 8));  
+  double actual_lo_freq = (f_ref * 8 * divisor);
+  double actual_freq = actual_lo_freq - d_first_IF;
+
+  if((divisor & ~0x7fff) != 0) {               // must be 15-bits or less
+    return args;
+  }
+
+  // build i2c command string
+  std::vector<int> buf(4);
+  buf[0] = (divisor >> 8) & 0xff;         // DB1
+  buf[1] = divisor & 0xff;                // DB2
+  buf[2] = control_byte_1(d_fast_tuning, d_reference_divisor);
+  buf[3] = control_byte_2(actual_freq, true);
+
+  args.ok = usrp()->write_i2c(d_i2c_addr, int_seq_to_str (buf));
+  args.baseband_freq = actual_freq - d_second_IF;
+  return args;
+}
+
+float
+db_tv_rx::gain_min()
+{
+  return 0;
+}
+
+float
+db_tv_rx::gain_max()
+{
+  return 115;
+}
+
+float
+db_tv_rx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool 
+db_tv_rx::set_gain(float gain)
+{
+  // Set the gain.
+  // 
+  // @param gain:  gain in decibels
+  // @returns True/False
+
+  float rfgain, ifgain, pgagain;
+
+  assert(gain>=0 && gain<=115);
+  if(gain>60) {
+    rfgain = 60;
+    gain = gain - 60;
+  }
+  else {
+    rfgain = gain;
+    gain = 0;
+  }
+   
+  if(gain > 35) {
+    ifgain = 35;
+    gain = gain - 35;
+  }
+  else {
+    ifgain = gain;
+    gain = 0;
+  }
+
+  pgagain = gain;
+  _set_rfagc(rfgain);
+  _set_ifagc(ifgain);
+  _set_pga(pgagain);
+
+  return true;
+}
+
+bool 
+db_tv_rx::is_quadrature()
+{
+  // Return True if this board requires both I & Q analog channels.  
+  return false;
+}
+
+bool
+db_tv_rx::spectrum_inverted() 
+{
+  // The 43.75 MHz version is inverted
+  return d_inverted;
+}
diff --git a/usrp/host/lib/db_tv_rx_mimo.cc b/usrp/host/lib/db_tv_rx_mimo.cc
new file mode 100644 (file)
index 0000000..0964c5d
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_tv_rx_mimo.h>
+
+db_tv_rx_mimo::db_tv_rx_mimo(usrp_basic_sptr usrp, int which,
+                  double first_IF, double second_IF)
+  : db_tv_rx(usrp, which,first_IF,second_IF)
+{
+  _enable_refclk(true);//enable FPGA refclock output on gpio 0
+}
+
+int 
+db_tv_rx_mimo::_refclk_divisor()
+{
+  return 16;// 64/16=> 4 Mhz refclock
+}
+
diff --git a/usrp/host/lib/db_util.cc b/usrp/host/lib/db_util.cc
new file mode 100644 (file)
index 0000000..4b46383
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <db_util.h>
+#include <sstream>
+
+std::string
+int_seq_to_str(std::vector<int> &seq)
+{
+  //convert a sequence of integers into a string
+
+  std::stringstream str; 
+  std::vector<int>::iterator i;
+  for(i = seq.begin(); i != seq.end(); i++) {
+    str << char((unsigned int)*i);
+  }
+  return str.str();
+}
+
+std::vector<int> 
+str_to_int_seq(std::string str)
+{
+  //convert a string to a list of integers
+  std::vector<int> seq;
+  std::vector<int>::iterator sitr;
+  std::string::iterator i;
+  for(i=str.begin(); i != str.end(); i++) {
+    int a = (int)(*i);
+    seq.push_back(a);
+  }
+  return seq;
+}
+
diff --git a/usrp/host/lib/db_util.h b/usrp/host/lib/db_util.h
new file mode 100644 (file)
index 0000000..e07abb6
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_DB_UTIL_H
+#define INCLUDED_DB_UTIL_H
+
+#include <string>
+#include <vector>
+
+std::string int_seq_to_str(std::vector<int> &seq);
+std::vector<int> str_to_int_seq(std::string str);
+
+#endif /* INCLUDED_DB_UTIL_H */
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
new file mode 100644 (file)
index 0000000..bd836df
--- /dev/null
@@ -0,0 +1,511 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_wbxng.h>
+#include "db_wbxng_adf4350.h"
+#include <db_base_impl.h>
+#include <stdio.h>
+
+// d'board i/o pin defs
+// Tx and Rx have shared defs, but different i/o regs
+#define ENABLE_5        (1 << 7)         // enables 5.0V power supply
+#define ENABLE_33       (1 << 6)         // enables 3.3V supply
+//#define RX_TXN          (1 << 15)         // Tx only: T/R antenna switch for TX/RX port
+//#define RX2_RX1N        (1 << 15)         // Rx only: antenna switch between RX2 and TX/RX port
+#define RX_TXN          ((1 << 5)|(1 << 15))         // Tx only: T/R antenna switch for TX/RX port
+#define RX2_RX1N        ((1 << 5)|(1 << 15))         // Rx only: antenna switch between RX2 and TX/RX port
+#define RXBB_EN         (1 << 4)
+#define TXMOD_EN        (1 << 4)
+#define PLL_CE          (1 << 3)
+#define PLL_PDBRF       (1 << 2)
+#define PLL_MUXOUT      (1 << 1)
+#define PLL_LOCK_DETECT (1 << 0)
+
+// RX Attenuator constants
+#define ATTN_SHIFT     8
+#define ATTN_MASK      (63 << ATTN_SHIFT)
+
+wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
+  : db_base(_usrp, which), d_power_on(_power_on)
+{
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: which side: 0 or 1 corresponding to side A or B respectively
+    @type which: int
+  */
+
+  usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
+
+  d_first = true;
+  d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+  _enable_refclk(false);                // disable refclk
+
+  set_auto_tr(false);
+}
+
+wbxng_base::~wbxng_base()
+{
+  if (d_common)
+    delete d_common;
+}
+
+struct freq_result_t
+wbxng_base::set_freq(double freq)
+{
+  /*
+    @returns (ok, actual_baseband_freq) where:
+    ok is True or False and indicates success or failure,
+    actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+  */
+
+  // clamp freq
+  freq_t int_freq = freq_t(std::max(freq_min(), std::min(freq, freq_max())));
+
+  bool ok = d_common->_set_freq(int_freq*2);
+  double freq_result = (double) d_common->_get_freq()/2.0;
+  struct freq_result_t args = {ok, freq_result};
+
+  /* Wait before reading Lock Detect*/
+  timespec t;
+  t.tv_sec = 0;
+  t.tv_nsec = 10000000;
+  nanosleep(&t, NULL);
+
+  //fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n",
+  //        int_freq, freq_result, d_common->_get_locked());
+
+  // FIXME
+  // Offsetting the LO helps get the Tx carrier leakage out of the way.
+  // This also ensures that on Rx, we're not getting hosed by the
+  // FPGA's DC removal loop's time constant.  We were seeing a
+  // problem when running with discontinuous transmission.
+  // Offsetting the LO made the problem go away.
+  //freq += d_lo_offset;
+
+  return args;
+}
+
+bool
+wbxng_base::_set_pga(float pga_gain)
+{
+  if(d_which == 0) {
+    usrp()->set_pga(0, pga_gain);
+    usrp()->set_pga(1, pga_gain);
+  }
+  else {
+    usrp()->set_pga(2, pga_gain);
+    usrp()->set_pga(3, pga_gain);
+  }
+  return true;
+}
+
+bool
+wbxng_base::is_quadrature()
+{
+  /*
+    Return True if this board requires both I & Q analog channels.
+
+    This bit of info is useful when setting up the USRP Rx mux register.
+  */
+  return true;
+}
+
+double
+wbxng_base::freq_min()
+{
+  return (double) d_common->_get_min_freq()/2.0;
+}
+
+double
+wbxng_base::freq_max()
+{
+  return (double) d_common->_get_max_freq()/2.0;
+}
+
+// ----------------------------------------------------------------
+
+wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : wbxng_base(_usrp, which, _power_on)
+{
+  /*
+    @param usrp: instance of usrp.sink_c
+    @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+  */
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_TX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_TX_B;
+  }
+
+  d_common = new adf4350(_usrp, d_which, d_spi_enable);
+
+  // power up the transmit side, but don't enable the mixer
+  usrp()->_write_oe(d_which,(RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which, (power_on()|RX_TXN|ENABLE_33|ENABLE_5), (RX_TXN|ENABLE_33|ENABLE_5));
+  //set_lo_offset(4e6);
+  
+  // Disable VCO/PLL
+  d_common->_enable(true);
+
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+wbxng_base_tx::~wbxng_base_tx()
+{
+  shutdown();
+}
+
+
+void
+wbxng_base_tx::shutdown()
+{
+  // fprintf(stderr, "wbxng_base_tx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
+
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+
+    // Disable VCO/PLL
+    d_common->_enable(false);
+
+    // Power down and leave the T/R switch in the R position
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
+
+
+    /*
+    _write_control(_compute_control_reg());
+    */
+    _enable_refclk(false);                       // turn off refclk
+    set_auto_tr(false);
+  }
+}
+
+bool
+wbxng_base_tx::set_auto_tr(bool on)
+{
+  bool ok = true;
+  if(on) {
+    ok &= set_atr_mask (RX_TXN | TXMOD_EN);
+    ok &= set_atr_txval(0      | TXMOD_EN);
+    ok &= set_atr_rxval(RX_TXN);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  return ok;
+}
+
+bool
+wbxng_base_tx::set_enable(bool on)
+{
+  /*
+    Enable transmitter if on is true
+  */
+
+  int v;
+  int mask = RX_TXN | TXMOD_EN;
+  if(on) {
+    v = TXMOD_EN;
+    // Enable VCO/PLL
+    //d_common->_enable(true);
+  }
+  else {
+    v = RX_TXN;
+    // Disable VCO/PLL
+    //d_common->_enable(false);
+  }
+  return usrp()->write_io(d_which, v, mask);
+}
+
+float
+wbxng_base_tx::gain_min()
+{
+  return 0.0;
+}
+
+float
+wbxng_base_tx::gain_max()
+{
+  return 25.0;
+}
+
+float
+wbxng_base_tx::gain_db_per_step()
+{
+  return gain_max()/(1+(1.4-0.5)*4096/3.3);
+}
+
+bool
+wbxng_base_tx::set_gain(float gain)
+{
+  /*
+    Set the gain.
+
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+
+  // clamp gain
+  gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+  float pga_gain, agc_gain;
+  float V_maxgain, V_mingain, V_fullscale, dac_value;
+
+  float maxgain = gain_max();
+  float mingain = gain_min();
+  pga_gain = 0;
+  agc_gain = gain;
+
+  V_maxgain = 0.5;
+  V_mingain = 1.4;
+  V_fullscale = 3.3;
+  dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  //fprintf(stderr, "TXGAIN: %f dB, Dac Code: %d, Voltage: %f\n", gain, int(dac_value), float((dac_value/4096.0)*V_fullscale));
+  assert(dac_value>=0 && dac_value<4096);
+
+  return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
+     && _set_pga(usrp()->pga_max()));
+
+}
+
+
+/**************************************************************************/
+
+
+wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : wbxng_base(_usrp, which, _power_on)
+{
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+  */
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  d_common = new adf4350(_usrp, d_which, d_spi_enable);
+  
+  // Disable VCO/PLL
+  d_common->_enable(true);
+
+  usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
+  //fprintf(stderr,"Setting WBXNG RXBB on");
+
+  // set up for RX on TX/RX port
+  select_rx_antenna("TX/RX");
+
+  bypass_adc_buffers(true);
+
+  /*
+  set_lo_offset(-4e6);
+  */
+}
+
+wbxng_base_rx::~wbxng_base_rx()
+{
+  shutdown();
+}
+
+void
+wbxng_base_rx::shutdown()
+{
+  // fprintf(stderr, "wbxng_base_rx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
+
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+
+    // Power down VCO/PLL
+    d_common->_enable(false);
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before _write_control\n");
+    //_write_control(_compute_control_reg());
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before _enable_refclk\n");
+    _enable_refclk(false);                       // turn off refclk
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before set_auto_tr\n");
+    set_auto_tr(false);
+
+    // Power down
+    usrp()->write_io(d_which, power_off(), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  after set_auto_tr\n");
+  }
+}
+
+bool
+wbxng_base_rx::set_auto_tr(bool on)
+{
+  bool ok = true;
+  if(on) {
+    ok &= set_atr_mask (RXBB_EN|RX2_RX1N);
+    ok &= set_atr_txval(      0|RX2_RX1N);
+    ok &= set_atr_rxval(RXBB_EN|       0);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  return true;
+}
+
+bool
+wbxng_base_rx::select_rx_antenna(int which_antenna)
+{
+  /*
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  */
+
+  if(which_antenna == 0) {
+    usrp()->write_io(d_which, 0,RX2_RX1N);
+  }
+  else if(which_antenna == 1) {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    return false;
+  }
+  return true;
+}
+
+bool
+wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
+{
+  /*
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  */
+
+
+  if(which_antenna == "TX/RX") {
+    usrp()->write_io(d_which, 0, RX2_RX1N);
+  }
+  else if(which_antenna == "RX2") {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    return false;
+  }
+
+  return true;
+}
+
+bool
+wbxng_base_rx::set_gain(float gain)
+{
+  /*
+    Set the gain.
+
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+
+  // clamp gain
+  gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+  float pga_gain, agc_gain;
+
+  float maxgain = gain_max() - usrp()->pga_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    pga_gain = gain-maxgain;
+    assert(pga_gain <= usrp()->pga_max());
+    agc_gain = maxgain;
+  }
+  else {
+    pga_gain = 0;
+    agc_gain = gain;
+  }
+
+  return _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain));
+}
+
+bool
+wbxng_base_rx::_set_attn(float attn)
+{
+  int attn_code = int(floor(attn/0.5));
+  unsigned int iobits = (~attn_code) << ATTN_SHIFT;
+  //fprintf(stderr, "Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x \n", attn, attn_code, iobits & ATTN_MASK, ATTN_MASK);
+  return usrp()->write_io(d_which, iobits, ATTN_MASK);
+}
+
+// ----------------------------------------------------------------
+
+db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which)
+  : wbxng_base_tx(usrp, which)
+{
+}
+
+db_wbxng_tx::~db_wbxng_tx()
+{
+}
+
+db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which)
+  : wbxng_base_rx(usrp, which)
+{
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+}
+
+db_wbxng_rx::~db_wbxng_rx()
+{
+}
+
+float
+db_wbxng_rx::gain_min()
+{
+  return usrp()->pga_min();
+}
+
+float
+db_wbxng_rx::gain_max()
+{
+  return usrp()->pga_max()+30.5;
+}
+
+float
+db_wbxng_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+
+bool
+db_wbxng_rx::i_and_q_swapped()
+{
+  return false;
+}
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
new file mode 100644 (file)
index 0000000..c17e8d6
--- /dev/null
@@ -0,0 +1,206 @@
+//
+// Copyright 2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "db_wbxng_adf4350.h"
+#include <db_base_impl.h>
+#include <stdio.h>
+
+#define FREQ_C(freq) uint64_t(freq)
+#define INPUT_REF_FREQ FREQ_C(64e6)
+#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
+#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
+#define MIN_INT_DIV uint16_t(23)                                        /* minimum int divider, prescaler 4/5 only */
+#define MAX_RF_DIV uint8_t(16)                                          /* max rf divider, divides rf output */
+#define MIN_VCO_FREQ FREQ_C(2.2e9)                                      /* minimum vco freq */
+#define MAX_VCO_FREQ FREQ_C(4.4e9)                                      /* minimum vco freq */
+#define MAX_FREQ DIV_ROUND(MAX_VCO_FREQ, 1)                                           /* upper bound freq (rf div = 1) */
+#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV)                    /* calculated lower bound freq */
+
+#define CE_PIN        (1 << 3)
+#define PDB_RF_PIN    (1 << 2)
+#define MUX_PIN       (1 << 1)
+#define LD_PIN        (1 << 0)
+
+adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable)
+{
+    /* Initialize the pin directions. */
+
+    d_usrp = _usrp;
+    d_which = _which;
+    d_spi_enable = _spi_enable;
+    d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+    d_regs = new adf4350_regs(this);
+
+    /* Outputs */
+    d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
+    d_usrp->write_io(d_which, (CE_PIN), (CE_PIN | PDB_RF_PIN));
+
+    /* Initialize the pin levels. */
+    _enable(true);
+    /* Initialize the registers. */
+    d_regs->_load_register(5);
+    d_regs->_load_register(4);
+    d_regs->_load_register(3);
+    d_regs->_load_register(2);
+    d_regs->_load_register(1);
+    d_regs->_load_register(0);
+}
+
+adf4350::~adf4350()
+{
+    d_usrp->write_io(d_which, (0), (CE_PIN | PDB_RF_PIN));
+    delete d_regs;
+}
+
+freq_t
+adf4350::_get_max_freq(void)
+{
+    return MAX_FREQ;
+}
+
+freq_t
+adf4350::_get_min_freq(void)
+{
+    return MIN_FREQ;
+}
+
+bool
+adf4350::_get_locked(void)
+{
+    return d_usrp->read_io(d_which) & LD_PIN;
+}
+
+void
+adf4350::_enable(bool enable)
+{
+    if (enable){ /* chip enable */
+        d_usrp->write_io(d_which, (PDB_RF_PIN), (PDB_RF_PIN));
+    }else{
+        d_usrp->write_io(d_which, 0, (PDB_RF_PIN));
+    }
+}
+
+void
+adf4350::_write(uint8_t addr, uint32_t data)
+{
+    data |= addr;
+
+    // create str from data here
+    char s[4];
+    s[0] = (char)((data >> 24) & 0xff);
+    s[1] = (char)((data >> 16) & 0xff);
+    s[2] = (char)((data >>  8) & 0xff);
+    s[3] = (char)(data & 0xff);
+    std::string str(s, 4);
+
+    timespec t;
+    t.tv_sec = 0;
+    t.tv_nsec = 5e6;
+
+    nanosleep(&t, NULL);
+    d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str);
+    nanosleep(&t, NULL);
+
+    //fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data);
+    /* pulse latch */
+    //d_usrp->write_io(d_which, 1, LE_PIN);
+    //d_usrp->write_io(d_which, 0, LE_PIN);
+}
+
+bool
+adf4350::_set_freq(freq_t freq)
+{
+    /* Set the frequency by setting int, frac, mod, r, div */
+    if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
+    int min_int_div = 23;
+    d_regs->d_prescaler = 0;
+    if (freq > FREQ_C(3e9)) {
+        min_int_div = 75;
+        d_regs->d_prescaler = 1;
+    }
+    /* Ramp up the RF divider until the VCO is within range. */
+    d_regs->d_divider_select = 0;
+    while (freq < MIN_VCO_FREQ){
+        freq <<= 1; //double the freq
+        d_regs->d_divider_select++; //double the divider
+    }
+    /* Ramp up the R divider until the N divider is at least the minimum. */
+    //d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
+    d_regs->d_10_bit_r_counter = 2;
+    uint64_t n_mod;
+    do{
+        d_regs->d_10_bit_r_counter++;
+        n_mod = freq;
+        n_mod *= d_regs->d_10_bit_r_counter;
+        n_mod *= d_regs->d_mod;
+        n_mod /= INPUT_REF_FREQ;
+        /* calculate int and frac */
+        d_regs->d_int = n_mod/d_regs->d_mod;
+        d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
+        /*
+        fprintf(stderr,
+            "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
+            freq, d_regs->d_int, d_regs->d_frac,
+            d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
+        );
+        */
+    }while(d_regs->d_int < min_int_div);
+    /* calculate the band select so PFD is under 125 KHz */
+    d_regs->d_8_bit_band_select_clock_divider_value = \
+        INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1;
+    /*
+    fprintf(stderr, "Band Selection: Div %u, Freq %lu\n",
+        d_regs->d_8_bit_band_select_clock_divider_value,
+        INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1
+    );
+    */
+    d_regs->_load_register(5);
+    d_regs->_load_register(3);
+    d_regs->_load_register(1);
+    /* load involved registers */
+    d_regs->_load_register(2);
+    d_regs->_load_register(4);
+    d_regs->_load_register(0); /* register 0 must be last */
+    return true;
+}
+
+freq_t
+adf4350::_get_freq(void)
+{
+    /* Calculate the freq from int, frac, mod, ref, r, div:
+     *  freq = (int + frac/mod) * (ref/r)
+     * Keep precision by doing multiplies first:
+     *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
+     */
+    uint64_t temp;
+    temp = d_regs->d_int;
+    temp *= d_regs->d_mod;
+    temp += d_regs->d_frac;
+    temp *= INPUT_REF_FREQ;
+    temp /= d_regs->d_mod;
+    temp /= d_regs->d_10_bit_r_counter;
+    temp /= (1 << d_regs->d_divider_select);
+    return temp;
+}
diff --git a/usrp/host/lib/db_wbxng_adf4350.h b/usrp/host/lib/db_wbxng_adf4350.h
new file mode 100644 (file)
index 0000000..2b0783c
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// Copyright 2009 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 asversion 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.
+
+#ifndef INCLUDED_ADF4350_H
+#define INCLUDED_ADF4350_H
+
+#include "db_wbxng_adf4350_regs.h"
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+typedef uint64_t freq_t;
+class adf4350_regs;
+
+class adf4350
+{
+public:
+    adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable);
+    ~adf4350();
+    void _update();
+    bool _get_locked();
+    void _enable(bool enable);
+    void _write(uint8_t addr, uint32_t data);
+    bool _set_freq(freq_t freq);
+    freq_t _get_freq();
+    freq_t _get_max_freq();
+    freq_t _get_min_freq();
+
+protected:
+    usrp_basic_sptr d_usrp;
+    int d_which;
+    int d_spi_enable;
+    int d_spi_format;
+    adf4350_regs *d_regs;
+};
+
+#endif /* INCLUDED_ADF4350_H */
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
new file mode 100644 (file)
index 0000000..21d77dc
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// Copyright 2009 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 asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#include "db_wbxng_adf4350_regs.h"
+#include "db_wbxng_adf4350.h"
+
+//#include "cal_div.h"
+
+/* reg 0 */
+/* reg 1 */
+const uint16_t adf4350_regs::s_phase = 0;
+/* reg 2 */
+const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 3;
+const uint8_t adf4350_regs::s_muxout = 6;
+const uint8_t adf4350_regs::s_reference_doubler = 0;
+const uint8_t adf4350_regs::s_rdiv2 = 0;
+const uint8_t adf4350_regs::s_double_buff = 0;
+const uint8_t adf4350_regs::s_charge_pump_setting = 5;
+const uint8_t adf4350_regs::s_ldf = 0;
+const uint8_t adf4350_regs::s_ldp = 0;
+const uint8_t adf4350_regs::s_pd_polarity = 1;
+const uint8_t adf4350_regs::s_power_down = 0;
+const uint8_t adf4350_regs::s_cp_three_state = 0;
+const uint8_t adf4350_regs::s_counter_reset = 0;
+/* reg 3 */
+const uint8_t adf4350_regs::s_csr = 0;
+const uint8_t adf4350_regs::s_clk_div_mode = 0;
+const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0;
+/* reg 4 */
+const uint8_t adf4350_regs::s_feedback_select = 1;
+const uint8_t adf4350_regs::s_vco_power_down = 0;
+const uint8_t adf4350_regs::s_mtld = 0;
+const uint8_t adf4350_regs::s_aux_output_select = 1;
+const uint8_t adf4350_regs::s_aux_output_enable = 0;
+const uint8_t adf4350_regs::s_aux_output_power = 0;
+const uint8_t adf4350_regs::s_rf_output_enable = 1;
+const uint8_t adf4350_regs::s_output_power = 3;
+/* reg 5 */
+const uint8_t adf4350_regs::s_ld_pin_mode = 1;
+
+adf4350_regs::adf4350_regs(adf4350* _adf4350){
+    d_adf4350 = _adf4350;
+
+    /* reg 0 */
+    d_int = uint16_t(100);
+    d_frac = 0;
+    /* reg 1 */
+    d_prescaler = uint8_t(0);
+    d_mod = uint16_t(0xfff);                      /* max fractional accuracy */
+    /* reg 2 */
+    d_10_bit_r_counter = uint16_t(2);
+    /* reg 3 */
+    /* reg 4 */
+    d_divider_select = 0;
+    d_8_bit_band_select_clock_divider_value = 0;
+    /* reg 5 */
+}
+
+adf4350_regs::~adf4350_regs(void){
+}
+
+uint32_t
+adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){
+        return data << shift;
+    }
+
+void
+adf4350_regs::_load_register(uint8_t addr){
+       uint32_t data;
+       switch (addr){
+               case 0: data = (
+                       _reg_shift(d_int, 15)                           |
+                       _reg_shift(d_frac, 3)); break;
+               case 1: data = (
+                       _reg_shift(d_prescaler, 27)                     |
+                       _reg_shift(s_phase, 15)                         |
+                       _reg_shift(d_mod, 3)); break;
+               case 2: data = (
+                       _reg_shift(s_low_noise_and_low_spur_modes, 29)  |
+                       _reg_shift(s_muxout, 26)                        |
+                       _reg_shift(s_reference_doubler, 25)             |
+                       _reg_shift(s_rdiv2, 24)                         |
+                       _reg_shift(d_10_bit_r_counter, 14)              |
+                       _reg_shift(s_double_buff, 13)                   |
+                       _reg_shift(s_charge_pump_setting, 9)            |
+                       _reg_shift(s_ldf, 8)                            |
+                       _reg_shift(s_ldp, 7)                            |
+                       _reg_shift(s_pd_polarity, 6)                    |
+                       _reg_shift(s_power_down, 5)                     |
+                       _reg_shift(s_cp_three_state, 4)                 |
+                       _reg_shift(s_counter_reset, 3)); break;
+               case 3: data = (
+                       _reg_shift(s_csr, 18)                           |
+                       _reg_shift(s_clk_div_mode, 15)                  |
+                       _reg_shift(s_12_bit_clock_divider_value, 3)); break;
+               case 4: data = (
+                       _reg_shift(s_feedback_select, 23)               |
+                       _reg_shift(d_divider_select, 20)                |
+                       _reg_shift(d_8_bit_band_select_clock_divider_value, 12) |
+                       _reg_shift(s_vco_power_down, 11)                |
+                       _reg_shift(s_mtld, 10)                          |
+                       _reg_shift(s_aux_output_select, 9)              |
+                       _reg_shift(s_aux_output_enable, 8)              |
+                       _reg_shift(s_aux_output_power, 6)               |
+                       _reg_shift(s_rf_output_enable, 5)               |
+                       _reg_shift(s_output_power, 3)); break;
+               case 5: data = (
+                       _reg_shift(s_ld_pin_mode, 22)); break;
+               default: return;
+       }
+       /* write the data out to spi */
+       d_adf4350->_write(addr, data);
+}
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.h b/usrp/host/lib/db_wbxng_adf4350_regs.h
new file mode 100644 (file)
index 0000000..0018aa0
--- /dev/null
@@ -0,0 +1,80 @@
+//
+// Copyright 2009 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 asversion 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.
+
+#ifndef ADF4350_REGS_H
+#define ADF4350_REGS_H
+
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+class adf4350;
+
+class adf4350_regs
+{
+public:
+    adf4350_regs(adf4350* _adf4350);
+    ~adf4350_regs();
+
+    adf4350* d_adf4350;
+
+    uint32_t _reg_shift(uint32_t data, uint32_t shift);
+    void _load_register(uint8_t addr);
+
+    /* reg 0 */
+    uint16_t d_int;
+    uint16_t d_frac;
+    /* reg 1 */
+    uint8_t d_prescaler;
+    static const uint16_t s_phase;
+    uint16_t d_mod;
+    /* reg 2 */
+    static const uint8_t s_low_noise_and_low_spur_modes;
+    static const uint8_t s_muxout;
+    static const uint8_t s_reference_doubler;
+    static const uint8_t s_rdiv2;
+    uint16_t d_10_bit_r_counter;
+    static const uint8_t s_double_buff;
+    static const uint8_t s_charge_pump_setting;
+    static const uint8_t s_ldf;
+    static const uint8_t s_ldp;
+    static const uint8_t s_pd_polarity;
+    static const uint8_t s_power_down;
+    static const uint8_t s_cp_three_state;
+    static const uint8_t s_counter_reset;
+    /* reg 3 */
+    static const uint8_t s_csr;
+    static const uint8_t s_clk_div_mode;
+    static const uint16_t s_12_bit_clock_divider_value;
+    /* reg 4 */
+    static const uint8_t s_feedback_select;
+    uint8_t d_divider_select;
+    uint8_t d_8_bit_band_select_clock_divider_value;
+    static const uint8_t s_vco_power_down;
+    static const uint8_t s_mtld;
+    static const uint8_t s_aux_output_select;
+    static const uint8_t s_aux_output_enable;
+    static const uint8_t s_aux_output_power;
+    static const uint8_t s_rf_output_enable;
+    static const uint8_t s_output_power;
+    /* reg 5 */
+    static const uint8_t s_ld_pin_mode;
+};
+
+#endif /* ADF4350_REGS_H */
diff --git a/usrp/host/lib/db_xcvr2450.cc b/usrp/host/lib/db_xcvr2450.cc
new file mode 100644 (file)
index 0000000..ce9d1f4
--- /dev/null
@@ -0,0 +1,795 @@
+//
+// Copyright 2008,2009 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 asversion 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.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/db_xcvr2450.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <boost/thread.hpp>
+#include <boost/weak_ptr.hpp>
+#include <cstdio>
+
+#if 0
+#define LO_OFFSET 4.25e6
+#else
+#define LO_OFFSET 0
+#define NO_LO_OFFSET
+#endif
+
+
+/* ------------------------------------------------------------------------
+ *  A few comments about the XCVR2450:
+ *
+ * It is half-duplex.  I.e., transmit and receive are mutually exclusive.
+ * There is a single LO for both the Tx and Rx sides.
+ * For our purposes the board is always either receiving or transmitting.
+ *
+ * Each board is uniquely identified by the *USRP hardware* instance and side
+ * This dictionary holds a weak reference to existing board controller so it
+ * can be created or retrieved as needed.
+ */
+
+
+
+// TX IO Pins
+#define HB_PA_OFF      (1 << 15)    // 5GHz PA, 1 = off, 0 = on
+#define LB_PA_OFF      (1 << 14)    // 2.4GHz PA, 1 = off, 0 = on
+#define ANTSEL_TX1_RX2 (1 << 13)    // 1 = Ant 1 to TX, Ant 2 to RX
+#define ANTSEL_TX2_RX1 (1 << 12)    // 1 = Ant 2 to TX, Ant 1 to RX
+#define TX_EN          (1 << 11)    // 1 = TX on, 0 = TX off
+#define AD9515DIV      (1 << 4)     // 1 = Div  by 3, 0 = Div by 2
+
+#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV
+#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV
+
+// RX IO Pins
+#define LOCKDET (1 << 15)           // This is an INPUT!!!
+#define EN      (1 << 14)
+#define RX_EN   (1 << 13)           // 1 = RX on, 0 = RX off
+#define RX_HP   (1 << 12)
+#define RX_OE_MASK EN|RX_EN|RX_HP
+#define RX_SAFE_IO EN
+
+struct xcvr2450_key {
+  std::string serial_no;
+  int which;
+
+  bool operator==(const xcvr2450_key &x){
+    return x.serial_no ==serial_no && x.which == which;
+  }
+};
+
+class xcvr2450
+{
+private:
+  usrp_basic *d_raw_usrp;
+  int d_which;
+
+  bool d_is_shutdown;
+  int d_spi_format, d_spi_enable;
+  
+  int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig;
+  int d_cp_current, d_ref_div, d_rssi_hbw;
+  int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser;
+  int d_rssi_range, d_rssi_mode, d_rssi_mux;
+  int d_rx_hp_pin, d_rx_hpf, d_rx_ant;
+  int d_tx_ant, d_txvga_ser, d_tx_driver_lin;
+  int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain;
+  int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain;
+  int d_rx_rf_gain, d_rx_bb_gain;
+
+  int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll;
+  int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain;
+  int d_reg_pabias, d_reg_rxgain, d_reg_txgain;
+
+  int d_ad9515_div;
+
+  void _set_rfagc(float gain);
+  void _set_ifagc(float gain);
+  void _set_pga(float pga_gain);
+
+public:
+  usrp_basic *usrp(){
+    return d_raw_usrp;
+  }
+
+  xcvr2450(usrp_basic_sptr usrp, int which);
+  ~xcvr2450();
+  void shutdown();
+
+  void set_reg_standby();
+  
+  // Integer-Divider Ratio (3)
+  void set_reg_int_divider();
+  
+  // Fractional-Divider Ratio (4)
+  void set_reg_frac_divider();
+  
+  // Band Select and PLL (5)
+  void set_reg_bandselpll();
+  
+  // Calibration (6)
+  void set_reg_cal();
+
+  // Lowpass Filter (7)
+  void set_reg_lpf();
+  
+  // Rx Control/RSSI (8)
+  void set_reg_rxrssi_ctrl();
+  
+  // Tx Linearity/Baseband Gain (9)
+  void set_reg_txlin_gain();
+  
+  // PA Bias DAC (10)
+  void set_reg_pabias();
+  
+  // Rx Gain (11)
+  void set_reg_rxgain();
+  
+  // Tx Gain (12)
+  void set_reg_txgain();
+  
+  // Send register write to SPI
+  void send_reg(int v);
+
+  void set_gpio();
+  bool lock_detect();
+  bool set_rx_gain(float gain);
+  bool set_tx_gain(float gain);
+
+  struct freq_result_t set_freq(double target_freq);
+};
+
+
+/*****************************************************************************/
+
+
+xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which)
+  : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false)
+{
+  // Handler for Tv Rx daughterboards.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+  // Use MSB with no header
+  d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  // Sane defaults
+  d_mimo = 1;          // 0 = OFF, 1 = ON
+  d_int_div = 192;     // 128 = min, 255 = max
+  d_frac_div = 0;      // 0 = min, 65535 = max
+  d_highband = 0;      // 0 = freq <= 5.4e9, 1 = freq > 5.4e9
+  d_five_gig = 0;      // 0 = freq <= 3.e9, 1 = freq > 3e9
+  d_cp_current = 1;    // 0 = 2mA, 1 = 4mA
+  d_ref_div = 1;       // 1 to 7
+  d_rssi_hbw = 0;      // 0 = 2 MHz, 1 = 6 MHz
+  d_txlpf_bw = 1;      // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz
+  d_rxlpf_bw = 1;      // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz
+  d_rxlpf_fine = 2;    // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110%
+  d_rxvga_ser = 1;     // 0 = RXVGA controlled by B7:1, 1=controlled serially
+  d_rssi_range = 1;    // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V) 
+  d_rssi_mode = 1;     // 0 = enable follows RXHP, 1 = enabled
+  d_rssi_mux = 0;      // 0 = RSSI, 1 = TEMP
+  d_rx_hp_pin = 0;     // 0 = Fc set by rx_hpf, 1 = 600 KHz
+  d_rx_hpf = 0;        // 0 = 100Hz, 1 = 30KHz
+  d_rx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
+  d_tx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
+  d_txvga_ser = 1;     // 0 = TXVGA controlled by B6:1, 1=controlled serially
+  d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_vga_lin = 2;    // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_bb_gain = 3;    // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max
+  d_pabias_delay = 15; // 0 = 0, 15 = 7uS
+  d_pabias = 0;        // 0 = 0 uA, 63 = 315uA
+  d_rx_rf_gain = 0;    // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB
+  d_rx_bb_gain = 16;   // 0 = min, 31 = max (0 - 62 dB)
+
+  d_txgain = 63;       // 0 = min, 63 = max
+
+  // Initialize GPIO and ATR  
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+
+  // Initialize chipset
+  // TODO: perform reset sequence to ensure power up defaults
+  set_reg_standby();
+  set_reg_bandselpll();
+  set_reg_cal();
+  set_reg_lpf();
+  set_reg_rxrssi_ctrl();
+  set_reg_txlin_gain();
+  set_reg_pabias();
+  set_reg_rxgain();
+  set_reg_txgain();
+  //FIXME: set_freq(2.45e9);
+}
+
+xcvr2450::~xcvr2450()
+{
+  //printf("xcvr2450::destructor\n");
+  shutdown();
+}
+
+void
+xcvr2450::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+  }
+}
+
+
+void
+xcvr2450::set_reg_standby()
+{
+  d_reg_standby = ((d_mimo<<17) | 
+                  (1<<16)      | 
+                  (1<<6)       | 
+                  (1<<5)       | 
+                  (1<<4)       | 2);
+  send_reg(d_reg_standby);
+}
+
+void
+xcvr2450::set_reg_int_divider()
+{
+  d_reg_int_divider = (((d_frac_div & 0x03)<<16) | 
+                      (d_int_div<<4)            | 3);
+  send_reg(d_reg_int_divider);
+}
+
+void
+xcvr2450::set_reg_frac_divider()
+{
+  d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4;
+  send_reg(d_reg_frac_divider);
+}
+        
+void
+xcvr2450::set_reg_bandselpll()
+{
+  d_reg_bandselpll = ((d_mimo<<17)      |
+                     (1<<16)           |
+                     (1<<15)           |
+                     (0<<11)           |
+                     (d_highband<<10)  |
+                     (d_cp_current<<9) |
+                     (d_ref_div<<5)    |
+                     (d_five_gig<<4)   | 5);
+  send_reg(d_reg_bandselpll);
+  d_reg_bandselpll = ((d_mimo<<17)      |
+                     (1<<16)           |
+                     (1<<15)           |
+                     (1<<11)           |
+                     (d_highband<<10)  |
+                     (d_cp_current<<9) |
+                     (d_ref_div<<5)    |
+                     (d_five_gig<<4)   | 5);
+  send_reg(d_reg_bandselpll);
+}
+     
+void
+xcvr2450::set_reg_cal()
+{
+  // FIXME do calibration
+  d_reg_cal = (1<<14)|6;
+  send_reg(d_reg_cal);
+}
+
+void
+xcvr2450::set_reg_lpf()
+{
+  d_reg_lpf = (
+            (d_rssi_hbw<<15)  |
+            (d_txlpf_bw<<9)  |
+            (d_rxlpf_bw<<7)   |
+            (d_rxlpf_fine<<4) | 7);
+  send_reg(d_reg_lpf);
+}
+
+void
+xcvr2450::set_reg_rxrssi_ctrl()
+{
+  d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16)  |
+                      (d_rssi_range<<15) |
+                      (d_rssi_mode<<14)  |
+                      (d_rssi_mux<<12)   |
+                      (1<<9)             |
+                      (d_rx_hpf<<6)      |
+                      (1<<4)             | 8);
+  send_reg(d_reg_rxrssi_ctrl);
+}
+
+void
+xcvr2450::set_reg_txlin_gain()
+{
+  d_reg_txlin_gain = ((d_txvga_ser<<14)     |
+                     (d_tx_driver_lin<<12) |
+                     (d_tx_vga_lin<<10)    |
+                     (d_tx_upconv_lin<<6)  |
+                     (d_tx_bb_gain<<4)     | 9);
+  send_reg(d_reg_txlin_gain);
+}
+
+void
+xcvr2450::set_reg_pabias()
+{
+  d_reg_pabias = (
+                 (d_pabias_delay<<10) |
+                 (d_pabias<<4)        | 10);
+  send_reg(d_reg_pabias);
+}
+
+void
+xcvr2450::set_reg_rxgain()
+{
+  d_reg_rxgain = (
+                 (d_rx_rf_gain<<9) |
+                 (d_rx_bb_gain<<4) | 11);
+  send_reg(d_reg_rxgain);
+}
+
+void
+xcvr2450::set_reg_txgain()
+{
+  d_reg_txgain = (d_txgain<<4) | 12;
+  send_reg(d_reg_txgain);
+}
+
+void
+xcvr2450::send_reg(int v)
+{
+  // Send 24 bits, it keeps last 18 clocked in
+  char c[3];
+  c[0] = (char)((v >> 16) & 0xff);
+  c[1] = (char)((v >>  8) & 0xff);
+  c[2] = (char)((v & 0xff));
+  std::string s(c, 3);
+  
+  usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
+  //printf("xcvr2450: Setting reg %d to %X\n", (v&15), v);
+}
+
+// ----------------------------------------------------------------
+
+void
+xcvr2450::set_gpio()
+{
+  // We calculate four values:
+  //
+  // io_rx_while_rx: what to drive onto io_rx_* when receiving
+  // io_rx_while_tx: what to drive onto io_rx_* when transmitting
+  // io_tx_while_rx: what to drive onto io_tx_* when receiving
+  // io_tx_while_tx: what to drive onto io_tx_* when transmitting
+  //
+  // B1-B7 is ignored as gain is set serially for now.
+  
+  int rx_hp, tx_antsel, rx_antsel, tx_pa_sel;
+  if(d_rx_hp_pin)
+    rx_hp = RX_HP;
+  else
+    rx_hp = 0;
+  
+  if(d_tx_ant)
+    tx_antsel = ANTSEL_TX2_RX1;
+  else
+    tx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_rx_ant)
+    rx_antsel = ANTSEL_TX2_RX1;
+  else
+    rx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_five_gig)
+    tx_pa_sel = LB_PA_OFF;
+  else
+    tx_pa_sel = HB_PA_OFF;
+  // Reset GPIO and ATR
+  // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV);
+  usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp);
+  usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN);
+  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+
+  //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n",
+  //       io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx);
+}
+  
+
+struct freq_result_t
+xcvr2450::set_freq(double target_freq)
+{
+  struct freq_result_t args = {false, 0};
+
+  double scaler;
+
+  if(target_freq > 3e9) {
+    d_five_gig = 1;
+    d_ad9515_div = 3;
+    scaler = 4.0/5.0;
+  }
+  else {
+    d_five_gig = 0;
+    d_ad9515_div = 3;
+    scaler = 4.0/3.0;
+  }
+
+  if(target_freq > 5.408e9) {
+    d_highband = 1;
+  }
+  else {
+    d_highband = 0;
+  }
+
+  double vco_freq = target_freq*scaler;
+  double sys_clk = usrp()->fpga_master_clock_freq();  // Usually 64e6 
+  double ref_clk = sys_clk / d_ad9515_div;
+        
+  double phdet_freq = ref_clk/d_ref_div;
+  double div = vco_freq/phdet_freq;
+  d_int_div = int(floor(div));
+  d_frac_div = int((div-d_int_div)*65536.0);
+  // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler;
+  
+  //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n",
+  //    target_freq, vco_freq, d_ref_div, phdet_freq,
+  //    div, d_int_div, d_frac_div, actual_freq);
+
+  set_gpio();
+  set_reg_int_divider();
+  set_reg_frac_divider();
+  set_reg_bandselpll();
+
+  args.ok = lock_detect();
+#ifdef NO_LO_OFFSET
+  args.baseband_freq = target_freq;
+#else
+  args.baseband_freq = actual_freq;
+#endif
+
+  if(!args.ok){
+    printf("Fail %f\n", target_freq);
+  }
+  return args;
+}
+
+bool
+xcvr2450::lock_detect()
+{
+  /*
+    @returns: the value of the VCO/PLL lock detect bit.
+    @rtype: 0 or 1
+  */
+  if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) {
+    return true;
+  }
+  else {      // Give it a second chance
+    if(usrp()->common_read_io(C_RX, d_which) & LOCKDET)
+      return true;
+    else
+      return false;
+  }
+}
+
+bool
+xcvr2450::set_rx_gain(float gain)
+{
+  if(gain < 0.0) 
+    gain = 0.0;
+  if(gain > 92.0)
+    gain = 92.0;
+
+  // Split the gain between RF and baseband
+  // This is experimental, not prescribed
+  if(gain < 31.0) {
+    d_rx_rf_gain = 0;                     // 0 dB RF gain
+    rx_bb_gain = int(gain/2.0);
+  }
+  
+  if(gain >= 30.0 and gain < 60.5) {
+    d_rx_rf_gain = 2;                    // 15 dB RF gain
+    d_rx_bb_gain = int((gain-15.0)/2.0);
+  }
+  
+  if(gain >= 60.5) {
+    d_rx_rf_gain = 3;                     // 30.5 dB RF gain
+    d_rx_bb_gain = int((gain-30.5)/2.0);
+  }
+  
+  set_reg_rxgain();
+  
+  return true;
+}
+
+bool
+xcvr2450::set_tx_gain(float gain)
+{
+  if(gain < 0.0) {
+    gain = 0.0;
+  }
+  if(gain > 30.0) {
+    gain = 30.0;
+  }
+  
+  d_txgain = int((gain/30.0)*63);
+  set_reg_txgain();
+
+  return true;
+}
+
+
+/*****************************************************************************/
+
+
+struct xcvr2450_table_entry {
+  xcvr2450_key                         key;
+  boost::weak_ptr<xcvr2450>    value;
+
+  xcvr2450_table_entry(const xcvr2450_key &_key, boost::weak_ptr<xcvr2450> _value)
+    : key(_key), value(_value) {}
+};
+
+typedef std::vector<xcvr2450_table_entry> xcvr2450_table;
+
+static boost::mutex s_table_mutex;
+static xcvr2450_table s_table;
+
+static xcvr2450_sptr
+_get_or_make_xcvr2450(usrp_basic_sptr usrp, int which)
+{
+  xcvr2450_key key = {usrp->serial_number(), which};
+
+  boost::mutex::scoped_lock    guard(s_table_mutex);
+
+  for (xcvr2450_table::iterator p = s_table.begin(); p != s_table.end();){
+    if (p->value.expired())    // weak pointer is now dead
+      p = s_table.erase(p);    // erase it
+    else {
+      if (key == p->key){      // found it
+       return xcvr2450_sptr(p->value);
+      }
+      else                     
+       ++p;                    // keep looking
+    }
+  }
+
+  // We don't have the xcvr2450 we're looking for
+
+  // create a new one and stick it in the table.
+  xcvr2450_sptr r(new xcvr2450(usrp, which));
+  xcvr2450_table_entry t(key, r);
+  s_table.push_back(t);
+
+  return r;
+}
+
+
+/*****************************************************************************/
+
+
+db_xcvr2450_base::db_xcvr2450_base(usrp_basic_sptr usrp, int which)
+  : db_base(usrp, which)
+{
+  /*
+   * Abstract base class for all xcvr2450 boards.
+   * 
+   * Derive board specific subclasses from db_xcvr2450_base_{tx,rx}
+   *
+   * @param usrp: instance of usrp.source_c
+   * @param which: which side: 0 or 1 corresponding to side A or B respectively
+   * @type which: int
+   */
+  
+  d_xcvr = _get_or_make_xcvr2450(usrp, which);
+}
+
+db_xcvr2450_base::~db_xcvr2450_base()
+{
+}
+
+void
+db_xcvr2450_base::shutdown_common()
+{
+  // If the usrp_basic in the xcvr2450 is the same as the usrp_basic
+  // in the daughterboard, shutdown the xcvr now (when only one of Tx
+  // and Rx is open, this is always true).
+
+  if (d_xcvr->usrp() == usrp()){
+    //std::cerr << "db_xcvr2450_base::shutdown_common: same -> shutting down\n";
+    d_xcvr->shutdown();
+  }
+  else {
+    //std::cerr << "db_xcvr2450_base::shutdown_common: different -> ignoring\n";
+  }
+}
+
+struct freq_result_t
+db_xcvr2450_base::set_freq(double target_freq)
+{
+  /*
+   * @returns (ok, actual_baseband_freq) where:
+   * ok is True or False and indicates success or failure,
+   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+   */
+  return d_xcvr->set_freq(target_freq+d_lo_offset);
+}
+
+bool
+db_xcvr2450_base::is_quadrature()
+{
+  /*
+   * Return True if this board requires both I & Q analog channels.
+   *
+   * This bit of info is useful when setting up the USRP Rx mux register.
+   */
+   return true;
+}
+
+double
+db_xcvr2450_base::freq_min()
+{
+  return 2.4e9;
+}
+
+double
+db_xcvr2450_base::freq_max()
+{
+  return 6.0e9;
+}
+
+
+/******************************************************************************/
+
+
+db_xcvr2450_tx::db_xcvr2450_tx(usrp_basic_sptr usrp, int which)
+  : db_xcvr2450_base(usrp, which)
+{
+  set_lo_offset(LO_OFFSET);
+  //printf("db_xcvr2450_tx::db_xcvr2450_tx\n");
+}
+
+db_xcvr2450_tx::~db_xcvr2450_tx()
+{
+  shutdown();
+}
+
+void
+db_xcvr2450_tx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+float
+db_xcvr2450_tx::gain_min()
+{
+  return 0;
+}
+
+float
+db_xcvr2450_tx::gain_max()
+{
+  return 30;
+}
+
+float
+db_xcvr2450_tx::gain_db_per_step()
+{
+  return (30.0/63.0);
+}
+
+bool
+db_xcvr2450_tx::set_gain(float gain)
+{
+  return d_xcvr->set_tx_gain(gain);
+}
+
+bool
+db_xcvr2450_tx::i_and_q_swapped()
+{
+  return true;
+}
+
+
+/******************************************************************************/
+
+
+db_xcvr2450_rx::db_xcvr2450_rx(usrp_basic_sptr usrp, int which)
+  : db_xcvr2450_base(usrp, which)
+{
+  /*
+   * @param usrp: instance of usrp.source_c
+   * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+   */
+  set_lo_offset(LO_OFFSET);
+  //printf("db_xcvr2450_rx:d_xcvr_2450_rx\n");
+}
+
+db_xcvr2450_rx::~db_xcvr2450_rx()
+{
+  shutdown();
+}
+
+void
+db_xcvr2450_rx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+float
+db_xcvr2450_rx::gain_min()
+{
+  return 0.0;
+}
+
+float
+db_xcvr2450_rx::gain_max()
+{
+  return 92.0;
+}
+
+float
+db_xcvr2450_rx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool
+db_xcvr2450_rx::set_gain(float gain)
+{
+  return d_xcvr->set_rx_gain(gain);
+}
diff --git a/usrp/host/lib/dump_data.py b/usrp/host/lib/dump_data.py
new file mode 100755 (executable)
index 0000000..034586d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+import sys
+import struct
+
+fin = sys.stdin
+
+count = 0
+
+while 1:
+    s = fin.read(2)
+    if not s or len(s) != 2:
+        break
+
+    v, = struct.unpack ('H', s)
+    iv = int(v) & 0xffff
+    print "%8d  %6d  0x%04x" % (count, iv, iv)
+    count += 1
+    
+
+
diff --git a/usrp/host/lib/fusb.cc b/usrp/host/lib/fusb.cc
new file mode 100644 (file)
index 0000000..2a597b6
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb.h>
+
+// ------------------------------------------------------------------------
+//                          device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle::fusb_devhandle (libusb_device_handle *udh)
+  : d_udh (udh)
+{
+  // that's it
+};
+
+fusb_devhandle::~fusb_devhandle ()
+{
+  // nop
+}
+
+// ------------------------------------------------------------------------
+//                          end point handle
+// ------------------------------------------------------------------------
+
+fusb_ephandle::fusb_ephandle (int endpoint, bool input_p,
+                             int block_size, int nblocks)
+  : d_endpoint (endpoint), d_input_p (input_p),
+    d_block_size (block_size), d_nblocks (nblocks), d_started (false)
+{
+  // that't it
+}
+
+fusb_ephandle::~fusb_ephandle ()
+{
+  // nop
+}
diff --git a/usrp/host/lib/fusb.h b/usrp/host/lib/fusb.h
new file mode 100644 (file)
index 0000000..538ae1a
--- /dev/null
@@ -0,0 +1,138 @@
+/*  -*- c++ -*- */
+/*
+ * Copyright 2005,2009 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.
+ */
+
+#ifndef _FUSB_H_
+#define _FUSB_H_
+
+#include <usrp/libusb_types.h>
+
+struct         libusb_context;
+class   fusb_ephandle;
+
+/*!
+ * \brief abstract usb device handle
+ */
+class fusb_devhandle {
+private:
+  // NOT IMPLEMENTED
+  fusb_devhandle (const fusb_devhandle &rhs);            // no copy constructor
+  fusb_devhandle &operator= (const fusb_devhandle &rhs);  // no assignment operator
+
+protected:
+  libusb_device_handle         *d_udh;
+
+public:
+  // CREATORS
+  fusb_devhandle (libusb_device_handle *udh);
+  virtual ~fusb_devhandle ();
+
+  // MANIPULATORS
+  
+  /*!
+   * \brief return an ephandle of the correct subtype
+   */
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0) = 0;
+  
+  // ACCESSORS
+  libusb_device_handle *get_usb_dev_handle () const { return d_udh; }
+};
+
+
+/*!
+ * \brief abstract usb end point handle
+ */
+class fusb_ephandle {
+private:
+  // NOT IMPLEMENTED
+  fusb_ephandle (const fusb_ephandle &rhs);            // no copy constructor
+  fusb_ephandle &operator= (const fusb_ephandle &rhs);  // no assignment operator
+
+protected:
+  int                          d_endpoint;
+  bool                         d_input_p;
+  int                          d_block_size;
+  int                          d_nblocks;
+  bool                         d_started;
+
+public:
+  fusb_ephandle (int endpoint, bool input_p,
+                int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle ();
+
+  virtual bool start () = 0;   //!< begin streaming i/o
+  virtual bool stop () = 0;    //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes) = 0;
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes) = 0;
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion () = 0;
+
+  /*!
+   * \brief returns current block size.
+   */
+  int block_size () { return d_block_size; };
+};
+
+
+/*!
+ * \brief factory for creating concrete instances of the appropriate subtype.
+ */
+class fusb_sysconfig {
+public:
+  /*!
+   * \brief returns fusb_devhandle or throws if trouble
+   */
+  static fusb_devhandle *make_devhandle (libusb_device_handle *udh,
+                                         libusb_context *ctx = 0);
+
+  /*!
+   * \brief Returns max block size in bytes (hard limit).
+   */
+  static int max_block_size ();
+
+  /*!
+   * \brief Returns default block size in bytes.
+   */
+  static int default_block_size ();
+
+  /*!
+   * \brief Returns the default buffer size in bytes.
+   */
+  static int default_buffer_size ();
+
+};
+
+#endif /* _FUSB_H_ */
diff --git a/usrp/host/lib/fusb_darwin.cc b/usrp/host/lib/fusb_darwin.cc
new file mode 100644 (file)
index 0000000..d2966c1
--- /dev/null
@@ -0,0 +1,582 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define DO_DEBUG 0
+
+#include <usb.h>
+#include "fusb.h"
+#include "fusb_darwin.h"
+#include "darwin_libusb.h"
+#include <iostream>
+
+static const int USB_TIMEOUT = 100;    // in milliseconds
+static const UInt8 NUM_QUEUE_ITEMS = 20;
+
+fusb_devhandle_darwin::fusb_devhandle_darwin (usb_dev_handle* udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_darwin::~fusb_devhandle_darwin ()
+{
+  // nop
+}
+
+fusb_ephandle*
+fusb_devhandle_darwin::make_ephandle (int endpoint, bool input_p,
+                                     int block_size, int nblocks)
+{
+  return new fusb_ephandle_darwin (this, endpoint, input_p,
+                                  block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_darwin::fusb_ephandle_darwin (fusb_devhandle_darwin* dh,
+                                           int endpoint, bool input_p,
+                                           int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_pipeRef (0), d_transferType (0),
+    d_interfaceRef (0),  d_interface (0), d_queue (0),
+    d_buffer (0), d_bufLenBytes (0)
+{
+  d_bufLenBytes = fusb_sysconfig::max_block_size();
+
+// create circular buffer
+  d_buffer = new circular_buffer<char> (NUM_QUEUE_ITEMS * d_bufLenBytes,
+                                       !d_input_p, d_input_p);
+
+// create the queue
+  d_queue = new circular_linked_list <s_buffer_ptr> (NUM_QUEUE_ITEMS);
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    l_node->both (new s_both<s_buffer_ptr> (l_node, this));
+    s_buffer_ptr l_buf = new s_buffer (d_bufLenBytes);
+    l_node->object (l_buf);
+    l_node = d_queue->iterate_next ();
+    l_buf = NULL;
+  }
+
+  d_readRunning = new gruel::mutex ();
+  d_runThreadRunning = new gruel::mutex ();
+  d_runBlock = new gruel::condition_variable ();
+  d_readBlock = new gruel::condition_variable ();
+  d_runBlock_mutex = new gruel::mutex ();
+  d_readBlock_mutex = new gruel::mutex ();
+}
+
+fusb_ephandle_darwin::~fusb_ephandle_darwin ()
+{
+  stop ();
+
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    s_both_ptr l_both = l_node->both ();
+    delete l_both;
+    l_both = NULL;
+    l_node->both (NULL);
+    s_buffer_ptr l_buf = l_node->object ();
+    delete l_buf;
+    l_buf = NULL;
+    l_node->object (NULL);
+    l_node = d_queue->iterate_next ();
+  }
+  delete d_queue;
+  d_queue = NULL;
+  delete d_buffer;
+  d_buffer = NULL;
+  delete d_readRunning;
+  d_readRunning = NULL;
+  delete d_runThreadRunning;
+  d_runThreadRunning = NULL;
+  delete d_runBlock_mutex;
+  d_runBlock_mutex = NULL;
+  delete d_readBlock_mutex;
+  d_readBlock_mutex = NULL;
+  delete d_runBlock;
+  d_runBlock = NULL;
+  delete d_readBlock;
+  d_readBlock = NULL;
+}
+
+bool
+fusb_ephandle_darwin::start ()
+{
+  UInt8  direction, number, interval;
+  UInt16 maxPacketSize;
+
+// reset circular buffer
+  d_buffer->reset ();
+
+// reset the queue
+  d_queue->num_used (0);
+  d_queue->iterate_start ();
+  s_node_ptr l_node = d_queue->iterate_next ();
+  while (l_node) {
+    l_node->both()->set (l_node, this);
+    l_node->object()->reset ();
+    l_node->set_available ();
+    l_node = d_queue->iterate_next ();
+  }
+
+  d_pipeRef = d_transferType = 0;
+
+  usb_dev_handle* dev = d_devhandle->get_usb_dev_handle ();
+  if (! dev)
+    USB_ERROR_STR (false, -ENXIO, "fusb_ephandle_darwin::start: "
+                  "null device");
+
+  darwin_dev_handle* device = (darwin_dev_handle*) dev->impl_info;
+  if (! device)
+    USB_ERROR_STR (false, -ENOENT, "fusb_ephandle_darwin::start: "
+                  "device not initialized");
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::start: dev = " <<
+      (void*) dev << ", device = " << (void*) device << std::endl;
+  }
+
+  d_interfaceRef = device->interface;
+  if (! d_interfaceRef)
+    USB_ERROR_STR (false, -EACCES, "fusb_ephandle_darwin::start: "
+                  "interface used without being claimed");
+  d_interface = *d_interfaceRef;
+
+// get read or write pipe info (depends on "d_input_p")
+
+  if (usb_debug > 3) {
+    std::cerr << "fusb_ephandle_darwin::start d_endpoint = " << d_endpoint
+             << ", d_input_p = " << (d_input_p ? "TRUE" : "FALSE") << std::endl;
+  }
+
+  int l_endpoint = (d_input_p ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT);
+  int pipeRef = ep_to_pipeRef (device, d_endpoint | l_endpoint);
+  if (pipeRef < 0)
+    USB_ERROR_STR (false, -EINVAL, "fusb_ephandle_darwin::start "
+                  " invalid pipeRef.\n");
+
+  d_pipeRef = pipeRef;
+  d_interface->GetPipeProperties (d_interfaceRef,
+                                 d_pipeRef,
+                                 &direction,
+                                 &number,
+                                 &d_transferType,
+                                 &maxPacketSize,
+                                 &interval);
+  if (usb_debug == 3) {
+    std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write")
+             << ": ep = " << d_endpoint << ", pipeRef = " << d_pipeRef << "interface = "
+             << d_interface << ", interfaceRef = " << d_interfaceRef
+             << ", if_direction = " << direction << ", if_# = " << number
+             << ", if_interval = " << interval << ", if_maxPacketSize = "
+             << maxPacketSize << std::endl;
+  }
+
+  // set global start boolean
+  d_started = true;
+
+  // lock the runBlock mutex, before creating the run thread.
+  // this guarantees that we can control execution between these 2 threads
+  gruel::scoped_lock l (*d_runBlock_mutex);
+
+  // create the run thread, which allows OSX to process I/O separately
+  d_runThread = new gruel::thread (run_thread, this);
+
+  // wait until the run thread (and possibky read thread) are -really-
+  // going; this will unlock the mutex before waiting for a signal ()
+  d_runBlock->wait (l);
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write")
+             << " started." << std::endl;
+  }
+
+  return (true);
+}
+
+void
+fusb_ephandle_darwin::run_thread (void* arg)
+{
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+
+  // lock the run thread running mutex; if ::stop() is called, it will
+  // first abort() the pipe then wait for the run thread to finish,
+  // via a lock() on this mutex
+  gruel::mutex* l_runThreadRunning = This->d_runThreadRunning;
+  gruel::scoped_lock l0 (*l_runThreadRunning);
+
+  gruel::mutex* l_readRunning = This->d_readRunning;
+  gruel::condition_variable* l_readBlock = This->d_readBlock;
+  gruel::mutex* l_readBlock_mutex = This->d_readBlock_mutex;
+
+  bool l_input_p = This->d_input_p;
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::run_thread: starting for "
+             << (l_input_p ? "read" : "write") << "." << std::endl;
+  }
+
+  usb_interface_t** l_interfaceRef = This->d_interfaceRef;
+  usb_interface_t* l_interface = This->d_interface;
+  CFRunLoopSourceRef l_cfSource;
+
+// create async run loop
+  l_interface->CreateInterfaceAsyncEventSource (l_interfaceRef, &l_cfSource);
+  CFRunLoopAddSource (CFRunLoopGetCurrent (), l_cfSource,
+                     kCFRunLoopDefaultMode);
+// get run loop reference, to allow other threads to stop
+  This->d_CFRunLoopRef = CFRunLoopGetCurrent ();
+
+  gruel::thread* l_rwThread = NULL;
+
+  if (l_input_p) {
+    // lock the readBlock mutex, before creating the read thread.
+    // this guarantees that we can control execution between these 2 threads
+    gruel::scoped_lock l1 (*l_readBlock_mutex);
+    // create the read thread, which just issues all of the starting
+    // async read commands, then returns
+    l_rwThread = new gruel::thread (read_thread, arg);
+    // wait until the the read thread is -really- going; this will
+    // unlock the read block mutex before waiting for a signal ()
+    l_readBlock->wait (l1);
+  }
+
+  {
+    // now signal the run condition to release and finish ::start().
+
+    // lock the runBlock mutex first; this will force waiting until the
+    // ->wait() command is issued in ::start()
+    gruel::mutex* l_run_block_mutex = This->d_runBlock_mutex;
+    gruel::scoped_lock l2 (*l_run_block_mutex);
+
+    // now that the lock is in place, signal the parent thread that
+    // things are running
+    This->d_runBlock->notify_one ();
+  }
+
+  // run the loop
+  CFRunLoopRun ();
+
+  if (l_input_p) {
+    // wait for read_thread () to finish, if needed
+    gruel::scoped_lock l3 (*l_readRunning);
+  }
+
+  // remove run loop stuff
+  CFRunLoopRemoveSource (CFRunLoopGetCurrent (),
+                        l_cfSource, kCFRunLoopDefaultMode);
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::run_thread: finished for "
+             << (l_input_p ? "read" : "write") << "." << std::endl;
+  }
+}
+
+void
+fusb_ephandle_darwin::read_thread (void* arg)
+{
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::read_thread: starting." << std::endl;
+  }
+
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+
+  // before doing anything else, lock the read running mutex.  this
+  // mutex does flow control between this thread and the run_thread
+  gruel::mutex* l_readRunning = This->d_readRunning;
+  gruel::scoped_lock l0 (*l_readRunning);
+
+  // signal the read condition from run_thread() to continue
+
+  // lock the readBlock mutex first; this will force waiting until the
+  // ->wait() command is issued in ::run_thread()
+  gruel::condition_variable* l_readBlock = This->d_readBlock;
+  gruel::mutex* l_read_block_mutex = This->d_readBlock_mutex;
+
+  {
+    gruel::scoped_lock l1 (*l_read_block_mutex);
+
+    // now that the lock is in place, signal the parent thread that
+    // things are running here
+    l_readBlock->notify_one ();
+  }
+
+  // queue up all of the available read requests
+  s_queue_ptr l_queue = This->d_queue;
+  l_queue->iterate_start ();
+  s_node_ptr l_node = l_queue->iterate_next ();
+  while (l_node) {
+    This->read_issue (l_node->both ());
+    l_node = l_queue->iterate_next ();
+  }
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::read_thread: finished." << std::endl;
+  }
+}
+
+void
+fusb_ephandle_darwin::read_issue (s_both_ptr l_both)
+{
+  if ((! l_both) || (! d_started)) {
+    if (usb_debug > 4) {
+      std::cerr << "fusb_ephandle_darwin::read_issue: Doing nothing; "
+               << "l_both is " << (void*) l_both << "; started is "
+               << (d_started ? "TRUE" : "FALSE") << std::endl;
+    }
+    return;
+  }
+
+// set the node and buffer from the input "both"
+  s_node_ptr l_node = l_both->node ();
+  s_buffer_ptr l_buf = l_node->object ();
+  void* v_buffer = (void*) l_buf->buffer ();
+
+// read up to d_bufLenBytes
+  size_t bufLen = d_bufLenBytes;
+  l_buf->n_used (bufLen);
+
+// setup system call result
+  io_return_t result = kIOReturnSuccess;
+
+  if (d_transferType == kUSBInterrupt)
+/* This is an interrupt pipe. We can't specify a timeout. */
+    result = d_interface->ReadPipeAsync
+      (d_interfaceRef, d_pipeRef, v_buffer, bufLen,
+       (IOAsyncCallback1) read_completed, (void*) l_both);
+  else
+    result = d_interface->ReadPipeAsyncTO
+      (d_interfaceRef, d_pipeRef, v_buffer, bufLen, 0, USB_TIMEOUT,
+       (IOAsyncCallback1) read_completed, (void*) l_both);
+
+  if (result != kIOReturnSuccess)
+    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
+                         "fusb_ephandle_darwin::read_issue "
+                         "(ReadPipeAsync%s): %s",
+                         d_transferType == kUSBInterrupt ? "" : "TO",
+                         darwin_error_str (result));
+  else if (usb_debug > 4) {
+    std::cerr << "fusb_ephandle_darwin::read_issue: Queued " << (void*) l_both
+             << " (" << bufLen << " Bytes)" << std::endl;
+  }
+}
+
+void
+fusb_ephandle_darwin::read_completed (void* refCon,
+                                     io_return_t result,
+                                     void* io_size)
+{
+  size_t l_size = (size_t) io_size;
+  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
+  s_node_ptr l_node = l_both->node ();
+  circular_buffer<char>* l_buffer = This->d_buffer;
+  s_buffer_ptr l_buf = l_node->object ();
+  size_t l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size)) {
+    std::cerr << "fusb_ephandle_darwin::read_completed: Expected " << l_i_size
+             << " bytes; read " << l_size << "." << std::endl;
+  } else if (usb_debug > 4) {
+    std::cerr << "fusb_ephandle_darwin::read_completed: Read " << (void*) l_both
+             << " (" << l_size << " bytes)" << std::endl;
+  }
+
+// add this read to the transfer buffer, and check for overflow
+// -> data is being enqueued faster than it can be dequeued
+  if (l_buffer->enqueue (l_buf->buffer (), l_size) == -1) {
+// print out that there's an overflow
+    fputs ("uO", stderr);
+    fflush (stderr);
+  }
+
+// set buffer's # data to 0
+  l_buf->n_used (0);
+
+// issue another read for this "both"
+  This->read_issue (l_both);
+}
+
+int
+fusb_ephandle_darwin::read (void* buffer, int nbytes)
+{
+  size_t l_nbytes = (size_t) nbytes;
+  d_buffer->dequeue ((char*) buffer, &l_nbytes);
+
+  if (usb_debug > 4) {
+    std::cerr << "fusb_ephandle_darwin::read: request for " << nbytes
+             << " bytes, " << l_nbytes << " bytes retrieved." << std::endl;
+  }
+
+  return ((int) l_nbytes);
+}
+
+int
+fusb_ephandle_darwin::write (const void* buffer, int nbytes)
+{
+  size_t l_nbytes = (size_t) nbytes;
+
+  if (! d_started) {
+    if (usb_debug) {
+      std::cerr << "fusb_ephandle_darwin::write: Not yet started." << std::endl;
+    }
+    return (0);
+  }
+
+  while (l_nbytes != 0) {
+// find out how much data to copy; limited to "d_bufLenBytes" per node
+    size_t t_nbytes = (l_nbytes > d_bufLenBytes) ? d_bufLenBytes : l_nbytes;
+
+// get next available node to write into;
+// blocks internally if none available
+    s_node_ptr l_node = d_queue->find_next_available_node ();
+
+// copy the input into the node's buffer
+    s_buffer_ptr l_buf = l_node->object ();
+    l_buf->buffer ((char*) buffer, t_nbytes);
+    void* v_buffer = (void*) l_buf->buffer ();
+
+// setup callback parameter & system call return
+    s_both_ptr l_both = l_node->both ();
+    io_return_t result = kIOReturnSuccess;
+
+    if (d_transferType == kUSBInterrupt)
+/* This is an interrupt pipe ... can't specify a timeout. */
+      result = d_interface->WritePipeAsync
+       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes,
+        (IOAsyncCallback1) write_completed, (void*) l_both);
+    else
+      result = d_interface->WritePipeAsyncTO
+       (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes, 0, USB_TIMEOUT,
+        (IOAsyncCallback1) write_completed, (void*) l_both);
+
+    if (result != kIOReturnSuccess)
+      USB_ERROR_STR (-1, - darwin_to_errno (result),
+                    "fusb_ephandle_darwin::write_thread "
+                    "(WritePipeAsync%s): %s",
+                    d_transferType == kUSBInterrupt ? "" : "TO",
+                    darwin_error_str (result));
+    else if (usb_debug > 4) {
+      std::cerr << "fusb_ephandle_darwin::write_thread: Queued " << (void*) l_both
+               << " (" << t_nbytes << " Bytes)" << std::endl;
+    }
+    l_nbytes -= t_nbytes;
+  }
+
+  return (nbytes);
+}
+
+void
+fusb_ephandle_darwin::write_completed (void* refCon,
+                                      io_return_t result,
+                                      void* io_size)
+{
+  s_both_ptr l_both = static_cast<s_both_ptr>(refCon);
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(l_both->This ());
+  size_t l_size = (size_t) io_size;
+  s_node_ptr l_node = l_both->node ();
+  s_queue_ptr l_queue = This->d_queue;
+  s_buffer_ptr l_buf = l_node->object ();
+  size_t l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size)) {
+    std::cerr << "fusb_ephandle_darwin::write_completed: Expected " << l_i_size
+             << " bytes written; wrote " << l_size << "." << std::endl;
+  } else if (usb_debug > 4) {
+    std::cerr << "fusb_ephandle_darwin::write_completed: Wrote " << (void*) l_both
+             << " (" << l_size << " Bytes)" << std::endl;
+  }
+
+// set buffer's # data to 0
+  l_buf->n_used (0);
+// make the node available for reuse
+  l_queue->make_node_available (l_node);
+}
+
+void
+fusb_ephandle_darwin::abort ()
+{
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::abort: starting." << std::endl;
+  }
+
+  io_return_t result = d_interface->AbortPipe (d_interfaceRef, d_pipeRef);
+
+  if (result != kIOReturnSuccess)
+    USB_ERROR_STR_NO_RET (- darwin_to_errno (result),
+                         "fusb_ephandle_darwin::abort "
+                         "(AbortPipe): %s", darwin_error_str (result));
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::abort: finished." << std::endl;
+  }
+}
+
+bool
+fusb_ephandle_darwin::stop ()
+{
+  if (! d_started)
+    return (true);
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::stop: stopping "
+             << (d_input_p ? "read" : "write") << "." << std::endl;
+  }
+
+  d_started = false;
+
+// abort any pending IO transfers
+  abort ();
+
+// wait for write transfer to finish
+  wait_for_completion ();
+
+// tell IO buffer to abort any waiting conditions
+  d_buffer->abort ();
+
+// stop the run loop
+  CFRunLoopStop (d_CFRunLoopRef);
+
+// wait for the runThread to stop
+  gruel::scoped_lock l (*d_runThreadRunning);
+
+  if (usb_debug) {
+    std::cerr << "fusb_ephandle_darwin::stop: " << (d_input_p ? "read" : "write")
+             << " stopped." << std::endl;
+  }
+
+  return (true);
+}
+
+void
+fusb_ephandle_darwin::wait_for_completion ()
+{
+  if (d_queue)
+    while (d_queue->in_use ())
+      usleep (1000);
+}
diff --git a/usrp/host/lib/fusb_darwin.h b/usrp/host/lib/fusb_darwin.h
new file mode 100644 (file)
index 0000000..4d18177
--- /dev/null
@@ -0,0 +1,218 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifndef _FUSB_DARWIN_H_
+#define _FUSB_DARWIN_H_
+
+#include <usb.h>
+#include "fusb.h"
+#include <IOKit/IOCFBundle.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <IOKit/IOKitLib.h>
+#include "circular_linked_list.h"
+#include "circular_buffer.h"
+
+// for MacOS X 10.4.[0-3]
+#define usb_interface_t IOUSBInterfaceInterface220
+#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
+#define InterfaceVersion 220
+
+// for MacOS X 10.3.[0-9] and 10.4.[0-3]
+#define usb_device_t    IOUSBDeviceInterface197
+#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
+#define DeviceVersion 197
+
+extern "C" {
+typedef struct usb_dev_handle {
+  int fd;
+
+  struct usb_bus *bus;
+  struct usb_device *device;
+
+  int config;
+  int interface;
+  int altsetting;
+
+  /* Added by RMT so implementations can store other per-open-device data */
+  void *impl_info;
+} usb_dev_handle;
+
+/* Darwin/OS X impl does not use fd field, instead it uses this */
+typedef struct darwin_dev_handle {
+  usb_device_t** device;
+  usb_interface_t** interface;
+  int open;
+} darwin_dev_handle;
+
+typedef IOReturn io_return_t;
+typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
+
+static int ep_to_pipeRef (darwin_dev_handle* device, int ep);
+extern int usb_debug;
+}
+
+class s_buffer
+{
+private:
+  char* d_buffer;
+  size_t d_n_used, d_n_alloc;
+
+public:
+  inline s_buffer (size_t n_alloc = 0) {
+    d_n_used = 0;
+    d_n_alloc = n_alloc;
+    if (n_alloc) {
+      d_buffer = (char*) new char [n_alloc];
+    } else {
+      d_buffer = 0;
+    }
+  };
+  inline ~s_buffer () {
+    if (d_n_alloc) {
+      delete [] d_buffer;
+    }
+  };
+  inline size_t n_used () { return (d_n_used); };
+  inline void n_used (size_t bufLen) {
+    d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; };
+  inline size_t n_alloc () { return (d_n_alloc); };
+  void buffer (char* l_buffer, size_t bufLen) {
+    if (bufLen > d_n_alloc) {
+      std::cerr << "s_buffer::set: Copying only allocated bytes." << std::endl;
+      bufLen = d_n_alloc;
+    }
+    if (!l_buffer) {
+      std::cerr << "s_buffer::set: NULL buffer." << std::endl;
+      return;
+    }
+    bcopy (l_buffer, d_buffer, bufLen);
+    d_n_used = bufLen;
+  };
+  inline char* buffer () { return (d_buffer); };
+  inline void reset () {
+    bzero (d_buffer, d_n_alloc);
+    d_n_used = 0;
+  };
+};
+
+typedef s_buffer* s_buffer_ptr;
+typedef s_node<s_buffer_ptr>* s_node_ptr;
+typedef circular_linked_list<s_buffer_ptr>* s_queue_ptr;
+typedef s_both<s_buffer_ptr>* s_both_ptr;
+
+/*!
+ * \brief darwin implementation of fusb_devhandle
+ *
+ * This is currently identical to the generic implementation
+ * and is intended as a starting point for whatever magic is
+ * required to make usb fly.
+ */
+class fusb_devhandle_darwin : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_darwin (usb_dev_handle* udh);
+  virtual ~fusb_devhandle_darwin ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle* make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+/*!
+ * \brief darwin implementation of fusb_ephandle
+ *
+ * This is currently identical to the generic implementation
+ * and is intended as a starting point for whatever magic is
+ * required to make usb fly.
+ */
+class fusb_ephandle_darwin : public fusb_ephandle
+{
+private:
+  fusb_devhandle_darwin* d_devhandle;
+  gruel::thread* d_runThread;
+  gruel::mutex* d_runThreadRunning;
+
+  CFRunLoopRef d_CFRunLoopRef;
+
+  static void write_completed (void* ret_io_size,
+                              io_return_t result,
+                              void* io_size);
+  static void read_completed (void* ret_io_size,
+                             io_return_t result,
+                             void* io_size);
+  static void run_thread (void* arg);
+  static void read_thread (void* arg);
+
+  void read_issue (s_both_ptr l_both);
+
+public:
+  // variables, for now
+  UInt8 d_pipeRef, d_transferType;
+  usb_interface_t** d_interfaceRef;
+  usb_interface_t* d_interface;
+  s_queue_ptr d_queue;
+  circular_buffer<char>* d_buffer;
+  size_t d_bufLenBytes;
+  gruel::mutex* d_readRunning;
+  gruel::mutex* d_runBlock_mutex;
+  gruel::mutex* d_readBlock_mutex;
+  gruel::condition_variable* d_runBlock;
+  gruel::condition_variable* d_readBlock;
+
+// CREATORS
+
+  fusb_ephandle_darwin (fusb_devhandle_darwin *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_darwin ();
+
+// MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void* buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void* buffer, int nbytes);
+
+  /*
+   * abort any pending IO transfers
+   */
+  void abort ();
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_DARWIN_H_ */
diff --git a/usrp/host/lib/fusb_generic.cc b/usrp/host/lib/fusb_generic.cc
new file mode 100644 (file)
index 0000000..0958716
--- /dev/null
@@ -0,0 +1,108 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_generic.h>
+#include <usb.h>
+
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+
+fusb_devhandle_generic::fusb_devhandle_generic (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_generic::~fusb_devhandle_generic ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_generic::make_ephandle (int endpoint, bool input_p,
+                                      int block_size, int nblocks)
+{
+  return new fusb_ephandle_generic (this, endpoint, input_p,
+                                   block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_generic::fusb_ephandle_generic (fusb_devhandle_generic *dh,
+                                             int endpoint, bool input_p,
+                                             int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh)
+{
+  // that's it
+}
+
+fusb_ephandle_generic::~fusb_ephandle_generic ()
+{
+  // nop
+}
+
+bool
+fusb_ephandle_generic::start ()
+{
+  d_started = true;
+  return true;
+}
+
+bool
+fusb_ephandle_generic::stop ()
+{
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_generic::write (const void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+  
+  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
+                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
+}
+
+int
+fusb_ephandle_generic::read (void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
+                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
+                       USB_TIMEOUT);
+}
diff --git a/usrp/host/lib/fusb_generic.h b/usrp/host/lib/fusb_generic.h
new file mode 100644 (file)
index 0000000..b9aef27
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+#ifndef _FUSB_GENERIC_H_
+#define _FUSB_GENERIC_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief generic implementation of fusb_devhandle using only libusb
+ */
+class fusb_devhandle_generic : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_generic (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_generic ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief generic implementation of fusb_ephandle using only libusb
+ */
+class fusb_ephandle_generic : public fusb_ephandle
+{
+private:
+  fusb_devhandle_generic       *d_devhandle;
+  
+public:
+  // CREATORS
+  fusb_ephandle_generic (fusb_devhandle_generic *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_generic ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion () { };
+};
+
+#endif /* _FUSB_GENERIC_H_ */
+
diff --git a/usrp/host/lib/fusb_libusb1.cc b/usrp/host/lib/fusb_libusb1.cc
new file mode 100644 (file)
index 0000000..7707084
--- /dev/null
@@ -0,0 +1,702 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_libusb1.h>
+#include <fusb.h>
+#include <libusb-1.0/libusb.h>
+#include <stdexcept>
+#include <cstdio>
+#include <assert.h>
+#include <string.h>
+#include <algorithm>
+#include <errno.h>
+#include <string.h>
+
+#define MINIMIZE_TX_BUFFERING true
+
+static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();
+static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
+static const int DEFAULT_BUFFER_SIZE = 4 * (1L << 20);  // 4 MB endpoint
+static const int LIBUSB_TIMEOUT = 0;                   // no timeout
+
+inline static fusb_ephandle_libusb1 *
+lut_get_ephandle (libusb_transfer *lut)
+{
+  return (fusb_ephandle_libusb1 *) lut->user_data;
+}
+
+// ------------------------------------------------------------------------
+//     libusb_transfer allocation, deallocation, and callback
+// ------------------------------------------------------------------------
+
+static void
+free_lut (libusb_transfer *lut)
+{
+
+  // if this was an input transfer, free the buffer
+  if (lut->endpoint & 0x80)
+    delete [] ((unsigned char *) lut->buffer);
+
+  libusb_free_transfer(lut);
+
+}
+
+/*
+ * The callback means the libusb_transfer is completed whether sent, cancelled,
+ * or failed. Move the libusb_transfer from the pending list to the
+ * completed list. If the cancel is from the destructor then free the
+ * transfer instead; normally this won't happen since all endpoints should be
+ * destroyed first leaving the pending list empty.
+ */
+
+static void
+generic_callback(struct libusb_transfer *lut)
+{
+
+  // Fish out devhandle from endpoint
+  fusb_devhandle_libusb1* dev_handle =
+    lut_get_ephandle(lut)->get_fusb_devhandle_libusb1();
+
+  dev_handle->pending_remove(lut);
+
+  if (lut->status == LIBUSB_TRANSFER_CANCELLED && dev_handle->_teardown() == 1)
+  {
+    free_lut (lut);
+    return;
+  }
+
+  lut_get_ephandle(lut)->completed_list_add(lut);
+
+}
+
+static libusb_transfer*
+alloc_lut (fusb_ephandle_libusb1 *self, int buffer_length, int endpoint,
+           bool input_p, unsigned char *write_buffer,
+           fusb_devhandle_libusb1 *dh)
+{
+
+  struct libusb_transfer* lut = libusb_alloc_transfer(0);
+
+  endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0);
+
+  if (input_p)
+    write_buffer = new unsigned char [buffer_length];
+
+  // We need the base class libusb_device_handle
+  libusb_device_handle *dev_handle = dh->get_usb_dev_handle();
+
+  // Load the libusb_transfer for bulk transfer
+  libusb_fill_bulk_transfer (lut,              // transfer
+                             dev_handle,        // dev_handle
+                             endpoint,         // endpoint
+                             write_buffer,     // buffer
+                             buffer_length,    // length
+                             generic_callback, // callback
+                             self,             // user_data
+                             LIBUSB_TIMEOUT);  // timeout
+
+  return lut;
+}
+
+// ------------------------------------------------------------------------
+//                             device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle_libusb1::fusb_devhandle_libusb1 (libusb_device_handle *udh,
+                                                libusb_context *ctx)
+  : fusb_devhandle (udh), d_ctx (ctx), d_teardown (false)
+{
+  // that's it
+}
+
+fusb_devhandle_libusb1::~fusb_devhandle_libusb1 ()
+{
+  d_teardown = true;
+
+  std::list<libusb_transfer*>::reverse_iterator it;
+
+  // After cancellation the libusb_transfer is still active so delay freeing
+  // transfer until callback occurs. In most cases the pending list should
+  // already be empty by the time this destructor is called.
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++) {
+    _cancel_lut (*it);
+  }
+
+  // Wait for pending list to empty
+  _wait_for_completion ();
+
+}
+
+fusb_ephandle*
+fusb_devhandle_libusb1::make_ephandle (int endpoint, bool input_p,
+                                      int block_size, int nblocks)
+{
+  return new fusb_ephandle_libusb1 (this, endpoint, input_p,
+                                   block_size, nblocks);
+}
+
+/*
+ * devhandle list manipulators
+ */
+
+void
+fusb_devhandle_libusb1::pending_add (libusb_transfer *lut)
+{
+  d_pending_rqsts.push_back (lut);
+}
+
+
+/*
+ * Attempt to cancel all transations associated with eph
+ */
+
+void
+fusb_devhandle_libusb1::_cancel_pending_rqsts (fusb_ephandle_libusb1 *eph)
+{
+  std::list<libusb_transfer*>::reverse_iterator it;
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
+    if (lut_get_ephandle (*it) == eph)
+      _cancel_lut (*it);
+  }
+}
+
+/*
+ * Pull from the pending list
+ */
+
+libusb_transfer *
+fusb_devhandle_libusb1::pending_get ()
+{
+  if (d_pending_rqsts.empty ())
+    return 0;
+
+  libusb_transfer *lut = d_pending_rqsts.front ();
+  d_pending_rqsts.pop_front ();
+  return lut;
+}
+
+/*
+ * Match libusb_tranfer with the pending list and erase
+ * Return true if found, false otherwise
+ */
+
+bool
+fusb_devhandle_libusb1::pending_remove (libusb_transfer *lut)
+{
+  std::list<libusb_transfer*>::iterator        result;
+  result = find (d_pending_rqsts.begin (), d_pending_rqsts.end (), lut);
+
+  if (result == d_pending_rqsts.end ()) {
+    fprintf (stderr, "fusb::pending_remove: failed to find lut in pending_rqsts: %p\n", lut);
+
+    return false;
+  }
+  d_pending_rqsts.erase (result);
+  return true;
+}
+
+/*
+ * Submit the libusb_transfer to libusb
+ * iff successful, the transfer will be placed on the devhandle pending list.
+ */
+
+bool
+fusb_devhandle_libusb1::_submit_lut (libusb_transfer *lut)
+{
+
+  int ret = libusb_submit_transfer (lut);
+  if (ret < 0) {
+    fprintf(stderr, "fusb::_submit_lut %d", ret);
+    return false;
+  }
+
+  pending_add(lut);
+  return true;
+
+}
+
+/*
+ * Attempt to cancel any pending libusb_transfer transactions.
+ * Return true in the absence of errors, which does not mean that the transfer
+ * is cancelled. Cancellation can be checked after the callback is fired off
+ * by libusb.
+ */
+
+bool
+fusb_devhandle_libusb1::_cancel_lut (libusb_transfer *lut)
+{
+
+  int ret = libusb_cancel_transfer (lut);
+  if (ret < 0) {
+    fprintf (stderr, "fusb::_cancel_lut");
+    return false;
+  }
+  return true;
+
+}
+
+/*
+ * Reimplementing _reap for context use and compatibiliy with libusb-0.12.
+ *
+ * Returns false on timeout or error, true if an event was handled
+ *
+ * If ok_to_block_p is false then handle already pending events and return
+ * immediately.
+ *
+ * If ok_to_block_p is true then call libusb_handle_events_timeout with default
+ * timeout value of 2 seconds, which waits and returns on event arrival or
+ * timeout.
+ */
+
+bool
+fusb_devhandle_libusb1::_reap (bool ok_to_block_p)
+{
+  int ret;
+  struct timeval tv;
+
+  // Save pending size
+  int pnd_size = d_pending_rqsts.size();
+
+  if (ok_to_block_p) {
+    tv.tv_sec = 2;
+    tv.tv_usec =  0;
+  }
+  else {
+    tv.tv_sec = 0;
+    tv.tv_usec =  0;
+  }
+
+  if ((ret = libusb_handle_events_timeout(d_ctx, &tv)) < 0) {
+    fprintf (stderr, "fusb::_reap libusb_handle_events() %i\n", ret);
+    return false;
+  }
+
+  // Check that a pending transfer was removed
+  if (pnd_size > d_pending_rqsts.size())
+    return true;
+  else {
+    return false;
+  }
+}
+
+void
+fusb_devhandle_libusb1::_wait_for_completion ()
+{
+
+  while (!d_pending_rqsts.empty ())
+    if (!_reap(true))
+      break;
+
+}
+
+// ------------------------------------------------------------------------
+//                             endpoint handle
+// ------------------------------------------------------------------------
+
+fusb_ephandle_libusb1::fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh,
+                                             int endpoint, bool input_p,
+                                             int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh),
+    d_write_work_in_progress (0), d_write_buffer (0),
+    d_read_work_in_progress (0), d_read_buffer (0), d_read_buffer_end (0)
+{
+
+  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
+    throw std::out_of_range ("fusb_ephandle_libusb1: block_size");
+
+  if (d_nblocks < 0)
+    throw std::out_of_range ("fusb_ephandle_libusb1: nblocks");
+
+  if (d_block_size == 0)
+    d_block_size = DEFAULT_BLOCK_SIZE;
+
+  if (d_nblocks == 0)
+    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
+
+  if (!d_input_p)
+    if (!MINIMIZE_TX_BUFFERING)
+      d_write_buffer = new unsigned char [d_block_size];
+
+  if (0)
+    fprintf(stderr, "fusb_ephandle_libusb1::ctor: d_block_size = %d  d_nblocks = %d\n",
+      d_block_size, d_nblocks);
+
+  // allocate libusb_transfers
+  for (int i = 0; i < d_nblocks; i++)
+    d_free_list.push_back (alloc_lut (this, d_block_size, d_endpoint,
+                                      d_input_p, d_write_buffer, d_devhandle));
+}
+
+fusb_ephandle_libusb1::~fusb_ephandle_libusb1 ()
+{
+
+  stop ();
+
+  libusb_transfer *lut;
+
+  while ((lut = free_list_get ()) != 0)
+    free_lut (lut);
+
+  while ((lut = completed_list_get ()) != 0)
+    free_lut (lut);
+
+  if (d_write_work_in_progress)
+    free_lut (d_write_work_in_progress);
+
+  delete [] d_write_buffer;
+
+  if (d_read_work_in_progress)
+    free_lut (d_read_work_in_progress);
+
+}
+
+bool
+fusb_ephandle_libusb1::start ()
+{
+  if (d_started)
+    return true;
+
+  d_started = true;
+
+  if (d_input_p) {
+     libusb_transfer *lut;
+
+     int nerrors = 0;
+     while ((lut = free_list_get ()) !=0 && nerrors < d_nblocks) {
+       if (!submit_lut (lut))
+         nerrors++;
+     }
+  }
+
+  return true;
+
+}
+
+/*
+ * Cancel all transfers in progress or pending and return to initial state
+ */
+
+bool
+fusb_ephandle_libusb1::stop ()
+{
+
+  if (!d_started)
+    return true;
+
+  if (d_write_work_in_progress){
+    free_list_add (d_write_work_in_progress);
+    d_write_work_in_progress = 0;
+  }
+
+  if (d_read_work_in_progress){
+    free_list_add (d_read_work_in_progress);
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+  }
+
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+  while (1) {
+    libusb_transfer *lut;
+    while ((lut = completed_list_get ()) != 0)
+      free_list_add (lut);
+
+    if (d_free_list.size () == (unsigned) d_nblocks)
+      break;
+
+    if (!d_devhandle->_reap(true))
+      break;
+  }
+
+  d_started = false;
+
+  return true;
+}
+
+// ------------------------------------------------------------------------
+//                     routines for writing
+// ------------------------------------------------------------------------
+
+#if (MINIMIZE_TX_BUFFERING)
+
+int
+fusb_ephandle_libusb1::write (const void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (d_input_p)
+    return -1;
+
+  assert(nbytes % 512 == 0);
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    struct libusb_transfer *lut = get_write_work_in_progress();
+    if (!lut)
+      return -1;
+    assert(lut->actual_length == 0);
+    int m = std::min(nbytes - n, MAX_BLOCK_SIZE);
+    lut->buffer = src;
+    lut->length = m;
+
+    n += m;
+    src += m;
+
+    if (!submit_lut(lut))
+      return -1;
+
+    d_write_work_in_progress = 0;
+  }
+
+  return n;
+}
+
+#else
+
+int
+fusb_ephandle_libusb1::write (const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+
+  if (d_input_p)
+    return -1;
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    libusb_transfer *lut = get_write_work_in_progress ();
+    if (!lut)
+      return -1;
+    unsigned char *dst = (unsigned char *) lut->buffer;
+    int m = std::min (nbytes - n, lut->length - lut->actual_length);
+
+    memcpy (&dst[lut->actual_length], &src[n], m);
+    lut->actual_length += m;
+    n += m;
+
+    if (lut->actual_length == lut->length){
+      if (!submit_lut (lut))
+        return -1;
+      d_write_work_in_progress = 0;
+    }
+  }
+
+  return n;
+}
+
+#endif
+
+struct libusb_transfer *
+fusb_ephandle_libusb1::get_write_work_in_progress ()
+{
+  if (d_write_work_in_progress)
+    return d_write_work_in_progress;
+
+  while (1) {
+
+    reap_complete_writes ();
+
+    struct libusb_transfer *lut = free_list_get ();
+
+    if (lut != 0){
+      assert (lut->actual_length == 0);
+      d_write_work_in_progress = lut;
+      return lut;
+    }
+
+    if (!d_devhandle->_reap (true))
+      return 0;
+  }
+}
+
+void
+fusb_ephandle_libusb1::reap_complete_writes ()
+{
+  // take a look at the completed list and xfer to free list after
+  // checking for errors.
+
+  libusb_transfer *lut;
+
+  while ((lut = completed_list_get ()) != 0) {
+
+    // Check for any errors or short writes that were reporetd in the transfer.
+    // libusb1 sets status, actual_length.
+
+    if (lut->status != LIBUSB_TRANSFER_COMPLETED) {
+      fprintf (stderr, "fusb: (status %d) \n", lut->status );
+    }
+    else if (lut->actual_length != lut->length){
+      fprintf (stderr, "fusb: short write xfer: %d != %d\n",
+               lut->actual_length, lut->length);
+    }
+
+    free_list_add (lut);
+  }
+}
+
+void
+fusb_ephandle_libusb1::wait_for_completion ()
+{
+  d_devhandle->_wait_for_completion ();
+}
+
+// ------------------------------------------------------------------------
+//                     routines for reading
+// ------------------------------------------------------------------------
+
+int
+fusb_ephandle_libusb1::read (void *buffer, int nbytes)
+{
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  unsigned char *dst = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes) {
+
+    if (d_read_buffer >= d_read_buffer_end)
+      if (!reload_read_buffer ())
+        return -1;
+
+    int m = std::min (nbytes - n, (int) (d_read_buffer_end - d_read_buffer));
+
+    memcpy (&dst[n], d_read_buffer, m);
+    d_read_buffer += m;
+    n += m;
+  }
+
+  return n;
+
+}
+
+bool
+fusb_ephandle_libusb1::reload_read_buffer ()
+{
+  assert (d_read_buffer >= d_read_buffer_end);
+
+  libusb_transfer *lut;
+
+  if (d_read_work_in_progress) {
+    lut = d_read_work_in_progress;
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+    lut->actual_length = 0;
+    if (!submit_lut (lut))
+      return false;
+  }
+
+  while (1) {
+
+    while ((lut = completed_list_get ()) == 0 )
+      if (!d_devhandle->_reap(true))
+        return false;
+
+    if (lut->status != LIBUSB_TRANSFER_COMPLETED) {
+      fprintf (stderr, "fust: (rd status %d) %s\n", lut->status,
+               strerror (-lut->status));
+      lut->actual_length = 0;
+      free_list_add (lut);
+      return false;
+    }
+
+    d_read_work_in_progress = lut;
+    d_read_buffer = (unsigned char *) lut->buffer;
+    d_read_buffer_end = d_read_buffer + lut->actual_length;
+
+    return true;
+  }
+}
+
+
+/*
+ * ephandle list manipulation
+ */
+
+
+void
+fusb_ephandle_libusb1::free_list_add (libusb_transfer *lut)
+{
+  assert (lut_get_ephandle (lut) == this);
+  lut->actual_length = 0;
+  d_free_list.push_back (lut);
+}
+
+libusb_transfer *
+fusb_ephandle_libusb1::free_list_get ()
+{
+  if (d_free_list.empty ())
+    return 0;
+
+  libusb_transfer *lut = d_free_list.front ();
+  d_free_list.pop_front ();
+  return lut;
+}
+
+void
+fusb_ephandle_libusb1::completed_list_add (libusb_transfer *lut)
+{
+  assert (lut_get_ephandle (lut) == this);
+  d_completed_list.push_back (lut);
+}
+
+libusb_transfer *
+fusb_ephandle_libusb1::completed_list_get ()
+{
+  if (d_completed_list.empty ())
+    return 0;
+
+  libusb_transfer *lut = d_completed_list.front ();
+  d_completed_list.pop_front ();
+  return lut;
+}
+
+bool
+fusb_ephandle_libusb1::submit_lut (libusb_transfer *lut)
+{
+  if (!d_devhandle->_submit_lut (lut)) {
+    fprintf (stderr, "_submit_lut failed\n");
+    free_list_add (lut);
+    return false;
+  }
+  return true;
+}
diff --git a/usrp/host/lib/fusb_libusb1.h b/usrp/host/lib/fusb_libusb1.h
new file mode 100644 (file)
index 0000000..c0e3736
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 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.
+ */
+
+#ifndef _FUSB_LIBUSB1_H_
+#define _FUSB_LIBUSB1_H_
+
+#include <fusb.h>
+#include <list>
+
+struct libusb_transfer;
+struct libusb_context;
+
+class fusb_ephandle_libusb1;
+
+/*!
+ * \brief libusb1 implementation of fusb_devhandle
+ */
+class fusb_devhandle_libusb1 : public fusb_devhandle
+{
+private:
+  std::list<libusb_transfer*>   d_pending_rqsts;
+  libusb_context               *d_ctx;
+
+  void pending_add (struct libusb_transfer *lut);
+  struct libusb_transfer * pending_get ();
+
+  bool d_teardown;
+
+public:
+  // CREATORS
+  fusb_devhandle_libusb1 (libusb_device_handle *udh, libusb_context *ctx);
+  virtual ~fusb_devhandle_libusb1 ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+  // internal use only
+  bool _submit_lut (libusb_transfer *);
+  bool _cancel_lut (libusb_transfer *);
+  void _cancel_pending_rqsts (fusb_ephandle_libusb1 *eph);
+  bool _reap (bool ok_to_block_p);
+  void _wait_for_completion ();
+
+  // accessors to work from callback context
+  bool pending_remove (struct libusb_transfer *lut);
+  inline bool _teardown() { return d_teardown; }
+
+};
+
+
+/*!
+ * \brief libusb1 implementation of fusb_ephandle
+ */
+class fusb_ephandle_libusb1 : public fusb_ephandle
+{
+private:
+  fusb_devhandle_libusb1        *d_devhandle;
+  std::list<libusb_transfer*>     d_free_list;
+  std::list<libusb_transfer*>     d_completed_list;
+  libusb_transfer                *d_write_work_in_progress;
+  unsigned char                  *d_write_buffer;
+  libusb_transfer                *d_read_work_in_progress;
+  unsigned char                  *d_read_buffer;
+  unsigned char                  *d_read_buffer_end;
+
+  libusb_transfer *get_write_work_in_progress ();
+  void reap_complete_writes ();
+  bool reload_read_buffer ();
+  bool submit_lut (libusb_transfer *lut);
+
+public:
+  // CREATORS
+  fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_libusb1 ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+
+  void free_list_add (struct libusb_transfer *lut);
+  void completed_list_add (struct libusb_transfer *lut);
+  struct libusb_transfer *free_list_get ();
+  struct libusb_transfer *completed_list_get ();
+
+  // accessor to work from callback context
+  fusb_devhandle_libusb1* get_fusb_devhandle_libusb1 () const {
+    return d_devhandle;
+  }
+};
+
+#endif /* _FUSB_LINUX1_H_ */
+
diff --git a/usrp/host/lib/fusb_linux.cc b/usrp/host/lib/fusb_linux.cc
new file mode 100644 (file)
index 0000000..6c48456
--- /dev/null
@@ -0,0 +1,692 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_linux.h>
+#include <usb.h>               // libusb header
+#include <stdexcept>
+#ifdef HAVE_LINUX_COMPILER_H
+#include <linux/compiler.h>
+#endif
+#include <linux/usbdevice_fs.h>        // interface to kernel portion of user mode usb driver
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <string.h>
+#include <algorithm>
+#include <errno.h>
+#include <string.h>
+#include <cstdio>
+
+#define MINIMIZE_TX_BUFFERING 1                // must be defined to 0 or 1
+
+
+static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();            // hard limit
+static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
+static const int DEFAULT_BUFFER_SIZE = 4 * (1L << 20);                         // 4 MB / endpoint
+
+
+// Totally evil and fragile extraction of file descriptor from
+// guts of libusb.  They don't install usbi.h, which is what we'd need
+// to do this nicely.
+//
+// FIXME if everything breaks someday in the future, look here...
+
+static int
+fd_from_usb_dev_handle (usb_dev_handle *udh)
+{
+  return *((int *) udh);
+}
+
+inline static void
+urb_set_ephandle (usbdevfs_urb *urb, fusb_ephandle_linux *handle)
+{
+  urb->usercontext = handle;
+}
+
+inline static fusb_ephandle_linux *
+urb_get_ephandle (usbdevfs_urb *urb)
+{
+  return (fusb_ephandle_linux *) urb->usercontext;
+}
+
+// ------------------------------------------------------------------------
+//                USB request block (urb) allocation
+// ------------------------------------------------------------------------
+
+static usbdevfs_urb *
+alloc_urb (fusb_ephandle_linux *self, int buffer_length, int endpoint,
+          bool input_p, unsigned char *write_buffer)
+{
+  usbdevfs_urb *urb = new usbdevfs_urb;
+  memset (urb, 0, sizeof (*urb));
+
+  urb->buffer_length = buffer_length;
+
+  // We allocate dedicated memory only for input buffers.
+  // For output buffers we reuse the same buffer (the kernel 
+  // copies the data at submital time)
+
+  if (input_p)
+    urb->buffer = new unsigned char [buffer_length];
+  else
+    urb->buffer = write_buffer;
+
+  // init common values
+
+  urb->type = USBDEVFS_URB_TYPE_BULK;
+  urb->endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0);
+
+  // USBDEVFS_URB_QUEUE_BULK goes away in linux 2.5, but is needed if
+  // we are using a 2.4 usb-uhci host controller driver.  This is
+  // unlikely since we're almost always going to be plugged into a
+  // high speed host controller (ehci)
+#if 0 && defined (USBDEVFS_URB_QUEUE_BULK)
+  urb->flags = USBDEVFS_URB_QUEUE_BULK;
+#endif
+
+  urb->signr = 0;
+  urb_set_ephandle (urb, self);
+
+  return urb;
+}
+
+static void
+free_urb (usbdevfs_urb *urb)
+{
+  // if this was an input urb, free the buffer
+  if (urb->endpoint & 0x80)
+    delete [] ((unsigned char *) urb->buffer);
+
+  delete urb;
+}
+
+// ------------------------------------------------------------------------
+//                             device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle_linux::fusb_devhandle_linux (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's all
+}
+
+fusb_devhandle_linux::~fusb_devhandle_linux ()
+{
+  // if there are any pending requests, cancel them and free the urbs.
+  
+  std::list<usbdevfs_urb*>::reverse_iterator it;
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
+    _cancel_urb (*it);
+    free_urb (*it);
+  }
+}
+
+fusb_ephandle *
+fusb_devhandle_linux::make_ephandle (int endpoint, bool input_p,
+                                    int block_size, int nblocks)
+{
+  return new fusb_ephandle_linux (this, endpoint, input_p,
+                                 block_size, nblocks);
+}
+
+
+// Attempt to cancel all transactions associated with eph.
+
+void
+fusb_devhandle_linux::_cancel_pending_rqsts (fusb_ephandle_linux *eph)
+{
+  std::list<usbdevfs_urb*>::reverse_iterator it;
+
+  for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){
+    if (urb_get_ephandle (*it) == eph)
+      _cancel_urb (*it);
+  }
+}
+
+void 
+fusb_devhandle_linux::pending_add (usbdevfs_urb *urb)
+{
+  d_pending_rqsts.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_devhandle_linux::pending_get ()
+{
+  if (d_pending_rqsts.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_pending_rqsts.front ();
+  d_pending_rqsts.pop_front ();
+  return urb;
+}
+
+bool
+fusb_devhandle_linux::pending_remove (usbdevfs_urb *urb)
+{
+  std::list<usbdevfs_urb*>::iterator   result = find (d_pending_rqsts.begin (),
+                                                      d_pending_rqsts.end (),
+                                                      urb);
+  if (result == d_pending_rqsts.end ()){
+    fprintf (stderr, "fusb::pending_remove: failed to find urb in pending_rqsts: %p\n", urb);
+    return false;
+  }
+  d_pending_rqsts.erase (result);
+  return true;
+}
+
+/*
+ * Submit the urb to the kernel.
+ * iff successful, the urb will be placed on the devhandle's pending list.
+ */
+bool
+fusb_devhandle_linux::_submit_urb (usbdevfs_urb *urb)
+{
+  int  ret;
+
+  ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_SUBMITURB, urb);
+  if (ret < 0){
+    perror ("fusb::_submit_urb");
+    return false;
+  }
+  
+  pending_add (urb);
+  return true;
+}
+
+/*
+ * Attempt to cancel the in pending or in-progress urb transaction.
+ * Return true iff transaction was sucessfully cancelled.
+ *
+ * Failure to cancel should not be considered a problem.  This frequently
+ * occurs if the transaction has already completed in the kernel but hasn't
+ * yet been reaped by the user mode code.
+ *
+ * urbs which were cancelled have their status field set to -ENOENT when
+ * they are reaped.
+ */
+bool
+fusb_devhandle_linux::_cancel_urb (usbdevfs_urb *urb)
+{
+  int ret = ioctl (fd_from_usb_dev_handle (d_udh), USBDEVFS_DISCARDURB, urb);
+  if (ret < 0){
+    // perror ("fusb::_cancel_urb");
+    return false;
+  }
+  return true;
+}
+
+/*
+ * Check with the kernel and see if any of our outstanding requests
+ * have completed.  For each completed transaction, remove it from the
+ * devhandle's pending list and append it to the completed list for
+ * the corresponding endpoint.
+ *
+ * If any transactions are reaped return true.
+ *
+ * If ok_to_block_p is true, then this will block until at least one
+ * transaction completes or an unrecoverable error occurs.
+ */
+bool
+fusb_devhandle_linux::_reap (bool ok_to_block_p)
+{
+  int          ret;
+  int          nreaped = 0;
+  usbdevfs_urb *urb = 0;
+
+  int  fd = fd_from_usb_dev_handle (d_udh);
+  
+  // try to reap as many as possible without blocking...
+
+  while ((ret = ioctl (fd, USBDEVFS_REAPURBNDELAY, &urb)) == 0){
+    if (urb->status != 0 && urb->status != -ENOENT){
+      fprintf (stderr, "_reap: usb->status = %d, actual_length = %5d\n",
+              urb->status, urb->actual_length);
+    }
+    pending_remove (urb);
+    urb_get_ephandle (urb)->completed_list_add (urb);
+    nreaped++;
+  }
+
+  if (nreaped > 0)             // if we got any, return w/o blocking
+    return true;
+
+  if (!ok_to_block_p)
+    return false;
+  
+  ret = ioctl (fd, USBDEVFS_REAPURB, &urb);
+  if (ret < 0){
+    perror ("fusb::_reap");
+    return false;
+  }
+
+  pending_remove (urb);
+  urb_get_ephandle (urb)->completed_list_add (urb);
+  return true;
+}
+
+void
+fusb_devhandle_linux::_wait_for_completion ()
+{
+  while (!d_pending_rqsts.empty ())
+    if (!_reap(true))
+      break;
+}
+\f// ------------------------------------------------------------------------
+//                          end point handle
+// ------------------------------------------------------------------------
+
+fusb_ephandle_linux::fusb_ephandle_linux (fusb_devhandle_linux *devhandle,
+                                         int endpoint,
+                                         bool input_p,
+                                         int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (devhandle), 
+    d_write_work_in_progress (0), d_write_buffer (0),
+    d_read_work_in_progress (0), d_read_buffer (0), d_read_buffer_end (0)
+{
+
+  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
+    throw std::out_of_range ("fusb_ephandle_linux: block_size");
+
+  if (d_nblocks < 0)
+    throw std::out_of_range ("fusb_ephandle_linux: nblocks");
+
+  if (d_block_size == 0)
+    d_block_size = DEFAULT_BLOCK_SIZE;
+
+  if (d_nblocks == 0)
+    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
+
+  if (!d_input_p)
+    if (!MINIMIZE_TX_BUFFERING)
+      d_write_buffer = new unsigned char [d_block_size];
+
+  if (0)
+    fprintf(stderr, "fusb_ephandle_linux::ctor: d_block_size = %d  d_nblocks = %d\n",
+           d_block_size, d_nblocks);
+
+  // allocate urbs
+
+  for (int i = 0; i < d_nblocks; i++)
+    d_free_list.push_back (alloc_urb (this, d_block_size, d_endpoint,
+                                     d_input_p, d_write_buffer));
+}
+
+fusb_ephandle_linux::~fusb_ephandle_linux ()
+{
+  stop ();
+
+  usbdevfs_urb *urb;
+
+  while ((urb = free_list_get ()) != 0)
+    free_urb (urb);
+
+  while ((urb = completed_list_get ()) != 0)
+    free_urb (urb);
+
+  if (d_write_work_in_progress)
+    free_urb (d_write_work_in_progress);
+
+  delete [] d_write_buffer;
+
+  if (d_read_work_in_progress)
+    free_urb (d_read_work_in_progress);
+}
+
+// ----------------------------------------------------------------
+
+bool
+fusb_ephandle_linux::start ()
+{
+  if (d_started)
+    return true;               // already running
+
+  d_started = true;
+
+  if (d_input_p){              // fire off all the reads
+    usbdevfs_urb *urb;
+
+    int nerrors = 0;
+    while ((urb = free_list_get ()) != 0 && nerrors < d_nblocks){
+      if (!submit_urb (urb))
+       nerrors++;
+    }
+  }
+
+  return true;
+}
+
+//
+// kill all i/o in progress.
+// kill any completed but unprocessed transactions.
+//
+bool
+fusb_ephandle_linux::stop ()
+{
+  if (!d_started)
+    return true;
+
+  if (d_write_work_in_progress){
+    free_list_add (d_write_work_in_progress);
+    d_write_work_in_progress = 0;
+  }
+
+  if (d_read_work_in_progress){
+    free_list_add (d_read_work_in_progress);
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+  }
+
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+  while (1){
+    usbdevfs_urb *urb;
+    while ((urb = completed_list_get ()) != 0)
+      free_list_add (urb);
+
+    if (d_free_list.size () == (unsigned) d_nblocks)
+      break;
+
+    if (!d_devhandle->_reap(true))
+      break;
+  }
+
+  d_started = false;
+  return true;
+}
+
+// ----------------------------------------------------------------
+//                     routines for writing 
+// ----------------------------------------------------------------
+
+#if (MINIMIZE_TX_BUFFERING)
+
+int 
+fusb_ephandle_linux::write(const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+
+  assert(nbytes % 512 == 0);
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    usbdevfs_urb *urb = get_write_work_in_progress();
+    if (!urb)
+      return -1;
+    assert(urb->actual_length == 0);
+    int m = std::min(nbytes - n, MAX_BLOCK_SIZE);
+    urb->buffer = src;
+    urb->buffer_length = m;
+
+    n += m;
+    src += m;
+
+    if (!submit_urb(urb))
+      return -1;
+
+    d_write_work_in_progress = 0;
+  }
+
+  return n;
+}
+
+#else
+
+int 
+fusb_ephandle_linux::write (const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+
+  unsigned char *src = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    usbdevfs_urb *urb = get_write_work_in_progress ();
+    if (!urb)
+      return -1;
+    unsigned char *dst = (unsigned char *) urb->buffer;
+    int m = std::min (nbytes - n, urb->buffer_length - urb->actual_length);
+
+    memcpy (&dst[urb->actual_length], &src[n], m);
+    urb->actual_length += m;
+    n += m;
+
+    if (urb->actual_length == urb->buffer_length){
+      if (!submit_urb (urb))
+       return -1;
+      d_write_work_in_progress = 0;
+    }
+  }
+
+  return n;
+}
+
+#endif
+
+usbdevfs_urb *
+fusb_ephandle_linux::get_write_work_in_progress ()
+{
+  // if we've already got some work in progress, return it
+
+  if (d_write_work_in_progress)
+    return d_write_work_in_progress;
+
+  while (1){
+
+    reap_complete_writes ();
+
+    usbdevfs_urb *urb = free_list_get ();
+
+    if (urb != 0){
+      assert (urb->actual_length == 0);
+      d_write_work_in_progress = urb;
+      return urb;
+    }
+
+    // The free list is empty.  Tell the device handle to reap.
+    // Anything it reaps for us will end up on our completed list.
+
+    if (!d_devhandle->_reap (true))
+      return 0;
+  }
+}
+
+void
+fusb_ephandle_linux::reap_complete_writes ()
+{
+  // take a look at the completed_list and xfer to free list after
+  // checking for errors.
+
+  usbdevfs_urb *urb;
+  
+  while ((urb = completed_list_get ()) != 0){
+
+    // Check for any errors or short writes that were reported in the urb.
+    // The kernel sets status, actual_length and error_count.
+    // error_count is only used for ISO xfers.
+    // status is 0 if successful, else is an errno kind of thing
+
+    if (urb->status != 0){
+      fprintf (stderr, "fusb: (status %d) %s\n", urb->status, strerror (-urb->status));
+    }
+    else if (urb->actual_length != urb->buffer_length){
+      fprintf (stderr, "fusb: short write xfer: %d != %d\n",
+              urb->actual_length, urb->buffer_length);
+    }
+
+    free_list_add (urb);
+  }
+}
+
+void
+fusb_ephandle_linux::wait_for_completion ()
+{
+  d_devhandle->_wait_for_completion ();
+}
+
+// ----------------------------------------------------------------
+//                    routines for reading
+// ----------------------------------------------------------------
+
+int
+fusb_ephandle_linux::read (void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (!d_input_p)
+    return -1;
+
+  unsigned char *dst = (unsigned char *) buffer;
+
+  int n = 0;
+  while (n < nbytes){
+
+    if (d_read_buffer >= d_read_buffer_end)
+      if (!reload_read_buffer ())
+       return -1;
+
+    int m = std::min (nbytes - n, (int) (d_read_buffer_end - d_read_buffer));
+
+    memcpy (&dst[n], d_read_buffer, m);
+    d_read_buffer += m;
+    n += m;
+  }
+
+  return n;
+}
+
+bool
+fusb_ephandle_linux::reload_read_buffer ()
+{
+  assert (d_read_buffer >= d_read_buffer_end);
+
+  usbdevfs_urb *urb;
+
+  if (d_read_work_in_progress){
+    // We're done with this urb.  Fire off a read to refill it.
+    urb = d_read_work_in_progress;
+    d_read_work_in_progress = 0;
+    d_read_buffer = 0;
+    d_read_buffer_end = 0;
+    urb->actual_length = 0;
+    if (!submit_urb (urb))
+      return false;
+  }
+
+  while (1){
+
+    while ((urb = completed_list_get ()) == 0)
+      if (!d_devhandle->_reap (true))
+       return false;
+
+    // check result of completed read
+
+    if (urb->status != 0){
+      // We've got a problem. Report it and fail.
+      fprintf (stderr, "fusb: (rd status %d) %s\n", urb->status, strerror (-urb->status));
+      urb->actual_length = 0;
+      free_list_add (urb);
+      return false;
+    }
+
+    // we've got a happy urb, full of data...
+
+    d_read_work_in_progress = urb;
+    d_read_buffer = (unsigned char *) urb->buffer;
+    d_read_buffer_end = d_read_buffer + urb->actual_length;
+
+    return true;
+  }
+}
+
+// ----------------------------------------------------------------
+
+void
+fusb_ephandle_linux::free_list_add (usbdevfs_urb *urb)
+{
+  assert (urb_get_ephandle (urb) == this);
+  urb->actual_length = 0;
+  d_free_list.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_ephandle_linux::free_list_get ()
+{
+  if (d_free_list.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_free_list.front ();
+  d_free_list.pop_front ();
+  return urb;
+}
+
+void
+fusb_ephandle_linux::completed_list_add (usbdevfs_urb *urb)
+{
+  assert (urb_get_ephandle (urb) == this);
+  d_completed_list.push_back (urb);
+}
+
+usbdevfs_urb *
+fusb_ephandle_linux::completed_list_get ()
+{
+  if (d_completed_list.empty ())
+    return 0;
+
+  usbdevfs_urb *urb = d_completed_list.front ();
+  d_completed_list.pop_front ();
+  return urb;
+}
+
+/*
+ * Submit the urb.  If successful the urb ends up on the devhandle's
+ * pending list, otherwise, it's back on our free list.
+ */
+bool
+fusb_ephandle_linux::submit_urb (usbdevfs_urb *urb)
+{
+  if (!d_devhandle->_submit_urb (urb)){    // FIXME record the problem somewhere
+    fprintf (stderr, "_submit_urb failed\n");
+    free_list_add (urb);
+    return false;
+  }
+  return true;
+}
diff --git a/usrp/host/lib/fusb_linux.h b/usrp/host/lib/fusb_linux.h
new file mode 100644 (file)
index 0000000..107e1af
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+// Fast USB interface
+
+#ifndef _FUSB_LINUX_H_
+#define _FUSB_LINUX_H_
+
+#include <fusb.h>
+#include <list>
+
+struct  usbdevfs_urb;
+class   fusb_ephandle_linux;
+
+/*!
+ * \brief linux specific implementation of fusb_devhandle using usbdevice_fs
+ */
+class fusb_devhandle_linux : public fusb_devhandle {
+private:
+  std::list<usbdevfs_urb*>      d_pending_rqsts;
+
+  void pending_add (usbdevfs_urb *urb);
+  bool pending_remove (usbdevfs_urb *urb);
+  usbdevfs_urb * pending_get ();
+
+
+public:
+  // CREATORS
+  fusb_devhandle_linux (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_linux ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+
+  // internal use only
+  bool _submit_urb (usbdevfs_urb *urb);
+  bool _cancel_urb (usbdevfs_urb *urb);
+  void _cancel_pending_rqsts (fusb_ephandle_linux *eph);
+  bool _reap (bool ok_to_block_p);
+  void _wait_for_completion ();
+};
+
+\f/*!
+ * \brief linux specific implementation of fusb_ephandle using usbdevice_fs
+ */
+
+class fusb_ephandle_linux : public fusb_ephandle {
+private:
+  fusb_devhandle_linux        *d_devhandle;
+  std::list<usbdevfs_urb*>     d_free_list;
+  std::list<usbdevfs_urb*>     d_completed_list;
+  usbdevfs_urb                *d_write_work_in_progress;
+  unsigned char                       *d_write_buffer;
+  usbdevfs_urb                *d_read_work_in_progress;
+  unsigned char                       *d_read_buffer;
+  unsigned char                       *d_read_buffer_end;
+
+  usbdevfs_urb *get_write_work_in_progress ();
+  void reap_complete_writes ();
+  bool reload_read_buffer ();
+  bool submit_urb (usbdevfs_urb *urb);
+  
+public:
+  fusb_ephandle_linux (fusb_devhandle_linux *dh, int endpoint, bool input_p,
+                      int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_linux ();
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+
+  // internal use only
+  void free_list_add (usbdevfs_urb *urb);
+  void completed_list_add (usbdevfs_urb *urb);
+  usbdevfs_urb *free_list_get ();              // pop and return head of list or 0
+  usbdevfs_urb *completed_list_get ();         // pop and return head of list or 0
+};
+
+#endif /* _FUSB_LINUX_H_ */
diff --git a/usrp/host/lib/fusb_ra_wb.cc b/usrp/host/lib/fusb_ra_wb.cc
new file mode 100644 (file)
index 0000000..699a34b
--- /dev/null
@@ -0,0 +1,258 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_ra_wb.h>
+#include <usb.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/event.h>
+#include <dev/usb/usb.h>
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+// the following comment and function is from fusb_linux.cc
+#if 0
+// Totally evil and fragile extraction of file descriptor from
+// guts of libusb.  They don't install usbi.h, which is what we'd need
+// to do this nicely.
+//
+// FIXME if everything breaks someday in the future, look here...
+
+static int
+fd_from_usb_dev_handle (usb_dev_handle *udh)
+{
+  return *((int *) udh);
+}
+#endif
+
+// the control endpoint doesn't actually do us any good so here is a
+// new "fragile extraction"
+static int
+ep_fd_from_usb_dev_handle (usb_dev_handle *udh, int endpoint)
+{
+  struct usb_dev_handle_kludge2 { // see also usrp_prims.cc
+    int                         fd;
+    struct usb_bus     *bus;
+    struct usb_device  *device;
+    int                         config;
+    int                         interface;
+    int                         altsetting;
+    void               *impl_info;
+  };
+  struct bsd_usb_dev_handle_info_kludge {
+    int                         ep_fd[USB_MAX_ENDPOINTS];
+  };
+  struct bsd_usb_dev_handle_info_kludge *info
+      = (struct bsd_usb_dev_handle_info_kludge *)
+           ((struct usb_dev_handle_kludge2 *)udh)->impl_info;
+  return info->ep_fd[UE_GET_ADDR(endpoint)];
+}
+
+
+fusb_devhandle_ra_wb::fusb_devhandle_ra_wb (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_ra_wb::~fusb_devhandle_ra_wb ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_ra_wb::make_ephandle (int endpoint, bool input_p,
+                                    int block_size, int nblocks)
+{
+  return new fusb_ephandle_ra_wb (this, endpoint, input_p,
+                                 block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_ra_wb::fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh,
+                                         int endpoint, bool input_p,
+                                         int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_ra_wb_on (false)
+{
+  // that's it 
+}
+
+fusb_ephandle_ra_wb::~fusb_ephandle_ra_wb ()
+{
+  // nop
+}
+
+bool
+fusb_ephandle_ra_wb::start ()
+{
+  d_started = true;
+
+  char buf = '\0';
+  int fd;
+
+  // this is to cause libusb to open the endpoint
+  if (!d_input_p) {
+    write(&buf, 0);
+    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                   d_endpoint);
+  }
+  else {
+    read(&buf, 0);
+    fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                   d_endpoint|USB_ENDPOINT_IN);
+  }
+
+  // enable read ahead/write behind
+  int ret;
+  struct usb_bulk_ra_wb_opt opts;
+  int enable = 1;
+
+  opts.ra_wb_buffer_size = d_block_size*d_nblocks;
+  opts.ra_wb_request_size = d_block_size;
+//  fprintf (stderr, "setting buffer size to %d, request size to %d\n",
+//        opts.ra_wb_buffer_size, opts.ra_wb_request_size);
+  if (!d_input_p) {
+    ret = ioctl (fd, USB_SET_BULK_WB_OPT, &opts);
+    if (ret < 0)
+      fprintf (stderr, "USB_SET_BULK_WB_OPT: %s\n", strerror(errno));
+    else {
+      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = true;
+    }
+  }
+  else {
+    ret = ioctl (fd, USB_SET_BULK_RA_OPT, &opts);
+    if (ret < 0)
+      fprintf (stderr, "USB_SET_BULK_RA_OPT: %s\n", strerror(errno));
+    else {
+      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = true;
+    }
+  }
+
+  return true;
+}
+
+bool
+fusb_ephandle_ra_wb::stop ()
+{
+  int fd;
+  int ret;
+  int enable = 0;
+  if (d_ra_wb_on) {
+    if (!d_input_p) {
+      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                     d_endpoint);
+      ret = ioctl (fd, USB_SET_BULK_WB, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_WB: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = false;
+    }
+    else {
+      fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                     d_endpoint|USB_ENDPOINT_IN);
+      ret = ioctl (fd, USB_SET_BULK_RA, &enable);
+      if (ret < 0)
+       fprintf (stderr, "USB_SET_BULK_RA: %s\n", strerror(errno));
+      else
+       d_ra_wb_on = false;
+    }
+  }
+
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_ra_wb::write (const void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+  
+  if (d_input_p)
+    return -1;
+  
+  return usb_bulk_write (d_devhandle->get_usb_dev_handle (),
+                        d_endpoint, (char *) buffer, nbytes, USB_TIMEOUT);
+}
+
+int
+fusb_ephandle_ra_wb::read (void *buffer, int nbytes)
+{
+  if (!d_started)
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  return usb_bulk_read (d_devhandle->get_usb_dev_handle (),
+                       d_endpoint|USB_ENDPOINT_IN, (char *) buffer, nbytes,
+                       USB_TIMEOUT);
+}
+
+void
+fusb_ephandle_ra_wb::wait_for_completion ()
+{
+  // as the driver is implemented this only makes sense for write 
+  if (d_ra_wb_on && !d_input_p) {
+    int fd = ep_fd_from_usb_dev_handle (d_devhandle->get_usb_dev_handle(),
+                                       d_endpoint);
+    int kq = kqueue();
+    if (kq < 0)
+      return;
+    struct kevent evt;
+    int nevents;
+    EV_SET (&evt, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, 0/*NULL*/);
+    nevents = kevent (kq, &evt, 1, &evt, 1, NULL);
+    if (nevents < 1) {
+      close(kq);
+      return;
+    }
+    while (!(evt.flags & EV_ERROR) && evt.data < (d_block_size*d_nblocks)) {
+      // it's a busy loop, but that's all I can do at the moment
+      nevents = kevent (kq, NULL, 0, &evt, 1, NULL);
+      // let's see if this improves the test_usrp_standard_tx throughput &
+      // "CPU usage" by looping less frequently
+      struct timeval timeout;
+      timeout.tv_sec = 0;
+      timeout.tv_usec = 1000; // 1 ms
+      select (0, NULL, NULL, NULL, &timeout);
+    }
+    close (kq);
+  }
+}
diff --git a/usrp/host/lib/fusb_ra_wb.h b/usrp/host/lib/fusb_ra_wb.h
new file mode 100644 (file)
index 0000000..233976a
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef _FUSB_RA_WB_H_
+#define _FUSB_RA_WB_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief generic implementation of fusb_devhandle using only libusb
+ */
+class fusb_devhandle_ra_wb : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_ra_wb (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_ra_wb ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief generic implementation of fusb_ephandle using only libusb
+ */
+class fusb_ephandle_ra_wb : public fusb_ephandle
+{
+private:
+  fusb_devhandle_ra_wb *d_devhandle;
+  bool d_ra_wb_on;
+  
+public:
+  // CREATORS
+  fusb_ephandle_ra_wb (fusb_devhandle_ra_wb *dh, int endpoint, bool input_p,
+                      int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_ra_wb ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_RA_WB_H_ */
+
diff --git a/usrp/host/lib/fusb_sysconfig_darwin.cc b/usrp/host/lib/fusb_sysconfig_darwin.cc
new file mode 100644 (file)
index 0000000..68dd648
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_darwin.h>
+
+static const int MAX_BLOCK_SIZE = 32 * 1024;           // hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_darwin (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
+
diff --git a/usrp/host/lib/fusb_sysconfig_generic.cc b/usrp/host/lib/fusb_sysconfig_generic.cc
new file mode 100644 (file)
index 0000000..e098651
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_generic.h>
+
+static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_generic (udh);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_libusb1.cc b/usrp/host/lib/fusb_sysconfig_libusb1.cc
new file mode 100644 (file)
index 0000000..46daf56
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_libusb1.h>
+
+static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
+static const int DEFAULT_BLOCK_SIZE =   4 * 1024;
+static const int FUSB_BUFFER_SIZE = 1 * (1L << 20);    // 1 MB
+
+struct libusb_context;
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (libusb_device_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_libusb1 (udh, ctx);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return DEFAULT_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_linux.cc b/usrp/host/lib/fusb_sysconfig_linux.cc
new file mode 100644 (file)
index 0000000..e33b90b
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_linux.h>
+
+static const int MAX_BLOCK_SIZE     =  16 * 1024;      // hard limit
+static const int DEFAULT_BLOCK_SIZE =   4 * 1024;      // fewer kernel memory problems
+static const int FUSB_BUFFER_SIZE   =   1 * (1L << 20); // 1MB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_linux (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return DEFAULT_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_ra_wb.cc b/usrp/host/lib/fusb_sysconfig_ra_wb.cc
new file mode 100644 (file)
index 0000000..c527e30
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2006,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_ra_wb.h>
+
+//static const int MAX_BLOCK_SIZE = 16 * 1024;         // hard limit
+// there's no hard limit, even before making any changes to the driver
+// 64k is empirically a pretty good number
+static const int MAX_BLOCK_SIZE = 64 * 1024;
+// there is a limit of 1 MB in the driver for the buffer size
+static const int FUSB_BUFFER_SIZE = 256 * (1L << 10);  // 256 kB
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_ra_wb (udh);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_sysconfig_win32.cc b/usrp/host/lib/fusb_sysconfig_win32.cc
new file mode 100644 (file)
index 0000000..fb4be88
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005,2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <fusb.h>
+#include <fusb_win32.h>
+
+static const int MAX_BLOCK_SIZE = 64 * 1024;           // Windows kernel hard limit
+static const int FUSB_BUFFER_SIZE = 2 * (1L << 20);    // 2 MB
+       
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh, libusb_context *ctx)
+{
+  return new fusb_devhandle_win32 (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
+
+int fusb_sysconfig::default_block_size ()
+{
+  return fusb_sysconfig::max_block_size ();
+}
+
+int fusb_sysconfig::default_buffer_size ()
+{
+  return FUSB_BUFFER_SIZE;
+}
diff --git a/usrp/host/lib/fusb_win32.cc b/usrp/host/lib/fusb_win32.cc
new file mode 100644 (file)
index 0000000..8900576
--- /dev/null
@@ -0,0 +1,266 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_win32.h>
+#include <usb.h>
+#include <assert.h>
+#include <stdexcept>
+#include <string.h>
+
+static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();
+static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
+static const int DEFAULT_BUFFER_SIZE = 16 * (1L << 20);                // 16 MB / endpoint
+
+
+static const int USB_TIMEOUT = 1000;   // in milliseconds
+
+
+fusb_devhandle_win32::fusb_devhandle_win32 (usb_dev_handle *udh)
+  : fusb_devhandle (udh)
+{
+  // that's it
+}
+
+fusb_devhandle_win32::~fusb_devhandle_win32 ()
+{
+  // nop
+}
+
+fusb_ephandle *
+fusb_devhandle_win32::make_ephandle (int endpoint, bool input_p,
+                                      int block_size, int nblocks)
+{
+  return new fusb_ephandle_win32 (this, endpoint, input_p,
+                                   block_size, nblocks);
+}
+
+// ----------------------------------------------------------------
+
+fusb_ephandle_win32::fusb_ephandle_win32 (fusb_devhandle_win32 *dh,
+                                             int endpoint, bool input_p,
+                                             int block_size, int nblocks)
+  : fusb_ephandle (endpoint, input_p, block_size, nblocks),
+    d_devhandle (dh), d_input_leftover(0),d_output_short(0)
+{
+  if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE)
+    throw std::out_of_range ("fusb_ephandle_win32: block_size");
+
+  if (d_nblocks < 0)
+    throw std::out_of_range ("fusb_ephandle_win32: nblocks");
+
+  if (d_block_size == 0)
+    d_block_size = DEFAULT_BLOCK_SIZE;
+
+  if (d_nblocks == 0)
+    d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size);
+
+  d_buffer = new char [d_block_size*d_nblocks];
+  d_context = new void * [d_nblocks];
+
+  // allocate contexts
+
+  usb_dev_handle *dev = dh->get_usb_dev_handle ();
+  int i;
+
+  if (d_input_p)
+    endpoint |= USB_ENDPOINT_IN;
+
+  for (i=0; i<d_nblocks; i++)
+    usb_bulk_setup_async(dev, &d_context[i], endpoint);
+}
+
+fusb_ephandle_win32::~fusb_ephandle_win32 ()
+{
+  int i;
+
+  stop ();
+
+  for (i=0; i<d_nblocks; i++)
+    usb_free_async(&d_context[i]);
+
+  delete [] d_buffer;
+  delete [] d_context;
+}
+
+bool
+fusb_ephandle_win32::start ()
+{
+  if (d_started)
+    return true;       // already running
+
+  d_started = true;
+
+  d_curr = d_nblocks-1;
+  d_outstanding_write = 0;
+  d_input_leftover =0;
+  d_output_short = 0;
+
+  if (d_input_p){      // fire off all the reads
+    int i;
+
+    for (i=0; i<d_nblocks; i++) {
+      usb_submit_async(d_context[i], (char * ) d_buffer+i*d_block_size,
+                     d_block_size);
+    }
+  }
+
+  return true;
+}
+
+bool
+fusb_ephandle_win32::stop ()
+{
+  if (!d_started)
+    return true;
+
+  if (!d_input_p)
+    wait_for_completion ();
+
+  d_started = false;
+  return true;
+}
+
+int
+fusb_ephandle_win32::write (const void *buffer, int nbytes)
+{
+  int retval=0;
+  char *buf;
+
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (d_input_p)
+    return -1;
+
+  int bytes_to_write = nbytes;
+  int a=0;
+
+  if (d_output_short != 0) {
+
+       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_output_short];
+       a = std::min(nbytes, d_output_short);
+       memcpy(buf, buffer, a);
+       bytes_to_write -= a;
+       d_output_short -= a;
+
+    if (d_output_short == 0)
+        usb_submit_async(d_context[d_curr],
+                        &d_buffer[d_curr*d_block_size], d_block_size);
+  }
+
+  while (bytes_to_write > 0) {
+    d_curr = (d_curr+1)%d_nblocks;
+    buf = &d_buffer[d_curr*d_block_size];
+
+    if (d_outstanding_write != d_nblocks) {
+      d_outstanding_write++;
+    } else {
+      retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
+      if (retval < 0) {
+                 fprintf(stderr, "%s: usb_reap_async: %s\n",
+                         __FUNCTION__, usb_strerror());
+         return retval;
+       }
+    }
+
+    int ncopy = std::min(bytes_to_write, d_block_size);
+    memcpy(buf, (void *) &(((char*)buffer)[a]), ncopy);
+    bytes_to_write -= ncopy;
+    a += ncopy;
+
+    d_output_short = d_block_size - ncopy;
+    if (d_output_short == 0)
+           usb_submit_async(d_context[d_curr], buf, d_block_size);
+  }
+
+  return retval < 0 ? retval : nbytes;
+}
+
+int
+fusb_ephandle_win32::read (void *buffer, int nbytes)
+{
+  int retval=0;
+  char *buf;
+
+  if (!d_started)      // doesn't matter here, but keeps semantics constant
+    return -1;
+
+  if (!d_input_p)
+    return -1;
+
+  int bytes_to_read = nbytes;
+
+  int a=0;
+  if (d_input_leftover != 0) {
+
+       buf = &d_buffer[d_curr*d_block_size + d_block_size - d_input_leftover];
+       a = std::min(nbytes, d_input_leftover);
+       memcpy(buffer, buf, a);
+       bytes_to_read -= a;
+       d_input_leftover -= a;
+
+    if (d_input_leftover == 0)
+        usb_submit_async(d_context[d_curr],
+                        &d_buffer[d_curr*d_block_size], d_block_size);
+  }
+
+  while (bytes_to_read > 0) {
+
+    d_curr = (d_curr+1)%d_nblocks;
+    buf = &d_buffer[d_curr*d_block_size];
+
+    retval = usb_reap_async(d_context[d_curr], USB_TIMEOUT);
+    if (retval < 0)
+         fprintf(stderr, "%s: usb_reap_async: %s\n",
+                         __FUNCTION__, usb_strerror());
+
+    int ncopy = std::min(bytes_to_read, d_block_size);
+    memcpy((void *) &(((char*)buffer)[a]), buf, ncopy);
+    bytes_to_read -= ncopy;
+    a += ncopy;
+
+    d_input_leftover = d_block_size - ncopy;
+    if (d_input_leftover == 0)
+           usb_submit_async(d_context[d_curr], buf, d_block_size);
+  }
+
+  return retval < 0 ? retval : nbytes;
+}
+
+void
+fusb_ephandle_win32::wait_for_completion ()
+{
+  int i;
+
+  for (i=0; i<d_outstanding_write; i++) {
+    int context_num;
+
+    context_num = (d_curr+d_outstanding_write+i+1)%d_nblocks;
+    usb_reap_async(d_context[context_num], USB_TIMEOUT);
+  }
+
+  d_outstanding_write = 0;
+}
diff --git a/usrp/host/lib/fusb_win32.h b/usrp/host/lib/fusb_win32.h
new file mode 100644 (file)
index 0000000..3ad2132
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+#ifndef _FUSB_WIN32_H_
+#define _FUSB_WIN32_H_
+
+#include <fusb.h>
+
+/*!
+ * \brief win32 implementation of fusb_devhandle using libusb-win32
+ */
+class fusb_devhandle_win32 : public fusb_devhandle
+{
+public:
+  // CREATORS
+  fusb_devhandle_win32 (usb_dev_handle *udh);
+  virtual ~fusb_devhandle_win32 ();
+
+  // MANIPULATORS
+  virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
+                                       int block_size = 0, int nblocks = 0);
+};
+
+
+/*!
+ * \brief win32 implementation of fusb_ephandle using libusb-win32
+ */
+class fusb_ephandle_win32 : public fusb_ephandle
+{
+private:
+  fusb_devhandle_win32 *d_devhandle;
+
+  unsigned d_curr;
+  unsigned d_outstanding_write;
+  int d_output_short;
+  int d_input_leftover;
+  void ** d_context;
+  char * d_buffer;
+
+public:
+  // CREATORS
+  fusb_ephandle_win32 (fusb_devhandle_win32 *dh, int endpoint, bool input_p,
+                        int block_size = 0, int nblocks = 0);
+  virtual ~fusb_ephandle_win32 ();
+
+  // MANIPULATORS
+
+  virtual bool start ();       //!< begin streaming i/o
+  virtual bool stop ();                //!< stop streaming i/o
+
+  /*!
+   * \returns \p nbytes if write was successfully enqueued, else -1.
+   * Will block if no free buffers available.
+   */
+  virtual int write (const void *buffer, int nbytes);
+
+  /*!
+   * \returns number of bytes read or -1 if error.
+   * number of bytes read will be <= nbytes.
+   * Will block if no input available.
+   */
+  virtual int read (void *buffer, int nbytes);
+
+  /*
+   * block until all outstanding writes have completed
+   */
+  virtual void wait_for_completion ();
+};
+
+#endif /* _FUSB_WIN32_H_ */
+
diff --git a/usrp/host/lib/gen-ratios b/usrp/host/lib/gen-ratios
new file mode 100755 (executable)
index 0000000..2250090
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# -*- python -*-
+
+def how_good (x):
+    pof2 = [1,2,4,8,16]
+    if x in pof2:
+        return 0
+    if x in map (lambda x: x+1, pof2):
+        return -10
+    if x in map (lambda x: x-1, pof2):
+        return -5
+    return -2
+
+    
+def better (v1, v2):
+    return abs ((v1 & 0xf) - ((v1 >> 4) & 0xf)) < abs ((v2 & 0xf) - ((v2 >> 4) & 0xf))
+
+
+def foo ():
+    result = {}
+    for i in range (1,17):
+        for j in range (1,17):
+            i_goodness = how_good (i)
+            j_goodness = how_good (j)
+            goodness = i_goodness + j_goodness
+            v = ((i - 1) << 4) | (j - 1)
+
+            key = i * j
+            prev = result.get (key, None)
+            # print "i=%3d j=%3d key=%3d good=%3d v=0x%02x prev=%s" % (i, j, key, goodness, v, prev)
+
+            if not prev:
+                result[key] = (goodness, v)
+            elif goodness > prev[0]:
+                result[key] = (goodness, v)
+            elif goodness == prev[0] and better(v, prev[1]):
+                result[key] = (goodness, v)
+
+    r = result.items ()
+    r.sort ()
+    for k, d in r:
+        print "(%3d, 0x%02x)" % (k, d[1])
+
+    
+            
+foo ()
+
+       
diff --git a/usrp/host/lib/gen_usrp_dbid.py b/usrp/host/lib/gen_usrp_dbid.py
new file mode 100755 (executable)
index 0000000..c7d3770
--- /dev/null
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import os.path
+import re
+from optparse import OptionParser
+
+def write_header(f, comment_char):
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(' Machine generated by gen_usrp_dbid.py from usrp_dbid.dat\n')
+    f.write(comment_char); f.write(' Do not edit by hand.  All edits will be overwritten.\n')
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+
+def gen_dbid_py(r):
+    f = open('usrp_dbid.py', 'w')
+    comment_char = '#'
+    write_header(f, comment_char)
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+    for x in r:
+        f.write('%-16s = %s\n' % (x[1], x[2]))
+
+def gen_dbid_h(r):
+    f = open('../include/usrp/usrp_dbid.h', 'w')
+    comment_char = '//'
+    write_header(f, comment_char)
+    f.write(comment_char); f.write('\n')
+    f.write(comment_char); f.write(" USRP Daughterboard ID's\n")
+    f.write(comment_char); f.write('\n')
+    f.write('\n')
+    f.write('#ifndef INCLUDED_USRP_DBID_H\n')
+    f.write('#define INCLUDED_USRP_DBID_H\n')
+    f.write('\n')
+    for x in r:
+        f.write('#define %-25s %s\n' % ('USRP_DBID_' + x[1], x[2]))
+    f.write('\n')
+    f.write('#endif /* INCLUDED_USRP_DBID_H */\n')
+
+def gen_dbid_cc(r):
+    f = open('usrp_dbid.cc', 'w')
+    write_header(f, '//')
+    head = '''/*
+ * 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.
+ */
+
+#include <usrp/usrp_prims.h>
+#include <usrp/usrp_dbid.h>
+#include <stdio.h>
+
+#define NELEM(x) sizeof(x)/sizeof(x[0])
+
+static struct {
+  unsigned short       dbid;
+  const char          *name;
+} dbid_map[] = {
+'''
+    
+    tail = '''};
+
+const std::string
+usrp_dbid_to_string (int dbid)
+{
+  if (dbid == -1)
+    return "<none>";
+
+  if (dbid == -2)
+    return "<invalid EEPROM contents>";
+
+  for (unsigned i = 0; i < NELEM (dbid_map); i++)
+    if (dbid == dbid_map[i].dbid)
+      return dbid_map[i].name;
+
+  char tmp[64];
+  snprintf (tmp, sizeof (tmp), "Unknown (0x%04x)", dbid);
+  return tmp;
+}
+'''
+    f.write(head)
+    for x in r:
+        f.write('  { %-27s "%s" },\n' % (
+            'USRP_DBID_' + x[1] + ',', x[0]))
+    f.write(tail)
+
+def gen_all(src_filename):
+    src_file = open(src_filename, 'r')
+    r = []
+    for line in src_file:
+        line = line.strip()
+        line = re.sub(r'\s*#.*$','', line)
+        if len(line) == 0:
+            continue
+        mo = re.match('"([^"]+)"\s*(0x[0-9a-fA-F]+)', line)
+        if mo:
+            str_name = mo.group(1)
+            id_name = str_name.upper().replace(' ', '_')
+            id_val = mo.group(2)
+            r.append((str_name, id_name, id_val))
+            #sys.stdout.write('%-16s\t%-16s\t%s\n' % ('"'+str_name+'"', id_name, id_val))
+
+    gen_dbid_h(r)
+    gen_dbid_py(r)
+    gen_dbid_cc(r)
+    
+
+def main():
+    usage = "usage: %prog [options] usrp_dbid.dat"
+    parser = OptionParser(usage=usage)
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(1)
+
+    gen_all(args[0])
+
+if __name__ == '__main__':
+    main()
diff --git a/usrp/host/lib/limbo/db_wbx.cc b/usrp/host/lib/limbo/db_wbx.cc
new file mode 100644 (file)
index 0000000..9f1d729
--- /dev/null
@@ -0,0 +1,953 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+// 
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#include <db_wbx.h>
+#include <fpga_regs_standard.h>
+#include <fpga_regs_common.h>
+#include <usrp_prims.h>
+#include <usrp_spi_defs.h>
+#include <stdexcept>
+#include <cmath>
+
+// d'board i/o pin defs
+
+// TX IO Pins
+#define TX_POWER        (1 << 0)  // TX Side Power
+#define RX_TXN          (1 << 1)  // T/R antenna switch for TX/RX port
+#define TX_ENB_MIX      (1 << 2)  // Enable IQ mixer
+#define TX_ENB_VGA      (1 << 3)
+
+// RX IO Pins
+#define RX2_RX1N        (1 << 0)  // antenna switch between RX2 and TX/RX port
+#define RXENABLE        (1 << 1)  // enables mixer
+#define PLL_LOCK_DETECT (1 << 2)  // Muxout pin from PLL -- MUST BE INPUT
+#define MReset          (1 << 3)  // NB6L239 Master Reset, asserted low
+#define SELA0           (1 << 4)  // NB6L239 SelA0
+#define SELA1           (1 << 5)  // NB6L239 SelA1
+#define SELB0           (1 << 6)  // NB6L239 SelB0
+#define SELB1           (1 << 7)  // NB6L239 SelB1
+#define PLL_ENABLE      (1 << 8)  // CE Pin on PLL
+#define AUX_SCLK        (1 << 9)  // ALT SPI SCLK
+#define AUX_SDO         (1 << 10) // ALT SPI SDO
+#define AUX_SEN         (1 << 11) // ALT SPI SEN
+
+
+wbx_base::wbx_base(usrp_basic_sptr usrp, int which)
+  : db_base(usrp, which)
+{
+  /*
+   * @param usrp: instance of usrp.source_c
+   * @param which: which side: 0 or 1 corresponding to side A or B respectively
+   * @type which: int
+   */
+
+  d_first = true;
+  d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+  // FIXME -- the write reg functions don't work with 0xffff for masks
+  _rx_write_oe(int(PLL_ENABLE|MReset|SELA0|SELA1|SELB0|SELB1|RX2_RX1N|RXENABLE), 0x7fff);
+  _rx_write_io((PLL_ENABLE|MReset|0|RXENABLE), (PLL_ENABLE|MReset|RX2_RX1N|RXENABLE));
+
+  _tx_write_oe((TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA), 0x7fff);
+  _tx_write_io((0|RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA));  // TX off, TR switch set to RX
+
+  if(d_which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  set_auto_tr(false);
+        
+}
+
+wbx_base::~wbx_base()
+{        
+  shutdown();
+}
+
+
+void
+wbx_base::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
+
+    write_io(d_which, d_power_off, POWER_UP);   // turn off power to board
+    _write_oe(d_which, 0, 0xffff);   // turn off all outputs
+    set_auto_tr(false); // disable auto transmit
+  }
+}
+
+bool
+wbx_base::_lock_detect()
+{
+  /*
+   * @returns: the value of the VCO/PLL lock detect bit.
+   * @rtype: 0 or 1
+   */
+
+  if(_rx_read_io() & PLL_LOCK_DETECT) {
+    return true;
+  }
+  else {     // Give it a second chance
+    if(_rx_read_io() & PLL_LOCK_DETECT) {
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+}
+
+bool 
+wbx_base::_tx_write_oe(int value, int mask)
+{
+  int reg = (d_which == 0 ? FR_OE_0 : FR_OE_2);
+  return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool 
+wbx_base::_rx_write_oe(int value, int mask)
+{
+  int reg = (d_which == 0 ? FR_OE_1 : FR_OE_3);
+  return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_tx_write_io(int value, int mask)
+{
+  int reg = (d_which == 0 ? FR_IO_0 : FR_IO_2);
+  return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_rx_write_io(int value, int mask)
+{
+  int reg = (d_which == 0 ? FR_IO_1 : FR_IO_3);
+  return d_usrp->_write_fpga_reg(reg, ((mask & 0xffff) << 16) | (value & 0xffff));
+}
+
+bool
+wbx_base::_rx_read_io()
+{
+  int reg = (d_which == 0 ? FR_RB_IO_RX_A_IO_TX_A : FR_RB_IO_RX_B_IO_TX_B);
+  int t = d_usrp->_read_fpga_reg(reg);
+  return (t >> 16) & 0xffff;
+}
+
+bool
+wbx_base::_tx_read_io()
+{
+  int reg = (d_which == 0 ? FR_RB_IO_RX_A_IO_TX_A : FR_RB_IO_RX_B_IO_TX_B);
+  int t = d_usrp->_read_fpga_reg(reg);
+  return (t & 0xffff);
+}
+
+bool
+wbx_base::_compute_regs(double freq)
+{
+  /*
+   * Determine values of registers, along with actual freq.
+   * 
+   * @param freq: target frequency in Hz
+   * @type freq: double
+   * @returns: (R, N, func, init, actual_freq)
+   * @rtype: tuple(int, int, int, int, double)
+   * 
+   * Override this in derived classes.
+   */
+  throw std::runtime_error("_compute_regs called from base class\n");
+}
+
+double
+wbx_base::_refclk_freq()
+{
+  return (double)(d_usrp->fpga_master_clock_freq())/_refclk_divisor();
+}
+
+int
+wbx_base::_refclk_divisor()
+{
+  /*
+   * Return value to stick in REFCLK_DIVISOR register
+   */
+  return 1;
+}
+
+struct freq_result_t
+wbx_base::set_freq(double freq)
+{
+  /*
+   * @returns (ok, actual_baseband_freq) where:
+   * ok is True or False and indicates success or failure,
+   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+   */
+  throw std::runtime_error("set_freq called from base class\n");
+}
+
+float
+wbx_base::gain_min()
+{
+  throw std::runtime_error("gain_min called from base class\n");
+}
+
+float
+wbx_base::gain_max()
+{
+  throw std::runtime_error("gain_max called from base class\n");
+}
+
+float
+wbx_base::gain_db_per_step()
+{
+  throw std::runtime_error("gain_db_per_step called from base class\n");
+}
+
+bool
+wbx_base::set_gain(float gain)
+{
+  /*
+   * Set the gain.
+   * 
+   * @param gain:  gain in decibels
+   * @returns True/False
+   */
+  throw std::runtime_error("set_gain called from base class\n");
+}
+
+bool
+wbx_base::_set_pga(float pga_gain)
+{
+  bool ok;
+  if(d_which == 0) {
+    ok  = d_usrp->set_pga(0, pga_gain);
+    ok |= d_usrp->set_pga(1, pga_gain);
+  }
+  else {
+    ok  = d_usrp->set_pga(2, pga_gain);
+    ok |= d_usrp->set_pga(3, pga_gain);
+  }
+  return ok;
+}
+
+bool
+wbx_base::is_quadrature()
+{
+  /*
+   * Return True if this board requires both I & Q analog channels.
+   * 
+   * This bit of info is useful when setting up the USRP Rx mux register.
+   */
+  return true;
+}
+
+
+/****************************************************************************/
+
+
+wbx_base_tx::wbx_base_tx(usrp_basic_sptr usrp, int which)
+  : wbx_base(usrp, which)
+{        
+  /*
+   * @param usrp: instance of usrp.sink_c
+   * @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+   */
+  
+  // power up the transmit side, NO -- but set antenna to receive
+  d_usrp->write_io(d_which, (TX_POWER), (TX_POWER|RX_TXN));
+  d_lo_offset = 0e6;
+  
+  // Gain is not set by the PGA, but the PGA must be set at max gain in the TX
+  _set_pga(d_usrp->pga_max());
+}
+
+wbx_base_tx::~wbx_base_tx()
+{
+  // Power down and leave the T/R switch in the R position
+  d_usrp->write_io(d_which, (RX_TXN), (TX_POWER|RX_TXN|TX_ENB_MIX|TX_ENB_VGA));
+}
+
+void
+wbx_base_tx::set_auto_tr(bool on)
+{
+  if(on) {
+    set_atr_mask (RX_TXN);
+    set_atr_txval(0);
+    set_atr_rxval(RX_TXN);
+  }
+  else {
+    set_atr_mask (0);
+    set_atr_txval(0);
+    set_atr_rxval(0);
+  }
+}
+
+void
+wbx_base_tx::set_enable(bool on)
+{
+  /*
+   * Enable transmitter if on is True
+   */
+
+  int mask = RX_TXN|TX_ENB_MIX|TX_ENB_VGA;
+  //printf("HERE!!!!\n");
+  if(on) {
+    d_usrp->write_io(d_which, TX_ENB_MIX|TX_ENB_VGA, mask);
+  }
+  else {
+    d_usrp->write_io(d_which, RX_TXN, mask);
+  }
+}
+
+void
+wbx_base_tx::set_lo_offset(double offset)
+{
+  /*
+   * Set amount by which LO is offset from requested tuning frequency.
+   * 
+   * @param offset: offset in Hz
+   */
+  
+  d_lo_offset = offset;
+}
+
+double
+wbx_base_tx::lo_offset()
+{
+  /*
+   * Get amount by which LO is offset from requested tuning frequency.
+   * 
+   * @returns Offset in Hz
+   */
+
+  return d_lo_offset;
+}
+
+
+/****************************************************************************/
+
+
+wbx_base_rx::wbx_base_rx(usrp_basic_sptr usrp, int which)
+  : wbx_base(usrp, which)
+{
+  /*
+   * @param usrp: instance of usrp.source_c
+   * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+   */
+  
+  // set up for RX on TX/RX port
+  select_rx_antenna("TX/RX");
+  
+  bypass_adc_buffers(true);
+
+  d_lo_offset = 0.0;
+}
+
+wbx_base_rx::~wbx_base_rx()
+{
+  // Power down
+  d_usrp->write_io(d_which, 0, (RXENABLE));
+}
+  
+void
+wbx_base_rx::set_auto_tr(bool on)
+{
+  if(on) {
+    // FIXME: where does ENABLE come from?
+    //set_atr_mask (ENABLE);
+    set_atr_txval(     0);
+    //set_atr_rxval(ENABLE);
+  }
+  else {
+    set_atr_mask (0);
+    set_atr_txval(0);
+    set_atr_rxval(0);
+  }
+}
+
+void
+wbx_base_rx::select_rx_antenna(int which_antenna)
+{
+  /*
+   * Specify which antenna port to use for reception.
+   * @param which_antenna: either 'TX/RX' or 'RX2'
+   */
+  
+  if(which_antenna == 0) {
+    d_usrp->write_io(d_which, 0,        RX2_RX1N);
+  }
+  else if(which_antenna == 1) {
+    d_usrp->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+  }
+}
+
+void
+wbx_base_rx::select_rx_antenna(const std::string &which_antenna)
+{
+  if(which_antenna == "TX/RX") {
+    select_rx_antenna(0);
+  }
+  else if(which_antenna == "RX2") {
+    select_rx_antenna(1);
+  }
+  else {
+    throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+  }
+}
+
+bool
+wbx_base_rx::set_gain(float gain)
+{
+  /*
+   * Set the gain.
+   * 
+   * @param gain:  gain in decibels
+   * @returns True/False
+   */
+  
+  float pga_gain, agc_gain;
+  float maxgain = gain_max() - d_usrp->pga_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    pga_gain = gain-maxgain;
+    assert(pga_gain <= d_usrp->pga_max());
+    agc_gain = maxgain;
+  }
+  else {
+    pga_gain = 0;
+    agc_gain = gain;
+  }
+   
+  float V_maxgain = .2;
+  float V_mingain = 1.2;
+  float V_fullscale = 3.3;
+  float dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  assert(dac_value>=0 && dac_value<4096);
+
+  return d_usrp->write_aux_dac(d_which, 0, (int)(dac_value)) && _set_pga((int)(pga_gain));
+}
+
+void
+wbx_base_rx::set_lo_offset(double offset)
+{
+  /*
+   * Set amount by which LO is offset from requested tuning frequency.
+   * 
+   * @param offset: offset in Hz
+   */
+  d_lo_offset = offset;
+}
+
+double
+wbx_base_rx::lo_offset()
+{
+  /*
+   * Get amount by which LO is offset from requested tuning frequency.
+   * 
+   * @returns Offset in Hz
+   */
+  return d_lo_offset;
+}
+
+bool
+wbx_base_rx::i_and_q_swapped()
+{
+  /*
+   * Return True if this is a quadrature device and ADC 0 is Q.
+   */
+  return false;
+}
+
+
+/****************************************************************************/
+
+_ADF410X_common::_ADF410X_common()
+{
+  // R-Register Common Values
+  d_R_RSV = 0;    // bits 23,22,21
+  d_LDP = 1;      // bit 20     Lock detect in 5 cycles
+  d_TEST = 0;     // bit 19,18  Normal
+  d_ABP = 0;      // bit 17,16  2.9ns
+    
+  // N-Register Common Values
+  d_N_RSV = 0;    // 23,22
+  d_CP_GAIN = 0;  // 21
+    
+  // Function Register Common Values
+  d_P = 0;        // bits 23,22    0 = 8/9, 1 = 16/17, 2 = 32/33, 3 = 64/65
+  d_PD2 = 0;      // bit  21       Normal operation
+  d_CP2 = 4;      // bits 20,19,18 CP Gain = 5mA
+  d_CP1 = 4;      // bits 17,16,15 CP Gain = 5mA
+  d_TC = 0;       // bits 14-11    PFD Timeout
+  d_FL = 0;       // bit 10,9      Fastlock Disabled
+  d_CP3S = 0;     // bit 8         CP Enabled
+  d_PDP = 0;      // bit 7         Phase detector polarity, Positive=1
+  d_MUXOUT = 1;   // bits 6:4      Digital Lock Detect
+  d_PD1 = 0;      // bit 3         Normal operation
+  d_CR = 0;       // bit 2         Normal operation
+}
+
+_ADF410X_common::~_ADF410X_common()
+{
+}
+
+bool 
+_ADF410X_common::_compute_regs(double freq, int &retR, int &retcontrol, 
+                              int &retN, double &retfreq)
+{
+  /*
+   * Determine values of R, control, and N registers, along with actual freq.
+   * 
+   * @param freq: target frequency in Hz
+   * @type freq: double
+   * @returns: (R, N, control, actual_freq)
+   * @rtype: tuple(int, int, int, double)
+   */
+  
+  //  Band-specific N-Register Values
+  double phdet_freq = _refclk_freq()/d_R_DIV;
+  printf("phdet_freq = %f\n", phdet_freq);
+
+  double desired_n = round(freq*d_freq_mult/phdet_freq);
+  printf("desired_n %f\n", desired_n);
+
+  double actual_freq = desired_n * phdet_freq;
+  printf("actual freq %f\n", actual_freq);
+
+  double B = floor(desired_n/_prescaler());
+  double A = desired_n - _prescaler()*B;
+  printf("A %f B %f\n", A, B);
+
+  d_B_DIV = int(B);    // bits 20:8;
+  d_A_DIV = int(A);    // bit 6:2;
+
+  if(d_B_DIV < d_A_DIV) {
+    retR = 0;
+    retN = 0;
+    retcontrol = 0;
+    retfreq = 0;
+    return false;
+  }
+
+  retR = (d_R_RSV<<21) | (d_LDP<<20) | (d_TEST<<18) |
+    (d_ABP<<16) | (d_R_DIV<<2);
+        
+  retN = (d_N_RSV<<22) | (d_CP_GAIN<<21) | (d_B_DIV<<8) | (d_A_DIV<<2);
+
+  retcontrol = (d_P<<22) | (d_PD2<<21) | (d_CP2<<18) | (d_CP1<<15) | 
+    (d_TC<<11) | (d_FL<<9) | (d_CP3S<<8) | (d_PDP<<7) |
+    (d_MUXOUT<<4) | (d_PD1<<3) | (d_CR<<2);
+  
+  retfreq = actual_freq/d_freq_mult;
+  
+  return true;
+}
+
+void 
+_ADF410X_common::_write_all(int R, int N, int control)
+{
+  /*
+   * Write all PLL registers:
+   *   R counter latch,
+   *   N counter latch,
+   *   Function latch,
+   *   Initialization latch
+   * 
+   * Adds 10ms delay between writing control and N if this is first call.
+   * This is the required power-up sequence.
+   * 
+   * @param R: 24-bit R counter latch
+   * @type R: int
+   * @param N: 24-bit N counter latch
+   * @type N: int
+   * @param control: 24-bit control latch
+   * @type control: int
+   */
+  static bool first = true;
+
+  timespec t;
+  t.tv_sec = 0;
+  t.tv_nsec = 10000000;
+  
+  _write_R(R);
+  _write_func(control);
+  _write_init(control);
+  if(first) {
+    //time.sleep(0.010);
+    nanosleep(&t, NULL);
+    first = false;
+  }
+  _write_N(N);
+}
+
+void
+_ADF410X_common::_write_R(int R)
+{
+  _write_it((R & ~0x3) | 0);
+}
+
+void
+_ADF410X_common::_write_N(int N)
+{
+  _write_it((N & ~0x3) | 1);
+}
+
+void
+_ADF410X_common::_write_func(int func)
+{
+  _write_it((func & ~0x3) | 2);
+}
+
+void
+_ADF410X_common::_write_init(int init)
+{
+  _write_it((init & ~0x3) | 3);
+}
+
+void
+_ADF410X_common::_write_it(int v)
+{
+  char c[3];
+  c[0] = (char)((v >> 16) & 0xff);
+  c[1] = (char)((v >>  8) & 0xff);
+  c[2] = (char)((v & 0xff));
+  std::string s(c, 3);
+  //d_usrp->_write_spi(0, d_spi_enable, d_spi_format, s);
+  usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
+}
+
+int
+_ADF410X_common::_prescaler()
+{
+  if(d_P == 0) {
+    return 8;
+  }
+  else if(d_P == 1) {
+    return 16;
+  }
+  else if(d_P == 2) {
+    return 32;
+  }
+  else if(d_P == 3) {
+    return 64;
+  }
+  else {
+    throw std::invalid_argument("Prescaler out of range\n");
+  }
+}
+
+double
+_ADF410X_common::_refclk_freq()
+{
+  throw std::runtime_error("_refclk_freq called from base class.");
+}
+
+bool
+_ADF410X_common::_rx_write_io(int value, int mask)
+{
+  throw std::runtime_error("_rx_write_io called from base class.");
+}
+
+bool
+_ADF410X_common::_lock_detect()
+{
+  throw std::runtime_error("_lock_detect called from base class.");
+}
+
+usrp_basic* 
+_ADF410X_common::usrp()
+{
+  throw std::runtime_error("usrp() called from base class.");
+}
+
+
+/****************************************************************************/
+
+
+_lo_common::_lo_common()
+  : _ADF410X_common()
+{
+  // Band-specific R-Register Values
+  d_R_DIV = 4;    // bits 15:2
+  
+  // Band-specific C-Register values
+  d_P = 0;        // bits 23,22   0 = Div by 8/9
+  d_CP2 = 4;      // bits 19:17
+  d_CP1 = 4;      // bits 16:14
+  
+  // Band specifc N-Register Values
+  d_DIVSEL = 0;   // bit 23
+  d_DIV2 = 0;     // bit 22
+  d_CPGAIN = 0;   // bit 21
+  d_freq_mult = 1;
+  
+  d_div = 1;
+  d_aux_div = 2;
+  d_main_div = 0;
+}
+
+_lo_common::~_lo_common()
+{
+}
+
+double
+_lo_common::freq_min()
+{
+  return 50e6;
+}
+
+double
+_lo_common::freq_max()
+{
+  return 1000e6;
+}
+
+void
+_lo_common::set_divider(int main_or_aux, int divisor)
+{
+  if(main_or_aux == 0) {
+    if((divisor != 1) || (divisor != 2) || (divisor != 4) || (divisor != 8)) {
+      throw std::invalid_argument("Main Divider Must be 1, 2, 4, or 8\n");
+    }
+    d_main_div = (int)(log10(divisor)/log10(2.0));
+  }
+  else if(main_or_aux == 1) {
+    if((divisor != 2) || (divisor != 4) || (divisor != 8) || (divisor != 16)) {
+      throw std::invalid_argument("Aux Divider Must be 2, 4, 8 or 16\n");
+    }
+    d_main_div = (int)(log10(divisor/2.0)/log10(2.0));
+  }   
+  else {
+    throw std::invalid_argument("main_or_aux must be 'main' or 'aux'\n");
+  }
+  
+  int vala = d_main_div*SELA0;
+  int valb = d_aux_div*SELB0;
+  int mask = SELA0|SELA1|SELB0|SELB1;
+  
+  _rx_write_io((vala | valb), mask);
+}
+
+void
+_lo_common::set_divider(const std::string &main_or_aux, int divisor)
+{
+  if(main_or_aux == "main") {
+    set_divider(0, divisor);
+  }
+  else if(main_or_aux == "aux") {
+    set_divider(1, divisor);
+  }
+  else {
+    throw std::invalid_argument("main_or_aux must be 'main' or 'aux'\n");
+  }
+}
+
+struct freq_result_t
+_lo_common::set_freq(double freq)
+{
+  struct freq_result_t ret;
+  
+  if(freq < 20e6 or freq > 1200e6) {
+    throw std::invalid_argument("Requested frequency out of range\n");
+  }
+
+  int div = 1;
+  double lo_freq = freq * 2;
+  while((lo_freq < 1e9) && (div < 8)) {
+    div = div * 2;
+    lo_freq = lo_freq * 2;
+  }
+  
+  printf("For RF freq of %f, we set DIV=%d and LO Freq=%f\n", freq, div, lo_freq);
+
+  set_divider("main", div);
+  set_divider("aux", div*2);
+  
+  int R, N, control;
+  double actual_freq;
+  _compute_regs(lo_freq, R, N, control, actual_freq);
+  
+  printf("R %d N %d control %d actual freq %f\n", R, N, control, actual_freq);
+  if(R==0) {
+    ret.ok = false;
+    ret.baseband_freq = 0.0;
+    return ret;
+  }
+  _write_all(R, N, control);
+  
+  ret.ok = _lock_detect();
+  ret.baseband_freq = actual_freq/div/2;
+  return ret;
+}
+        
+
+/****************************************************************************/
+
+
+db_wbx_lo_tx::db_wbx_lo_tx(usrp_basic_sptr usrp, int which)
+  : _lo_common(),
+    wbx_base_tx(usrp, which)
+{
+}
+
+db_wbx_lo_tx::~db_wbx_lo_tx()
+{
+}
+
+float
+db_wbx_lo_tx::gain_min()
+{
+  return -56.0;
+}
+
+float
+db_wbx_lo_tx::gain_max()
+{
+  return 0.0;
+}
+
+float
+db_wbx_lo_tx::gain_db_per_step()
+{
+  return 0.1;
+}
+
+bool
+db_wbx_lo_tx::set_gain(float gain)
+{
+  /*
+   * Set the gain.
+   * 
+   * @param gain:  gain in decibels
+   * @returns True/False
+   */
+
+  float txvga_gain;
+  float maxgain = gain_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    txvga_gain = maxgain;
+  }
+  else if(gain < mingain) {
+    txvga_gain = mingain;
+  }
+  else {
+    txvga_gain = gain;
+  }
+
+  float V_maxgain = 1.4;
+  float V_mingain = 0.1;
+  float V_fullscale = 3.3;
+  float dac_value = ((txvga_gain-mingain)*(V_maxgain-V_mingain)/
+                    (maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  assert(dac_value>=0 && dac_value<4096);
+  printf("DAC value %f\n", dac_value);
+
+  return d_usrp->write_aux_dac(d_which, 1, (int)(dac_value));
+}
+
+double
+db_wbx_lo_tx::_refclk_freq()
+{
+  return wbx_base::_refclk_freq();
+}
+
+bool
+db_wbx_lo_tx::_rx_write_io(int value, int mask)
+{
+  return wbx_base::_rx_write_io(value, mask);
+}
+
+bool
+db_wbx_lo_tx::_lock_detect()
+{
+  return wbx_base::_lock_detect();
+}
+
+usrp_basic* 
+db_wbx_lo_tx::usrp()
+{
+  return d_usrp;
+}
+
+
+/****************************************************************************/
+
+
+db_wbx_lo_rx::db_wbx_lo_rx(usrp_basic_sptr usrp, int which)
+  : _lo_common(),
+    wbx_base_rx(usrp, which)    
+{
+}
+
+db_wbx_lo_rx::~db_wbx_lo_rx()
+{
+}
+
+float
+db_wbx_lo_rx::gain_min()
+{
+  return d_usrp->pga_min();
+}
+
+float
+db_wbx_lo_rx::gain_max()
+{
+  return d_usrp->pga_max() + 45;
+}
+
+float
+db_wbx_lo_rx::gain_db_per_step()
+{
+  return 0.05;
+}
+
+double
+db_wbx_lo_rx::_refclk_freq()
+{
+  return wbx_base::_refclk_freq();
+}
+
+bool
+db_wbx_lo_rx::_rx_write_io(int value, int mask)
+{
+  return wbx_base::_rx_write_io(value, mask);
+}
+
+bool
+db_wbx_lo_rx::_lock_detect()
+{
+  return wbx_base::_lock_detect();
+}
+
+usrp_basic* 
+db_wbx_lo_rx::usrp()
+{
+  return d_usrp;
+}
diff --git a/usrp/host/lib/limbo/db_wbx.h b/usrp/host/lib/limbo/db_wbx.h
new file mode 100644 (file)
index 0000000..3202d36
--- /dev/null
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 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.
+
+#ifndef DB_WBX_H
+#define DB_WBX_H
+
+#include <db_base.h>
+#include <boost/shared_ptr.hpp>
+
+
+/*
+  A few comments about the WBX boards:
+  They are half-duplex.  I.e., transmit and receive are mutually exclusive.
+  There is a single LO for both the Tx and Rx sides.
+  The the shared control signals are hung off of the Rx side.
+  The shared io controls are duplexed onto the Rx side pins.
+  The wbx_high d'board always needs to be in 'auto_tr_mode'
+*/
+
+
+class wbx_base : public db_base
+{
+protected:
+  void shutdown();
+
+  /*
+   * Abstract base class for all wbx boards.
+   * 
+   * Derive board specific subclasses from db_wbx_base_{tx,rx}
+   */
+
+public:
+  wbx_base(usrp_basic_sptr usrp, int which);
+  ~wbx_base();
+  
+  struct freq_result_t set_freq(double freq);
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool set_gain(float gain);  
+  bool is_quadrature();
+
+
+protected:
+  virtual bool _lock_detect();
+
+  // FIXME: After testing, replace these with usrp_basic::common_write_io/oe
+  bool _tx_write_oe(int value, int mask);
+  bool _rx_write_oe(int value, int mask);
+  bool _tx_write_io(int value, int mask);
+  bool _rx_write_io(int value, int mask);
+  virtual bool _rx_read_io();
+  bool _tx_read_io();
+  bool  _compute_regs(double freq);
+  virtual double _refclk_freq();
+  int _refclk_divisor();
+
+  bool _set_pga(float pga_gain);
+
+  bool d_first;
+  int d_spi_format;
+  int d_spi_enable;
+  double d_lo_offset;
+};
+
+
+/****************************************************************************/
+
+
+class wbx_base_tx : public wbx_base
+{
+public:
+  wbx_base_tx(usrp_basic_sptr usrp, int which);
+  ~wbx_base_tx();
+
+  bool set_auto_tr(bool on);
+  bool set_enable(bool on);
+};
+
+
+/****************************************************************************/
+
+
+class wbx_base_rx : public wbx_base
+{
+public:
+  wbx_base_rx(usrp_basic_sptr usrp, int which);
+  ~wbx_base_rx();
+  
+  bool set_auto_tr(bool on);
+  bool select_rx_antenna(int which_antenna);
+  bool select_rx_antenna(const std::string &which_antenna);
+  bool set_gain(float gain);
+  bool i_and_q_swapped();
+};
+
+
+/****************************************************************************/
+
+
+class _ADF410X_common
+{
+public:
+  _ADF410X_common();
+  virtual ~_ADF410X_common();
+  
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+                    int &retN, double &retfreq);
+  void _write_all(int R, int N, int control);
+  void _write_R(int R);
+  void _write_N(int N);
+  void _write_func(int func);
+  void _write_init(int init);
+  int  _prescaler();
+  virtual void _write_it(int v);
+  virtual double _refclk_freq();
+  virtual bool _rx_write_io(int value, int mask);
+  virtual bool _lock_detect();
+
+protected:
+  virtual usrp_basic* usrp();
+
+  int d_R_RSV, d_LDP, d_TEST, d_ABP;
+  int d_N_RSV, d_CP_GAIN;
+  int d_P, d_PD2, d_CP2, d_CP1, d_TC, d_FL;
+  int d_CP3S, d_PDP, d_MUXOUT, d_PD1, d_CR;
+  int d_R_DIV, d_A_DIV, d_B_DIV;
+  int d_freq_mult;
+
+  int d_spi_format;
+  int d_spi_enable;
+};
+
+
+/****************************************************************************/
+
+
+class _lo_common : public _ADF410X_common
+{
+public:
+  _lo_common();
+  ~_lo_common();
+
+  double freq_min();
+  double freq_max();
+  
+  void set_divider(int main_or_aux, int divisor);
+  void set_divider(const std::string &main_or_aux, int divisor);
+
+  struct freq_result_t set_freq(double freq);
+
+protected:
+  int d_R_DIV, d_P, d_CP2, d_CP1;
+  int d_DIVSEL, d_DIV2, d_CPGAIN;
+  int d_div, d_aux_div, d_main_div;
+};
+        
+
+/****************************************************************************/
+
+
+class db_wbx_lo_tx : public _lo_common, public wbx_base_tx
+{
+public:
+  db_wbx_lo_tx(usrp_basic_sptr usrp, int which);
+  ~db_wbx_lo_tx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+
+  double _refclk_freq();
+  bool _rx_write_io(int value, int mask);
+  bool _lock_detect();
+
+protected:
+  usrp_basic* usrp();
+};
+        
+
+/****************************************************************************/
+
+
+class db_wbx_lo_rx : public _lo_common, public  wbx_base_rx
+{
+public:
+  db_wbx_lo_rx(usrp_basic_sptr usrp, int which);
+  ~db_wbx_lo_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+
+  double _refclk_freq();
+  bool _rx_write_io(int value, int mask);
+  bool _lock_detect();
+
+protected:
+  usrp_basic* usrp();
+};
+
+#endif
diff --git a/usrp/host/lib/md5.c b/usrp/host/lib/md5.c
new file mode 100644 (file)
index 0000000..b15ab39
--- /dev/null
@@ -0,0 +1,452 @@
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+   according to the definition of MD5 in RFC 1321 from April 1992.
+   Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc.
+   NOTE: The canonical source of this file is maintained with the GNU C
+   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   This program 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.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "md5.h"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+// #include "unlocked-io.h"
+
+#ifdef _LIBC
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define WORDS_BIGENDIAN 1
+# endif
+/* We need to keep the namespace clean so define the MD5 function
+   protected using leading __ .  */
+# define md5_init_ctx __md5_init_ctx
+# define md5_process_block __md5_process_block
+# define md5_process_bytes __md5_process_bytes
+# define md5_finish_ctx __md5_finish_ctx
+# define md5_read_ctx __md5_read_ctx
+# define md5_stream __md5_stream
+# define md5_buffer __md5_buffer
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n)                                                       \
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+#define BLOCKSIZE 4096
+/* Ensure that BLOCKSIZE is a multiple of 64.  */
+#if BLOCKSIZE % 64 != 0
+/* FIXME-someday (soon?): use #error instead of this kludge.  */
+"invalid BLOCKSIZE"
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+void
+md5_init_ctx (struct md5_ctx *ctx)
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->total[0] = ctx->total[1] = 0;
+  ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result
+   must be in little endian byte order.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+  return resbuf;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
+{
+  /* Take yet unprocessed bytes into account.  */
+  md5_uint32 bytes = ctx->buflen;
+  size_t pad;
+
+  /* Now count remaining bytes.  */
+  ctx->total[0] += bytes;
+  if (ctx->total[0] < bytes)
+    ++ctx->total[1];
+
+  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+  memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
+  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
+                                                       (ctx->total[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+  return md5_read_ctx (ctx, resbuf);
+}
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int
+md5_stream (FILE *stream, void *resblock)
+{
+  struct md5_ctx ctx;
+  char buffer[BLOCKSIZE + 72];
+  size_t sum;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+        computation function processes the whole buffer so that with the
+        next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      while (1)
+       {
+         n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+         sum += n;
+
+         if (sum == BLOCKSIZE)
+           break;
+
+         if (n == 0)
+           {
+             /* Check for the error flag IFF N == 0, so that we don't
+                exit the loop after a partial read due to e.g., EAGAIN
+                or EWOULDBLOCK.  */
+             if (ferror (stream))
+               return 1;
+             goto process_partial_block;
+           }
+
+         /* We've read at least one byte, so ignore errors.  But always
+            check for EOF, since feof may be true even though N > 0.
+            Otherwise, we could end up calling fread after EOF.  */
+         if (feof (stream))
+           goto process_partial_block;
+       }
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+                       BLOCKSIZE % 64 == 0
+       */
+      md5_process_block (buffer, BLOCKSIZE, &ctx);
+    }
+
+ process_partial_block:;
+
+  /* Process any remaining bytes.  */
+  if (sum > 0)
+    md5_process_bytes (buffer, sum, &ctx);
+
+  /* Construct result in desired memory.  */
+  md5_finish_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *
+md5_buffer (const char *buffer, size_t len, void *resblock)
+{
+  struct md5_ctx ctx;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_bytes (buffer, len, &ctx);
+
+  /* Put result in desired memory area.  */
+  return md5_finish_ctx (&ctx, resblock);
+}
+
+
+void
+md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  /* When we already have some bits in our internal buffer concatenate
+     both inputs first.  */
+  if (ctx->buflen != 0)
+    {
+      size_t left_over = ctx->buflen;
+      size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+      memcpy (&ctx->buffer[left_over], buffer, add);
+      ctx->buflen += add;
+
+      if (ctx->buflen > 64)
+       {
+         md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+         ctx->buflen &= 63;
+         /* The regions in the following copy operation cannot overlap.  */
+         memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+                 ctx->buflen);
+       }
+
+      buffer = (const char *) buffer + add;
+      len -= add;
+    }
+
+  /* Process available complete blocks.  */
+  if (len >= 64)
+    {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator.  Other
+   compilers don't.  */
+# if __GNUC__ >= 2
+#  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
+# else
+#  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
+# endif
+      if (UNALIGNED_P (buffer))
+       while (len > 64)
+         {
+           md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+           buffer = (const char *) buffer + 64;
+           len -= 64;
+         }
+      else
+#endif
+       {
+         md5_process_block (buffer, len & ~63, ctx);
+         buffer = (const char *) buffer + (len & ~63);
+         len &= 63;
+       }
+    }
+
+  /* Move remaining bytes in internal buffer.  */
+  if (len > 0)
+    {
+      size_t left_over = ctx->buflen;
+
+      memcpy (&ctx->buffer[left_over], buffer, len);
+      left_over += len;
+      if (left_over >= 64)
+       {
+         md5_process_block (ctx->buffer, 64, ctx);
+         left_over -= 64;
+         memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+       }
+      ctx->buflen = left_over;
+    }
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+
+void
+md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  md5_uint32 correct_words[16];
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof (md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 A = ctx->A;
+  md5_uint32 B = ctx->B;
+  md5_uint32 C = ctx->C;
+  md5_uint32 D = ctx->D;
+
+  /* First increment the byte count.  RFC 1321 specifies the possible
+     length of the file up to 2^64 bits.  Here we only compute the
+     number of bytes.  Do a double word increment.  */
+  ctx->total[0] += len;
+  if (ctx->total[0] < len)
+    ++ctx->total[1];
+
+  /* Process all bytes in the buffer with 64 bytes in each round of
+     the loop.  */
+  while (words < endp)
+    {
+      md5_uint32 *cwp = correct_words;
+      md5_uint32 A_save = A;
+      md5_uint32 B_save = B;
+      md5_uint32 C_save = C;
+      md5_uint32 D_save = D;
+
+      /* First round: using the given function, the context and a constant
+        the next context is computed.  Because the algorithms processing
+        unit is a 32-bit word and it is determined to work on words in
+        little endian byte order we perhaps have to change the byte order
+        before the computation.  To reduce the work for the next steps
+        we store the swapped words in the array CORRECT_WORDS.  */
+
+#define OP(a, b, c, d, s, T)                                           \
+      do                                                               \
+        {                                                              \
+         a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
+         ++words;                                                      \
+         a = rol (a, s);                                               \
+         a += b;                                                       \
+        }                                                              \
+      while (0)
+
+      /* Before we start, one word to the strange constants.
+        They are defined in RFC 1321 as
+
+        T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
+        perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
+       */
+
+      /* Round 1.  */
+      OP (A, B, C, D,  7, 0xd76aa478);
+      OP (D, A, B, C, 12, 0xe8c7b756);
+      OP (C, D, A, B, 17, 0x242070db);
+      OP (B, C, D, A, 22, 0xc1bdceee);
+      OP (A, B, C, D,  7, 0xf57c0faf);
+      OP (D, A, B, C, 12, 0x4787c62a);
+      OP (C, D, A, B, 17, 0xa8304613);
+      OP (B, C, D, A, 22, 0xfd469501);
+      OP (A, B, C, D,  7, 0x698098d8);
+      OP (D, A, B, C, 12, 0x8b44f7af);
+      OP (C, D, A, B, 17, 0xffff5bb1);
+      OP (B, C, D, A, 22, 0x895cd7be);
+      OP (A, B, C, D,  7, 0x6b901122);
+      OP (D, A, B, C, 12, 0xfd987193);
+      OP (C, D, A, B, 17, 0xa679438e);
+      OP (B, C, D, A, 22, 0x49b40821);
+
+      /* For the second to fourth round we have the possibly swapped words
+        in CORRECT_WORDS.  Redefine the macro to take an additional first
+        argument specifying the function to use.  */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)                                     \
+      do                                                               \
+       {                                                               \
+         a += f (b, c, d) + correct_words[k] + T;                      \
+         a = rol (a, s);                                               \
+         a += b;                                                       \
+       }                                                               \
+      while (0)
+
+      /* Round 2.  */
+      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+      OP (FG, D, A, B, C, 10,  9, 0x02441453);
+      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+      /* Round 3.  */
+      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+      /* Round 4.  */
+      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+      /* Add the starting values of the context.  */
+      A += A_save;
+      B += B_save;
+      C += C_save;
+      D += D_save;
+    }
+
+  /* Put checksum in context given as argument.  */
+  ctx->A = A;
+  ctx->B = B;
+  ctx->C = C;
+  ctx->D = D;
+}
diff --git a/usrp/host/lib/md5.h b/usrp/host/lib/md5.h
new file mode 100644 (file)
index 0000000..4a4e790
--- /dev/null
@@ -0,0 +1,129 @@
+/* md5.h - Declaration of functions and data types used for MD5 sum
+   computing library functions.
+   Copyright (C) 1995, 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
+   NOTE: The canonical source of this file is maintained with the GNU C
+   Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   This program 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.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Boston, MA 02110-1301, USA.  */
+
+#ifndef _MD5_H
+#define _MD5_H 1
+
+#include <stdio.h>
+#include <limits.h>
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#ifdef _LIBC
+# include <stdint.h>
+typedef uint32_t md5_uint32;
+typedef uintptr_t md5_uintptr;
+#else
+# define UINT_MAX_32_BITS 4294967295U
+
+# if UINT_MAX == UINT_MAX_32_BITS
+   typedef unsigned int md5_uint32;
+# else
+#  if USHRT_MAX == UINT_MAX_32_BITS
+    typedef unsigned short md5_uint32;
+#  else
+#   if ULONG_MAX == UINT_MAX_32_BITS
+     typedef unsigned long md5_uint32;
+#   else
+     /* The following line is intended to evoke an error.
+        Using #error is not portable enough.  */
+     "Cannot determine unsigned 32-bit data type."
+#   endif
+#  endif
+# endif
+/* We have to make a guess about the integer type equivalent in size
+   to pointers which should always be correct.  */
+typedef unsigned long int md5_uintptr;
+#endif
+
+/* Structure to save state of computation between the single steps.  */
+struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+
+  md5_uint32 total[2];
+  md5_uint32 buflen;
+  char buffer[128];
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+extern void md5_init_ctx (struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+extern void md5_process_block (const void *buffer, size_t len,
+                              struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is NOT required that LEN is a multiple of 64.  */
+extern void md5_process_bytes (const void *buffer, size_t len,
+                              struct md5_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+   in first 16 bytes following RESBUF.  The result is always in little
+   endian byte order, so that a byte-wise output yields to the wanted
+   ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF be correctly
+   aligned for a 32 bits value.  */
+extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
+
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+extern int md5_stream (FILE *stream, void *resblock);
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+extern void *md5_buffer (const char *buffer, size_t len, void *resblock);
+
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+
+#endif
diff --git a/usrp/host/lib/rate_to_regval.h b/usrp/host/lib/rate_to_regval.h
new file mode 100644 (file)
index 0000000..1ffdc0f
--- /dev/null
@@ -0,0 +1,97 @@
+  {   1, 0x00 },
+  {   2, 0x01 },
+  {   3, 0x02 },
+  {   4, 0x11 },
+  {   5, 0x04 },
+  {   6, 0x05 },
+  {   7, 0x06 },
+  {   8, 0x13 },
+  {   9, 0x08 },
+  {  10, 0x09 },
+  {  11, 0x0a },
+  {  12, 0x15 },
+  {  13, 0x0c },
+  {  14, 0x0d },
+  {  15, 0x0e },
+  {  16, 0x33 },
+  {  18, 0x18 },
+  {  20, 0x19 },
+  {  21, 0x26 },
+  {  22, 0x1a },
+  {  24, 0x35 },
+  {  25, 0x44 },
+  {  26, 0x1c },
+  {  27, 0x28 },
+  {  28, 0x1d },
+  {  30, 0x1e },
+  {  32, 0x37 },
+  {  33, 0x2a },
+  {  35, 0x46 },
+  {  36, 0x55 },
+  {  39, 0x2c },
+  {  40, 0x39 },
+  {  42, 0x56 },
+  {  44, 0x3a },
+  {  45, 0x2e },
+  {  48, 0x57 },
+  {  49, 0x66 },
+  {  50, 0x49 },
+  {  52, 0x3c },
+  {  54, 0x58 },
+  {  55, 0x4a },
+  {  56, 0x3d },
+  {  60, 0x59 },
+  {  63, 0x68 },
+  {  64, 0x77 },
+  {  65, 0x4c },
+  {  66, 0x5a },
+  {  70, 0x69 },
+  {  72, 0x5b },
+  {  75, 0x4e },
+  {  77, 0x6a },
+  {  78, 0x5c },
+  {  80, 0x79 },
+  {  81, 0x88 },
+  {  84, 0x5d },
+  {  88, 0x7a },
+  {  90, 0x5e },
+  {  91, 0x6c },
+  {  96, 0x7b },
+  {  98, 0x6d },
+  {  99, 0x8a },
+  { 100, 0x99 },
+  { 104, 0x7c },
+  { 105, 0x6e },
+  { 108, 0x8b },
+  { 110, 0x9a },
+  { 112, 0x7d },
+  { 117, 0x8c },
+  { 120, 0x9b },
+  { 121, 0xaa },
+  { 126, 0x8d },
+  { 128, 0x7f },
+  { 130, 0x9c },
+  { 132, 0xab },
+  { 135, 0x8e },
+  { 140, 0x9d },
+  { 143, 0xac },
+  { 144, 0xbb },
+  { 150, 0x9e },
+  { 154, 0xad },
+  { 156, 0xbc },
+  { 160, 0x9f },
+  { 165, 0xae },
+  { 168, 0xbd },
+  { 169, 0xcc },
+  { 176, 0xaf },
+  { 180, 0xbe },
+  { 182, 0xcd },
+  { 192, 0xbf },
+  { 195, 0xce },
+  { 196, 0xdd },
+  { 208, 0xcf },
+  { 210, 0xde },
+  { 224, 0xdf },
+  { 225, 0xee },
+  { 240, 0xef },
+  { 256, 0xff }
diff --git a/usrp/host/lib/std_paths.h.in b/usrp/host/lib/std_paths.h.in
new file mode 100644 (file)
index 0000000..e09499e
--- /dev/null
@@ -0,0 +1,27 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+static const char *std_paths[] = {
+  "@prefix@/share/usrp",
+  "/usr/local/share/usrp",
+  0
+};
diff --git a/usrp/host/lib/usrp_basic.cc b/usrp/host/lib/usrp_basic.cc
new file mode 100644 (file)
index 0000000..5b2f7ff
--- /dev/null
@@ -0,0 +1,1538 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2008,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp/usrp_basic.h"
+#include "usrp/usrp_prims.h"
+#include "usrp_interfaces.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include "fusb.h"
+#include "db_boards.h"
+#include <stdexcept>
+#include <assert.h>
+#include <math.h>
+#include <ad9862.h>
+#include <string.h>
+#include <cstdio>
+
+using namespace ad9862;
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+// These set the buffer size used for each end point using the fast
+// usb interface.  The kernel ends up locking down this much memory.
+
+static const int FUSB_BUFFER_SIZE = fusb_sysconfig::default_buffer_size();
+static const int FUSB_BLOCK_SIZE = fusb_sysconfig::max_block_size();
+static const int FUSB_NBLOCKS    = FUSB_BUFFER_SIZE / FUSB_BLOCK_SIZE;
+
+
+static const double POLLING_INTERVAL = 0.1;    // seconds
+
+////////////////////////////////////////////////////////////////
+
+static libusb_device_handle *
+open_rx_interface (libusb_device *dev)
+{
+  libusb_device_handle *udh = usrp_open_rx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
+  }
+  return udh;
+}
+
+static libusb_device_handle *
+open_tx_interface (libusb_device *dev)
+{
+  libusb_device_handle *udh = usrp_open_tx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
+  }
+  return udh;
+}
+
+//////////////////////////////////////////////////////////////////
+//
+//                     usrp_basic
+//
+////////////////////////////////////////////////////////////////
+
+// Given:
+//   CLKIN = 64 MHz
+//   CLKSEL pin = high
+//
+// These settings give us:
+//   CLKOUT1 = CLKIN = 64 MHz
+//   CLKOUT2 = CLKIN = 64 MHz
+//   ADC is clocked at  64 MHz
+//   DAC is clocked at 128 MHz
+
+static unsigned char common_regs[] = {
+  REG_GENERAL,         0,
+  REG_DLL,             (DLL_DISABLE_INTERNAL_XTAL_OSC
+                        | DLL_MULT_2X
+                        | DLL_FAST),
+  REG_CLKOUT,          CLKOUT2_EQ_DLL_OVER_2,
+  REG_AUX_ADC_CLK,     AUX_ADC_CLK_CLK_OVER_4
+};
+
+usrp_basic::usrp_basic (int which_board,
+                       libusb_device_handle *
+                       open_interface (libusb_device *dev),
+                       const std::string fpga_filename,
+                       const std::string firmware_filename)
+  : d_udh (0), d_ctx (0),
+    d_usb_data_rate (16000000),        // SWAG, see below
+    d_bytes_per_poll ((int) (POLLING_INTERVAL * d_usb_data_rate)),
+    d_verbose (false), d_fpga_master_clock_freq(64000000), d_db(2)
+{
+  /*
+   * SWAG: Scientific Wild Ass Guess.
+   *
+   * d_usb_data_rate is used only to determine how often to poll for over- and
+   * under-runs. We defualt it to 1/2  of our best case.  Classes derived from
+   * usrp_basic (e.g., usrp_standard_tx and usrp_standard_rx) call
+   * set_usb_data_rate() to tell us the actual rate. This doesn't change our
+   * throughput, that's determined by the signal processing code in the FPGA
+   * (which we know nothing about), and the system limits determined by libusb,
+   * fusb_*, and the underlying drivers.
+   */
+  memset (d_fpga_shadows, 0, sizeof (d_fpga_shadows));
+
+  usrp_one_time_init (&d_ctx);
+
+  if (!usrp_load_standard_bits (which_board, false, fpga_filename,
+                                firmware_filename, d_ctx))
+    throw std::runtime_error ("usrp_basic/usrp_load_standard_bits");
+
+  libusb_device *dev = usrp_find_device (which_board, false, d_ctx);
+  if (dev == 0){
+    fprintf (stderr, "usrp_basic: can't find usrp[%d]\n", which_board);
+    throw std::runtime_error ("usrp_basic/usrp_find_device");
+  }
+
+  if (!(usrp_usrp_p(dev) && usrp_hw_rev(dev) >= 1)){
+    fprintf (stderr, "usrp_basic: sorry, this code only works with USRP revs >= 1\n");
+    throw std::runtime_error ("usrp_basic/bad_rev");
+  }
+
+  if ((d_udh = open_interface (dev)) == 0)
+    throw std::runtime_error ("usrp_basic/open_interface");
+
+  // initialize registers that are common to rx and tx
+
+  if (!usrp_9862_write_many_all (d_udh, common_regs, sizeof (common_regs))) {
+    fprintf (stderr, "usrp_basic: failed to init common AD9862 regs\n");
+    throw std::runtime_error ("usrp_basic/init_9862");
+  }
+
+  _write_fpga_reg (FR_MODE, 0);                // ensure we're in normal mode
+  _write_fpga_reg (FR_DEBUG_EN, 0);    // disable debug outputs
+
+}
+
+usrp_basic::~usrp_basic ()
+{
+  d_db.resize(0); // forget db shared ptrs
+
+  if (d_udh)
+    usrp_close_interface (d_udh);
+
+  usrp_deinit (d_ctx);
+}
+
+void
+usrp_basic::shutdown_daughterboards()
+{
+  // nuke d'boards before we close down USB in ~usrp_basic
+  // shutdown() will do any board shutdown while the USRP can still
+  // be talked to
+  for(size_t i = 0; i < d_db.size(); i++)
+    for(size_t j = 0; j < d_db[i].size(); j++)
+      d_db[i][j]->shutdown();
+}
+
+void
+usrp_basic::init_db(usrp_basic_sptr u)
+{
+  if (u.get() != this)
+    throw std::invalid_argument("u is not this");
+
+  d_db[0] = instantiate_dbs(d_dbid[0], u, 0);
+  d_db[1] = instantiate_dbs(d_dbid[1], u, 1);
+}
+
+std::vector<db_base_sptr>
+usrp_basic::db(int which_side)
+{
+  which_side &= 0x1;   // clamp it to avoid any reporting any errors
+  return d_db[which_side];
+}
+
+bool
+usrp_basic::is_valid(const usrp_subdev_spec &ss)
+{
+  if (ss.side < 0 || ss.side > 1)
+    return false;
+
+  if (ss.subdev < 0 || ss.subdev >= d_db[ss.side].size())
+    return false;
+
+  return true;
+}
+
+db_base_sptr
+usrp_basic::selected_subdev(const usrp_subdev_spec &ss)
+{
+  if (!is_valid(ss))
+    throw std::invalid_argument("invalid subdev_spec");
+
+  return d_db[ss.side][ss.subdev];
+}
+
+bool
+usrp_basic::start ()
+{
+  return true;         // nop
+}
+
+bool
+usrp_basic::stop ()
+{
+  return true;         // nop
+}
+
+void
+usrp_basic::set_usb_data_rate (int usb_data_rate)
+{
+  d_usb_data_rate = usb_data_rate;
+  d_bytes_per_poll = (int) (usb_data_rate * POLLING_INTERVAL);
+}
+
+bool
+usrp_basic::_write_aux_dac (int slot, int which_dac, int value)
+{
+  return usrp_write_aux_dac (d_udh, slot, which_dac, value);
+}
+
+bool
+usrp_basic::_read_aux_adc (int slot, int which_adc, int *value)
+{
+  return usrp_read_aux_adc (d_udh, slot, which_adc, value);
+}
+
+int
+usrp_basic::_read_aux_adc (int slot, int which_adc)
+{
+  int  value;
+  if (!_read_aux_adc (slot, which_adc, &value))
+    return READ_FAILED;
+
+  return value;
+}
+
+bool
+usrp_basic::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+{
+  return usrp_eeprom_write (d_udh, i2c_addr, eeprom_offset, buf.data (), buf.size ());
+}
+
+std::string
+usrp_basic::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+{
+  if (len <= 0)
+    return "";
+
+  char buf[len];
+
+  if (!usrp_eeprom_read (d_udh, i2c_addr, eeprom_offset, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+bool
+usrp_basic::write_i2c (int i2c_addr, const std::string buf)
+{
+  return usrp_i2c_write (d_udh, i2c_addr, buf.data (), buf.size ());
+}
+
+std::string
+usrp_basic::read_i2c (int i2c_addr, int len)
+{
+  if (len <= 0)
+    return "";
+
+  char buf[len];
+
+  if (!usrp_i2c_read (d_udh, i2c_addr, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+std::string
+usrp_basic::serial_number()
+{
+  return usrp_serial_number(d_udh);
+}
+
+// ----------------------------------------------------------------
+
+bool
+usrp_basic::set_adc_offset (int which_adc, int offset)
+{
+  if (which_adc < 0 || which_adc > 3)
+    return false;
+
+  return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
+}
+
+bool
+usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
+{
+  if (which_dac < 0 || which_dac > 3)
+    return false;
+
+  int which_codec = which_dac >> 1;
+  int tx_a = (which_dac & 0x1) == 0;
+  int lo = ((offset & 0x3) << 6) | (offset_pin & 0x1);
+  int hi = (offset >> 2);
+  bool ok;
+
+  if (tx_a){
+    ok =  _write_9862 (which_codec, REG_TX_A_OFFSET_LO, lo);
+    ok &= _write_9862 (which_codec, REG_TX_A_OFFSET_HI, hi);
+  }
+  else {
+    ok =  _write_9862 (which_codec, REG_TX_B_OFFSET_LO, lo);
+    ok &= _write_9862 (which_codec, REG_TX_B_OFFSET_HI, hi);
+  }
+  return ok;
+}
+
+bool
+usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
+{
+  if (which_adc < 0 || which_adc > 3)
+    return false;
+
+  int codec = which_adc >> 1;
+  int reg = (which_adc & 1) == 0 ? REG_RX_A : REG_RX_B;
+
+  unsigned char cur_rx;
+  unsigned char cur_pwr_dn;
+
+  // If the input buffer is bypassed, we need to power it down too.
+
+  bool ok = _read_9862 (codec, reg, &cur_rx);
+  ok &= _read_9862 (codec, REG_RX_PWR_DN, &cur_pwr_dn);
+  if (!ok)
+    return false;
+
+  if (bypass){
+    cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
+    cur_pwr_dn |= ((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
+  }
+  else {
+    cur_rx &= ~RX_X_BYPASS_INPUT_BUFFER;
+    cur_pwr_dn &= ~(((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
+  }
+
+  ok &= _write_9862 (codec, reg, cur_rx);
+  ok &= _write_9862 (codec, REG_RX_PWR_DN, cur_pwr_dn);
+  return ok;
+}
+
+bool
+usrp_basic::set_dc_offset_cl_enable(int bits, int mask)
+{
+  return _write_fpga_reg(FR_DC_OFFSET_CL_EN,
+                        (d_fpga_shadows[FR_DC_OFFSET_CL_EN] & ~mask) | (bits & mask));
+}
+
+// ----------------------------------------------------------------
+
+bool
+usrp_basic::_write_fpga_reg (int regno, int value)
+{
+  if (d_verbose){
+    fprintf (stdout, "_write_fpga_reg(%3d, 0x%08x)\n", regno, value);
+    fflush (stdout);
+  }
+
+  if (regno >= 0 && regno < MAX_REGS)
+    d_fpga_shadows[regno] = value;
+
+  return usrp_write_fpga_reg (d_udh, regno, value);
+}
+
+bool
+usrp_basic::_write_fpga_reg_masked (int regno, int value, int mask)
+{
+  //Only use this for registers who actually use a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
+  //value is a 16 bits value and mask is a 16 bits mask
+  if (d_verbose){
+    fprintf (stdout, "_write_fpga_reg_masked(%3d, 0x%04x,0x%04x)\n", regno, value, mask);
+    fflush (stdout);
+  }
+
+  if (regno >= 0 && regno < MAX_REGS)
+    d_fpga_shadows[regno] = value;
+
+  return usrp_write_fpga_reg (d_udh, regno, (value & 0xffff) | ((mask & 0xffff)<<16));
+}
+
+
+bool
+usrp_basic::_read_fpga_reg (int regno, int *value)
+{
+  return usrp_read_fpga_reg (d_udh, regno, value);
+}
+
+int
+usrp_basic::_read_fpga_reg (int regno)
+{
+  int value;
+  if (!_read_fpga_reg (regno, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic::_write_9862 (int which_codec, int regno, unsigned char value)
+{
+  if (0 && d_verbose){
+    // FIXME really want to enable logging in usrp_prims:usrp_9862_write
+    fprintf(stdout, "_write_9862(codec = %d, regno = %2d, val = 0x%02x)\n", which_codec, regno, value);
+    fflush(stdout);
+  }
+
+  return usrp_9862_write (d_udh, which_codec, regno, value);
+}
+
+
+bool
+usrp_basic::_read_9862 (int which_codec, int regno, unsigned char *value) const
+{
+  return usrp_9862_read (d_udh, which_codec, regno, value);
+}
+
+int
+usrp_basic::_read_9862 (int which_codec, int regno) const
+{
+  unsigned char value;
+  if (!_read_9862 (which_codec, regno, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic::_write_spi (int optional_header, int enables, int format, std::string buf)
+{
+  return usrp_spi_write (d_udh, optional_header, enables, format,
+                        buf.data(), buf.size());
+}
+
+std::string
+usrp_basic::_read_spi (int optional_header, int enables, int format, int len)
+{
+  if (len <= 0)
+    return "";
+
+  char buf[len];
+
+  if (!usrp_spi_read (d_udh, optional_header, enables, format, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+
+bool
+usrp_basic::_set_led (int which_led, bool on)
+{
+  return usrp_set_led (d_udh, which_led, on);
+}
+
+bool
+usrp_basic::write_atr_tx_delay(int value)
+{
+  return _write_fpga_reg(FR_ATR_TX_DELAY, value);
+}
+
+bool
+usrp_basic::write_atr_rx_delay(int value)
+{
+  return _write_fpga_reg(FR_ATR_RX_DELAY, value);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Routines to access and control daughterboard specific i/o
+ * ----------------------------------------------------------------
+ */
+static int
+slot_id_to_oe_reg (int slot_id)
+{
+  static int reg[4]  = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+slot_id_to_io_reg (int slot_id)
+{
+  static int reg[4]  = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+slot_id_to_refclk_reg(int slot_id)
+{
+  static int reg[4]  = { FR_TX_A_REFCLK, FR_RX_A_REFCLK, FR_TX_B_REFCLK, FR_RX_B_REFCLK };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_mask_reg(int slot_id)
+{
+  static int reg[4]  = { FR_ATR_MASK_0, FR_ATR_MASK_1, FR_ATR_MASK_2, FR_ATR_MASK_3 };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_txval_reg(int slot_id)
+{
+  static int reg[4]  = { FR_ATR_TXVAL_0, FR_ATR_TXVAL_1, FR_ATR_TXVAL_2, FR_ATR_TXVAL_3 };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+slot_id_to_atr_rxval_reg(int slot_id)
+{
+  static int reg[4]  = { FR_ATR_RXVAL_0, FR_ATR_RXVAL_1, FR_ATR_RXVAL_2, FR_ATR_RXVAL_3 };
+  assert (0 <= slot_id && slot_id < 4);
+  return reg[slot_id];
+}
+
+static int
+to_slot(txrx_t txrx, int which_side)
+{
+  // TX_A = 0
+  // RX_A = 1
+  // TX_B = 2
+  // RX_B = 3
+  return ((which_side & 0x1) << 1) | ((txrx & 0x1) == C_RX);
+}
+
+bool
+usrp_basic::common_set_pga(txrx_t txrx, int which_amp, double gain)
+{
+  if (which_amp < 0 || which_amp > 3)
+    return false;
+
+  gain = std::min(common_pga_max(txrx),
+                 std::max(common_pga_min(txrx), gain));
+
+  int codec = which_amp >> 1;  
+  int int_gain = (int) rint((gain - common_pga_min(txrx)) / common_pga_db_per_step(txrx));
+
+  if (txrx == C_TX){           // 0 and 1 are same, as are 2 and 3
+    return _write_9862(codec, REG_TX_PGA, int_gain);
+  }
+  else {
+    int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
+
+    // read current value to get input buffer bypass flag.
+    unsigned char cur_rx;
+    if (!_read_9862(codec, reg, &cur_rx))
+      return false;
+
+    cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
+    return _write_9862(codec, reg, cur_rx);
+  }
+}
+
+double
+usrp_basic::common_pga(txrx_t txrx, int which_amp) const
+{
+  if (which_amp < 0 || which_amp > 3)
+    return READ_FAILED;
+
+  if (txrx == C_TX){
+    int codec = which_amp >> 1;
+    unsigned char v;
+    bool ok = _read_9862 (codec, REG_TX_PGA, &v);
+    if (!ok)
+      return READ_FAILED;
+
+    return (pga_db_per_step() * v) + pga_min();
+  }
+  else {
+    int codec = which_amp >> 1;
+    int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
+    unsigned char v;
+    bool ok = _read_9862 (codec, reg, &v);
+    if (!ok)
+      return READ_FAILED;
+
+    return (pga_db_per_step() * (v & 0x1f)) + pga_min();
+  }
+}
+
+double
+usrp_basic::common_pga_min(txrx_t txrx) const
+{
+  if (txrx == C_TX)
+    return -20.0;
+  else
+    return   0.0;
+}
+
+double
+usrp_basic::common_pga_max(txrx_t txrx) const
+{
+  if (txrx == C_TX)
+    return   0.0;
+  else
+    return  20.0;
+}
+
+double
+usrp_basic::common_pga_db_per_step(txrx_t txrx) const
+{
+  if (txrx == C_TX)
+    return  20.0 / 255;
+  else
+    return  20.0 / 20;
+}
+
+bool
+usrp_basic::_common_write_oe(txrx_t txrx, int which_side, int value, int mask)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_oe_reg(to_slot(txrx, which_side)),
+                        (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic::common_write_io(txrx_t txrx, int which_side, int value, int mask)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_io_reg(to_slot(txrx, which_side)),
+                        (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic::common_read_io(txrx_t txrx, int which_side, int *value)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  int t;
+  int reg = which_side + 1;    // FIXME, *very* magic number (fix in serial_io.v)
+  bool ok = _read_fpga_reg(reg, &t);
+  if (!ok)
+    return false;
+
+  if (txrx == C_TX){
+    *value = t & 0xffff;               // FIXME, more magic
+    return true;
+  }
+  else {
+    *value = (t >> 16) & 0xffff;       // FIXME, more magic
+    return true;
+  }
+}
+
+int
+usrp_basic::common_read_io(txrx_t txrx, int which_side)
+{
+  int  value;
+  if (!common_read_io(txrx, which_side, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic::common_write_refclk(txrx_t txrx, int which_side, int value)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_refclk_reg(to_slot(txrx, which_side)),
+                        value);
+}
+
+bool
+usrp_basic::common_write_atr_mask(txrx_t txrx, int which_side, int value)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_atr_mask_reg(to_slot(txrx, which_side)),
+                        value);
+}
+
+bool
+usrp_basic::common_write_atr_txval(txrx_t txrx, int which_side, int value)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_atr_txval_reg(to_slot(txrx, which_side)),
+                        value);
+}
+
+bool
+usrp_basic::common_write_atr_rxval(txrx_t txrx, int which_side, int value)
+{
+  if (! (0 <= which_side && which_side <= 1))
+    return false;
+
+  return _write_fpga_reg(slot_id_to_atr_rxval_reg(to_slot(txrx, which_side)),
+                        value);
+}
+
+bool
+usrp_basic::common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value)
+{
+  return _write_aux_dac(to_slot(txrx, which_side), which_dac, value);
+}
+
+bool
+usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value)
+{
+  return _read_aux_adc(to_slot(txrx, which_side), which_adc, value);
+}
+
+int
+usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc)
+{
+  return _read_aux_adc(to_slot(txrx, which_side), which_adc);
+}
+
+
+////////////////////////////////////////////////////////////////
+//
+//                        usrp_basic_rx
+//
+////////////////////////////////////////////////////////////////
+
+static unsigned char rx_init_regs[] = {
+  REG_RX_PWR_DN,       0,
+  REG_RX_A,            0,      // minimum gain = 0x00 (max gain = 0x14)
+  REG_RX_B,            0,      // minimum gain = 0x00 (max gain = 0x14)
+  REG_RX_MISC,         (RX_MISC_HS_DUTY_CYCLE | RX_MISC_CLK_DUTY),
+  REG_RX_IF,           (RX_IF_USE_CLKOUT1
+                        | RX_IF_2S_COMP),
+  REG_RX_DIGITAL,      (RX_DIGITAL_2_CHAN)
+};
+
+
+usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nblocks,
+                             const std::string fpga_filename,
+                             const std::string firmware_filename
+                             )
+  : usrp_basic (which_board, open_rx_interface, fpga_filename, firmware_filename),
+    d_devhandle (0), d_ephandle (0),
+    d_bytes_seen (0), d_first_read (true),
+    d_rx_enable (false)
+{
+  // initialize rx specific registers
+
+  if (!usrp_9862_write_many_all (d_udh, rx_init_regs, sizeof (rx_init_regs))){
+    fprintf (stderr, "usrp_basic_rx: failed to init AD9862 RX regs\n");
+    throw std::runtime_error ("usrp_basic_rx/init_9862");
+  }
+
+  if (0){
+    // FIXME power down 2nd codec rx path
+    usrp_9862_write (d_udh, 1, REG_RX_PWR_DN, 0x1);    // power down everything
+  }
+
+  // Reset the rx path and leave it disabled.
+  set_rx_enable (false);
+  usrp_set_fpga_rx_reset (d_udh, true);
+  usrp_set_fpga_rx_reset (d_udh, false);
+
+  set_fpga_rx_sample_rate_divisor (2); // usually correct
+
+  set_dc_offset_cl_enable(0xf, 0xf);   // enable DC offset removal control loops
+
+  probe_rx_slots (false);
+
+  //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
+  //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
+
+  // check fusb buffering parameters
+
+  if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
+
+  if (fusb_nblocks < 0)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
+
+  if (fusb_block_size == 0)
+    fusb_block_size = fusb_sysconfig::default_block_size();
+
+  if (fusb_nblocks == 0)
+    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
+
+  d_devhandle = fusb_sysconfig::make_devhandle (d_udh, d_ctx);
+  d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
+                                          fusb_block_size, fusb_nblocks);
+
+  write_atr_mask(0, 0);                // zero Rx A Auto Transmit/Receive regs
+  write_atr_txval(0, 0);
+  write_atr_rxval(0, 0);
+  write_atr_mask(1, 0);                // zero Rx B Auto Transmit/Receive regs
+  write_atr_txval(1, 0);
+  write_atr_rxval(1, 0);
+}
+
+static unsigned char rx_fini_regs[] = {
+  REG_RX_PWR_DN,       0x1                             // power down everything
+};
+
+usrp_basic_rx::~usrp_basic_rx ()
+{
+  if (!set_rx_enable (false)){
+    fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n");
+  }
+
+  d_ephandle->stop ();
+  delete d_ephandle;
+  delete d_devhandle;
+
+  if (!usrp_9862_write_many_all (d_udh, rx_fini_regs, sizeof (rx_fini_regs))){
+    fprintf (stderr, "usrp_basic_rx: failed to fini AD9862 RX regs\n");
+  }
+
+  shutdown_daughterboards();
+}
+
+
+bool
+usrp_basic_rx::start ()
+{
+  if (!usrp_basic::start ())   // invoke parent's method
+    return false;
+
+  // fire off reads before asserting rx_enable
+
+  if (!d_ephandle->start ()){
+    fprintf (stderr, "usrp_basic_rx: failed to start end point streaming");
+    return false;
+  }
+
+  if (!set_rx_enable (true)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
+    return false;
+  }
+
+  return true;
+}
+
+bool
+usrp_basic_rx::stop ()
+{
+  bool ok = usrp_basic::stop();
+
+  if (!set_rx_enable(false)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
+    ok = false;
+  }
+
+  if (!d_ephandle->stop()){
+    fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
+    ok = false;
+  }
+
+  return ok;
+}
+
+usrp_basic_rx *
+usrp_basic_rx::make (int which_board, int fusb_block_size, int fusb_nblocks,
+                    const std::string fpga_filename,
+                    const std::string firmware_filename)
+{
+  usrp_basic_rx *u = 0;
+
+  try {
+    u = new usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
+                          fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+bool
+usrp_basic_rx::set_fpga_rx_sample_rate_divisor (unsigned int div)
+{
+  return _write_fpga_reg (FR_RX_SAMPLE_RATE_DIV, div - 1);
+}
+
+
+/*
+ * \brief read data from the D/A's via the FPGA.
+ * \p len must be a multiple of 512 bytes.
+ *
+ * \returns the number of bytes read, or -1 on error.
+ *
+ * If overrun is non-NULL it will be set true iff an RX overrun is detected.
+ */
+int
+usrp_basic_rx::read (void *buf, int len, bool *overrun)
+{
+  int  r;
+
+  if (overrun)
+    *overrun = false;
+
+  if (len < 0 || (len % 512) != 0){
+    fprintf (stderr, "usrp_basic_rx::read: invalid length = %d\n", len);
+    return -1;
+  }
+
+  r = d_ephandle->read (buf, len);
+  if (r > 0)
+    d_bytes_seen += r;
+
+  /*
+   * In many cases, the FPGA reports an rx overrun right after we
+   * enable the Rx path.  If this is our first read, check for the
+   * overrun to clear the condition, then ignore the result.
+   */
+  if (0 && d_first_read){      // FIXME
+    d_first_read = false;
+    bool bogus_overrun;
+    usrp_check_rx_overrun (d_udh, &bogus_overrun);
+  }
+
+  if (overrun != 0 && d_bytes_seen >= d_bytes_per_poll){
+    d_bytes_seen = 0;
+    if (!usrp_check_rx_overrun (d_udh, overrun)){
+      fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n");
+    }
+  }
+
+  return r;
+}
+
+bool
+usrp_basic_rx::set_rx_enable (bool on)
+{
+  d_rx_enable = on;
+  return usrp_set_fpga_rx_enable (d_udh, on);
+}
+
+// conditional disable, return prev state
+bool
+usrp_basic_rx::disable_rx ()
+{
+  bool enabled = rx_enable ();
+  if (enabled)
+    set_rx_enable (false);
+  return enabled;
+}
+
+// conditional set
+void
+usrp_basic_rx::restore_rx (bool on)
+{
+  if (on != rx_enable ())
+    set_rx_enable (on);
+}
+
+void
+usrp_basic_rx::probe_rx_slots (bool verbose)
+{
+  struct usrp_dboard_eeprom    eeprom;
+  static int slot_id_map[2] = { SLOT_RX_A, SLOT_RX_B };
+  static const char *slot_name[2] = { "RX d'board A", "RX d'board B" };
+
+  for (int i = 0; i < 2; i++){
+    int slot_id = slot_id_map [i];
+    const char *msg = 0;
+    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
+
+    switch (s){
+    case UDBE_OK:
+      d_dbid[i] = eeprom.id;
+      msg = usrp_dbid_to_string (eeprom.id).c_str ();
+      set_adc_offset (2*i+0, eeprom.offset[0]);
+      set_adc_offset (2*i+1, eeprom.offset[1]);
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_NO_EEPROM:
+      d_dbid[i] = -1;
+      msg = "<none>";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_INVALID_EEPROM:
+      d_dbid[i] = -2;
+      msg = "Invalid EEPROM contents";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_BAD_SLOT:
+    default:
+      assert (0);
+    }
+
+    if (verbose){
+      fflush (stdout);
+      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
+    }
+  }
+}
+
+bool
+usrp_basic_rx::set_pga (int which_amp, double gain)
+{
+  return common_set_pga(C_RX, which_amp, gain);
+}
+
+double
+usrp_basic_rx::pga(int which_amp) const
+{
+  return common_pga(C_RX, which_amp);
+}
+
+double
+usrp_basic_rx::pga_min() const
+{
+  return common_pga_min(C_RX);
+}
+
+double
+usrp_basic_rx::pga_max() const
+{
+  return common_pga_max(C_RX);
+}
+
+double
+usrp_basic_rx::pga_db_per_step() const
+{
+  return common_pga_db_per_step(C_RX);
+}
+
+bool
+usrp_basic_rx::_write_oe (int which_side, int value, int mask)
+{
+  return _common_write_oe(C_RX, which_side, value, mask);
+}
+
+bool
+usrp_basic_rx::write_io (int which_side, int value, int mask)
+{
+  return common_write_io(C_RX, which_side, value, mask);
+}
+
+bool
+usrp_basic_rx::read_io (int which_side, int *value)
+{
+  return common_read_io(C_RX, which_side, value);
+}
+
+int
+usrp_basic_rx::read_io (int which_side)
+{
+  return common_read_io(C_RX, which_side);
+}
+
+bool
+usrp_basic_rx::write_refclk(int which_side, int value)
+{
+  return common_write_refclk(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_atr_mask(int which_side, int value)
+{
+  return common_write_atr_mask(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_atr_txval(int which_side, int value)
+{
+  return common_write_atr_txval(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_atr_rxval(int which_side, int value)
+{
+  return common_write_atr_rxval(C_RX, which_side, value);
+}
+
+bool
+usrp_basic_rx::write_aux_dac (int which_side, int which_dac, int value)
+{
+  return common_write_aux_dac(C_RX, which_side, which_dac, value);
+}
+
+bool
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc, int *value)
+{
+  return common_read_aux_adc(C_RX, which_side, which_adc, value);
+}
+
+int
+usrp_basic_rx::read_aux_adc (int which_side, int which_adc)
+{
+  return common_read_aux_adc(C_RX, which_side, which_adc);
+}
+
+int
+usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+
+////////////////////////////////////////////////////////////////
+//
+//                        usrp_basic_tx
+//
+////////////////////////////////////////////////////////////////
+
+
+//
+// DAC input rate 64 MHz interleaved for a total input rate of 128 MHz
+// DAC input is latched on rising edge of CLKOUT2
+// NCO is disabled
+// interpolate 2x
+// coarse modulator disabled
+//
+
+static unsigned char tx_init_regs[] = {
+  REG_TX_PWR_DN,       0,
+  REG_TX_A_OFFSET_LO,  0,
+  REG_TX_A_OFFSET_HI,  0,
+  REG_TX_B_OFFSET_LO,  0,
+  REG_TX_B_OFFSET_HI,  0,
+  REG_TX_A_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
+  REG_TX_B_GAIN,       (TX_X_GAIN_COARSE_FULL | 0),
+  REG_TX_PGA,          0xff,                   // maximum gain (0 dB)
+  REG_TX_MISC,         0,
+  REG_TX_IF,           (TX_IF_USE_CLKOUT1
+                        | TX_IF_I_FIRST
+                        | TX_IF_INV_TX_SYNC
+                        | TX_IF_2S_COMP
+                        | TX_IF_INTERLEAVED),
+  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
+                        | TX_DIGITAL_INTERPOLATE_4X),
+  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
+                        | TX_MODULATOR_COARSE_MODULATION_NONE),
+  REG_TX_NCO_FTW_7_0,  0,
+  REG_TX_NCO_FTW_15_8, 0,
+  REG_TX_NCO_FTW_23_16,        0
+};
+
+usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nblocks,
+                             const std::string fpga_filename,
+                             const std::string firmware_filename)
+  : usrp_basic (which_board, open_tx_interface, fpga_filename, firmware_filename),
+    d_devhandle (0), d_ephandle (0),
+    d_bytes_seen (0), d_first_write (true),
+    d_tx_enable (false)
+{
+  if (!usrp_9862_write_many_all (d_udh, tx_init_regs, sizeof (tx_init_regs))){
+    fprintf (stderr, "usrp_basic_tx: failed to init AD9862 TX regs\n");
+    throw std::runtime_error ("usrp_basic_tx/init_9862");
+  }
+
+  if (0){
+    // FIXME power down 2nd codec tx path
+    usrp_9862_write (d_udh, 1, REG_TX_PWR_DN,
+                    (TX_PWR_DN_TX_DIGITAL
+                     | TX_PWR_DN_TX_ANALOG_BOTH));
+  }
+
+  // Reset the tx path and leave it disabled.
+  set_tx_enable (false);
+  usrp_set_fpga_tx_reset (d_udh, true);
+  usrp_set_fpga_tx_reset (d_udh, false);
+
+  set_fpga_tx_sample_rate_divisor (4); // we're using interp x4
+
+  probe_tx_slots (false);
+
+  //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
+  //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
+
+  // check fusb buffering parameters
+
+  if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
+
+  if (fusb_nblocks < 0)
+    throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
+
+  if (fusb_block_size == 0)
+    fusb_block_size = FUSB_BLOCK_SIZE;
+
+  if (fusb_nblocks == 0)
+    fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
+
+  d_devhandle = fusb_sysconfig::make_devhandle (d_udh, d_ctx);
+  d_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
+                                          fusb_block_size, fusb_nblocks);
+
+  write_atr_mask(0, 0);                // zero Tx A Auto Transmit/Receive regs
+  write_atr_txval(0, 0);
+  write_atr_rxval(0, 0);
+  write_atr_mask(1, 0);                // zero Tx B Auto Transmit/Receive regs
+  write_atr_txval(1, 0);
+  write_atr_rxval(1, 0);
+}
+
+
+static unsigned char tx_fini_regs[] = {
+  REG_TX_PWR_DN,       (TX_PWR_DN_TX_DIGITAL
+                        | TX_PWR_DN_TX_ANALOG_BOTH),
+  REG_TX_MODULATOR,    (TX_MODULATOR_DISABLE_NCO
+                        | TX_MODULATOR_COARSE_MODULATION_NONE)
+};
+
+usrp_basic_tx::~usrp_basic_tx ()
+{
+  d_ephandle->stop ();
+  delete d_ephandle;
+  delete d_devhandle;
+
+  if (!usrp_9862_write_many_all (d_udh, tx_fini_regs, sizeof (tx_fini_regs))){
+    fprintf (stderr, "usrp_basic_tx: failed to fini AD9862 TX regs\n");
+  }
+
+  shutdown_daughterboards();
+}
+
+bool
+usrp_basic_tx::start ()
+{
+  if (!usrp_basic::start ())
+    return false;
+
+  if (!set_tx_enable (true)){
+    fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n");
+    return false;
+  }
+
+  if (!d_ephandle->start ()){
+    fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
+    return false;
+  }
+
+  return true;
+}
+
+bool
+usrp_basic_tx::stop ()
+{
+  bool ok = usrp_basic::stop ();
+
+  if (!d_ephandle->stop ()){
+    fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
+    ok = false;
+  }
+
+  if (!set_tx_enable (false)){
+    fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
+    ok = false;
+  }
+
+  return ok;
+}
+
+usrp_basic_tx *
+usrp_basic_tx::make (int which_board, int fusb_block_size, int fusb_nblocks,
+                    const std::string fpga_filename,
+                    const std::string firmware_filename)
+{
+  usrp_basic_tx *u = 0;
+
+  try {
+    u = new usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks,
+                          fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+bool
+usrp_basic_tx::set_fpga_tx_sample_rate_divisor (unsigned int div)
+{
+  return _write_fpga_reg (FR_TX_SAMPLE_RATE_DIV, div - 1);
+}
+
+/*!
+ * \brief Write data to the A/D's via the FPGA.
+ *
+ * \p len must be a multiple of 512 bytes.
+ * \returns number of bytes written or -1 on error.
+ *
+ * if \p underrun is non-NULL, it will be set to true iff
+ * a transmit underrun condition is detected.
+ */
+int
+usrp_basic_tx::write (const void *buf, int len, bool *underrun)
+{
+  int  r;
+
+  if (underrun)
+    *underrun = false;
+
+  if (len < 0 || (len % 512) != 0){
+    fprintf (stderr, "usrp_basic_tx::write: invalid length = %d\n", len);
+    return -1;
+  }
+
+  r = d_ephandle->write (buf, len);
+  if (r > 0)
+    d_bytes_seen += r;
+
+  /*
+   * In many cases, the FPGA reports an tx underrun right after we
+   * enable the Tx path.  If this is our first write, check for the
+   * underrun to clear the condition, then ignore the result.
+   */
+  if (d_first_write && d_bytes_seen >= 4 * FUSB_BLOCK_SIZE){
+    d_first_write = false;
+    bool bogus_underrun;
+    usrp_check_tx_underrun (d_udh, &bogus_underrun);
+  }
+
+  if (underrun != 0 && d_bytes_seen >= d_bytes_per_poll){
+    d_bytes_seen = 0;
+    if (!usrp_check_tx_underrun (d_udh, underrun)){
+      fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n");
+    }
+  }
+
+  return r;
+}
+
+void
+usrp_basic_tx::wait_for_completion ()
+{
+  d_ephandle->wait_for_completion ();
+}
+
+bool
+usrp_basic_tx::set_tx_enable (bool on)
+{
+  d_tx_enable = on;
+  // fprintf (stderr, "set_tx_enable %d\n", on);
+  return usrp_set_fpga_tx_enable (d_udh, on);
+}
+
+// conditional disable, return prev state
+bool
+usrp_basic_tx::disable_tx ()
+{
+  bool enabled = tx_enable ();
+  if (enabled)
+    set_tx_enable (false);
+  return enabled;
+}
+
+// conditional set
+void
+usrp_basic_tx::restore_tx (bool on)
+{
+  if (on != tx_enable ())
+    set_tx_enable (on);
+}
+
+void
+usrp_basic_tx::probe_tx_slots (bool verbose)
+{
+  struct usrp_dboard_eeprom    eeprom;
+  static int slot_id_map[2] = { SLOT_TX_A, SLOT_TX_B };
+  static const char *slot_name[2] = { "TX d'board A", "TX d'board B" };
+
+  for (int i = 0; i < 2; i++){
+    int slot_id = slot_id_map [i];
+    const char *msg = 0;
+    usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
+
+    switch (s){
+    case UDBE_OK:
+      d_dbid[i] = eeprom.id;
+      msg = usrp_dbid_to_string (eeprom.id).c_str ();
+      // FIXME, figure out interpretation of dc offset for TX d'boards
+      // offset = (eeprom.offset[1] << 16) | (eeprom.offset[0] & 0xffff);
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_NO_EEPROM:
+      d_dbid[i] = -1;
+      msg = "<none>";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_INVALID_EEPROM:
+      d_dbid[i] = -2;
+      msg = "Invalid EEPROM contents";
+      _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
+      _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
+      break;
+
+    case UDBE_BAD_SLOT:
+    default:
+      assert (0);
+    }
+
+    if (verbose){
+      fflush (stdout);
+      fprintf (stderr, "%s: %s\n", slot_name[i], msg);
+    }
+  }
+}
+
+bool
+usrp_basic_tx::set_pga (int which_amp, double gain)
+{
+  return common_set_pga(C_TX, which_amp, gain);
+}
+
+double
+usrp_basic_tx::pga (int which_amp) const
+{
+  return common_pga(C_TX, which_amp);
+}
+
+double
+usrp_basic_tx::pga_min() const
+{
+  return common_pga_min(C_TX);
+}
+
+double
+usrp_basic_tx::pga_max() const
+{
+  return common_pga_max(C_TX);
+}
+
+double
+usrp_basic_tx::pga_db_per_step() const
+{
+  return common_pga_db_per_step(C_TX);
+}
+
+bool
+usrp_basic_tx::_write_oe (int which_side, int value, int mask)
+{
+  return _common_write_oe(C_TX, which_side, value, mask);
+}
+
+bool
+usrp_basic_tx::write_io (int which_side, int value, int mask)
+{
+  return common_write_io(C_TX, which_side, value, mask);
+}
+
+bool
+usrp_basic_tx::read_io (int which_side, int *value)
+{
+  return common_read_io(C_TX, which_side, value);
+}
+
+int
+usrp_basic_tx::read_io (int which_side)
+{
+  return common_read_io(C_TX, which_side);
+}
+
+bool
+usrp_basic_tx::write_refclk(int which_side, int value)
+{
+  return common_write_refclk(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_mask(int which_side, int value)
+{
+  return common_write_atr_mask(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_txval(int which_side, int value)
+{
+  return common_write_atr_txval(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_atr_rxval(int which_side, int value)
+{
+  return common_write_atr_rxval(C_TX, which_side, value);
+}
+
+bool
+usrp_basic_tx::write_aux_dac (int which_side, int which_dac, int value)
+{
+  return common_write_aux_dac(C_TX, which_side, which_dac, value);
+}
+
+bool
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
+{
+  return common_read_aux_adc(C_TX, which_side, which_adc, value);
+}
+
+int
+usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
+{
+  return common_read_aux_adc(C_TX, which_side, which_adc);
+}
+
+int
+usrp_basic_tx::block_size () const { return d_ephandle->block_size(); }
+
diff --git a/usrp/host/lib/usrp_config.cc b/usrp/host/lib/usrp_config.cc
new file mode 100644 (file)
index 0000000..fcf207f
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "usrp_config.h"
+
+int
+usrp_rx_config_stream_count (unsigned int usrp_rx_config)
+{
+  return 1;
+}
+
+int
+usrp_tx_config_stream_count (unsigned int usrp_tx_config)
+{
+  return 1;
+}
diff --git a/usrp/host/lib/usrp_config.h b/usrp/host/lib/usrp_config.h
new file mode 100644 (file)
index 0000000..ee5cb63
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+#ifndef _USRP_CONFIG_H_
+#define _USRP_CONFIG_H_
+
+/*
+ * ----------------------------------------------------------------
+ * USRP Rx configurations.
+ *
+ * For now this is a placeholder, but will eventually specify the
+ * mapping from A/D outputs to DDC inputs (I & Q).
+ *
+ * What's implemented today is a single DDC that has its I input
+ * connected to ADC0 and its Q input connected to ADC1
+ * ----------------------------------------------------------------
+ */
+
+#define        USRP_RX_CONFIG_DEFAULT  0
+
+/*!
+ * given a usrp_rx_config word, return the number of I & Q streams that
+ * are interleaved on the USB.
+ */
+
+int usrp_rx_config_stream_count (unsigned int usrp_rx_config);
+
+/*
+ * USRP Tx configurations.
+ *
+ * For now this is a placeholder, but will eventually specify the
+ * mapping from DUC outputs to D/A inputs.
+ *
+ * What's implemented today is a single DUC that has its I output
+ * connected to DAC0 and its Q output connected to DAC1
+ */
+
+#define        USRP_TX_CONFIG_DEFAULT  0
+
+/*!
+ * given a usrp_tx_config word, return the number of I & Q streams that
+ * are interleaved on the USB.
+ */
+
+int usrp_tx_config_stream_count (unsigned int usrp_tx_config);
+
+
+#endif /* _USRP_CONFIG_H_ */
diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat
new file mode 100644 (file)
index 0000000..5193a5f
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# Copyright 2005,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+# This file is used to generate usrp_dbid.h, usrp_dbid.cc and usrp_dbid.py
+
+"Basic Tx"             0x0000
+"Basic Rx"             0x0001
+"DBS Rx"               0x0002
+"TV Rx"                        0x0003
+
+"Flex 400 Rx"          0x0004
+"Flex 900 Rx"          0x0005
+"Flex 1200 Rx"         0x0006
+"Flex 2400 Rx"         0x0007
+
+"Flex 400 Tx"          0x0008
+"Flex 900 Tx"          0x0009
+"Flex 1200 Tx"         0x000a
+"Flex 2400 Tx"         0x000b
+
+"TV Rx Rev 2"          0x000c
+"DBS Rx ClkMod"                0x000d
+
+"LF Tx"                        0x000e
+"LF Rx"                        0x000f
+
+"Flex 400 Rx MIMO A"   0x0014
+"Flex 900 Rx MIMO A"   0x0015
+"Flex 1200 Rx MIMO A"  0x0016
+"Flex 2400 Rx MIMO A"  0x0017
+
+"Flex 400 Tx MIMO A"   0x0018
+"Flex 900 Tx MIMO A"   0x0019
+"Flex 1200 Tx MIMO A"  0x001a
+"Flex 2400 Tx MIMO A"  0x001b
+
+"Flex 400 Rx MIMO B"   0x0024
+"Flex 900 Rx MIMO B"   0x0025
+"Flex 1200 Rx MIMO B"  0x0026
+"Flex 2400 Rx MIMO B"  0x0027
+
+"Flex 400 Tx MIMO B"   0x0028
+"Flex 900 Tx MIMO B"   0x0029
+"Flex 1200 Tx MIMO B"  0x002a
+"Flex 2400 Tx MIMO B"  0x002b
+
+"Flex 1800 Rx"         0x0030
+"Flex 1800 Tx"         0x0031
+"Flex 1800 Rx MIMO A"  0x0032
+"Flex 1800 Tx MIMO A"  0x0033
+"Flex 1800 Rx MIMO B"  0x0034
+"Flex 1800 Tx MIMO B"  0x0035
+
+"TV Rx Rev 3"          0x0040
+"DTT754"               0x0041
+"DTT768"               0x0042
+"TV Rx MIMO"           0x0043
+"TV Rx Rev 2 MIMO"     0x0044
+"TV Rx Rev 3 MIMO"     0x0045
+
+"WBX LO TX"            0x0050
+"WBX LO RX"            0x0051
+
+"WBX NG TX"            0x0052
+"WBX NG RX"            0x0053
+
+"XCVR2450 Tx"          0x0060
+"XCVR2450 Rx"          0x0061
+
+"Bitshark Rx"           0x0070
+
+"Experimental Tx"      0xfffe
+"Experimental Rx"      0xffff
diff --git a/usrp/host/lib/usrp_local_sighandler.cc b/usrp/host/lib/usrp_local_sighandler.cc
new file mode 100644 (file)
index 0000000..5901397
--- /dev/null
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009 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 is actually the same as gr_local_signhandler, but with a different name.
+ * We don't have a common library to put this in, so...
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/usrp_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+
+usrp_local_sighandler::usrp_local_sighandler (int signum,
+                                             void (*new_handler)(int))
+  : d_signum (signum)
+{
+#ifdef HAVE_SIGACTION
+  struct sigaction new_action;
+  memset (&new_action, 0, sizeof (new_action));
+
+  new_action.sa_handler = new_handler;
+  sigemptyset (&new_action.sa_mask);
+  new_action.sa_flags = 0;
+
+  if (sigaction (d_signum, &new_action, &d_old_action) < 0){
+    perror ("sigaction (install new)");
+    throw std::runtime_error ("sigaction");
+  }
+#endif
+}
+
+usrp_local_sighandler::~usrp_local_sighandler ()
+{
+#ifdef HAVE_SIGACTION
+  if (sigaction (d_signum, &d_old_action, 0) < 0){
+    perror ("sigaction (restore old)");
+    throw std::runtime_error ("sigaction");
+  }
+#endif
+}
+
+void
+usrp_local_sighandler::throw_signal(int signum) throw(usrp_signal)
+{
+  throw usrp_signal (signum);
+}
+
+/*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+
+#define SIGNAME(x) case x: return #x
+
+std::string
+usrp_signal::name () const
+{
+  char tmp[128];
+
+  switch (signal ()){
+#ifdef SIGHUP
+    SIGNAME (SIGHUP);
+#endif
+#ifdef SIGINT
+    SIGNAME (SIGINT);
+#endif
+#ifdef SIGQUIT
+    SIGNAME (SIGQUIT);
+#endif
+#ifdef SIGILL
+    SIGNAME (SIGILL);
+#endif
+#ifdef SIGTRAP
+    SIGNAME (SIGTRAP);
+#endif
+#ifdef SIGABRT
+    SIGNAME (SIGABRT);
+#endif
+#ifdef SIGBUS
+    SIGNAME (SIGBUS);
+#endif
+#ifdef SIGFPE
+    SIGNAME (SIGFPE);
+#endif
+#ifdef SIGKILL
+    SIGNAME (SIGKILL);
+#endif
+#ifdef SIGUSR1
+    SIGNAME (SIGUSR1);
+#endif
+#ifdef SIGSEGV
+    SIGNAME (SIGSEGV);
+#endif
+#ifdef SIGUSR2
+    SIGNAME (SIGUSR2);
+#endif
+#ifdef SIGPIPE
+    SIGNAME (SIGPIPE);
+#endif
+#ifdef SIGALRM
+    SIGNAME (SIGALRM);
+#endif
+#ifdef SIGTERM
+    SIGNAME (SIGTERM);
+#endif
+#ifdef SIGSTKFLT
+    SIGNAME (SIGSTKFLT);
+#endif
+#ifdef SIGCHLD
+    SIGNAME (SIGCHLD);
+#endif
+#ifdef SIGCONT
+    SIGNAME (SIGCONT);
+#endif
+#ifdef SIGSTOP
+    SIGNAME (SIGSTOP);
+#endif
+#ifdef SIGTSTP
+    SIGNAME (SIGTSTP);
+#endif
+#ifdef SIGTTIN
+    SIGNAME (SIGTTIN);
+#endif
+#ifdef SIGTTOU
+    SIGNAME (SIGTTOU);
+#endif
+#ifdef SIGURG
+    SIGNAME (SIGURG);
+#endif
+#ifdef SIGXCPU
+    SIGNAME (SIGXCPU);
+#endif
+#ifdef SIGXFSZ
+    SIGNAME (SIGXFSZ);
+#endif
+#ifdef SIGVTALRM
+    SIGNAME (SIGVTALRM);
+#endif
+#ifdef SIGPROF
+    SIGNAME (SIGPROF);
+#endif
+#ifdef SIGWINCH
+    SIGNAME (SIGWINCH);
+#endif
+#ifdef SIGIO
+    SIGNAME (SIGIO);
+#endif
+#ifdef SIGPWR
+    SIGNAME (SIGPWR);
+#endif
+#ifdef SIGSYS
+    SIGNAME (SIGSYS);
+#endif
+  default:
+#if defined (HAVE_SNPRINTF)
+#if defined (SIGRTMIN) && defined (SIGRTMAX) 
+    if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
+      snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
+      return tmp;
+    }
+#endif
+    snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
+    return tmp;
+#else
+    return "Unknown signal";
+#endif
+  }
+}
diff --git a/usrp/host/lib/usrp_prims_common.cc b/usrp/host/lib/usrp_prims_common.cc
new file mode 100644 (file)
index 0000000..20a5565
--- /dev/null
@@ -0,0 +1,1241 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2006,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp_primsi.h"
+#include "usrp_commands.h"
+#include "usrp_ids.h"
+#include "usrp_i2c_addr.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>              // FIXME should check with autoconf (nanosleep)
+#include <algorithm>
+#include <ad9862.h>
+#include <assert.h>
+#include "std_paths.h"
+
+extern "C" {
+#include "md5.h"
+};
+
+#define VERBOSE 0
+
+using namespace ad9862;
+
+static const int FIRMWARE_HASH_SLOT    = 0;
+static const int FPGA_HASH_SLOT        = 1;
+
+static const int hash_slot_addr[2] = {
+  USRP_HASH_SLOT_0_ADDR,
+  USRP_HASH_SLOT_1_ADDR
+};
+
+static const char *default_firmware_filename = "std.ihx";
+static const char *default_fpga_filename     = "std_2rxhb_2tx.rbf";
+
+static char *
+find_file (const char *filename, int hw_rev)
+{
+  const char **sp = std_paths;
+  static char path[1000];
+  char *s;
+
+  s = getenv("USRP_PATH");
+  if (s) {
+    snprintf (path, sizeof (path), "%s/rev%d/%s", s, hw_rev, filename);
+    if (access (path, R_OK) == 0)
+      return path;
+  }
+
+  while (*sp){
+    snprintf (path, sizeof (path), "%s/rev%d/%s", *sp, hw_rev, filename);
+    if (access (path, R_OK) == 0)
+      return path;
+    sp++;
+  }
+  return 0;
+}
+
+static const char *
+get_proto_filename(const std::string user_filename, const char *env_var, const char *def)
+{
+  if (user_filename.length() != 0)
+    return user_filename.c_str();
+
+  char *s = getenv(env_var);
+  if (s && *s)
+    return s;
+
+  return def;
+}
+
+
+static void power_down_9862s (libusb_device_handle *udh);
+
+
+// ----------------------------------------------------------------
+
+/*
+ * q must be a real USRP, not an FX2.  Return its hardware rev number.
+ */
+
+int
+usrp_hw_rev (libusb_device *q)
+{
+  libusb_device_descriptor desc = _get_usb_device_descriptor(q);
+  return desc.bcdDevice & 0x00FF;
+}
+
+/*
+ * q must be a real USRP, not an FX2.  Return true if it's configured.
+ */
+static bool
+_usrp_configured_p (libusb_device *q)
+{
+  libusb_device_descriptor desc = _get_usb_device_descriptor(q);
+  return (desc.bcdDevice & 0xFF00) != 0;
+}
+
+bool
+usrp_usrp_p (libusb_device *q)
+{
+  libusb_device_descriptor desc = _get_usb_device_descriptor(q);
+  return (desc.idVendor == USB_VID_FSF
+          && desc.idProduct == USB_PID_FSF_USRP);
+}
+
+bool
+usrp_fx2_p (libusb_device *q)
+{
+  libusb_device_descriptor desc = _get_usb_device_descriptor(q);
+  return (desc.idVendor == USB_VID_CYPRESS
+          && desc.idProduct == USB_PID_CYPRESS_FX2);
+}
+
+bool
+usrp_usrp0_p (libusb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 0;
+}
+
+bool
+usrp_usrp1_p (libusb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 1;
+}
+
+bool
+usrp_usrp2_p (libusb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 2;
+}
+
+
+bool
+usrp_unconfigured_usrp_p (libusb_device *q)
+{
+  return usrp_usrp_p (q) && !_usrp_configured_p (q);
+}
+
+bool
+usrp_configured_usrp_p (libusb_device *q)
+{
+  return usrp_usrp_p (q) && _usrp_configured_p (q);
+}
+
+
+// ----------------------------------------------------------------
+
+
+libusb_device_handle *
+usrp_open_cmd_interface (libusb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE);
+}
+
+libusb_device_handle *
+usrp_open_rx_interface (libusb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE);
+}
+
+libusb_device_handle *
+usrp_open_tx_interface (libusb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE);
+}
+
+
+// ----------------------------------------------------------------
+// write internal ram using Cypress vendor extension
+
+static bool
+write_internal_ram (libusb_device_handle *udh, unsigned char *buf,
+                    int start_addr, size_t len)
+{
+  int addr;
+  int n;
+  int a;
+  int quanta = MAX_EP0_PKTSIZE;
+
+  for (addr = start_addr; addr < start_addr + (int) len; addr += quanta){
+    n = len + start_addr - addr;
+    if (n > quanta)
+      n = quanta;
+
+    a = _usb_control_transfer (udh, 0x40, 0xA0, addr, 0,
+                       (unsigned char*)(buf + (addr - start_addr)), n, 1000);
+
+    if (a < 0){
+      fprintf(stderr,"write_internal_ram failed\n");
+      return false;
+    }
+  }
+  return true;
+}
+
+
+// ----------------------------------------------------------------
+// whack the CPUCS register using the upload RAM vendor extension
+
+static bool
+reset_cpu (libusb_device_handle *udh, bool reset_p)
+{
+  unsigned char v;
+
+  if (reset_p)
+    v = 1;             // hold processor in reset
+  else
+    v = 0;             // release reset
+
+  return write_internal_ram (udh, &v, 0xE600, 1);
+}
+
+// ----------------------------------------------------------------
+// Load intel format file into cypress FX2 (8051)
+
+static bool
+_usrp_load_firmware (libusb_device_handle *udh, const char *filename,
+                    unsigned char hash[USRP_HASH_SIZE])
+{
+  FILE *f = fopen (filename, "ra");
+  if (f == 0){
+    perror (filename);
+    return false;
+  }
+
+  if (!reset_cpu (udh, true))  // hold CPU in reset while loading firmware
+    goto fail;
+
+
+  char s[1024];
+  int length;
+  int addr;
+  int type;
+  unsigned char data[256];
+  unsigned char checksum, a;
+  unsigned int b;
+  int i;
+
+  while (!feof(f)){
+    fgets(s, sizeof (s), f); /* we should not use more than 263 bytes normally */
+    if(s[0]!=':'){
+      fprintf(stderr,"%s: invalid line: \"%s\"\n", filename, s);
+      goto fail;
+    }
+    sscanf(s+1, "%02x", &length);
+    sscanf(s+3, "%04x", &addr);
+    sscanf(s+7, "%02x", &type);
+
+    if(type==0){
+
+      a=length+(addr &0xff)+(addr>>8)+type;
+      for(i=0;i<length;i++){
+       sscanf (s+9+i*2,"%02x", &b);
+       data[i]=b;
+       a=a+data[i];
+      }
+
+      sscanf (s+9+length*2,"%02x", &b);
+      checksum=b;
+      if (((a+checksum)&0xff)!=0x00){
+       fprintf (stderr, "  ** Checksum failed: got 0x%02x versus 0x%02x\n", (-a)&0xff, checksum);
+       goto fail;
+      }
+      if (!write_internal_ram (udh, data, addr, length))
+       goto fail;
+    }
+    else if (type == 0x01){      // EOF
+      break;
+    }
+    else if (type == 0x02){
+      fprintf (stderr, "Extended address: whatever I do with it?\n");
+      fprintf (stderr, "%s: invalid line: \"%s\"\n", filename, s);
+      goto fail;
+    }
+  }
+
+  // we jam the hash value into the FX2 memory before letting
+  // the cpu out of reset.  When it comes out of reset it
+  // may renumerate which will invalidate udh.
+
+  if (!usrp_set_hash (udh, FIRMWARE_HASH_SLOT, hash))
+    fprintf (stderr, "usrp: failed to write firmware hash slot\n");
+
+  if (!reset_cpu (udh, false))         // take CPU out of reset
+    goto fail;
+
+  fclose (f);
+  return true;
+
+ fail:
+  fclose (f);
+  return false;
+}
+
+// ----------------------------------------------------------------
+// load fpga
+
+static bool
+_usrp_load_fpga (libusb_device_handle *udh, const char *filename,
+                unsigned char hash[USRP_HASH_SIZE])
+{
+  bool ok = true;
+
+  FILE *fp = fopen (filename, "rb");
+  if (fp == 0){
+    perror (filename);
+    return false;
+  }
+
+  unsigned char buf[MAX_EP0_PKTSIZE];  // 64 is max size of EP0 packet on FX2
+  int n;
+
+  usrp_set_led (udh, 1, 1);            // led 1 on
+
+
+  // reset FPGA (and on rev1 both AD9862's, thus killing clock)
+  usrp_set_fpga_reset (udh, 1);                // hold fpga in reset
+
+  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_BEGIN, 0, 0) != 0)
+    goto fail;
+
+  while ((n = fread (buf, 1, sizeof (buf), fp)) > 0){
+    if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_XFER, buf, n) != n)
+      goto fail;
+  }
+
+  if (write_cmd (udh, VRQ_FPGA_LOAD, 0, FL_END, 0, 0) != 0)
+    goto fail;
+
+  fclose (fp);
+
+  if (!usrp_set_hash (udh, FPGA_HASH_SLOT, hash))
+    fprintf (stderr, "usrp: failed to write fpga hash slot\n");
+
+  // On the rev1 USRP, the {tx,rx}_{enable,reset} bits are
+  // controlled over the serial bus, and hence aren't observed until
+  // we've got a good fpga bitstream loaded.
+
+  usrp_set_fpga_reset (udh, 0);                // fpga out of master reset
+
+  // now these commands will work
+
+  ok &= usrp_set_fpga_tx_enable (udh, 0);
+  ok &= usrp_set_fpga_rx_enable (udh, 0);
+
+  ok &= usrp_set_fpga_tx_reset (udh, 1);       // reset tx and rx paths
+  ok &= usrp_set_fpga_rx_reset (udh, 1);
+  ok &= usrp_set_fpga_tx_reset (udh, 0);       // reset tx and rx paths
+  ok &= usrp_set_fpga_rx_reset (udh, 0);
+
+  if (!ok)
+    fprintf (stderr, "usrp: failed to reset tx and/or rx path\n");
+
+  // Manually reset all regs except master control to zero.
+  // FIXME may want to remove this when we rework FPGA reset strategy.
+  // In the mean while, this gets us reproducible behavior.
+  for (int i = 0; i < FR_USER_0; i++){
+    if (i == FR_MASTER_CTRL)
+      continue;
+    usrp_write_fpga_reg(udh, i, 0);
+  }
+
+  power_down_9862s (udh);              // on the rev1, power these down!
+  usrp_set_led (udh, 1, 0);            // led 1 off
+
+  return true;
+
+ fail:
+  power_down_9862s (udh);              // on the rev1, power these down!
+  fclose (fp);
+  return false;
+}
+
+// ----------------------------------------------------------------
+
+bool
+usrp_set_led (libusb_device_handle *udh, int which, bool on)
+{
+  int r = write_cmd (udh, VRQ_SET_LED, on, which, 0, 0);
+
+  return r == 0;
+}
+
+bool
+usrp_set_hash (libusb_device_handle *udh, int which,
+               const unsigned char hash[USRP_HASH_SIZE])
+{
+  which &= 1;
+
+  // we use the Cypress firmware down load command to jam it in.
+  int r = _usb_control_transfer (udh, 0x40, 0xa0, hash_slot_addr[which], 0,
+                                (unsigned char *) hash, USRP_HASH_SIZE, 1000);
+
+  if (r < 0)
+     fprintf (stderr, "usrp: failed to set hash\n");
+
+  return r == USRP_HASH_SIZE;
+}
+
+bool
+usrp_get_hash (libusb_device_handle *udh, int which,
+               unsigned char hash[USRP_HASH_SIZE])
+{
+  which &= 1;
+
+  // we use the Cypress firmware upload command to fetch it.
+  int r = _usb_control_transfer (udh, 0xc0, 0xa0, hash_slot_addr[which], 0,
+                                (unsigned char *) hash, USRP_HASH_SIZE, 1000);
+
+  if (r < 0)
+     fprintf (stderr, "usrp: failed to get hash\n");
+
+  return r == USRP_HASH_SIZE;
+}
+
+
+
+static bool
+usrp_set_switch (libusb_device_handle *udh, int cmd_byte, bool on)
+{
+  return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;
+}
+
+static bool
+usrp1_fpga_write (libusb_device_handle *udh,
+                 int regno, int value)
+{
+  // on the rev1 usrp, we use the generic spi_write interface
+
+  unsigned char buf[4];
+
+  buf[0] = (value >> 24) & 0xff;       // MSB first
+  buf[1] = (value >> 16) & 0xff;
+  buf[2] = (value >>  8) & 0xff;
+  buf[3] = (value >>  0) & 0xff;
+
+  return usrp_spi_write (udh, 0x00 | (regno & 0x7f),
+                        SPI_ENABLE_FPGA,
+                        SPI_FMT_MSB | SPI_FMT_HDR_1,
+                        buf, sizeof (buf));
+}
+
+static bool
+usrp1_fpga_read (libusb_device_handle *udh,
+                int regno, int *value)
+{
+  *value = 0;
+  unsigned char buf[4];
+
+  bool ok = usrp_spi_read (udh, 0x80 | (regno & 0x7f),
+                          SPI_ENABLE_FPGA,
+                          SPI_FMT_MSB | SPI_FMT_HDR_1,
+                          buf, sizeof (buf));
+
+  if (ok)
+    *value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+
+  return ok;
+}
+
+bool
+usrp_write_fpga_reg (libusb_device_handle *udh, int reg, int value)
+{
+  switch (usrp_hw_rev (_get_usb_device (udh))){
+  case 0:                       // not supported ;)
+    abort();
+
+  default:
+    return usrp1_fpga_write (udh, reg, value);
+  }
+}
+
+bool
+usrp_read_fpga_reg (libusb_device_handle *udh, int reg, int *value)
+{
+  switch (usrp_hw_rev (_get_usb_device (udh))){
+  case 0:               // not supported ;)
+    abort();
+
+  default:
+    return usrp1_fpga_read (udh, reg, value);
+  }
+}
+
+bool
+usrp_set_fpga_reset (libusb_device_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on);
+}
+
+bool
+usrp_set_fpga_tx_enable (libusb_device_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on);
+}
+
+bool
+usrp_set_fpga_rx_enable (libusb_device_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on);
+}
+
+bool
+usrp_set_fpga_tx_reset (libusb_device_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on);
+}
+
+bool
+usrp_set_fpga_rx_reset (libusb_device_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_RESET, on);
+}
+
+
+// ----------------------------------------------------------------
+// conditional load stuff
+
+static bool
+compute_hash (const char *filename, unsigned char hash[USRP_HASH_SIZE])
+{
+  assert (USRP_HASH_SIZE == 16);
+  memset (hash, 0, USRP_HASH_SIZE);
+
+  FILE *fp = fopen (filename, "rb");
+  if (fp == 0){
+    perror (filename);
+    return false;
+  }
+  int r = md5_stream (fp, hash);
+  fclose (fp);
+
+  return r == 0;
+}
+
+static usrp_load_status_t
+usrp_conditionally_load_something (libusb_device_handle *udh,
+                                  const char *filename,
+                                  bool force,
+                                  int slot,
+                                  bool loader (libusb_device_handle *,
+                                               const char *,
+                                               unsigned char [USRP_HASH_SIZE]))
+{
+  unsigned char file_hash[USRP_HASH_SIZE];
+  unsigned char usrp_hash[USRP_HASH_SIZE];
+
+  if (access (filename, R_OK) != 0){
+    perror (filename);
+    return ULS_ERROR;
+  }
+
+  if (!compute_hash (filename, file_hash))
+    return ULS_ERROR;
+
+  if (!force
+      && usrp_get_hash (udh, slot, usrp_hash)
+      && memcmp (file_hash, usrp_hash, USRP_HASH_SIZE) == 0)
+    return ULS_ALREADY_LOADED;
+
+  bool r = loader (udh, filename, file_hash);
+
+  if (!r)
+    return ULS_ERROR;
+
+  return ULS_OK;
+}
+
+usrp_load_status_t
+usrp_load_firmware (libusb_device_handle *udh,
+                   const char *filename,
+                   bool force)
+{
+  return usrp_conditionally_load_something (udh, filename, force,
+                                           FIRMWARE_HASH_SLOT,
+                                           _usrp_load_firmware);
+}
+
+usrp_load_status_t
+usrp_load_fpga (libusb_device_handle *udh,
+               const char *filename,
+               bool force)
+{
+  return usrp_conditionally_load_something (udh, filename, force,
+                                           FPGA_HASH_SLOT,
+                                           _usrp_load_fpga);
+}
+
+static libusb_device_handle *
+open_nth_cmd_interface (int nth, libusb_context *ctx)
+{
+
+  libusb_device *udev = usrp_find_device (nth, false, ctx);
+  if (udev == 0){
+    fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
+    return 0;
+  }
+
+  libusb_device_handle *udh;
+
+  udh = usrp_open_cmd_interface (udev);
+  if (udh == 0){
+    // FIXME this could be because somebody else has it open.
+    // We should delay and retry...
+    fprintf (stderr, "open_nth_cmd_interface: open_cmd_interface failed\n");
+    return 0;
+  }
+
+  return udh;
+}
+
+static bool
+our_nanosleep (const struct timespec *delay)
+{
+  struct timespec      new_delay = *delay;
+  struct timespec      remainder;
+
+  while (1){
+    int r = nanosleep (&new_delay, &remainder);
+    if (r == 0)
+      return true;
+    if (errno == EINTR)
+      new_delay = remainder;
+    else {
+      perror ("nanosleep");
+      return false;
+    }
+  }
+}
+
+static bool
+mdelay (int millisecs)
+{
+  struct timespec      ts;
+  ts.tv_sec = millisecs / 1000;
+  ts.tv_nsec = (millisecs - (1000 * ts.tv_sec)) * 1000000;
+  return our_nanosleep (&ts);
+}
+
+
+usrp_load_status_t
+usrp_load_firmware_nth (int nth, const char *filename, bool force, libusb_context *ctx)
+{
+  libusb_device_handle *udh = open_nth_cmd_interface (nth, ctx);
+  if (udh == 0)
+    return ULS_ERROR;
+
+  usrp_load_status_t s = usrp_load_firmware (udh, filename, force);
+  usrp_close_interface (udh);
+
+  switch (s){
+
+  case ULS_ALREADY_LOADED:              // nothing changed...
+    return ULS_ALREADY_LOADED;
+    break;
+
+  case ULS_OK:
+    // we loaded firmware successfully.
+
+    // It's highly likely that the board will renumerate (simulate a
+    // disconnect/reconnect sequence), invalidating our current
+    // handle.
+
+    // FIXME.  Turn this into a loop that rescans until we refind ourselves
+
+    struct timespec     t;      // delay for 2 second
+    t.tv_sec = 2;
+    t.tv_nsec = 0;
+    our_nanosleep (&t);
+
+    usrp_rescan ();
+
+    return ULS_OK;
+
+  default:
+  case ULS_ERROR:               // some kind of problem
+    return ULS_ERROR;
+  }
+}
+
+static void
+load_status_msg (usrp_load_status_t s, const char *type, const char *filename)
+{
+  char *e = getenv("USRP_VERBOSE");
+  bool verbose = e != 0;
+
+  switch (s){
+  case ULS_ERROR:
+    fprintf (stderr, "usrp: failed to load %s %s.\n", type, filename);
+    break;
+
+  case ULS_ALREADY_LOADED:
+    if (verbose)
+      fprintf (stderr, "usrp: %s %s already loaded.\n", type, filename);
+    break;
+
+  case ULS_OK:
+    if (verbose)
+      fprintf (stderr, "usrp: %s %s loaded successfully.\n", type, filename);
+    break;
+  }
+}
+
+bool
+usrp_load_standard_bits (int nth, bool force,
+                        const std::string fpga_filename,
+                        const std::string firmware_filename,
+                        libusb_context *ctx)
+{
+  usrp_load_status_t   s;
+  const char           *filename;
+  const char           *proto_filename;
+  int hw_rev;
+
+  // first, figure out what hardware rev we're dealing with
+  {
+    libusb_device *udev = usrp_find_device (nth, false, ctx);
+    if (udev == 0){
+      fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
+      return false;
+    }
+    hw_rev = usrp_hw_rev (udev);
+  }
+
+  // start by loading the firmware
+
+  proto_filename = get_proto_filename(firmware_filename, "USRP_FIRMWARE",
+                                     default_firmware_filename);
+  filename = find_file(proto_filename, hw_rev);
+  if (filename == 0){
+    fprintf (stderr, "Can't find firmware: %s\n", proto_filename);
+    return false;
+  }
+  s = usrp_load_firmware_nth (nth, filename, force, ctx);
+  load_status_msg (s, "firmware", filename);
+
+  if (s == ULS_ERROR)
+    return false;
+
+  // if we actually loaded firmware, we must reload fpga ...
+  if (s == ULS_OK)
+    force = true;
+
+  // now move on to the fpga configuration bitstream
+
+  proto_filename = get_proto_filename(fpga_filename, "USRP_FPGA",
+                                     default_fpga_filename);
+  filename = find_file (proto_filename, hw_rev);
+  if (filename == 0){
+    fprintf (stderr, "Can't find fpga bitstream: %s\n", proto_filename);
+    return false;
+  }
+  libusb_device_handle *udh = open_nth_cmd_interface (nth, ctx);
+  if (udh == 0)
+    return false;
+
+  s = usrp_load_fpga (udh, filename, force);
+  usrp_close_interface (udh);
+  load_status_msg (s, "fpga bitstream", filename);
+
+  if (s == ULS_ERROR)
+    return false;
+
+  return true;
+}
+
+
+bool
+_usrp_get_status (libusb_device_handle *udh, int which, bool *trouble)
+{
+  unsigned char        status;
+  *trouble = true;
+
+  if (write_cmd (udh, VRQ_GET_STATUS, 0, which,
+                &status, sizeof (status)) != sizeof (status))
+    return false;
+
+  *trouble = status;
+  return true;
+}
+
+bool
+usrp_check_rx_overrun (libusb_device_handle *udh, bool *overrun_p)
+{
+  return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);
+}
+
+bool
+usrp_check_tx_underrun (libusb_device_handle *udh, bool *underrun_p)
+{
+  return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);
+}
+
+
+bool
+usrp_i2c_write (libusb_device_handle *udh, int i2c_addr,
+               const void *buf, int len)
+{
+  if (len < 1 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_I2C_WRITE, i2c_addr, 0,
+                   (unsigned char *) buf, len) == len;
+}
+
+
+bool
+usrp_i2c_read (libusb_device_handle *udh, int i2c_addr,
+              void *buf, int len)
+{
+  if (len < 1 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_I2C_READ, i2c_addr, 0,
+                   (unsigned char *) buf, len) == len;
+}
+
+bool
+usrp_spi_write (libusb_device_handle *udh,
+               int optional_header, int enables, int format,
+               const void *buf, int len)
+{
+  if (len < 0 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_SPI_WRITE,
+                   optional_header,
+                   ((enables & 0xff) << 8) | (format & 0xff),
+                   (unsigned char *) buf, len) == len;
+}
+
+
+bool
+usrp_spi_read (libusb_device_handle *udh,
+              int optional_header, int enables, int format,
+              void *buf, int len)
+{
+  if (len < 0 || len > MAX_EP0_PKTSIZE)
+    return false;
+
+  return write_cmd (udh, VRQ_SPI_READ,
+                   optional_header,
+                   ((enables & 0xff) << 8) | (format & 0xff),
+                   (unsigned char *) buf, len) == len;
+}
+
+bool
+usrp_9862_write (libusb_device_handle *udh, int which_codec,
+                int regno, int value)
+{
+  if (0)
+    fprintf (stderr, "usrp_9862_write which = %d, reg = %2d, val = %3d (0x%02x)\n",
+            which_codec, regno, value, value);
+
+  unsigned char buf[1];
+
+  buf[0] = value;
+
+  return usrp_spi_write (udh, 0x00 | (regno & 0x3f),
+                        which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+                        SPI_FMT_MSB | SPI_FMT_HDR_1,
+                        buf, 1);
+}
+
+bool
+usrp_9862_read (libusb_device_handle *udh, int which_codec,
+               int regno, unsigned char *value)
+{
+  return usrp_spi_read (udh, 0x80 | (regno & 0x3f),
+                       which_codec == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+                       SPI_FMT_MSB | SPI_FMT_HDR_1,
+                       value, 1);
+}
+
+bool
+usrp_9862_write_many (libusb_device_handle *udh,
+                     int which_codec,
+                     const unsigned char *buf,
+                     int len)
+{
+  if (len & 0x1)
+    return false;              // must be even
+
+  bool result = true;
+
+  while (len > 0){
+    result &= usrp_9862_write (udh, which_codec, buf[0], buf[1]);
+    len -= 2;
+    buf += 2;
+  }
+
+  return result;
+}
+
+
+bool
+usrp_9862_write_many_all (libusb_device_handle *udh,
+                          const unsigned char *buf, int len)
+{
+  // FIXME handle 2/2 and 4/4 versions
+
+  bool result;
+  result  = usrp_9862_write_many (udh, 0, buf, len);
+  result &= usrp_9862_write_many (udh, 1, buf, len);
+  return result;
+}
+
+static void
+power_down_9862s (libusb_device_handle *udh)
+{
+  static const unsigned char regs[] = {
+    REG_RX_PWR_DN,     0x01,           // everything
+    REG_TX_PWR_DN,     0x0f,           // pwr dn digital and analog_both
+    REG_TX_MODULATOR,  0x00            // coarse & fine modulators disabled
+  };
+
+  switch (usrp_hw_rev (_get_usb_device (udh))){
+  case 0:
+    break;
+
+  default:
+    usrp_9862_write_many_all (udh, regs, sizeof (regs));
+    break;
+  }
+}
+
+
+static const int EEPROM_PAGESIZE = 16;
+
+bool
+usrp_eeprom_write (libusb_device_handle *udh, int i2c_addr,
+                  int eeprom_offset, const void *buf, int len)
+{
+  unsigned char cmd[2];
+  const unsigned char *p = (unsigned char *) buf;
+
+  // The simplest thing that could possibly work:
+  //   all writes are single byte writes.
+  //
+  // We could speed this up using the page write feature,
+  // but we write so infrequently, why bother...
+
+  while (len-- > 0){
+    cmd[0] = eeprom_offset++;
+    cmd[1] = *p++;
+    bool r = usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd));
+    mdelay (10);               // delay 10ms worst case write time
+    if (!r)
+      return false;
+  }
+
+  return true;
+}
+
+bool
+usrp_eeprom_read (libusb_device_handle *udh, int i2c_addr,
+                 int eeprom_offset, void *buf, int len)
+{
+  unsigned char *p = (unsigned char *) buf;
+
+  // We setup a random read by first doing a "zero byte write".
+  // Writes carry an address.  Reads use an implicit address.
+
+  unsigned char cmd[1];
+  cmd[0] = eeprom_offset;
+  if (!usrp_i2c_write (udh, i2c_addr, cmd, sizeof (cmd)))
+    return false;
+
+  while (len > 0){
+    int n = std::min (len, MAX_EP0_PKTSIZE);
+    if (!usrp_i2c_read (udh, i2c_addr, p, n))
+      return false;
+    len -= n;
+    p += n;
+  }
+  return true;
+}
+
+// ----------------------------------------------------------------
+
+static bool
+slot_to_codec (int slot, int *which_codec)
+{
+  *which_codec = 0;
+
+  switch (slot){
+  case SLOT_TX_A:
+  case SLOT_RX_A:
+    *which_codec = 0;
+    break;
+
+  case SLOT_TX_B:
+  case SLOT_RX_B:
+    *which_codec = 1;
+    break;
+
+  default:
+    fprintf (stderr, "usrp_prims:slot_to_codec: invalid slot = %d\n", slot);
+    return false;
+  }
+  return true;
+}
+
+static bool
+tx_slot_p (int slot)
+{
+  switch (slot){
+  case SLOT_TX_A:
+  case SLOT_TX_B:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool
+usrp_write_aux_dac (libusb_device_handle *udh, int slot,
+                   int which_dac, int value)
+{
+  int which_codec;
+
+  if (!slot_to_codec (slot, &which_codec))
+    return false;
+
+  if (!(0 <= which_dac && which_dac < 4)){
+    fprintf (stderr, "usrp_write_aux_dac: invalid dac = %d\n", which_dac);
+    return false;
+  }
+
+  value &= 0x0fff;     // mask to 12-bits
+
+  if (which_dac == 3){
+    // dac 3 is really 12-bits.  Use value as is.
+    bool r = true;
+    r &= usrp_9862_write (udh, which_codec, 43, (value >> 4));       // most sig
+    r &= usrp_9862_write (udh, which_codec, 42, (value & 0xf) << 4); // least sig
+    return r;
+  }
+  else {
+    // dac 0, 1, and 2 are really 8 bits.
+    value = value >> 4;                // shift value appropriately
+    return usrp_9862_write (udh, which_codec, 36 + which_dac, value);
+  }
+}
+
+
+bool
+usrp_read_aux_adc (libusb_device_handle *udh, int slot,
+                  int which_adc, int *value)
+{
+  *value = 0;
+  int  which_codec;
+
+  if (!slot_to_codec (slot, &which_codec))
+    return false;
+
+  if (!(0 <= which_codec && which_codec < 2)){
+    fprintf (stderr, "usrp_read_aux_adc: invalid adc = %d\n", which_adc);
+    return false;
+  }
+
+  unsigned char aux_adc_control =
+    AUX_ADC_CTRL_REFSEL_A              // on chip reference
+    | AUX_ADC_CTRL_REFSEL_B;           // on chip reference
+
+  int  rd_reg = 26;    // base address of two regs to read for result
+
+  // program the ADC mux bits
+  if (tx_slot_p (slot))
+    aux_adc_control |= AUX_ADC_CTRL_SELECT_A2 | AUX_ADC_CTRL_SELECT_B2;
+  else {
+    rd_reg += 2;
+    aux_adc_control |= AUX_ADC_CTRL_SELECT_A1 | AUX_ADC_CTRL_SELECT_B1;
+  }
+
+  // I'm not sure if we can set the mux and issue a start conversion
+  // in the same cycle, so let's do them one at a time.
+
+  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
+
+  if (which_adc == 0)
+    aux_adc_control |= AUX_ADC_CTRL_START_A;
+  else {
+    rd_reg += 4;
+    aux_adc_control |= AUX_ADC_CTRL_START_B;
+  }
+
+  // start the conversion
+  usrp_9862_write (udh, which_codec, 34, aux_adc_control);
+
+  // read the 10-bit result back
+  unsigned char v_lo = 0;
+  unsigned char v_hi = 0;
+  bool r = usrp_9862_read (udh, which_codec, rd_reg, &v_lo);
+  r &= usrp_9862_read (udh, which_codec, rd_reg + 1, &v_hi);
+
+  if (r)
+    *value = ((v_hi << 2) | ((v_lo >> 6) & 0x3)) << 2; // format as 12-bit
+
+  return r;
+}
+
+// ----------------------------------------------------------------
+
+static int slot_to_i2c_addr (int slot)
+{
+  switch (slot){
+  case SLOT_TX_A:      return I2C_ADDR_TX_A;
+  case SLOT_RX_A:      return I2C_ADDR_RX_A;
+  case SLOT_TX_B:      return I2C_ADDR_TX_B;
+  case SLOT_RX_B:      return I2C_ADDR_RX_B;
+  default:             return -1;
+  }
+}
+
+static void
+set_chksum (unsigned char *buf)
+{
+  int sum = 0;
+  unsigned int i;
+  for (i = 0; i < DB_EEPROM_CLEN - 1; i++)
+    sum += buf[i];
+  buf[i] = -sum;
+}
+
+static usrp_dbeeprom_status_t
+read_dboard_eeprom (libusb_device_handle *udh,
+                   int slot_id, unsigned char *buf)
+{
+  int i2c_addr = slot_to_i2c_addr (slot_id);
+  if (i2c_addr == -1)
+    return UDBE_BAD_SLOT;
+
+  if (!usrp_eeprom_read (udh, i2c_addr, 0, buf, DB_EEPROM_CLEN))
+    return UDBE_NO_EEPROM;
+
+  if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE)
+    return UDBE_INVALID_EEPROM;
+
+  int sum = 0;
+  for (unsigned int i = 0; i < DB_EEPROM_CLEN; i++)
+    sum += buf[i];
+
+  if ((sum & 0xff) != 0)
+    return UDBE_INVALID_EEPROM;
+
+  return UDBE_OK;
+}
+
+usrp_dbeeprom_status_t
+usrp_read_dboard_eeprom (libusb_device_handle *udh,
+                        int slot_id, usrp_dboard_eeprom *eeprom)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  memset (eeprom, 0, sizeof (*eeprom));
+
+  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
+  if (s != UDBE_OK)
+    return s;
+
+  eeprom->id = (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB];
+  eeprom->oe = (buf[DB_EEPROM_OE_MSB] << 8) | buf[DB_EEPROM_OE_LSB];
+  eeprom->offset[0] = (buf[DB_EEPROM_OFFSET_0_MSB] << 8) | buf[DB_EEPROM_OFFSET_0_LSB];
+  eeprom->offset[1] = (buf[DB_EEPROM_OFFSET_1_MSB] << 8) | buf[DB_EEPROM_OFFSET_1_LSB];
+
+  return UDBE_OK;
+}
+
+bool
+usrp_write_dboard_offsets (libusb_device_handle *udh, int slot_id,
+                          short offset0, short offset1)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  usrp_dbeeprom_status_t s = read_dboard_eeprom (udh, slot_id, buf);
+  if (s != UDBE_OK)
+    return false;
+
+  buf[DB_EEPROM_OFFSET_0_LSB] = (offset0 >> 0) & 0xff;
+  buf[DB_EEPROM_OFFSET_0_MSB] = (offset0 >> 8) & 0xff;
+  buf[DB_EEPROM_OFFSET_1_LSB] = (offset1 >> 0) & 0xff;
+  buf[DB_EEPROM_OFFSET_1_MSB] = (offset1 >> 8) & 0xff;
+  set_chksum (buf);
+
+  return usrp_eeprom_write (udh, slot_to_i2c_addr (slot_id),
+                           0, buf, sizeof (buf));
+}
+
+// ----------------------------------------------------------------
+
+std::string
+usrp_serial_number(libusb_device_handle *udh)
+{
+  libusb_device_descriptor desc =
+    _get_usb_device_descriptor (_get_usb_device (udh));
+
+  unsigned char iserial = desc.iSerialNumber;
+  if (iserial == 0)
+    return "";
+
+  unsigned char buf[1024];
+  if (_get_usb_string_descriptor (udh, iserial, buf, sizeof(buf)) < 0)
+    return "";
+
+  return (char*) buf;
+}
+
+
+
+
diff --git a/usrp/host/lib/usrp_prims_libusb0.cc b/usrp/host/lib/usrp_prims_libusb0.cc
new file mode 100644 (file)
index 0000000..4fbfabe
--- /dev/null
@@ -0,0 +1,230 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2006,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp_primsi.h"
+#include "usrp_commands.h"
+#include <usb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ad9862.h>
+#include <assert.h>
+
+extern "C" {
+#include "md5.h"
+};
+
+using namespace ad9862;
+
+/*
+ * libusb 0.12 / 1.0 compatibility
+ */
+
+struct usb_device *
+_get_usb_device (struct usb_dev_handle *udh)
+{
+  return usb_device (udh);
+}
+
+struct usb_device_descriptor
+_get_usb_device_descriptor (struct usb_device *q)
+{
+  return q->descriptor;
+}
+
+int
+_get_usb_string_descriptor (struct usb_dev_handle *udh, int index,
+                           unsigned char* data, int length)
+{
+  int ret;
+  ret =  usb_get_string_simple (udh, index, (char*) data, length);
+
+  if (ret < 0) {
+    fprintf (stderr, "usrp: usb_get_string_descriptor failed: %s\n",
+             usb_strerror());
+  }
+
+  return ret;
+}
+
+int
+_usb_control_transfer (struct usb_dev_handle *udh, int request_type,
+                      int request, int value, int index,
+                      unsigned char *data, int length, unsigned int timeout)
+{
+  int ret;
+
+  ret = usb_control_msg (udh, request_type,request, value, index,
+                         (char*) data, length, (int) timeout);
+  if (ret < 0) 
+    fprintf (stderr, "usrp: usb_control_msg failed: %s\n", usb_strerror());
+
+  return ret;
+}
+
+
+// ----------------------------------------------------------------
+
+
+void
+usrp_one_time_init (libusb_context **ctx)
+{
+  static bool first = true;
+
+  if (first) {
+    first = false;
+    usb_init ();                       // usb library init
+    usb_find_busses ();
+    usb_find_devices ();
+  }
+}
+
+void
+usrp_deinit (libusb_context *ctx)
+{
+  // nop
+}
+
+void
+usrp_rescan ()
+{
+  usb_find_busses ();
+  usb_find_devices ();
+}
+
+
+// ----------------------------------------------------------------
+
+
+struct usb_device *
+usrp_find_device (int nth, bool fx2_ok_p, libusb_context *ctx)
+{
+  struct usb_bus *p;
+  struct usb_device *q;
+  int   n_found = 0;
+
+  usrp_one_time_init ();
+
+  p = usb_get_busses();
+  while (p != NULL){
+    q = p->devices;
+    while (q != NULL){
+      if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))){
+       if (n_found == nth)     // return this one
+         return q;
+       n_found++;              // keep looking
+      }
+      q = q->next;
+    }
+    p = p->next;
+  }
+  return 0;    // not found
+}
+
+struct usb_dev_handle *
+usrp_open_interface (struct usb_device *dev, int interface, int altinterface)
+{
+  struct usb_dev_handle *udh = usb_open (dev);
+  if (udh == 0)
+    return 0;
+
+  if (dev != usb_device (udh)){
+    fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__);
+    abort ();
+  }
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+  // There's no get get_configuration function, and with some of the newer kernels
+  // setting the configuration, even if to the same value, hoses any other processes
+  // that have it open.  Hence we opt to not set it at all (We've only
+  // got a single configuration anyway).  This may hose the win32 stuff...
+
+  // Appears to be required for libusb-win32 and Cygwin -- dew 09/20/06
+  if (usb_set_configuration (udh, 1) < 0){
+    /*
+     * Ignore this error.
+     *
+     * Seems that something changed in drivers/usb/core/devio.c:proc_setconfig such that
+     * it returns -EBUSY if _any_ of the interfaces of a device are open.
+     * We've only got a single configuration, so setting it doesn't even seem
+     * like it should be required.
+     */
+  }
+#endif
+
+  if (usb_claim_interface (udh, interface) < 0){
+    fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", __FUNCTION__,interface);
+    fprintf (stderr, "%s\n", usb_strerror());
+    usb_close (udh);
+    return 0;
+  }
+
+  if (usb_set_altinterface (udh, altinterface) < 0){
+    fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__);
+    fprintf (stderr, "%s\n", usb_strerror());
+    usb_release_interface (udh, interface);
+    usb_close (udh);
+    return 0;
+  }
+
+  return udh;
+}
+
+bool
+usrp_close_interface (struct usb_dev_handle *udh)
+{
+  // we're assuming that closing an interface automatically releases it.
+  return usb_close (udh) == 0;
+}
+
+
+// ----------------------------------------------------------------
+// write vendor extension command to USRP
+
+
+int
+write_cmd (struct usb_dev_handle *udh,
+          int request, int value, int index,
+          unsigned char *bytes, int len)
+{
+  int  requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT;
+
+  int r = usb_control_msg (udh, requesttype, request, value, index,
+                          (char *) bytes, len, 1000);
+  if (r < 0){
+    // we get EPIPE if the firmware stalls the endpoint.
+    if (errno != EPIPE) {
+      fprintf (stderr, "usb_control_msg failed: %s\n", usb_strerror ());
+      fprintf (stderr, "write_cmd failed\n");
+    }
+  }
+
+  return r;
+}
+
diff --git a/usrp/host/lib/usrp_prims_libusb1.cc b/usrp/host/lib/usrp_prims_libusb1.cc
new file mode 100644 (file)
index 0000000..5dfe416
--- /dev/null
@@ -0,0 +1,276 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2006,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp_primsi.h"
+#include "usrp_commands.h"
+#include <libusb-1.0/libusb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ad9862.h>
+#include <assert.h>
+
+extern "C" {
+#include "md5.h"
+};
+
+using namespace ad9862;
+
+static const int LIBUSB1_DEBUG = 0;
+
+/*
+ * libusb 0.12 / 1.0 compatibility
+ */
+
+static const char *
+_get_usb_error_str (int usb_err)
+{
+  switch (usb_err) {
+  case LIBUSB_SUCCESS:
+    return "Success (no error)";
+  case LIBUSB_ERROR_IO:
+    return "Input/output error";
+  case LIBUSB_ERROR_INVALID_PARAM:
+    return "Invalid parameter";
+  case LIBUSB_ERROR_ACCESS:
+    return "Access denied (insufficient permissions)";
+  case LIBUSB_ERROR_NO_DEVICE:
+    return "No such device (it may have been disconnected)";
+  case LIBUSB_ERROR_NOT_FOUND:
+    return "Entity not found";
+  case LIBUSB_ERROR_BUSY:
+    return "Resource busy";
+  case LIBUSB_ERROR_TIMEOUT:
+    return "Operation timed out";
+  case LIBUSB_ERROR_OVERFLOW:
+    return "Overflow";
+  case LIBUSB_ERROR_PIPE:
+    return "Pipe error";
+   case LIBUSB_ERROR_INTERRUPTED:
+    return "System call interrupted (perhaps due to signal)";
+  case LIBUSB_ERROR_NO_MEM:
+    return "Insufficient memory";
+  case LIBUSB_ERROR_NOT_SUPPORTED:
+    return "Operation not supported or unimplemented on this platform";
+  case LIBUSB_ERROR_OTHER:
+    return "Unknown error";
+  }
+
+  return "Unknown error";
+}
+
+struct libusb_device *
+_get_usb_device (struct libusb_device_handle *udh)
+{
+  return libusb_get_device (udh);
+}
+
+struct libusb_device_descriptor
+_get_usb_device_descriptor(struct libusb_device *q)
+{
+  int ret;
+  struct libusb_device_descriptor desc;
+
+  ret = libusb_get_device_descriptor(q, &desc);
+
+  if (ret < 0) {
+    fprintf (stderr, "usrp: libusb_get_device_descriptor failed: %s\n",
+             _get_usb_error_str(ret));
+  }
+  return desc;
+}
+
+int
+_get_usb_string_descriptor (struct libusb_device_handle *udh, int index,
+                            unsigned char* data, int length)
+{
+  int ret;
+  ret = libusb_get_string_descriptor_ascii (udh, (uint8_t) index, data, length);
+
+  if (ret < 0) {
+    fprintf (stderr, "usrp: libusb_get_string_descriptor_ascii failed: %s\n",
+             _get_usb_error_str(ret));
+  }
+  return ret;
+}
+
+int
+_usb_control_transfer (struct libusb_device_handle *udh, int request_type,
+                       int request, int value, int index,
+                       unsigned char *data, int length, unsigned int timeout)
+{
+  int ret;
+  ret = libusb_control_transfer (udh, request_type, request, value, index,
+                                 data, length, timeout);
+  if (ret < 0) {
+    fprintf (stderr, "usrp: libusb_control_transfer failed: %s\n",
+             _get_usb_error_str(ret));
+  }
+  return ret;
+}
+
+
+// ----------------------------------------------------------------
+
+
+void
+usrp_one_time_init (libusb_context **ctx)
+{
+  int ret;
+
+  if ((ret = libusb_init (ctx)) < 0)
+    fprintf (stderr, "usrp: libusb_init failed: %s\n", _get_usb_error_str(ret));
+
+  // Enable debug verbosity if requested. This will only work if the debug
+  // option is compiled into libusb and may produce a generous amount of output
+  // on stdout. If debug output is not compiled into libusb, this call does
+  // nothing. 
+  if (LIBUSB1_DEBUG)
+    libusb_set_debug(*ctx, 3);
+}
+
+void
+usrp_deinit (struct libusb_context *ctx)
+{
+  // Each object _should_ be running in its own context. If running in default
+  // context then leave the instance open as it may be shared.
+  if (ctx != NULL)
+    libusb_exit (ctx);
+}
+
+void
+usrp_rescan ()
+{
+  // nop
+}
+
+struct libusb_device *
+usrp_find_device (int nth, bool fx2_ok_p, libusb_context *ctx)
+{
+  libusb_device **list;
+
+  struct libusb_device *q;
+  int   n_found = 0;
+
+  // Make sure not operating on default context. There are cases where operating
+  // with a single global (NULL) context may be preferable, so this check can be
+  // skipped if you know what you're doing.
+  assert (ctx != NULL);
+
+  size_t cnt = libusb_get_device_list(ctx, &list);
+  size_t i = 0;
+
+  if (cnt < 0)
+    fprintf(stderr, "usrp: libusb_get_device_list failed: %s\n",
+            _get_usb_error_str(cnt));
+
+  for (i = 0; i < cnt; i++) {
+    q = list[i];
+    if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))) {
+       if (n_found == nth)     // return this one
+         return q;
+       n_found++;              // keep looking
+    }
+  }
+
+  // The list needs to be freed. Right now just release it if nothing is found.
+  libusb_free_device_list(list, 1);
+
+  return 0;    // not found
+}
+
+struct libusb_device_handle *
+usrp_open_interface (libusb_device *dev, int interface, int altinterface)
+{
+  libusb_device_handle *udh;
+  int ret;
+
+  if (libusb_open (dev, &udh) < 0)
+    return 0;
+
+  if (dev != libusb_get_device (udh)){
+    fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__);
+    abort ();
+  }
+
+  if ((ret = libusb_claim_interface (udh, interface)) < 0) {
+    fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n",
+             __FUNCTION__, interface);
+    fprintf (stderr, "%s\n", _get_usb_error_str(ret));
+    libusb_close (udh);
+    return 0;
+  }
+
+  if ((ret = libusb_set_interface_alt_setting (udh, interface,
+                                               altinterface)) < 0) {
+    fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__);
+    fprintf (stderr, "%s\n", _get_usb_error_str(ret));
+    libusb_release_interface (udh, interface);
+    libusb_close (udh);
+    return 0;
+  }
+
+  return udh;
+}
+
+bool
+usrp_close_interface (libusb_device_handle *udh)
+{
+  // returns void
+  libusb_close(udh);
+  return 0;
+}
+
+
+// ----------------------------------------------------------------
+// write vendor extension command to USRP
+
+
+int
+write_cmd (struct libusb_device_handle *udh,
+           int request, int value, int index,
+           unsigned char *bytes, int len)
+{
+  int requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT;
+
+  int ret = libusb_control_transfer(udh, requesttype, request, value, index,
+                                    bytes, len, 1000);
+
+  if (ret < 0) {
+    // we get EPIPE if the firmware stalls the endpoint.
+    if (ret != LIBUSB_ERROR_PIPE) {
+      fprintf (stderr, "usrp: libusb_control_transfer failed: %s\n",
+               _get_usb_error_str(ret));
+      fprintf (stderr, "usrp: write_cmd failed\n");
+    }
+  }
+
+  return ret;
+}
+
diff --git a/usrp/host/lib/usrp_primsi.h b/usrp/host/lib/usrp_primsi.h
new file mode 100644 (file)
index 0000000..b1cf726
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 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.
+ */
+
+/*
+ * Internal usrp_prims header file
+ */
+
+#ifndef _USRP_PRIMSI_H_
+#define _USRP_PRIMSI_H_
+
+#include "usrp/usrp_prims.h"
+
+/*
+ * Internal functions
+ */
+
+libusb_device_handle *
+usrp_open_interface(libusb_device *dev, int interface, int altinterface);
+
+int write_cmd (libusb_device_handle *udh, int request, int value, int index,
+               unsigned char *bytes, int len);
+
+/*
+ * Compatibility functions
+ */
+
+libusb_device *_get_usb_device (libusb_device_handle *udh);
+
+libusb_device_descriptor _get_usb_device_descriptor (libusb_device *q);
+
+int _get_usb_string_descriptor (libusb_device_handle *udh, int index,
+                                unsigned char* data, int length);
+
+int _usb_control_transfer (libusb_device_handle *udh, int request_type,
+                           int request, int value, int index,
+                           unsigned char *data, int length,
+                           unsigned int timeout);
+
+#endif /* _USRP_PRIMSI_H_ */
+
diff --git a/usrp/host/lib/usrp_standard.cc b/usrp/host/lib/usrp_standard.cc
new file mode 100644 (file)
index 0000000..fe5afab
--- /dev/null
@@ -0,0 +1,1175 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp/usrp_standard.h>
+
+#include "usrp/usrp_prims.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include <stdexcept>
+#include <assert.h>
+#include <math.h>
+#include <ad9862.h>
+#include <cstdio>
+
+
+static const int OLD_CAPS_VAL = 0xaa55ff77;
+static const int DEFAULT_CAPS_VAL = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
+                                    | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
+                                    | bmFR_RB_CAPS_RX_HAS_HALFBAND);
+
+// #define USE_FPGA_TX_CORDIC
+
+
+using namespace ad9862;
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+void
+usrp_standard_common::calc_dxc_freq(double target_freq, double baseband_freq, double fs,
+                                   double *dxc_freq, bool *inverted)
+{
+  /*
+    Calculate the frequency to use for setting the digital up or down converter.
+    
+    @param target_freq: desired RF frequency (Hz)
+    @param baseband_freq: the RF frequency that corresponds to DC in the IF.
+    @param fs: converter sample rate
+    
+    @returns: 2-tuple (ddc_freq, inverted) where ddc_freq is the value
+      for the ddc and inverted is True if we're operating in an inverted
+      Nyquist zone.
+  */
+
+#if 0
+    printf("calc_dxc_freq:\n");
+    printf("  target   = %f\n", target_freq);
+    printf("  baseband = %f\n", baseband_freq);
+    printf("  fs       = %f\n", fs);
+#endif
+
+  double delta = target_freq - baseband_freq;
+    
+  if(delta >= 0) {
+    while(delta > fs) {
+      delta -= fs;
+    }
+    if(delta <= fs/2) {                // non-inverted region
+      *dxc_freq = -delta;      
+      *inverted = false;
+    }
+    else {                             // inverted region
+      *dxc_freq = delta - fs;
+      *inverted = true;
+    }
+  }
+  else {
+    while(delta < -fs) {
+      delta += fs;
+    }
+    if(delta >= -fs/2) {
+      *dxc_freq = -delta;      // non-inverted region
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta + fs;
+      *inverted = true;
+    }
+  }
+
+#if 0
+    printf("  dxc_freq  = %f\n", *dxc_freq);
+    printf("  inverted  = %s\n", *inverted ? "true" : "false");
+#endif
+}
+
+
+/* 
+ * Real lambda expressions would be _so_ much easier...
+ */
+class dxc_control {
+public:
+  virtual bool is_tx() = 0;
+  virtual bool set_dxc_freq(double dxc_freq) = 0;
+  virtual double dxc_freq() = 0;
+};
+
+class ddc_control : public dxc_control {
+  usrp_standard_rx     *d_u;
+  int                  d_chan;
+
+public:
+  ddc_control(usrp_standard_rx *u, int chan)
+    : d_u(u), d_chan(chan) {}
+  
+  bool is_tx(){ return false; }
+  bool set_dxc_freq(double dxc_freq){ return d_u->set_rx_freq(d_chan, dxc_freq); }
+  double dxc_freq(){ return d_u->rx_freq(d_chan); }
+};
+
+class duc_control : public dxc_control {
+  usrp_standard_tx     *d_u;
+  int                  d_chan;
+
+public:
+  duc_control(usrp_standard_tx *u, int chan)
+    : d_u(u), d_chan(chan) {}
+  
+  bool is_tx(){ return true; }
+  bool set_dxc_freq(double dxc_freq){ return d_u->set_tx_freq(d_chan, dxc_freq); }
+  double dxc_freq() { return d_u->tx_freq(d_chan); }
+};
+
+
+/*!
+ * \brief Tune such that target_frequency ends up at DC in the complex baseband
+ *
+ * \param db           the daughterboard to use
+ * \param target_freq  the center frequency we want at baseband (DC)
+ * \param fs           the sample rate
+ * \param dxc          DDC or DUC access and control object
+ * \param[out] result  details of what we did
+ *
+ * \returns true iff operation was successful
+ *
+ * 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.
+ */
+static bool
+tune_a_helper(db_base_sptr db, double target_freq, double fs,
+             dxc_control &dxc, usrp_tune_result *result)
+{
+  bool inverted = false;
+  double dxc_freq;
+  double actual_dxc_freq;
+
+  // Ask the d'board to tune as closely as it can to target_freq
+#if 0
+  bool ok = db->set_freq(target_freq, &result->baseband_freq);
+#else
+  bool ok;
+  {
+    freq_result_t fr = db->set_freq(target_freq);
+    ok = fr.ok;
+    result->baseband_freq = fr.baseband_freq;
+  }
+#endif
+
+  // Calculate the DDC setting that will downconvert the baseband from the
+  // daughterboard to our target frequency.
+  usrp_standard_common::calc_dxc_freq(target_freq, result->baseband_freq, fs,
+                                     &dxc_freq, &inverted);
+
+  // If the spectrum is inverted, and the daughterboard doesn't do
+  // quadrature downconversion, we can fix the inversion by flipping the
+  // sign of the dxc_freq...  (This only happens using the basic_rx board)
+  
+  if(db->spectrum_inverted())
+    inverted = !inverted;
+  
+  if(inverted && !db->is_quadrature()){
+    dxc_freq = -dxc_freq;
+    inverted = !inverted;
+  }
+  
+  if (dxc.is_tx() && !db->i_and_q_swapped())           // down conversion versus up conversion
+    dxc_freq = -dxc_freq;
+
+  ok &= dxc.set_dxc_freq(dxc_freq);
+  actual_dxc_freq = dxc.dxc_freq();
+  
+  result->dxc_freq = dxc_freq;
+  result->residual_freq = dxc_freq - actual_dxc_freq;
+  result->inverted = inverted;
+  return ok;
+}
+
+
+static unsigned int
+compute_freq_control_word_fpga (double master_freq, double target_freq,
+                               double *actual_freq, bool verbose)
+{
+  static const int NBITS = 14;
+  
+  int  v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
+
+  if (0)
+    v = (v >> (32 - NBITS)) << (32 - NBITS);   // keep only top NBITS
+
+  *actual_freq = v * master_freq / pow (2.0, 32.0);
+
+  if (verbose)
+    fprintf (stderr,
+            "compute_freq_control_word_fpga: target = %g  actual = %g  delta = %g\n",
+            target_freq, *actual_freq, *actual_freq - target_freq);
+
+  return (unsigned int) v;
+}
+
+// The 9862 uses an unsigned 24-bit frequency tuning word and 
+// a separate register to control the sign.
+
+static unsigned int
+compute_freq_control_word_9862 (double master_freq, double target_freq,
+                               double *actual_freq, bool verbose)
+{
+  double sign = 1.0;
+
+  if (target_freq < 0)
+    sign = -1.0;
+
+  int  v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0));
+  *actual_freq = v * master_freq / pow (2.0, 24.0) * sign;
+
+  if (verbose)
+    fprintf (stderr,
+     "compute_freq_control_word_9862: target = %g  actual = %g  delta = %g  v = %8d\n",
+     target_freq, *actual_freq, *actual_freq - target_freq, v);
+
+  return (unsigned int) v;
+}
+
+// ----------------------------------------------------------------
+
+usrp_standard_common::usrp_standard_common(usrp_basic *parent)
+{
+  // read new FPGA capability register
+  if (!parent->_read_fpga_reg(FR_RB_CAPS, &d_fpga_caps)){
+    fprintf (stderr, "usrp_standard_common: failed to read FPGA cap register.\n");
+    throw std::runtime_error ("usrp_standard_common::ctor");
+  }
+  // If we don't have the cap register, set the value to what it would
+  // have had if we did have one ;)
+  if (d_fpga_caps == OLD_CAPS_VAL)
+    d_fpga_caps = DEFAULT_CAPS_VAL;
+
+  if (0){
+    fprintf(stdout, "has_rx_halfband = %d\n", has_rx_halfband());
+    fprintf(stdout, "nddcs           = %d\n", nddcs());
+    fprintf(stdout, "has_tx_halfband = %d\n", has_tx_halfband());
+    fprintf(stdout, "nducs           = %d\n", nducs());
+  }
+}
+
+bool
+usrp_standard_common::has_rx_halfband() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND) ? true : false;
+}
+
+int
+usrp_standard_common::nddcs() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT;
+}
+
+bool
+usrp_standard_common::has_tx_halfband() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND) ? true : false;
+}
+
+int
+usrp_standard_common::nducs() const
+{
+  return (d_fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT;
+}
+
+// ----------------------------------------------------------------
+
+static int 
+real_rx_mux_value (int mux, int nchan)
+{
+  if (mux != -1)
+    return mux;
+
+  return 0x32103210;
+}
+
+usrp_standard_rx::usrp_standard_rx (int which_board,
+                                   unsigned int decim_rate,
+                                   int nchan, int mux, int mode,
+                                   int fusb_block_size, int fusb_nblocks,
+                                   const std::string fpga_filename,
+                                   const std::string firmware_filename
+                                   )
+  : usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
+                  fpga_filename, firmware_filename),
+    usrp_standard_common(this),
+    d_nchan (1), d_sw_mux (0x0), d_hw_mux (0x0)
+{
+  if (!set_format(make_format())){
+    fprintf (stderr, "usrp_standard_rx: set_format failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_nchannels (nchan)){
+    fprintf (stderr, "usrp_standard_rx: set_nchannels failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_decim_rate (decim_rate)){
+    fprintf (stderr, "usrp_standard_rx: set_decim_rate failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_mux (real_rx_mux_value (mux, nchan))){
+    fprintf (stderr, "usrp_standard_rx: set_mux failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+  if (!set_fpga_mode (mode)){
+    fprintf (stderr, "usrp_standard_rx: set_fpga_mode failed\n");
+    throw std::runtime_error ("usrp_standard_rx::ctor");
+  }
+
+  for (int i = 0; i < MAX_CHAN; i++){
+    set_rx_freq(i, 0);
+    set_ddc_phase(i, 0);
+  }
+}
+
+usrp_standard_rx::~usrp_standard_rx ()
+{
+  // fprintf(stderr, "\nusrp_standard_rx: dtor\n");
+}
+
+bool
+usrp_standard_rx::start ()
+{
+  if (!usrp_basic_rx::start ())
+    return false;
+
+  // add our code here
+
+  return true;
+}
+
+bool
+usrp_standard_rx::stop ()
+{
+  bool ok = usrp_basic_rx::stop ();
+
+  // add our code here
+
+  return ok;
+}
+
+usrp_standard_rx_sptr
+usrp_standard_rx::make (int which_board,
+                       unsigned int decim_rate,
+                       int nchan, int mux, int mode,
+                       int fusb_block_size, int fusb_nblocks,
+                       const std::string fpga_filename,
+                       const std::string firmware_filename
+                       )
+{
+  try {
+    usrp_standard_rx_sptr u = 
+      usrp_standard_rx_sptr(new usrp_standard_rx(which_board, decim_rate,
+                                                nchan, mux, mode,
+                                                fusb_block_size, fusb_nblocks,
+                                                fpga_filename, firmware_filename));
+    u->init_db(u);
+    return u;
+  }
+  catch (...){
+    return usrp_standard_rx_sptr();
+  }
+}
+
+bool
+usrp_standard_rx::set_decim_rate(unsigned int rate)
+{
+  if (has_rx_halfband()){
+    if ((rate & 0x1) || rate < 4 || rate > 256){
+      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be EVEN and in [4, 256]\n");
+      return false;
+    }
+  }
+  else {
+    if (rate < 4 || rate > 128){
+      fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be in [4, 128]\n");
+      return false;
+    }
+  }
+
+  d_decim_rate = rate;
+  set_usb_data_rate ((adc_rate () / rate * nchannels ())
+                    * (2 * sizeof (short)));
+
+  bool s = disable_rx ();
+  int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
+  bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
+  restore_rx (s);
+  return ok;
+}
+
+bool usrp_standard_rx::set_nchannels (int nchan)
+{
+  if (!(nchan == 1 || nchan == 2 || nchan == 4))
+    return false;
+
+  if (nchan > nddcs())
+    return false;
+
+  d_nchan = nchan;
+
+  return write_hw_mux_reg ();
+}
+
+
+// map software mux value to hw mux value
+//
+// Software mux value:
+//
+//    3                   2                   1                       
+//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-------+-------+-------+-------+-------+-------+-------+-------+
+// |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
+// +-------+-------+-------+-------+-------+-------+-------+-------+
+//
+// Each 4-bit I field is either 0,1,2,3
+// Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
+// All Q's must be 0xf or none of them may be 0xf
+//
+//
+// Hardware mux value:
+//
+//    3                   2                   1                       
+//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------+-------+-------+-------+-+-----+
+// |      must be zero     | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+
+
+static bool
+map_sw_mux_to_hw_mux (int sw_mux, int *hw_mux_ptr)
+{
+  // confirm that all I's are either 0,1,2,3 
+
+  for (int i = 0; i < 8; i += 2){
+    int t = (sw_mux >> (4 * i)) & 0xf;
+    if (!(0 <= t && t <= 3))
+      return false;
+  }
+
+  // confirm that all Q's are either 0,1,2,3 or 0xf
+
+  for (int i = 1; i < 8; i += 2){
+    int t = (sw_mux >> (4 * i)) & 0xf;
+    if (!(t == 0xf || (0 <= t && t <= 3)))
+      return false;
+  }
+
+  // confirm that all Q inputs are 0xf (const zero input),
+  // or none of them are 0xf
+
+  int q_and = 1;
+  int q_or =  0;
+
+  for (int i = 0; i < 4; i++){
+    int qx_is_0xf = ((sw_mux >> (8 * i + 4)) & 0xf) == 0xf;
+    q_and &= qx_is_0xf;
+    q_or  |= qx_is_0xf;
+  }
+
+  if (q_and || !q_or){         // OK
+    int hw_mux_value = 0;
+
+    for (int i = 0; i < 8; i++){
+      int t = (sw_mux >> (4 * i)) & 0x3;
+      hw_mux_value |= t << (2 * i + 4);
+    }
+
+    if (q_and)
+      hw_mux_value |= 0x8;     // all Q's zero
+
+    *hw_mux_ptr = hw_mux_value;
+    return true;
+  }
+  else
+    return false;
+}
+
+bool
+usrp_standard_rx::set_mux (int mux)
+{
+  if (!map_sw_mux_to_hw_mux (mux, &d_hw_mux))
+    return false;
+
+  // fprintf (stderr, "sw_mux = 0x%08x  hw_mux = 0x%08x\n", mux, d_hw_mux);
+
+  d_sw_mux = mux;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_rx::write_hw_mux_reg ()
+{
+  bool s = disable_rx ();
+  bool ok = _write_fpga_reg (FR_RX_MUX, d_hw_mux | d_nchan);
+  restore_rx (s);
+  return ok;
+}
+
+int
+usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss)
+{
+  /*
+    Determine appropriate Rx mux value as a function of the subdevice choosen and the
+    characteristics of the respective daughterboard.
+    
+    @param u:           instance of USRP source
+    @param subdev_spec: return value from subdev option parser.  
+    @type  subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1
+    @returns:           the Rx mux value
+  
+    Figure out which A/D's to connect to the DDC.
+    
+    Each daughterboard consists of 1 or 2 subdevices.  (At this time,
+    all but the Basic Rx have a single subdevice.  The Basic Rx
+    has two independent channels, treated as separate subdevices).
+    subdevice 0 of a daughterboard may use 1 or 2 A/D's.  We determine this
+    by checking the is_quadrature() method.  If subdevice 0 uses only a single
+    A/D, it's possible that the daughterboard has a second subdevice, subdevice 1,
+    and it uses the second A/D.
+    
+    If the card uses only a single A/D, we wire a zero into the DDC Q input.
+    
+    (side, 0) says connect only the A/D's used by subdevice 0 to the DDC.
+    (side, 1) says connect only the A/D's used by subdevice 1 to the DDC.
+  */
+
+  struct truth_table_element
+  {
+    int          d_side;
+    int         d_uses;
+    bool         d_swap_iq;
+    unsigned int d_mux_val;
+
+    truth_table_element(int side, unsigned int uses, bool swap_iq, unsigned int mux_val=0)
+      : d_side(side), d_uses(uses), d_swap_iq(swap_iq), d_mux_val(mux_val){}
+      
+    bool operator==(const truth_table_element &in)
+    {
+      return (d_side == in.d_side && d_uses == in.d_uses && d_swap_iq == in.d_swap_iq);
+    }
+
+    unsigned int mux_val() { return d_mux_val; }
+  };
+
+
+  if (!is_valid(ss))
+    throw std::invalid_argument("subdev_spec");
+
+
+  // This is a tuple of length 1 or 2 containing the subdevice
+  // classes for the selected side.
+  std::vector<db_base_sptr> db = this->db(ss.side);
+  
+  unsigned int uses;
+
+  // compute bitmasks of used A/D's
+  
+  if(db[ss.subdev]->is_quadrature())
+    uses = 0x3;               // uses A/D 0 and 1
+  else if (ss.subdev == 0)
+    uses = 0x1;               // uses A/D 0 only
+  else if(ss.subdev == 1)
+    uses = 0x2;               // uses A/D 1 only
+  else
+    uses = 0x0;               // uses no A/D (doesn't exist)
+  
+  if(uses == 0){
+    throw std::runtime_error("Determine RX Mux Error");
+  }
+  
+  bool swap_iq = db[ss.subdev]->i_and_q_swapped();
+  
+  truth_table_element truth_table[8] = {
+    // (side, uses, swap_iq) : mux_val
+    truth_table_element(0, 0x1, false, 0xf0f0f0f0),
+    truth_table_element(0, 0x2, false, 0xf0f0f0f1),
+    truth_table_element(0, 0x3, false, 0x00000010),
+    truth_table_element(0, 0x3, true,  0x00000001),
+    truth_table_element(1, 0x1, false, 0xf0f0f0f2),
+    truth_table_element(1, 0x2, false, 0xf0f0f0f3),
+    truth_table_element(1, 0x3, false, 0x00000032),
+    truth_table_element(1, 0x3, true,  0x00000023)
+  };
+  size_t nelements = sizeof(truth_table)/sizeof(truth_table[0]);
+  
+  truth_table_element target(ss.side, uses, swap_iq, 0);
+  
+  size_t i;
+  for(i = 0; i < nelements; i++){
+    if (truth_table[i] == target)
+      return truth_table[i].mux_val();
+  }
+  throw std::runtime_error("internal error");
+}
+
+int
+usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
+{
+  std::vector<db_base_sptr> db_a = this->db(ss_a.side);
+  std::vector<db_base_sptr> db_b = this->db(ss_b.side);
+  if (db_a[ss_a.subdev]->is_quadrature() != db_b[ss_b.subdev]->is_quadrature()){
+    throw std::runtime_error("Cannot compute dual mux when mixing quadrature and non-quadrature subdevices");
+  }
+  int mux_a = determine_rx_mux_value(ss_a);
+  int mux_b = determine_rx_mux_value(ss_b);
+  //move the lower byte of the mux b into the second byte of the mux a
+  return ((mux_b & 0xff) << 8) | (mux_a & 0xffff00ff);
+}
+
+bool
+usrp_standard_rx::set_rx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel > MAX_CHAN)
+    return false;
+
+  unsigned int v =
+    compute_freq_control_word_fpga (adc_rate(),
+                                   freq, &d_rx_freq[channel],
+                                   d_verbose);
+
+  return _write_fpga_reg (FR_RX_FREQ_0 + channel, v);
+}
+
+unsigned int
+usrp_standard_rx::decim_rate () const { return d_decim_rate; }
+
+int
+usrp_standard_rx::nchannels () const { return d_nchan; }
+
+int
+usrp_standard_rx::mux () const { return d_sw_mux; }
+
+double 
+usrp_standard_rx::rx_freq (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return 0;
+
+  return d_rx_freq[channel];
+}
+
+bool
+usrp_standard_rx::set_fpga_mode (int mode)
+{
+  return _write_fpga_reg (FR_MODE, mode);
+}
+
+bool
+usrp_standard_rx::set_ddc_phase(int channel, int phase)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  return _write_fpga_reg(FR_RX_PHASE_0 + channel, phase);
+}
+
+
+// To avoid quiet failures, check for things that our code cares about.
+
+static bool
+rx_format_is_valid(unsigned int format)
+{
+  int width =  usrp_standard_rx::format_width(format);
+  int want_q = usrp_standard_rx::format_want_q(format);
+
+  if (!(width == 8 || width == 16))    // FIXME add other widths when valid
+    return false;
+
+  if (!want_q)         // FIXME remove check when the rest of the code can handle I only
+    return false;
+
+  return true;
+}
+
+bool
+usrp_standard_rx::set_format(unsigned int format)
+{
+  if (!rx_format_is_valid(format))
+    return false;
+
+  return _write_fpga_reg(FR_RX_FORMAT, format);
+}
+
+unsigned int
+usrp_standard_rx::format() const
+{
+  return d_fpga_shadows[FR_RX_FORMAT];
+}
+
+// ----------------------------------------------------------------
+
+unsigned int 
+usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband)
+{
+  unsigned int format = 
+    (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK)
+     | ((shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK));
+
+  if (want_q)
+    format |= bmFR_RX_FORMAT_WANT_Q;
+  if (bypass_halfband)
+    format |= bmFR_RX_FORMAT_BYPASS_HB;
+
+  return format;
+}
+
+int
+usrp_standard_rx::format_width(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;
+}
+
+int
+usrp_standard_rx::format_shift(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;
+}
+
+bool
+usrp_standard_rx::format_want_q(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_WANT_Q) != 0;
+}
+
+bool
+usrp_standard_rx::format_bypass_halfband(unsigned int format)
+{
+  return (format & bmFR_RX_FORMAT_BYPASS_HB) != 0;
+}
+
+bool
+usrp_standard_rx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+  ddc_control dxc(this, chan);
+  return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
+}
+
+
+//////////////////////////////////////////////////////////////////
+
+
+// tx data is timed to CLKOUT1 (64 MHz)
+// interpolate 4x
+// fine modulator enabled
+
+
+static unsigned char tx_regs_use_nco[] = {
+  REG_TX_IF,           (TX_IF_USE_CLKOUT1
+                        | TX_IF_I_FIRST
+                        | TX_IF_2S_COMP
+                        | TX_IF_INTERLEAVED),
+  REG_TX_DIGITAL,      (TX_DIGITAL_2_DATA_PATHS
+                        | TX_DIGITAL_INTERPOLATE_4X)
+};
+
+
+static int
+real_tx_mux_value (int mux, int nchan)
+{
+  if (mux != -1)
+    return mux;
+
+  switch (nchan){
+  case 1:
+    return 0x0098;
+  case 2:
+    return 0xba98;
+  default:
+    assert (0);
+  }
+}
+
+usrp_standard_tx::usrp_standard_tx (int which_board,
+                                   unsigned int interp_rate,
+                                   int nchan, int mux,
+                                   int fusb_block_size, int fusb_nblocks,
+                                   const std::string fpga_filename,
+                                   const std::string firmware_filename
+                                   )
+  : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename),
+    usrp_standard_common(this),
+    d_sw_mux (0x8), d_hw_mux (0x81)
+{
+  if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){
+    fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_nchannels (nchan)){
+    fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_interp_rate (interp_rate)){
+    fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+  if (!set_mux (real_tx_mux_value (mux, nchan))){
+    fprintf (stderr, "usrp_standard_tx: set_mux failed\n");
+    throw std::runtime_error ("usrp_standard_tx::ctor");
+  }
+
+  for (int i = 0; i < MAX_CHAN; i++){
+    d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO
+                               | TX_MODULATOR_COARSE_MODULATION_NONE);
+    d_coarse_mod[i] = CM_OFF;
+    set_tx_freq (i, 0);
+  }
+}
+
+usrp_standard_tx::~usrp_standard_tx ()
+{
+  // fprintf(stderr, "\nusrp_standard_tx: dtor\n");
+}
+
+bool
+usrp_standard_tx::start ()
+{
+  if (!usrp_basic_tx::start ())
+    return false;
+
+  // add our code here
+
+  return true;
+}
+
+bool
+usrp_standard_tx::stop ()
+{
+  bool ok = usrp_basic_tx::stop ();
+
+  // add our code here
+
+  return ok;
+}
+
+usrp_standard_tx_sptr
+usrp_standard_tx::make (int which_board,
+                       unsigned int interp_rate,
+                       int nchan, int mux,
+                       int fusb_block_size, int fusb_nblocks,
+                       const std::string fpga_filename,
+                       const std::string firmware_filename
+                       )
+{
+  try {
+    usrp_standard_tx_sptr u  = 
+      usrp_standard_tx_sptr(new usrp_standard_tx(which_board, interp_rate, nchan, mux,
+                                                fusb_block_size, fusb_nblocks,
+                                                fpga_filename, firmware_filename));
+    u->init_db(u);
+    return u;
+  }
+  catch (...){
+    return usrp_standard_tx_sptr();
+  }
+}
+
+bool
+usrp_standard_tx::set_interp_rate (unsigned int rate)
+{
+  // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n");
+
+  if ((rate & 0x3) || rate < 4 || rate > 512){
+    fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n");
+    return false;
+  }
+
+  d_interp_rate = rate;
+  set_usb_data_rate ((dac_rate () / rate * nchannels ())
+                    * (2 * sizeof (short)));
+
+  // We're using the interp by 4 feature of the 9862 so that we can
+  // use its fine modulator.  Thus, we reduce the FPGA's interpolation rate
+  // by a factor of 4.
+
+  bool s = disable_tx ();
+  bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
+  restore_tx (s);
+  return ok;
+}
+
+bool
+usrp_standard_tx::set_nchannels (int nchan)
+{
+  if (!(nchan == 1 || nchan == 2))
+    return false;
+
+  if (nchan > nducs())
+    return false;
+
+  d_nchan = nchan;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_tx::set_mux (int mux)
+{
+  d_sw_mux = mux;
+  d_hw_mux = mux << 4;
+  return write_hw_mux_reg ();
+}
+
+bool
+usrp_standard_tx::write_hw_mux_reg ()
+{
+  bool s = disable_tx ();
+  bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan);
+  restore_tx (s);
+  return ok;
+}
+
+int
+usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss)
+{
+  /*
+    Determine appropriate Tx mux value as a function of the subdevice choosen.
+
+    @param u:           instance of USRP source
+    @param subdev_spec: return value from subdev option parser.  
+    @type  subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0
+    @returns:           the Rx mux value
+  
+    This is simpler than the rx case.  Either you want to talk
+    to side A or side B.  If you want to talk to both sides at once,
+    determine the value manually.
+  */
+
+  if (!is_valid(ss))
+    throw std::invalid_argument("subdev_spec");
+
+  std::vector<db_base_sptr> db = this->db(ss.side);
+  
+  if(db[ss.subdev]->i_and_q_swapped()) {
+    unsigned int mask[2] = {0x0089, 0x8900};
+    return mask[ss.side];
+  }
+  else {
+    unsigned int mask[2] = {0x0098, 0x9800};
+    return mask[ss.side];
+  }
+}
+
+int
+usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
+{
+  if (ss_a.side == ss_b.side && ss_a.subdev == ss_b.subdev){
+    throw std::runtime_error("Cannot compute dual mux, repeated subdevice");
+  }
+  int mux_a = determine_tx_mux_value(ss_a);
+  //Get the mux b:
+  //   DAC0 becomes DAC2
+  //   DAC1 becomes DAC3
+  unsigned int mask[2] = {0x0022, 0x2200};
+  int mux_b = determine_tx_mux_value(ss_b) + mask[ss_b.side];
+  return mux_b | mux_a;
+}
+
+#ifdef USE_FPGA_TX_CORDIC
+
+bool
+usrp_standard_tx::set_tx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  // This assumes we're running the 4x on-chip interpolator.
+
+  unsigned int v =
+    compute_freq_control_word_fpga (dac_rate () / 4,
+                                   freq, &d_tx_freq[channel],
+                                   d_verbose);
+
+  return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);
+}
+
+
+#else
+
+bool
+usrp_standard_tx::set_tx_freq (int channel, double freq)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  // split freq into fine and coarse components
+
+  coarse_mod_t cm;
+  double       coarse;
+
+  double coarse_freq_1 = dac_rate () / 8; // First coarse frequency
+  double coarse_freq_2 = dac_rate () / 4; // Second coarse frequency
+  double coarse_limit_1 = coarse_freq_1 / 2; // Midpoint of [0 , freq1] range
+  double coarse_limit_2 = (coarse_freq_1 + coarse_freq_2) / 2; // Midpoint of [freq1 , freq2] range
+  double high_limit = (double)44e6/128e6*dac_rate (); // Highest meaningful frequency
+
+  if (freq < -high_limit)              // too low
+    return false;
+  else if (freq < -coarse_limit_2){    // For 64MHz: [-44, -24)
+    cm = CM_NEG_FDAC_OVER_4;
+    coarse = -coarse_freq_2;
+  }
+  else if (freq < -coarse_limit_1){    // For 64MHz: [-24, -8)
+    cm = CM_NEG_FDAC_OVER_8;
+    coarse = -coarse_freq_1;
+  }
+  else if (freq < coarse_limit_1){             // For 64MHz: [-8, 8)
+    cm = CM_OFF;
+    coarse = 0;
+  }
+  else if (freq < coarse_limit_2){     // For 64MHz: [8, 24)
+    cm = CM_POS_FDAC_OVER_8;
+    coarse = coarse_freq_1;
+  }
+  else if (freq <= high_limit){        // For 64MHz: [24, 44]
+    cm = CM_POS_FDAC_OVER_4;
+    coarse = coarse_freq_2;
+  }
+  else                         // too high
+    return false;
+
+
+  set_coarse_modulator (channel, cm);  // set bits in d_tx_modulator_shadow
+
+  double fine = freq - coarse;
+
+
+  // Compute fine tuning word...
+  // This assumes we're running the 4x on-chip interpolator.
+  // (This is required to use the fine modulator.)
+
+  unsigned int v =
+    compute_freq_control_word_9862 (dac_rate () / 4,
+                                   fine, &d_tx_freq[channel], d_verbose);
+
+  d_tx_freq[channel] += coarse;                // adjust actual
+  
+  unsigned char high, mid, low;
+
+  high = (v >> 16) & 0xff;
+  mid =  (v >>  8) & 0xff;
+  low =  (v >>  0) & 0xff;
+
+  bool ok = true;
+
+  // write the fine tuning word
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high);
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8,  mid);
+  ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0,   low);
+
+
+  d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO;
+
+  if (fine < 0)
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE;
+  else
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE;
+
+  ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]);
+
+  return ok;
+}
+#endif
+
+bool
+usrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm)
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return false;
+
+  switch (cm){
+  case CM_NEG_FDAC_OVER_4:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
+    break;
+
+  case CM_NEG_FDAC_OVER_8:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
+    break;
+
+  case CM_OFF:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    break;
+
+  case CM_POS_FDAC_OVER_8:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
+    break;
+
+  case CM_POS_FDAC_OVER_4:
+    d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
+    d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
+    break;
+
+  default:
+    return false;
+  }
+
+  d_coarse_mod[channel] = cm;
+  return true;
+}
+
+unsigned int
+usrp_standard_tx::interp_rate () const { return d_interp_rate; }
+
+int
+usrp_standard_tx::nchannels () const { return d_nchan; }
+
+int
+usrp_standard_tx::mux () const { return d_sw_mux; }
+
+double
+usrp_standard_tx::tx_freq (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return 0;
+
+  return d_tx_freq[channel];
+}
+
+usrp_standard_tx::coarse_mod_t
+usrp_standard_tx::coarse_modulator (int channel) const
+{
+  if (channel < 0 || channel >= MAX_CHAN)
+    return CM_OFF;
+
+  return d_coarse_mod[channel];
+}
+
+bool
+usrp_standard_tx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
+{
+  duc_control dxc(this, chan);
+  return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
+}
diff --git a/usrp/host/misc/.gitignore b/usrp/host/misc/.gitignore
new file mode 100644 (file)
index 0000000..a02b6ff
--- /dev/null
@@ -0,0 +1,8 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
diff --git a/usrp/host/swig/.gitignore b/usrp/host/swig/.gitignore
new file mode 100644 (file)
index 0000000..3a08165
--- /dev/null
@@ -0,0 +1,14 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/gnuradio_swig_python.cc
+/gnuradio_swig_python.py
+/usrp_prims.cc
+/usrp_prims.py
+/prims.cc
+/prims.py
index 6af452b020858859a33cef34a766a3b7a297d9e0..d2e6b8bc10be5e7c6b0f0bbd37b5b88e02456e81 100644 (file)
@@ -25,6 +25,7 @@ AM_CPPFLAGS =                 \
        $(USRP_INCLUDES)        \
        $(PYTHON_CPPFLAGS)      \
        -I$(srcdir)             \
+       $(USB_INCLUDES)         \
        $(WITH_INCLUDES)
 
 #################################
index d973c6d78016d4fe827e536422a046edd2c18bc9..0476858da2701623a262b48ba04509f13edab2ce 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2004 Free Software Foundation, Inc.
+ * Copyright 2003,2004,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 
 
 %{
-#include <usrp_prims.h>
+#include <usrp/usrp_prims.h>
 %}
 
 
 enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED };
 
-struct usb_dev_handle;
-struct usb_device;
 
 /*!
  * \brief initialize libusb; probe busses and devices.
  * Safe to call more than once.
  */
-void usrp_one_time_init ();
+void usrp_one_time_init (libusb_context **ctx = NULL);
 
 void usrp_rescan ();
 
@@ -63,20 +61,20 @@ void usrp_rescan ();
  *   configured USRP (firmware loaded)
  *   unconfigured Cypress FX2 (only if fx2_ok_p is true)
  */
-struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false);
+libusb_device *usrp_find_device (int nth, bool fx2_ok_p = false, libusb_context *ctx = NULL);
 
-bool usrp_usrp_p (struct usb_device *q);               //< is this a USRP
-bool usrp_usrp0_p (struct usb_device *q);              //< is this a USRP Rev 0
-bool usrp_usrp1_p (struct usb_device *q);              //< is this a USRP Rev 1
-bool usrp_usrp2_p (struct usb_device *q);              //< is this a USRP Rev 2
-int  usrp_hw_rev (struct usb_device *q);               //< return h/w rev code
-bool usrp_fx2_p (struct usb_device *q);                        //< is this an unconfigured Cypress FX2
+bool usrp_usrp_p (libusb_device *q);           //< is this a USRP
+bool usrp_usrp0_p (libusb_device *q);          //< is this a USRP Rev 0
+bool usrp_usrp1_p (libusb_device *q);          //< is this a USRP Rev 1
+bool usrp_usrp2_p (libusb_device *q);          //< is this a USRP Rev 2
+int  usrp_hw_rev (libusb_device *q);           //< return h/w rev code
+bool usrp_fx2_p (libusb_device *q);                    //< is this an unconfigured Cypress FX2
 
-bool usrp_unconfigured_usrp_p (struct usb_device *q);  //< some kind of unconfigured USRP
-bool usrp_configured_usrp_p (struct usb_device *q);    //< some kind of configured USRP
+bool usrp_unconfigured_usrp_p (libusb_device *q);      //< some kind of unconfigured USRP
+bool usrp_configured_usrp_p (libusb_device *q);        //< some kind of configured USRP
 
 /*!
- * \brief given a usb_device return an instance of the appropriate usb_dev_handle
+ * \brief given a libusb_device return an instance of the appropriate libusb_device_handle
  *
  * These routines claim the specified interface and select the
  * correct alternate interface.  (USB nomenclature is totally screwed!)
@@ -84,14 +82,14 @@ bool usrp_configured_usrp_p (struct usb_device *q); //< some kind of configured
  * If interface can't be opened, or is already claimed by some other
  * process, 0 is returned.
  */
-struct usb_dev_handle *usrp_open_cmd_interface (struct usb_device *dev);
-struct usb_dev_handle *usrp_open_rx_interface (struct usb_device *dev);
-struct usb_dev_handle *usrp_open_tx_interface (struct usb_device *dev);
+libusb_device_handle *usrp_open_cmd_interface (libusb_device *dev);
+libusb_device_handle *usrp_open_rx_interface (libusb_device *dev);
+libusb_device_handle *usrp_open_tx_interface (libusb_device *dev);
 
 /*!
  * \brief close interface.
  */
-bool usrp_close_interface (struct usb_dev_handle *udh);
+bool usrp_close_interface (libusb_device_handle *udh);
 
 /*!
  * \brief load intel hex format file into USRP/Cypress FX2 (8051).
@@ -103,7 +101,7 @@ bool usrp_close_interface (struct usb_dev_handle *udh);
  */
 
 usrp_load_status_t 
-usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force);
+usrp_load_firmware (libusb_device_handle *udh, const char *filename, bool force);
 
 /*!
  * \brief load intel hex format file into USRP FX2 (8051).
@@ -116,13 +114,13 @@ usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force
  * then rescans the busses and devices.
  */
 usrp_load_status_t
-usrp_load_firmware_nth (int nth, const char *filename, bool force);
+usrp_load_firmware_nth (int nth, const char *filename, bool force, libusb_context *ctx = NULL);
 
 /*!
  * \brief load fpga configuration bitstream
  */
 usrp_load_status_t
-usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, bool force);
+usrp_load_fpga (libusb_device_handle *udh, const char *filename, bool force);
 
 /*!
  * \brief load the regular firmware and fpga bitstream in the Nth USRP.
@@ -136,12 +134,12 @@ bool usrp_load_standard_bits (int nth, bool force);
 %include <fpga_regs_standard.h>
 
 
-bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value);
+bool usrp_write_fpga_reg (libusb_device_handle *udh, int reg, int value);
 
 %inline %{
 
 int 
-usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg)
+usrp_read_fpga_reg (libusb_device_handle *udh, int reg)
 {
   int value;
   bool ok = usrp_read_fpga_reg (udh, reg, &value);
@@ -153,37 +151,37 @@ usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg)
 
 %}
 
-bool usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on);
-bool usrp_set_led (struct usb_dev_handle *udh, int which, bool on);
+bool usrp_set_fpga_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_tx_enable (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_rx_enable (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_tx_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_fpga_rx_reset (libusb_device_handle *udh, bool on);
+bool usrp_set_led (libusb_device_handle *udh, int which, bool on);
 
-bool usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p);
-bool usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p);
+bool usrp_check_rx_overrun (libusb_device_handle *udh, bool *overrun_p);
+bool usrp_check_tx_underrun (libusb_device_handle *udh, bool *underrun_p);
 
 // i2c_read and i2c_write are limited to a maximum len of 64 bytes.
 
-bool usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr,
+bool usrp_i2c_write (libusb_device_handle *udh, int i2c_addr,
                     void *buf, int len);
 
-bool usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr,
+bool usrp_i2c_read (libusb_device_handle *udh, int i2c_addr,
                    void *buf, int len);
 
 // spi_read and spi_write are limited to a maximum of 64 bytes
 // See usrp_spi_defs.h for more info
 
-bool usrp_spi_write (struct usb_dev_handle *udh,
+bool usrp_spi_write (libusb_device_handle *udh,
                     int optional_header, int enables, int format,
                     unsigned char *buf, int len);
 
-bool usrp_spi_read (struct usb_dev_handle *udh,
+bool usrp_spi_read (libusb_device_handle *udh,
                     int optional_header, int enables, int format,
                     unsigned char *buf, int len);
 
 
-bool usrp_9862_write (struct usb_dev_handle *udh,
+bool usrp_9862_write (libusb_device_handle *udh,
                      int which_codec,                  // [0,  1]
                      int regno,                        // [0, 63]
                      int value);                       // [0, 255]     
@@ -191,7 +189,7 @@ bool usrp_9862_write (struct usb_dev_handle *udh,
 %inline %{
 
 int 
-usrp_9862_read (struct usb_dev_handle *udh, int which_codec, int reg)
+usrp_9862_read (libusb_device_handle *udh, int which_codec, int reg)
 {
   unsigned char value;
   bool ok = usrp_9862_read (udh, which_codec, reg, &value);
@@ -206,7 +204,7 @@ usrp_9862_read (struct usb_dev_handle *udh, int which_codec, int reg)
 %inline %{
 
 bool 
-usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
+usrp_eeprom_write (libusb_device_handle *udh, int i2c_addr,
                   int eeprom_offset, const std::string buf)
 {
   return usrp_eeprom_write (udh, i2c_addr, eeprom_offset,
@@ -214,7 +212,7 @@ usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
 }
   
 std::string
-usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
+usrp_eeprom_read (libusb_device_handle *udh, int i2c_addr,
                  int eeprom_offset, int len)
 {
   if (len <= 0)
@@ -230,12 +228,12 @@ usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
 
 %}
 
-bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot,
+bool usrp_write_aux_dac (libusb_device_handle *uhd, int slot,
                         int which_dac, int value);
 
 %inline %{
 
-int usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, int which_adc)
+int usrp_read_aux_adc (libusb_device_handle *udh, int slot, int which_adc)
 {
   int value;
   bool ok = usrp_read_aux_adc (udh, slot, which_adc, &value);
@@ -253,7 +251,7 @@ int usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, int which_adc)
  * Note that this only works on a configured usrp.
  * \returns non-zero length string iff successful.
  */
-std::string usrp_serial_number(struct usb_dev_handle *udh);
+std::string usrp_serial_number(libusb_device_handle *udh);
 
 /*!
  * \brief usrp daughterboard id to name mapping
diff --git a/usrp/host/swig/util.py b/usrp/host/swig/util.py
new file mode 100644 (file)
index 0000000..089bcaa
--- /dev/null
@@ -0,0 +1,95 @@
+# utilities
+
+from usrp_prims import *
+
+def setup (which_board = 0):
+    if not usrp_load_standard_bits (which_board, False):
+        raise RuntimeError, "usrp_load_standard_bits"
+    dev = usrp_find_device (which_board)
+    if not dev:
+        raise RuntimeError, "usrp_find_device"
+    u = usrp_open_cmd_interface (dev)
+    if not u:
+        raise RuntimeError, "usrp_open_cmd_interface"
+
+    # FIXME setup high speed paths, Aux ADC Clock, ...
+
+    # usrp_9862_write (u, 0, 35, 0x1)     # aux ADC clock = CLK/4
+    # usrp_9862_write (u, 1, 35, 0x1)
+
+    return u
+
+def write_slot_oe (u, slot, value, mask):
+    assert 0 <= slot and slot < 4
+    return usrp_write_fpga_reg (u, slot + FR_OE_0,
+                                ((mask & 0xffff) << 16) | (value & 0xffff))
+
+def write_slot_io (u, slot, value, mask):
+    assert 0 <= slot and slot < 4
+    return usrp_write_fpga_reg (u, slot + FR_IO_0,
+                                ((mask & 0xffff) << 16) | (value & 0xffff))
+
+
+# ----------------------------------------------------------------
+
+
+def ramp_aux_dac (u, which_codec, which_dac):
+    if not (which_codec == 0 or which_codec == 1):
+        raise AssertionError
+    if not (which_dac >= 0 and which_dac < 4):
+        raise AssertionError
+    try:
+        if which_dac == 3:                  # sigma delta output
+            sigma_delta_loop (u, which_codec)
+        else:
+            aux_dac_loop (u, which_codec, which_dac)
+    except KeyboardInterrupt:
+        return
+
+def sigma_delta_loop (u, which_codec):
+    counter = 0
+    while True:
+        usrp_9862_write (u, which_codec, 43, counter >> 4)
+        usrp_9862_write (u, which_codec, 42, (counter & 0xf) << 4)
+        # counter += 1 FIXME
+        counter += 4
+        if counter > 0xfff:
+            counter = 0
+
+def aux_dac_loop (u, which_codec, which_dac):
+    reg = 36 + which_dac                # Aux DAC A,B,C
+    counter = 0
+    while True:
+        usrp_9862_write (u, which_codec, reg, counter)
+        counter += 1
+        if counter > 0xff:
+            counter = 0
+
+
+def read_aux_adc_loop (u, slot, which_adc):
+    while True:
+        v = usrp_read_aux_adc (u, slot, which_adc)
+        print "%3d  %5.3f" % (v, v * 3.3 / 1024)
+
+def ramp_io_port (u, slot):
+    counter = 0
+    try:
+        while True:
+            write_slot_io (u, slot, counter, 0xffff)
+            counter += 1
+            if counter > 0xffff:
+                counter = 0
+    except KeyboardInterrupt:
+        return
+
+def walk_io_port (u, slot):
+    bit = 1
+    try:
+        while True:
+            write_slot_io (u, slot, bit, 0xffff)
+            bit = (bit << 1) & 0xffff
+            if bit == 0:
+                bit = 1
+    except KeyboardInterrupt:
+        return
+
index 77430ea463f46c42a6111ed7d3e3eb04479d4a30..3c30de62259aa72b59338fd8aad985667f92ad9e 100644 (file)
@@ -5,7 +5,7 @@ includedir=@includedir@
 
 Name: usrp
 Description: USRP Client Side C++ interface
-Requires: libusb @usrp_darwin_omnithread_pc_requires@
-Version: @VERSION@
+Requires: @LIBUSB_PKG_CONFIG_NAME@
+Version: @LIBVER@
 Libs: -L${libdir} -lusrp
-Cflags: -I${includedir} @DEFINES@
+Cflags: -I${includedir}
diff --git a/usrp2/.gitignore b/usrp2/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp2/doc/inband-signaling-eth b/usrp2/doc/inband-signaling-eth
new file mode 100644 (file)
index 0000000..f4f497b
--- /dev/null
@@ -0,0 +1,390 @@
+#
+# Copyright 2007 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+FIXME Needless to say, this is _very much_ a work in progress
+
+
+
+This file specifies the format of ethernet packets used for in-band data
+transmission and signaling on the USRP2.
+
+IN packets are sent towards the host.
+OUT packets are sent away from the host.
+
+The layout is 32-bits wide.  All data is transmitted in BIG-endian
+format across the ethernet.
+
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Chan   |                     mbz                       |I|S|E|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                           Timestamp                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   +                                                               +
+   |                            Payload                            |
+   .                                                               .
+   .                                                               .
+   .                                                               .
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+  mbz   Must be Zero: these bits must be zero in both IN and OUT packets.
+
+  I    Send Immediately. Set on Tx data that should be transmitted now.
+       FIXME: change definition to honor 0xffffffff timestamp.
+
+  S     Start of Burst Flag:  Set in an OUT packet if the data is the
+        first segment of what is logically a continuous burst of data.
+        Must be zero in IN packets.
+
+  E     End of Burst Flag:  Set in an OUT packet if the data is the
+        last segment of what is logically a continuous burst of data.
+        Must be zero in IN packets.  Underruns are not reported
+        when the FPGA runs out of samples between bursts.
+
+
+  Chan  5-bit logical channel number.  Channel number 0x1f is reserved
+        for control information.  See "Control Channel" below.  Other
+        channels are "data channels."  Each data channel is logically
+        independent of the others.  A data channel payload field
+        contains a sequence of homogeneous samples.  The format of the
+        samples is determined by the configuration associated with the
+        given channel.  It is often the case that the payload field
+        contains 32-bit complex samples, each containing 16-bit real
+        and imaginary components.
+
+  Timestamp: 32-bit timestamp.
+
+       FIXME: update to reflect that the time is measured at the
+       time the samples inserted into or pulled out of the 
+       DSP pipeline, not the A/D time.  Using A/D time is problematic
+       because of group delay through filtering, etc.
+
+       On IN packets, the timestamp indicates the time at which the
+       first sample of the packet was produced by the A/D converter(s)
+        for that channel.  On OUT packets, the timestamp specifies the
+        time at which the first sample in the packet should go out the
+        D/A converter(s) for that channel.  If a packet reaches the
+       head of the transmit queue, and the current time is later than
+       the timestamp, an error is assumed to have occurred and the
+       packet is discarded.  As a special case, the timestamp
+       0xffffffff is interpreted as "Now".
+
+       The time base is a free running 32-bit counter that is
+       incremented by the A/D sample-clock.
+
+  Payload: Variable length field.  Length is specified by the
+        length of the containing ethernet frame.
+
+
+// FIXME need to revisit this stuff
+
+  O     Overrun Flag: set in an IN packet if an overrun condition was
+        detected.  Must be zero in OUT packets.  Overrun occurs when
+        the FPGA has data to transmit to the host and there is no
+        buffer space available.  This generally indicates a problem on
+        the host.  Either it is not keeping up, or it has configured
+        the FPGA to transmit data at a higher rate than the transport
+        (USB) can support.
+
+  U     Underrun Flag: set in an IN packet if an underrun condition
+        was detected.  Must be zero in OUT packets.  Underrun occurs
+        when the FPGA runs out of samples, and it's not between
+        bursts.  See the "End of Burst flag" below.
+
+  D     Dropped Packet Flag: Set in an IN packet if the FPGA
+       discarded an OUT packet because its timestamp had already
+       passed.
+
+
+  RSSI  6-bit Received Strength Signal Indicator:  Must be zero in OUT
+        packets.  In IN packets, indicates RSSI as reported by front end.
+       FIXME The format and interpretation are to be determined.
+
+
+  Tag   4-bit tag for matching IN packets with OUT packets.
+        [FIXME, write more...]
+
+
+
+"Data Channel" payload format:
+-------------------------------
+
+If Chan != 0x1f, the packet is a "data packet" and the payload is a
+sequence of homogeneous samples.  The format of the samples is
+determined by the configuration associated with the given channel.  
+It is often the case that the payload field contains 32-bit complex
+samples, each containing 16-bit real and imaginary components.
+
+
+"Control Channel" payload format:
+---------------------------------
+
+If Chan == 0x1f, the packet is a "control packet".  The control channel
+payload consists of a sequence of 0 or more sub-packets.
+
+Each sub-packet starts on a 32-bit boundary, and consists of an 8-bit
+Opcode field, an 8-bit Length field, Length bytes of arguments, and 0,
+1, 2 or 3 bytes of padding to align the tail of the sub-packet to
+a 32-bit boundary.
+
+Control channel packets shall be processed at the head of the queue,
+and shall observe the timestamp semantics described above.
+
+
+General sub-packet format:
+--------------------------
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-//-+-+-+-+-+-+-+-+
+   |     Opcode    |    Length     |        <length bytes> ...    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-//-+-+-+-+-+-+-+-+
+
+
+Specific sub-packet formats:
+----------------------------
+
+  RID: 8-bit Request-ID. Copied from request sub-packet into corresponding
+       reply sub-packet.  RID allows the host to match requests and replies.
+
+  Reg Number: 8-bit Register Number.
+
+
+
+Identify:
+
+    Opcode:    OP_ID
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |       RID     |      mbz      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Identify Reply:
+
+    Opcode:    OP_ID_REPLY
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |      50       |      RID      |      mbz      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Mac Addr 0   |  Mac Addr 1   |  Mac Addr 2   |  Mac Addr 3   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Mac Addr 4   |  Mac Addr 5   | H/W rev major | H/W rev minor |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Serial Num 0  | Serial Num 1  | Serial Num 2  | Serial Num 3  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Serial Num 4  | Serial Num 5  | Serial Num 6  | Serial Num 7  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   +                                                               +
+   |                                                               |
+   +                         FPGA MD5SUM                           +
+   |                                                               |
+   +                                                               +
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                                               |
+   +                                                               +
+   |                                                               |
+   +                          S/W MD5SUM                           +
+   |                                                               |
+   +                                                               +
+   |                                                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Write Register:
+
+    Opcode:    OP_WRITE_REG
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       6       |      mbz      |   Reg Number  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Register Value                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Write Register Masked:
+
+    Opcode:    OP_WRITE_REG_MASKED
+
+    REG[Num] = (REG[Num] & ~Mask) | (Value & Mask)
+
+    That is, only the register bits that correspond to 1's in the
+    mask are written with the new value.
+
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |      10       |      mbz      |   Reg Number  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Register Value                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                           Mask Value                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Read Register:
+
+    Opcode:    OP_READ_REG
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |      RID      |   Reg Number  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Read Register Reply:
+
+    Opcode:    OP_READ_REG_REPLY
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       6       |      RID      |   Reg Number  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Register Value                         |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+// FIXME these may not be implemented...
+
+I2C Write:
+
+    Opcode:    OP_I2C_WRITE
+    I2C Addr:   7-bit I2C address
+    Data:      The bytes to write to the I2C bus
+    Length:     Length of Data + 2
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |    Length     |      RID      |    I2C Addr   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+I2C Write Reply:
+
+    Opcode:    OP_I2C_WRITE_REPLY
+    Length:     2
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |      RID      |      OK       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+OK is 1 if successful, else 0.
+
+
+I2C Read:
+
+    Opcode:    OP_I2C_READ
+    I2C Addr:  7-bit I2C address
+    Nbytes:    Number of bytes to read from I2C bus
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       3       |      RID      |    I2C Addr   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Nbytes    |              unspecified padding              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+I2C Read Reply:
+
+    Opcode:    OP_I2C_READ_REPLY
+    I2C Addr:  7-bit I2C address
+    Data:      Length - 2 bytes of data read from I2C bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |     Length    |      RID      |      OK       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+OK is 1 if successful, else 0
+
+
+SPI Write:
+
+    Opcode:          OP_SPI_WRITE
+    Enables:         Which SPI enables to assert (mask)
+    Format:          Specifies format of SPI data and Opt Header Bytes
+    Opt Header Bytes: 2-byte field containing optional Tx bytes; see Format
+    Data:            The bytes to write to the SPI bus
+    Length:          Length of Data + 6
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |     Length    |      RID      |      mbz      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Enables    |    Format     |        Opt Header Bytes       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+SPI Write Reply:
+
+    Opcode:    OP_SPI_WRITE_REPLY
+    Length:     2
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |      RID      |      OK       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+OK is 1 if successful, else 0.
+
+
+SPI Read:
+
+    Opcode:          OP_SPI_READ
+    Enables:         Which SPI enables to assert (mask)
+    Format:          Specifies format of SPI data and Opt Header Bytes
+    Opt Header Bytes: 2-byte field containing optional Tx bytes; see Format
+    Nbytes:          Number of bytes to read from SPI bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       7       |      RID      |      mbz      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Enables    |    Format     |        Opt Header Bytes       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Nbytes    |              unspecified padding              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+SPI Read Reply:
+
+    Opcode:   OP_SPI_READ_REPLY
+    Data:     Length - 2 bytes of data read from SPI bus.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |     Length    |    RID    |        mbz        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...                                                  .
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+Delay:
+
+    Opcode:    OP_DELAY
+    Ticks:     16-bit unsigned delay count
+
+    Delay Ticks clock ticks before executing next operation.
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Opcode    |       2       |            Ticks              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
diff --git a/usrp2/firmware/.gitignore b/usrp2/firmware/.gitignore
new file mode 100644 (file)
index 0000000..2381f13
--- /dev/null
@@ -0,0 +1,40 @@
+/*-stamp
+/*.a
+/*.bin
+/*.dump
+/*.log
+/*.rom
+/.deps
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/blink_leds
+/blink_leds2
+/build
+/compile
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/eth_test
+/gen_eth_packets
+/ibs_rx_test
+/ibs_tx_test
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/py-compile
+/rcv_eth_packets
+/run_tests.sh
+/stamp-h1
+/test1
+/test_phy_comm
+/timer_test
+/buf_ram_test
+/buf_ram_zero
+/hello
+/configure.lineno
index 62b2d5bad25873e4ca4e48681c91b4be25e149bd..c75136de1cc16481704b99e1af10da3dbbc12aed 100644 (file)
@@ -22,8 +22,8 @@ include $(top_srcdir)/Makefile.common
 EXTRA_DIST = \
        bootstrap \
        configure \
-       configure.gnu
-
+       configure.gnu \
+       u2_flash_tool
 
 SUBDIRS = config 
 
diff --git a/usrp2/firmware/apps/.gitignore b/usrp2/firmware/apps/.gitignore
new file mode 100644 (file)
index 0000000..33469a7
--- /dev/null
@@ -0,0 +1,79 @@
+/*-stamp
+/*.a
+/*.bin
+/*.dump
+/*.log
+/*.rom
+/*.map
+/.deps
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/blink_leds
+/blink_leds2
+/build
+/compile
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/echo
+/eth_test
+/gen_eth_packets
+/ibs_rx_test
+/ibs_tx_test
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/py-compile
+/rcv_eth_packets
+/run_tests.sh
+/stamp-h1
+/test1
+/test_phy_comm
+/timer_test
+/buf_ram_test
+/buf_ram_zero
+/hello
+/test_printf
+/test_spi
+/test_i2c
+/gen_pause_frames
+/test_serdes
+/rx_only
+/tx_only
+/tx_standalone
+/tx_drop
+/tx_drop2
+/tx_drop_rate_limited
+/test_lsdac
+/test_lsadc
+/read_dbids
+/test_db_spi
+/ramp_lsdac
+/eth_to_serdes
+/serdes_to_dsp
+/sd_gentest
+/sd_bounce
+/can_i_sub
+/tx_only_v2
+/rx_only_v2
+/txrx
+/txrx_wbx
+/txrx_xcvr
+/eth_serdes
+/serdes_txrx
+/set_hw_rev
+/test_sd
+/factory_test
+/test_ram
+/mimo_tx
+/mimo_tx_slave
+/burn_dbsrx_eeprom
+/burnrev30
+/burnrev31
+/burnrev40
index b809039d028027f59b4f4b0ccf2c5dd372b70b97..1dc8b0a7371a6171e3644694a17ee29e02d63b3a 100644 (file)
@@ -45,6 +45,8 @@ noinst_PROGRAMS = \
        timer_test \
        tx_standalone \
        txrx \
+       txrx_wbx \
+       txrx_xcvr \
        factory_test \
        burnrev30 \
        burnrev31 \
@@ -61,12 +63,19 @@ noinst_PROGRAMS = \
 # tx_drop_rate_limited_SOURCES = tx_drop_rate_limited.c app_common.c
 # tx_drop2_SOURCES = tx_drop2.c app_common.c
 txrx_SOURCES = txrx.c app_common_v2.c
+txrx_wbx_SOURCES = txrx.c app_common_v2.c
+txrx_xcvr_SOURCES = txrx.c app_common_v2.c
 factory_test_SOURCES = factory_test.c app_common_v2.c
 eth_serdes_SOURCES = eth_serdes.c app_passthru_v2.c
 serdes_txrx_SOURCES = serdes_txrx.c app_common_v2.c
 mimo_tx_SOURCES = mimo_tx.c mimo_app_common_v2.c
 mimo_tx_slave_SOURCES = mimo_tx_slave.c app_common_v2.c
 
+txrx_wbx_LDADD = ../lib/libu2fw_wbx.a
+
+txrx_xcvr_LDADD = ../lib/libu2fw_xcvr.a
+
+
 noinst_HEADERS = \
         app_common_v2.h \
         app_passthru_v2.h \
index 6d9606d45e980f9eafebb2d1b3bd6ad1debb629f..7716ed992932bccfaa23b770c481dc12db74317b 100644 (file)
@@ -31,6 +31,7 @@
 #include "clocks.h"
 #include "u2_init.h"
 #include <string.h>
+#include "usrp2_i2c_addr.h"
 
 volatile bool link_is_up = false;      // eth handler sets this
 int cpu_tx_buf_dest_port = PORT_ETH;
@@ -70,6 +71,7 @@ void
 set_reply_hdr(u2_eth_packet_t *reply_pkt, u2_eth_packet_t const *cmd_pkt)
 {
   reply_pkt->ehdr.dst = cmd_pkt->ehdr.src;
+  reply_pkt->ehdr.src = *ethernet_mac_addr();
   reply_pkt->ehdr.ethertype = U2_ETHERTYPE;
   reply_pkt->thdr.flags = 0;
   reply_pkt->thdr.fifo_status = 0;     // written by protocol engine
@@ -151,7 +153,7 @@ config_tx_v2_cmd(const op_config_tx_v2_t *p,
   memset(&tune_result, 0, sizeof(tune_result));
 
   bool ok = true;
-  
+
   if (p->valid & CFGV_GAIN){
     ok &= db_set_gain(tx_dboard, p->gain);
   }
@@ -160,7 +162,7 @@ config_tx_v2_cmd(const op_config_tx_v2_t *p,
     bool was_streaming = is_streaming();
     if (was_streaming)
       stop_rx_cmd();
-    
+
     u2_fxpt_freq_t f = u2_fxpt_freq_from_hilo(p->freq_hi, p->freq_lo);
     bool tune_ok = db_tune(tx_dboard, f, &tune_result);
     ok &= tune_ok;
@@ -184,7 +186,7 @@ config_tx_v2_cmd(const op_config_tx_v2_t *p,
       hb1 = 1;
       interp = interp >> 1;
     }
-    
+
     if (interp < MIN_CIC_INTERP || interp > MAX_CIC_INTERP)
       ok = false;
     else {
@@ -214,7 +216,7 @@ config_tx_v2_cmd(const op_config_tx_v2_t *p,
 }
 
 static size_t
-config_rx_v2_cmd(const op_config_rx_v2_t *p, 
+config_rx_v2_cmd(const op_config_rx_v2_t *p,
                 void *reply_payload, size_t reply_payload_space)
 {
   op_config_rx_reply_v2_t *r = (op_config_rx_reply_v2_t *) reply_payload;
@@ -225,7 +227,7 @@ config_rx_v2_cmd(const op_config_rx_v2_t *p,
   memset(&tune_result, 0, sizeof(tune_result));
 
   bool ok = true;
-  
+
   if (p->valid & CFGV_GAIN){
     ok &= db_set_gain(rx_dboard, p->gain);
   }
@@ -234,7 +236,7 @@ config_rx_v2_cmd(const op_config_rx_v2_t *p,
     bool was_streaming = is_streaming();
     if (was_streaming)
       stop_rx_cmd();
-    
+
     u2_fxpt_freq_t f = u2_fxpt_freq_from_hilo(p->freq_hi, p->freq_lo);
     bool tune_ok = db_tune(rx_dboard, f, &tune_result);
     ok &= tune_ok;
@@ -248,17 +250,17 @@ config_rx_v2_cmd(const op_config_rx_v2_t *p,
     int decim = p->decim;
     int hb1 = 0;
     int hb2 = 0;
-    
+
     if(!(decim & 1)) {
       hb2 = 1;
       decim = decim >> 1;
     }
-    
+
     if(!(decim & 1)) {
       hb1 = 1;
       decim = decim >> 1;
     }
-    
+
     if (decim < MIN_CIC_DECIM || decim > MAX_CIC_DECIM)
       ok = false;
     else {
@@ -293,7 +295,7 @@ read_time_cmd(const op_generic_t *p,
              void *reply_payload, size_t reply_payload_space)
 {
   op_read_time_reply_t *r = (op_read_time_reply_t *) reply_payload;
-  if (reply_payload_space < sizeof(*r))                
+  if (reply_payload_space < sizeof(*r))
     return 0;                                  // no room
 
   r->opcode = OP_READ_TIME_REPLY;
@@ -307,7 +309,7 @@ read_time_cmd(const op_generic_t *p,
 static void
 fill_db_info(u2_db_info_t *p, const struct db_base *db)
 {
-  p->dbid = db->dbid;
+  //p->dbid = db->dbid;
   p->freq_min_hi = u2_fxpt_freq_hi(db->freq_min);
   p->freq_min_lo = u2_fxpt_freq_lo(db->freq_min);
   p->freq_max_hi = u2_fxpt_freq_hi(db->freq_max);
@@ -322,7 +324,7 @@ dboard_info_cmd(const op_generic_t *p,
                void *reply_payload, size_t reply_payload_space)
 {
   op_dboard_info_reply_t *r = (op_dboard_info_reply_t *) reply_payload;
-  if (reply_payload_space < sizeof(*r))                
+  if (reply_payload_space < sizeof(*r))
     return 0;                                  // no room
 
   r->opcode = OP_DBOARD_INFO_REPLY;
@@ -333,6 +335,9 @@ dboard_info_cmd(const op_generic_t *p,
   fill_db_info(&r->tx_db_info, tx_dboard);
   fill_db_info(&r->rx_db_info, rx_dboard);
 
+  r->tx_db_info.dbid = read_dboard_eeprom(I2C_ADDR_TX_A);
+  r->rx_db_info.dbid = read_dboard_eeprom(I2C_ADDR_RX_A);
+
   return r->len;
 }
 
@@ -410,14 +415,14 @@ generic_reply(const op_generic_t *p,
              bool ok)
 {
   op_generic_t *r = (op_generic_t *) reply_payload;
-  if (reply_payload_space < sizeof(*r))                
+  if (reply_payload_space < sizeof(*r))
     return 0;                                  // no room
-  
+
   r->opcode = p->opcode | OP_REPLY_BIT;
   r->len = sizeof(*r);
   r->rid = p->rid;
   r->ok = ok;
-  
+
   return r->len;
 }
 
@@ -425,14 +430,14 @@ static size_t
 add_eop(void *reply_payload, size_t reply_payload_space)
 {
   op_generic_t *r = (op_generic_t *) reply_payload;
-  if (reply_payload_space < sizeof(*r))                
+  if (reply_payload_space < sizeof(*r))
     return 0;                                  // no room
-  
+
   r->opcode = OP_EOP;
   r->len = sizeof(*r);
   r->rid = 0;
   r->ok =  0;
-  
+
   return r->len;
 }
 
@@ -442,15 +447,15 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
   unsigned char reply[sizeof(u2_eth_packet_t) + 4 * sizeof(u2_subpkt_t)] _AL4;
   unsigned char *reply_payload = &reply[sizeof(u2_eth_packet_t)];
   int reply_payload_space = sizeof(reply) - sizeof(u2_eth_packet_t);
-  
+
   // initialize reply
   memset(reply, 0, sizeof(reply));
   set_reply_hdr((u2_eth_packet_t *) reply, pkt);
-  
+
   // point to beginning of payload (subpackets)
   unsigned char *payload = ((unsigned char *) pkt) + sizeof(u2_eth_packet_t);
   int payload_len = len - sizeof(u2_eth_packet_t);
-  
+
   size_t subpktlen = 0;
   bool ok = false;
 
@@ -467,7 +472,7 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
     case OP_ID:
       subpktlen = op_id_cmd(gp, reply_payload, reply_payload_space);
       break;
-    
+
     case OP_CONFIG_TX_V2:
       subpktlen = config_tx_v2_cmd((op_config_tx_v2_t *) payload, reply_payload, reply_payload_space);
       break;
@@ -477,15 +482,26 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
       break;
 
     case OP_START_RX_STREAMING:
-      start_rx_streaming_cmd(&pkt->ehdr.src, (op_start_rx_streaming_t *) payload);
+      if (pkt->fixed.timestamp == -1) // Start now (default)
+        start_rx_streaming_cmd(&pkt->ehdr.src, (op_start_rx_streaming_t *) payload);
+      else
+        start_rx_streaming_at_cmd(&pkt->ehdr.src, (op_start_rx_streaming_t *)payload, pkt->fixed.timestamp);
       ok = true;
       goto generic_reply;
-    
+
     case OP_STOP_RX:
       stop_rx_cmd();
       ok = true;
       goto generic_reply;
-    
+
+    case OP_RX_ANTENNA:
+        ok = db_set_antenna(rx_dboard, ((op_config_mimo_t *)payload)->flags);
+        goto generic_reply;
+
+    case OP_TX_ANTENNA:
+        ok = db_set_antenna(tx_dboard, ((op_config_mimo_t *)payload)->flags);
+        goto generic_reply;
+
     case OP_BURN_MAC_ADDR:
       ok = ethernet_set_mac_addr(&((op_burn_mac_addr_t *)payload)->addr);
       goto generic_reply;
@@ -531,8 +547,8 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
 
     case OP_GPIO_SET_DDR:
       ok = true;
-      hal_gpio_set_ddr(((op_gpio_t *)payload)->bank, 
-                      ((op_gpio_t *)payload)->value, 
+      hal_gpio_set_ddr(((op_gpio_t *)payload)->bank,
+                      ((op_gpio_t *)payload)->value,
                       ((op_gpio_t *)payload)->mask);
       goto generic_reply;
 
@@ -548,8 +564,8 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
 
     case OP_GPIO_WRITE:
       ok = true;
-      hal_gpio_write(((op_gpio_t *)payload)->bank, 
-                    ((op_gpio_t *)payload)->value, 
+      hal_gpio_write(((op_gpio_t *)payload)->bank,
+                    ((op_gpio_t *)payload)->value,
                     ((op_gpio_t *)payload)->mask);
       goto generic_reply;
 
@@ -599,7 +615,7 @@ bool
 eth_pkt_inspector(dbsm_t *sm, int bufno)
 {
   u2_eth_packet_t *pkt = (u2_eth_packet_t *) buffer_ram(bufno);
-  size_t byte_len = (buffer_pool_status->last_line[bufno] - 3) * 4;
+  size_t byte_len = (buffer_pool_status->last_line[bufno] - 1) * 4;
 
   //static size_t last_len = 0;
 
index 5058661ad05c437b02386f531fe7324433b6084f..ff1baec064affb894ad1dc9be1f272c52159efc3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,8 +55,10 @@ print_tune_result(char *msg, bool tune_ok,
 
 
 void start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p);
+void start_rx_streaming_at_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p, uint32_t time);
 void stop_rx_cmd(void);
 void restart_streaming(void);
+void restart_streaming_at(uint32_t time);
 bool is_streaming(void);
 
 void handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len);
index 660bcd774fafeb4a6992386c21f12b047cb6a607..406c56b3b8f460d38f1d88937f43485e1a5669b6 100644 (file)
@@ -42,6 +42,7 @@ void
 set_reply_hdr(u2_eth_packet_t *reply_pkt, u2_eth_packet_t const *cmd_pkt)
 {
   reply_pkt->ehdr.dst = cmd_pkt->ehdr.src;
+  reply_pkt->ehdr.src = *ethernet_mac_addr();
   reply_pkt->ehdr.ethertype = U2_ETHERTYPE;
   reply_pkt->thdr.flags = 0;
   reply_pkt->thdr.fifo_status = 0;     // written by protocol engine
diff --git a/usrp2/firmware/apps/bitrot/tx_drop.c b/usrp2/firmware/apps/bitrot/tx_drop.c
new file mode 100644 (file)
index 0000000..d5d6557
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "u2_init.h"
+#include "memory_map.h"
+#include "spi.h"
+#include "hal_io.h"
+#include "buffer_pool.h"
+#include "pic.h"
+#include "bool.h"
+#include "ethernet.h"
+#include "nonstdio.h"
+#include "usrp2_eth_packet.h"
+#include "dbsm.h"
+#include "app_common.h"
+#include "print_rmon_regs.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * Like tx_only.c, but we discard data packets instead of sending them to the
+ * DSP TX pipeline.
+ */
+
+int total_rx_pkts = 0;
+int total_rx_bytes = 0;
+
+
+static int timer_delta = MASTER_CLK_RATE/1000; // tick at 1kHz
+
+/*
+ * This program can respond to queries from the host
+ * and stream rx samples.
+ *
+ * Buffer 1 is used by the cpu to send frames to the host.
+ * Buffers 2 and 3 are used to double-buffer the DSP Rx to eth flow
+ * Buffers 4 and 5 are used to double-buffer the eth to DSP Tx  eth flow
+ */
+//#define CPU_RX_BUF   0       // eth -> cpu
+//#define CPU_TX_BUF   1       // cpu -> eth
+
+#define        DSP_RX_BUF_0    2       // dsp rx -> eth (double buffer)
+#define        DSP_RX_BUF_1    3       // dsp rx -> eth
+#define        DSP_TX_BUF_0    4       // eth -> dsp tx (double buffer)
+#define        DSP_TX_BUF_1    5       // eth -> dsp tx
+
+
+/*
+ * ================================================================
+ *      configure DSP TX double buffering state machine
+ * ================================================================
+ */
+
+// 4 lines of ethernet hdr + 2 lines (word0 + timestamp)
+// DSP Tx reads word0 (flags) + timestamp followed by samples
+
+#define DSP_TX_FIRST_LINE                4
+#define DSP_TX_SAMPLES_PER_FRAME       250     // not used except w/ debugging
+#define        DSP_TX_EXTRA_LINES                2     // reads word0 + timestamp
+
+// Receive from ethernet
+buf_cmd_args_t dsp_tx_recv_args = {
+  PORT_ETH,
+  0,
+  BP_LAST_LINE
+};
+
+// send to DSP Tx
+buf_cmd_args_t dsp_tx_send_args = {
+  PORT_DSP,
+  DSP_TX_FIRST_LINE,   // starts just past ethernet header
+  0                    // filled in from last_line register
+};
+
+dbsm_t dsp_tx_sm;      // the state machine
+
+
+// ----------------------------------------------------------------
+
+
+// The mac address of the host we're sending to.
+u2_mac_addr_t host_mac_addr;
+
+
+void
+timer_irq_handler(unsigned irq)
+{
+  hal_set_timeout(timer_delta);        // schedule next timeout
+}
+
+// Tx DSP underrun
+void
+underrun_irq_handler(unsigned irq)
+{
+  putchar('U');
+
+  dbsm_stop(&dsp_tx_sm);
+  dsp_tx_regs->clear_state = 1;
+  dbsm_start(&dsp_tx_sm);  // restart sm so we're listening to ethernet again
+
+  // putstr("\nirq: underrun\n");
+}
+
+
+void
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
+{
+}
+
+void
+stop_rx_cmd(void)
+{
+}
+
+static void
+setup_tx()
+{
+  dsp_tx_regs->clear_state = 1;
+  bp_clear_buf(DSP_TX_BUF_0);
+  bp_clear_buf(DSP_TX_BUF_1);
+
+  int tx_scale = 256;
+  int interp = 32;
+
+  op_config_tx_t def_config;
+  memset(&def_config, 0, sizeof(def_config));
+  def_config.phase_inc  = 408021893;                   // 9.5 MHz [2**32 * fc/fsample]
+  def_config.scale_iq = (tx_scale << 16) | tx_scale;
+  def_config.interp = interp;
+
+  // setup Tx DSP regs
+  config_tx_cmd(&def_config);
+}
+
+
+inline static void
+buffer_irq_handler(unsigned irq)
+{
+  uint32_t  status = buffer_pool_status->status;
+
+  if (status & BPS_ERROR_ALL){
+    // FIXME rare path, handle error conditions
+    putstr("Errors! status = ");
+    puthex32_nl(status);
+
+    printf("total_rx_pkts  = %d\n", total_rx_pkts);
+    printf("total_rx_bytes = %d\n", total_rx_bytes);
+
+    print_rmon_regs();
+
+    if (status & (BPS_ERROR(DSP_TX_BUF_0) | BPS_ERROR(DSP_TX_BUF_1))){
+      dbsm_stop(&dsp_tx_sm);           
+      dsp_tx_regs->clear_state = 1; // try to restart
+      dbsm_start(&dsp_tx_sm);
+      return;
+    }
+  }
+
+  dbsm_process_status(&dsp_tx_sm, status);
+
+  if (status & BPS_DONE(CPU_TX_BUF)){
+    bp_clear_buf(CPU_TX_BUF);
+  }
+}
+
+
+/*
+ * Called when an ethernet packet is received.
+ *
+ * Claim that we handled all the packets,
+ * dropping those destined for the TX DSP chain
+ * on the ground.
+ */
+bool
+nop_eth_pkt_inspector(dbsm_t *sm, int bufno)
+{
+  hal_toggle_leds(0x1);
+
+  u2_eth_packet_t *pkt = (u2_eth_packet_t *) buffer_ram(bufno);
+  size_t byte_len = (buffer_pool_status->last_line[bufno] - 1) * 4;
+
+  total_rx_pkts++;
+  total_rx_bytes += byte_len;
+
+  // inspect rcvd frame and figure out what do do.
+
+  if (pkt->ehdr.ethertype != U2_ETHERTYPE)
+    return true;       // ignore, probably bogus PAUSE frame from MAC
+
+  int chan = u2p_chan(&pkt->fixed);
+
+  switch (chan){
+  case CONTROL_CHAN:
+    handle_control_chan_frame(pkt, byte_len);
+    return true;       // we handled the packet
+    break;
+
+  case 0:
+  default:
+    return true;       // We handled the data by dropping it :)
+    break;
+  }
+}
+
+
+int
+main(void)
+{
+  u2_init();
+
+  // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
+  hal_gpio_set_tx_mode(15, 0, GPIOM_FPGA_1);
+  hal_gpio_set_rx_mode(15, 0, GPIOM_FPGA_1);
+
+  putstr("\ntx_drop\n");
+  
+  // Control LEDs
+  hal_set_leds(0x0, 0x3);
+
+  pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
+
+  ethernet_register_link_changed_callback(link_changed_callback);
+  ethernet_init();
+
+  // initialize double buffering state machine for ethernet -> DSP Tx
+
+  dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0,
+           &dsp_tx_recv_args, &dsp_tx_send_args,
+           nop_eth_pkt_inspector);
+
+  // program tx registers
+  setup_tx();
+
+  // kick off the state machine
+  dbsm_start(&dsp_tx_sm);
+
+  while(1){
+    buffer_irq_handler(0);
+  }
+}
+
diff --git a/usrp2/firmware/apps/bitrot/tx_drop2.c b/usrp2/firmware/apps/bitrot/tx_drop2.c
new file mode 100644 (file)
index 0000000..7f9b7a5
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "u2_init.h"
+#include "memory_map.h"
+#include "spi.h"
+#include "hal_io.h"
+#include "buffer_pool.h"
+#include "pic.h"
+#include "bool.h"
+#include "ethernet.h"
+#include "nonstdio.h"
+#include "usrp2_eth_packet.h"
+#include "dbsm.h"
+#include "app_common.h"
+#include "print_rmon_regs.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * Like tx_only.c, but we discard data packets instead of sending them to the
+ * DSP TX pipeline.
+ */
+
+int total_rx_pkts = 0;
+int total_rx_bytes = 0;
+
+
+static int timer_delta = MASTER_CLK_RATE/1000; // tick at 1kHz
+
+/*
+ * This program can respond to queries from the host
+ * and stream rx samples.
+ *
+ * Buffer 1 is used by the cpu to send frames to the host.
+ * Buffers 2 and 3 are used to double-buffer the DSP Rx to eth flow
+ * Buffers 4 and 5 are used to double-buffer the eth to DSP Tx  eth flow
+ */
+//#define CPU_RX_BUF   0       // eth -> cpu
+//#define CPU_TX_BUF   1       // cpu -> eth
+
+#define        DSP_RX_BUF_0    2       // dsp rx -> eth (double buffer)
+#define        DSP_RX_BUF_1    3       // dsp rx -> eth
+#define        DSP_TX_BUF_0    4       // eth -> dsp tx (double buffer)
+#define        DSP_TX_BUF_1    5       // eth -> dsp tx
+
+
+/*
+ * ================================================================
+ *      configure DSP RX double buffering state machine
+ * ================================================================
+ */
+
+// 4 lines of ethernet hdr + 1 line (word0)
+// DSP Rx writes timestamp followed by nlines_per_frame of samples
+#define DSP_RX_FIRST_LINE                5
+#define DSP_RX_SAMPLES_PER_FRAME       128
+#define        DSP_RX_EXTRA_LINES                1     // writes timestamp
+
+// Receive from DSP Rx
+buf_cmd_args_t dsp_rx_recv_args = {
+  PORT_DSP,
+  DSP_RX_FIRST_LINE,
+  BP_LAST_LINE
+};
+
+// send to ethernet
+buf_cmd_args_t dsp_rx_send_args = {
+  PORT_ETH,
+  0,           // starts with ethernet header in line 0
+  0,           // filled in from last_line register
+};
+
+dbsm_t dsp_rx_sm;      // the state machine
+
+/*
+ * ================================================================
+ *      configure DSP TX double buffering state machine
+ * ================================================================
+ */
+
+// 4 lines of ethernet hdr + 2 lines (word0 + timestamp)
+// DSP Tx reads word0 (flags) + timestamp followed by samples
+
+#define DSP_TX_FIRST_LINE                4
+#define DSP_TX_SAMPLES_PER_FRAME       250     // not used except w/ debugging
+#define        DSP_TX_EXTRA_LINES                2     // reads word0 + timestamp
+
+// Receive from ethernet
+buf_cmd_args_t dsp_tx_recv_args = {
+  PORT_ETH,
+  0,
+  BP_LAST_LINE
+};
+
+// send to DSP Tx
+buf_cmd_args_t dsp_tx_send_args = {
+  PORT_DSP,
+  DSP_TX_FIRST_LINE,   // starts just past ethernet header
+  0                    // filled in from last_line register
+};
+
+dbsm_t dsp_tx_sm;      // the state machine
+
+
+// ----------------------------------------------------------------
+
+
+// The mac address of the host we're sending to.
+u2_mac_addr_t host_mac_addr;
+
+
+void
+timer_irq_handler(unsigned irq)
+{
+  hal_set_timeout(timer_delta);        // schedule next timeout
+}
+
+// Tx DSP underrun
+void
+underrun_irq_handler(unsigned irq)
+{
+  putchar('U');
+
+  dbsm_stop(&dsp_tx_sm);
+  dsp_tx_regs->clear_state = 1;
+  dbsm_start(&dsp_tx_sm);  // restart sm so we're listening to ethernet again
+
+  // putstr("\nirq: underrun\n");
+}
+
+
+void
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
+{
+}
+
+void
+stop_rx_cmd(void)
+{
+}
+
+static void
+setup_tx()
+{
+  dsp_tx_regs->clear_state = 1;
+  bp_clear_buf(DSP_TX_BUF_0);
+  bp_clear_buf(DSP_TX_BUF_1);
+
+#if 1
+  int tx_scale = 256;
+  int interp = 32;
+
+  op_config_tx_t def_config;
+  memset(&def_config, 0, sizeof(def_config));
+  def_config.phase_inc  = 408021893;                   // 9.5 MHz [2**32 * fc/fsample]
+  def_config.scale_iq = (tx_scale << 16) | tx_scale;
+  def_config.interp = interp;
+
+  // setup Tx DSP regs
+  config_tx_cmd(&def_config);
+#endif
+}
+
+
+inline static void
+buffer_irq_handler(unsigned irq)
+{
+  uint32_t  status = buffer_pool_status->status;
+
+  if (status & BPS_ERROR_ALL){
+    // FIXME rare path, handle error conditions
+    putstr("Errors! status = ");
+    puthex32_nl(status);
+
+    printf("total_rx_pkts  = %d\n", total_rx_pkts);
+    printf("total_rx_bytes = %d\n", total_rx_bytes);
+
+    print_rmon_regs();
+
+    if (status & (BPS_ERROR(DSP_TX_BUF_0) | BPS_ERROR(DSP_TX_BUF_1))){
+      dbsm_stop(&dsp_tx_sm);           
+      dsp_tx_regs->clear_state = 1; // try to restart
+      dbsm_start(&dsp_tx_sm);
+      return;
+    }
+  }
+
+  dbsm_process_status(&dsp_tx_sm, status);
+
+  if (status & BPS_DONE(CPU_TX_BUF)){
+    bp_clear_buf(CPU_TX_BUF);
+  }
+}
+
+/*
+ * Called when an ethernet packet is received.
+ * Return true if we handled it here (always!)
+ */
+bool
+nop_eth_pkt_inspector(dbsm_t *sm, int bufno)
+{
+  hal_toggle_leds(0x1);
+
+  u2_eth_packet_t *pkt = (u2_eth_packet_t *) buffer_ram(bufno);
+  size_t byte_len = (buffer_pool_status->last_line[bufno] - 1) * 4;
+
+  total_rx_pkts++;
+  total_rx_bytes += byte_len;
+
+  // inspect rcvd frame and figure out what do do.
+
+  if (pkt->ehdr.ethertype != U2_ETHERTYPE)
+    return true;       // ignore, probably bogus PAUSE frame from MAC
+
+  int chan = u2p_chan(&pkt->fixed);
+
+  switch (chan){
+  case CONTROL_CHAN:
+    handle_control_chan_frame(pkt, byte_len);
+    return true;       // we handled the packet
+    break;
+
+  case 0:
+  default:
+    return true;       // say we handled it
+    break;
+  }
+}
+
+
+int
+main(void)
+{
+  u2_init();
+
+  // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
+  hal_gpio_set_tx_mode(15, 0, GPIOM_FPGA_1);
+  hal_gpio_set_rx_mode(15, 0, GPIOM_FPGA_1);   // no printing...
+
+  putstr("\ntx_drop2\n");
+  
+  // Control LEDs
+  hal_set_leds(0x0, 0x3);
+
+  // pic_register_handler(IRQ_OVERRUN,  overrun_irq_handler);
+  pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
+
+  //pic_register_handler(IRQ_TIMER, timer_irq_handler);
+  //hal_set_timeout(timer_delta);
+
+  ethernet_register_link_changed_callback(link_changed_callback);
+
+  ethernet_init();
+
+  // initialize double buffering state machine for ethernet -> DSP Tx
+
+  dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0,
+           &dsp_tx_recv_args, &dsp_tx_send_args,
+           nop_eth_pkt_inspector);
+
+  // program tx registers
+  setup_tx();
+
+  // kick off the state machine
+  dbsm_start(&dsp_tx_sm);
+
+  while(1){
+    buffer_irq_handler(0);
+  }
+}
+
diff --git a/usrp2/firmware/apps/bitrot/tx_drop_rate_limited.c b/usrp2/firmware/apps/bitrot/tx_drop_rate_limited.c
new file mode 100644 (file)
index 0000000..0eab25b
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "u2_init.h"
+#include "memory_map.h"
+#include "spi.h"
+#include "hal_io.h"
+#include "buffer_pool.h"
+#include "pic.h"
+#include "bool.h"
+#include "ethernet.h"
+#include "nonstdio.h"
+#include "usrp2_eth_packet.h"
+#include "dbsm.h"
+#include "app_common.h"
+#include "print_rmon_regs.h"
+#include "eth_mac.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * receive packets from ethernet at a fixed rate and discard them
+ */
+
+int total_rx_pkts = 0;
+int total_rx_bytes = 0;
+
+
+static int timer_delta = (int)(MASTER_CLK_RATE * 10e-6); // 10us / tick
+
+
+/*
+ * This program can respond to queries from the host
+ * and stream rx samples.
+ *
+ * Buffer 1 is used by the cpu to send frames to the host.
+ * Buffers 2 and 3 are used to double-buffer the DSP Rx to eth flow
+ * Buffers 4 and 5 are used to double-buffer the eth to DSP Tx  eth flow
+ */
+//#define CPU_RX_BUF   0       // eth -> cpu
+//#define CPU_TX_BUF   1       // cpu -> eth
+
+#define        DSP_RX_BUF_0    2       // dsp rx -> eth (double buffer)
+#define        DSP_RX_BUF_1    3       // dsp rx -> eth
+#define        DSP_TX_BUF_0    4       // eth -> dsp tx (double buffer)
+#define        DSP_TX_BUF_1    5       // eth -> dsp tx
+
+
+
+// ----------------------------------------------------------------
+
+
+// The mac address of the host we're sending to.
+u2_mac_addr_t host_mac_addr;
+
+
+static volatile bool receive_packet_now = false;
+
+void
+timer_irq_handler(unsigned irq)
+{
+  hal_set_timeout(timer_delta);        // schedule next timeout
+  receive_packet_now = true;
+}
+
+
+// Tx DSP underrun
+void
+underrun_irq_handler(unsigned irq)
+{
+  putchar('U');
+}
+
+
+void
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
+{
+}
+
+void
+stop_rx_cmd(void)
+{
+}
+
+static void
+setup_tx()
+{
+  dsp_tx_regs->clear_state = 1;
+  bp_clear_buf(DSP_TX_BUF_0);
+  bp_clear_buf(DSP_TX_BUF_1);
+
+  int tx_scale = 256;
+  int interp = 32;
+
+  op_config_tx_t def_config;
+  memset(&def_config, 0, sizeof(def_config));
+  def_config.phase_inc  = 408021893;                   // 9.5 MHz [2**32 * fc/fsample]
+  def_config.scale_iq = (tx_scale << 16) | tx_scale;
+  def_config.interp = interp;
+
+  // setup Tx DSP regs
+  config_tx_cmd(&def_config);
+}
+
+
+/*
+ * Called when an ethernet packet is received.
+ *
+ * Claim that we handled all the packets,
+ * dropping those destined for the TX DSP chain
+ * on the ground.
+ */
+bool
+nop_eth_pkt_inspector(dbsm_t *sm, int bufno)
+{
+  hal_toggle_leds(0x1);
+
+  u2_eth_packet_t *pkt = (u2_eth_packet_t *) buffer_ram(bufno);
+  size_t byte_len = (buffer_pool_status->last_line[bufno] - 1) * 4;
+
+  total_rx_pkts++;
+  total_rx_bytes += byte_len;
+
+  // inspect rcvd frame and figure out what do do.
+
+  if (pkt->ehdr.ethertype != U2_ETHERTYPE)
+    return true;       // ignore, probably bogus PAUSE frame from MAC
+
+  int chan = u2p_chan(&pkt->fixed);
+
+  switch (chan){
+  case CONTROL_CHAN:
+    handle_control_chan_frame(pkt, byte_len);
+    return true;       // we handled the packet
+    break;
+
+  case 0:
+  default:
+    return true;       // We handled the data by dropping it :)
+    break;
+  }
+}
+
+
+inline static void
+buffer_irq_handler(unsigned irq)
+{
+  uint32_t  status = buffer_pool_status->status;
+
+  if (status & (BPS_DONE(CPU_TX_BUF) | BPS_ERROR(CPU_TX_BUF)))
+    bp_clear_buf(CPU_TX_BUF);
+
+  if (status & (BPS_DONE(DSP_TX_BUF_0) | BPS_ERROR(DSP_TX_BUF_0))){
+    bp_clear_buf(DSP_TX_BUF_0);
+
+    if (status & BPS_ERROR(DSP_TX_BUF_0)){
+      int crc = eth_mac_read_rmon(0x05);
+      int fifo_full = eth_mac_read_rmon(0x06);
+      int too_short_too_long = eth_mac_read_rmon(0x07);
+      putstr("Errors! status = ");
+      puthex32_nl(status);
+
+      printf("crc_err\t\t= %d\n", crc);
+      printf("fifo_full\t\t= %d\n", fifo_full);
+      printf("too_short_too_long\t= %d\n", too_short_too_long);
+
+      printf("total_rx_pkts  = %d\n", total_rx_pkts);
+      printf("total_rx_bytes = %d\n", total_rx_bytes);
+    }
+    else
+      nop_eth_pkt_inspector(0, DSP_TX_BUF_0);
+  }
+
+  if (receive_packet_now && (status & BPS_IDLE(DSP_TX_BUF_0))){
+    receive_packet_now = false;
+    bp_receive_to_buf(DSP_TX_BUF_0, PORT_ETH, 1, 0, BP_LAST_LINE);
+  }
+}
+
+
+int
+main(void)
+{
+  u2_init();
+
+  // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
+  hal_gpio_set_tx_mode(15, 0, GPIOM_FPGA_1);
+  hal_gpio_set_rx_mode(15, 0, GPIOM_FPGA_1);
+
+  putstr("\ntx_drop_rate_limited\n");
+  
+  // Control LEDs
+  hal_set_leds(0x0, 0x3);
+
+  pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler);
+
+  pic_register_handler(IRQ_TIMER, timer_irq_handler);
+  hal_set_timeout(timer_delta);
+
+  ethernet_register_link_changed_callback(link_changed_callback);
+  ethernet_init();
+
+  // program tx registers
+  setup_tx();
+
+  // start a receive from ethernet
+  bp_receive_to_buf(DSP_TX_BUF_0, PORT_ETH, 1, 0, BP_LAST_LINE);
+
+  while(1){
+    buffer_irq_handler(0);
+  }
+}
+
diff --git a/usrp2/firmware/apps/double_buffer_fragment.c b/usrp2/firmware/apps/double_buffer_fragment.c
new file mode 100644 (file)
index 0000000..cfc0612
--- /dev/null
@@ -0,0 +1,138 @@
+#if 0
+void 
+double_buffering(int port) {
+  unsigned int localstatus = buffer_pool_status->status;
+
+  if(localstatus & BPS_DONE_0) {
+    bp_clear_buf(0);
+    if(buffer_state[0] == FILLING) {
+      buffer_state[0] = FULL;
+      if(buffer_state[1] == EMPTY) {
+       bp_receive_to_buf(1, 1, 1, 10, 509);  // DSP_RX to buffer 1, use 500 lines
+       buffer_state[1] = FILLING;
+      }
+      else
+       dsp_rx_idle = 1;
+      if(serdes_tx_idle) {
+       serdes_tx_idle = 0;
+       bp_send_from_buf(0, port, 1, 10, 509);  // SERDES_TX from buffer 0
+       buffer_state[0] = EMPTYING;
+      }
+    }
+    else {  // buffer was emptying
+      buffer_state[0] = EMPTY;
+      if(dsp_rx_idle) {
+       dsp_rx_idle = 0;
+       bp_receive_to_buf(0, 1, 1, 10, 509);  // DSP_RX to buffer 0, use 500 lines
+       buffer_state[0] = FILLING;
+      }
+      if(buffer_state[1] == FULL) {
+       bp_send_from_buf(1, port, 1, 10, 509);  // SERDES_TX from buffer 1
+       buffer_state[1] = EMPTYING;
+      }
+      else
+       serdes_tx_idle = 1;
+    }
+    putstr("Int Proc'ed 0\n");
+  }
+
+  if(localstatus & BPS_DONE_1) {
+    bp_clear_buf(1);
+    if(buffer_state[1] == FILLING) {
+      buffer_state[1] = FULL;
+      if(buffer_state[0] == EMPTY) {
+       bp_receive_to_buf(0, 1, 1, 10, 509);  // DSP_RX to buffer 1, use 500 lines
+       buffer_state[0] = FILLING;
+      }
+      else
+       dsp_rx_idle = 1;
+      if(serdes_tx_idle) {
+       serdes_tx_idle = 0;
+       bp_send_from_buf(1, port, 1, 10, 509);  // SERDES_TX from buffer 1
+       buffer_state[1] = EMPTYING;
+      }
+    }
+    else {  // buffer was emptying
+      buffer_state[1] = EMPTY;
+      if(dsp_rx_idle) {
+       dsp_rx_idle = 0;
+       bp_receive_to_buf(1, 1, 1, 10, 509);  // DSP_RX to buffer 1, use 500 lines
+       buffer_state[1] = FILLING;
+      }
+      if(buffer_state[0] == FULL) {
+       bp_send_from_buf(0, port, 1, 10, 509);  // SERDES_TX from buffer 0
+       buffer_state[0] = EMPTYING;
+      }
+      else
+       serdes_tx_idle = 1;
+    }
+  putstr("Int Proc'ed 1\n");
+  }
+
+  if(localstatus & BPS_DONE_2) {
+    bp_clear_buf(2);
+    if(buffer_state[2] == FILLING) {
+      buffer_state[2] = FULL;
+      if(buffer_state[3] == EMPTY) {
+       bp_receive_to_buf(3, port, 1, 5, 504);  // SERDES_RX to buffer 3, use 500 lines
+       buffer_state[3] = FILLING;
+      }
+      else
+       serdes_rx_idle = 1;
+      if(dsp_tx_idle) {
+       dsp_tx_idle = 0;
+       bp_send_from_buf(2, 1, 1, 5, 504);  // DSP_TX from buffer 2
+       buffer_state[2] = EMPTYING;
+      }
+    }
+    else {  // buffer was emptying
+      buffer_state[2] = EMPTY;
+      if(serdes_rx_idle) {
+       serdes_rx_idle = 0;
+       bp_receive_to_buf(2, port, 1, 5, 504);  // SERDES_RX to buffer 2
+       buffer_state[2] = FILLING;
+      }
+      if(buffer_state[3] == FULL) {
+       bp_send_from_buf(3, 1, 1, 5, 504);  // DSP_TX from buffer 3
+       buffer_state[3] = EMPTYING;
+      }
+      else
+       dsp_tx_idle = 1;
+    }
+  putstr("Int Proc'ed 2\n");
+  }
+
+  if(localstatus & BPS_DONE_3) {
+    bp_clear_buf(3);
+    if(buffer_state[3] == FILLING) {
+      buffer_state[3] = FULL;
+      if(buffer_state[2] == EMPTY) {
+       bp_receive_to_buf(2, port, 1, 5, 504);  // SERDES_RX to buffer 2, use 500 lines
+       buffer_state[2] = FILLING;
+      }
+      else
+       serdes_rx_idle = 1;
+      if(dsp_tx_idle) {
+       dsp_tx_idle = 0;
+       bp_send_from_buf(3, 1, 1, 5, 504);  // DSP_TX from buffer 3
+       buffer_state[3] = EMPTYING;
+      }
+    }
+    else {  // buffer was emptying
+      buffer_state[3] = EMPTY;
+      if(serdes_rx_idle) {
+       serdes_rx_idle = 0;
+       bp_receive_to_buf(3, port, 1, 5, 504);  // SERDES_RX to buffer 3
+       buffer_state[3] = FILLING;
+      }
+      if(buffer_state[2] == FULL) {
+       bp_send_from_buf(2, 1, 1, 5, 504);  // DSP_TX from buffer 2
+       buffer_state[2] = EMPTYING;
+      }
+      else
+       dsp_tx_idle = 1;
+    }
+  putstr("Int Proc'ed 3\n");
+  }
+}
+#endif
index b4b44dbdb99fef34c44c67eb15262cef8cf7aa48..e7dde524a2fcbc6d3b112a101a7ce006db4a1041 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -154,7 +154,7 @@ restart_streaming(void)
   dsp_rx_regs->rx_command =
     MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
              streaming_items_per_frame,
-             1, 1);                            
+             1, 1);
 
   dsp_rx_regs->rx_time = 0;            // enqueue second command
 }
@@ -170,6 +170,7 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed, 0, 0);
   // DSP RX will fill in timestamp
@@ -186,6 +187,11 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
 }
 
 
+void start_rx_streaming_at_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p, uint32_t time)
+{}
+void restart_streaming_at(uint32_t time)
+{}
+
 void
 stop_rx_cmd(void)
 {
@@ -223,7 +229,7 @@ setup_tx()
  * that we didn't handle the packet.  A bit of a kludge
  * but it should work.
  */
-bool 
+bool
 fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)      // returns false
 {
   uint32_t *p = buffer_ram(buf_this);
@@ -258,22 +264,22 @@ int test_ram()
 {
   int i,j,k;
   output_regs->ram_page = 1<<10;
-  
+
   extram[0] = 0xDEADBEEF;
   extram[1] = 0xF00D1234;
   extram[7] = 0x76543210;
-  
+
   output_regs->ram_page = 2<<10;
   extram[7] = 0x55555555;
   extram[1] = 0xaaaaaaaa;
   extram[0] = 0xeeeeeeee;
-  
+
   output_regs->ram_page = 1<<10;
-  
+
   i = extram[0];
   k = extram[1];
   j = extram[7];
-  
+
   if((i != 0xDEADBEEF)||(j!=0x76543210)||(k!=0xF00D1234)) {
     puts("RAM FAIL1!\n");
     puthex32_nl(i);
@@ -281,7 +287,7 @@ int test_ram()
     puthex32_nl(k);
     return 0;
   }
-  
+
   output_regs->ram_page = 2<<10;
 
   j = extram[7];
@@ -305,7 +311,7 @@ int test_sd()
     puts("FAILED INIT of Card\n");
     return 0;
   }
-  
+
   unsigned char buf[512];
   i = sd_read_block(2048,buf);
   if(i == 0) {
index ce1e8160bb41509e385ab4e0599e5f5c83a7ab90..5cda5bb8eca67f9d0f632c0c1a3b177316da8116 100644 (file)
@@ -104,8 +104,7 @@ init_packets(void)
   memset(&pkt, 0, sizeof(pkt));
 
   pkt.ehdr.dst = dst_mac_addr;
-  // src address filled in by mac
-
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   pkt.fixed.word0 = 0x01234567;
   pkt.fixed.timestamp = 0xffffffff;
@@ -141,10 +140,12 @@ main(void)
   ethernet_register_link_changed_callback(link_changed_callback);
   ethernet_init();
 
+  /*
   if (hwconfig_simulation_p()){
     eth_mac->speed = 4;        // hardcode mac speed to 1000
     link_is_up = true;
   }
+  */
 
   // fire off a receive from the ethernet
   bp_receive_to_buf(CPU_RX_BUF, PORT_ETH, 1, 0, BP_LAST_LINE);
@@ -159,10 +160,15 @@ main(void)
     }
 
     if (status & (BPS_DONE(CPU_TX_BUF) | BPS_ERROR(CPU_TX_BUF))){
+      if (status & BPS_ERROR(CPU_TX_BUF)){
+       putchar('E');
+      }
       bp_clear_buf(CPU_TX_BUF);
       npackets_sent++;
-      if ((npackets_sent & 0xF) == 0)  // print after every 16 packets
-       print_rmon_regs();
+      if ((npackets_sent & 0xF) == 0){ // print after every 16 packets
+       //print_rmon_regs();
+       putchar('.');
+      }
     }
 
     if (link_is_up && send_packet_now && (status & BPS_IDLE(CPU_TX_BUF))){
diff --git a/usrp2/firmware/apps/gen_pause_frames.c b/usrp2/firmware/apps/gen_pause_frames.c
new file mode 100644 (file)
index 0000000..8f2b2df
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "u2_init.h"
+#include "memory_map.h"
+#include "spi.h"
+#include "hal_io.h"
+#include "buffer_pool.h"
+#include "pic.h"
+#include "bool.h"
+#include "ethernet.h"
+#include "nonstdio.h"
+#include "u2_eth_packet.h"
+#include "memcpy_wa.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+
+// ----------------------------------------------------------------
+
+unsigned char dst_mac_addr[6] = {
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+// ----------------------------------------------------------------
+
+// #define     PACKET_SIZE 1500                // bytes
+// #define ETH_DATA_RATE 1000000               // 1MB/s
+// #define     ETH_PACKET_RATE (ETH_DATA_RATE/PACKET_SIZE)     // 13,3333 pkts/s
+
+// static int timer_delta = MASTER_CLK_RATE/ETH_PACKET_RATE;   // ticks between interrupts
+
+static int timer_delta = MASTER_CLK_RATE/1000; // tick at 1kHz
+
+static volatile bool send_packet_now = false;   // timer handler sets this
+static volatile bool link_is_up = false;       // eth handler sets this
+
+int packet_number = 0;
+
+// ----------------------------------------------------------------
+
+// debugging output on tx pins
+#define LS_MASK  0xE0000
+#define LS_1000  0x80000
+#define LS_100   0x40000
+#define LS_10    0x20000
+
+
+/*
+ * Called when eth phy state changes (w/ interrupts disabled)
+ */
+void
+link_changed_callback(int speed)
+{
+  int v = 0;
+  switch(speed){
+  case 10:
+    v = LS_10;
+    link_is_up = true;
+    break;
+    
+  case 100:
+    v = LS_100;
+    link_is_up = true;
+    break;
+    
+  case 1000:
+    v = LS_100;
+    link_is_up = true;
+    break;
+
+  default:
+    v = 0;
+    link_is_up = false;
+    break;
+  }
+
+  hal_gpio_set_tx(v, LS_MASK); /* set debug bits on d'board */
+
+  putstr("\neth link changed: speed = ");
+  puthex16_nl(speed);
+}
+
+void
+timer_irq_handler(unsigned irq)
+{
+  hal_set_timeout(timer_delta);        // schedule next timeout
+  send_packet_now = 1;
+}
+
+
+void
+buffer_irq_handler(unsigned irq)
+{
+  // FIXME
+}
+
+static void
+init_packet(int *buf, const u2_eth_packet_t *pkt, int bufnum)
+{
+  int i = 0;
+  int mark = ((bufnum & 0xff) << 24) | 0x005A0000;
+
+  for (i = 0; i < BP_NLINES; i++){
+    buf[i] = mark | i;
+    mark ^= 0x00FF0000;
+  }
+
+  // copy header into buffer
+  memcpy_wa(buf, pkt, sizeof(*pkt));
+}
+
+static void
+init_packets(void)
+{
+  int  i;
+  
+  u2_eth_packet_t      pkt __attribute__((aligned (4)));
+
+  for (i = 0; i < 6; i++){
+    pkt.ehdr.dst.addr[i] = dst_mac_addr[i];
+  }
+  pkt.ehdr.src = *ethernet_mac_addr();
+  pkt.ehdr.ethertype = U2_ETHERTYPE;
+
+  // fill ALL buffers for debugging
+  for (i = 0; i < 8; i++)
+    init_packet((void *)buffer_ram(i), &pkt, i);
+}
+
+static int led_counter = 0;
+
+int
+main(void)
+{
+  int send_pause = 1;
+  
+  u2_init();
+
+  // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
+  //hal_gpio_set_sels(GPIO_TX_BANK, "1111111111111111");
+  //hal_gpio_set_sels(GPIO_RX_BANK, "1111111111111111");
+
+  putstr("\ngen_eth_packets\n");
+  
+  // Control LEDs
+  output_regs->leds = 0x00;
+
+  init_packets();
+
+  // pic_register_handler(IRQ_BUFFER, buffer_irq_handler);  // poll for now
+  pic_register_handler(IRQ_TIMER, timer_irq_handler);
+  hal_set_timeout(timer_delta);
+
+  ethernet_register_link_changed_callback(link_changed_callback);
+
+  ethernet_init();
+
+  eth_mac->pause_frame_send_en = 1;
+  eth_mac->pause_quanta_set = 16384 / 512;
+
+  // eth_mac->speed = 4;       // FIXME hardcode mac speed to 1000
+
+  while(1){
+    if (link_is_up && send_packet_now){
+      send_packet_now = false;
+
+
+      if (send_pause)
+       eth_mac->xon_cpu = 1;
+      else
+       eth_mac->xon_cpu = 0;
+
+      send_pause ^= 1;
+
+      // kick off the next packet
+      // FIXME set packet number in packet
+
+#if 0
+      bp_send_from_buf(0, PORT_ETH, 1, 0, 255);        // 1KB total
+
+      while ((buffer_pool_status->status & (BPS_DONE_0|BPS_ERROR_0)) == 0)
+       ;
+      bp_clear_buf(0);
+#endif
+
+      output_regs->leds = ((++led_counter) & 0x1) | (link_is_up ? 0x2 : 0x0);
+    }
+  }
+
+  hal_finish();
+  return 1;
+}
index e5ab55fac6513e50c387f7399d840ce7aad13e2a..5dbecb0d0112ae900868038ae8668b40084b6e13 100644 (file)
@@ -67,6 +67,7 @@ void
 set_reply_hdr(u2_eth_packet_t *reply_pkt, u2_eth_packet_t const *cmd_pkt)
 {
   reply_pkt->ehdr.dst = cmd_pkt->ehdr.src;
+  reply_pkt->ehdr.src = *ethernet_mac_addr();
   reply_pkt->ehdr.ethertype = U2_ETHERTYPE;
   reply_pkt->thdr.flags = 0;
   reply_pkt->thdr.fifo_status = 0;     // written by protocol engine
index 730433bf4ff5982febb5e679edea19e18788c1b0..7fc7b486f8ef7b5850c1c02e32a7170e52eace75 100644 (file)
@@ -179,6 +179,7 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed, 0, 0);
   // DSP RX will fill in timestamp
index df7ddf9c43c4177d2308ec067c29e4c5c088c4dc..4c284b7c926cd3c3d4d7a73f030f04d52fdacab4 100644 (file)
@@ -160,7 +160,7 @@ restart_streaming(void)
   dsp_rx_regs->rx_command =
     MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
              streaming_items_per_frame,
-             1, 1);                            
+             1, 1);
 
   dsp_rx_regs->rx_time = 0;            // enqueue second command
 }
@@ -176,6 +176,7 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed, 0, 0);
   // DSP RX will fill in timestamp
@@ -191,6 +192,10 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   restart_streaming();
 }
 
+void start_rx_streaming_at_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p, uint32_t time)
+{}
+void restart_streaming_at(uint32_t time)
+{}
 
 void
 stop_rx_cmd(void)
@@ -229,7 +234,7 @@ setup_tx()
  * that we didn't handle the packet.  A bit of a kludge
  * but it should work.
  */
-bool 
+bool
 fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)      // returns false
 {
   uint32_t *p = buffer_ram(buf_this);
@@ -309,7 +314,7 @@ main(void)
 
 
   //output_regs->flush_icache = 1;
+
   // initialize double buffering state machine for DSP RX -> Ethernet
 
   if (FW_SETS_SEQNO){
index 92e41d92b8c381b0dd5172cbbfb4b2adf3122ff6..ec772ca753d847e643c12828b13944b60396be27 100644 (file)
@@ -135,7 +135,7 @@ init_packets(void)
   u2_eth_packet_t      pkt __attribute__((aligned (4)));
 
   pkt.ehdr.dst = dst_mac_addr;
-  // src filled in by mac
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
 
   // fill ALL buffers for debugging
diff --git a/usrp2/firmware/apps/serdes_to_dsp.c b/usrp2/firmware/apps/serdes_to_dsp.c
new file mode 100644 (file)
index 0000000..a9876d9
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "u2_init.h"
+#include "memory_map.h"
+#include "spi.h"
+#include "hal_io.h"
+#include "buffer_pool.h"
+#include "pic.h"
+#include "bool.h"
+#include "ethernet.h"
+#include "nonstdio.h"
+#include "usrp2_eth_packet.h"
+#include "dbsm.h"
+#include "app_common.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * This program can respond to queries from the host
+ * and stream rx samples.
+ *
+ * Buffer 1 is used by the cpu to send frames to the host.
+ * Buffers 2 and 3 are used to double-buffer the DSP Rx to eth flow
+ * Buffers 4 and 5 are used to double-buffer the eth to DSP Tx  eth flow
+ */
+//#define CPU_RX_BUF   0       // eth -> cpu
+//#define CPU_TX_BUF   1       // cpu -> eth
+
+#define        DSP_RX_BUF_0    2       // dsp rx -> eth (double buffer)
+#define        DSP_RX_BUF_1    3       // dsp rx -> eth
+#define        DSP_TX_BUF_0    4       // eth -> dsp tx (double buffer)
+#define        DSP_TX_BUF_1    5       // eth -> dsp tx
+
+/*
+ * ================================================================
+ *      configure DSP TX double buffering state machine
+ * ================================================================
+ */
+
+// 4 lines of ethernet hdr + 1 line transport hdr + 2 lines (word0 + timestamp)
+// DSP Tx reads word0 (flags) + timestamp followed by samples
+
+#define DSP_TX_FIRST_LINE ((sizeof(u2_eth_hdr_t) + sizeof(u2_transport_hdr_t))/4)
+
+// Receive from ethernet
+buf_cmd_args_t dsp_tx_recv_args = {
+  PORT_SERDES,
+  0,
+  BP_LAST_LINE
+};
+
+// send to DSP Tx
+buf_cmd_args_t dsp_tx_send_args = {
+  PORT_DSP,
+  DSP_TX_FIRST_LINE,   // starts just past transport header
+  0                    // filled in from last_line register
+};
+
+dbsm_t dsp_tx_sm;      // the state machine
+
+
+// ----------------------------------------------------------------
+
+
+// The mac address of the host we're sending to.
+u2_mac_addr_t host_mac_addr;
+
+
+void
+start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
+{
+}
+
+void
+stop_rx_cmd(void)
+{
+}
+
+static void
+setup_tx()
+{
+  dsp_tx_regs->clear_state = 1;
+  bp_clear_buf(DSP_TX_BUF_0);
+  bp_clear_buf(DSP_TX_BUF_1);
+
+  int tx_scale = 256;
+  int interp = 32;
+
+  op_config_tx_t def_config;
+  memset(&def_config, 0, sizeof(def_config));
+  def_config.phase_inc  = 408021893;                   // 9.5 MHz [2**32 * fc/fsample]
+  def_config.scale_iq = (tx_scale << 16) | tx_scale;
+  def_config.interp = interp;
+
+  // setup Tx DSP regs
+  config_tx_cmd(&def_config);
+}
+
+
+inline static void
+buffer_irq_handler(unsigned irq)
+{
+  //hal_toggle_leds(0x2);
+
+  uint32_t  status = buffer_pool_status->status;
+
+  dbsm_process_status(&dsp_tx_sm, status);
+
+  if (status & BPS_DONE(CPU_TX_BUF)){
+    bp_clear_buf(CPU_TX_BUF);
+  }
+}
+
+int
+main(void)
+{
+  u2_init();
+
+  // Get our clock from the mimo interface
+
+  clocks_enable_test_clk(true,1);
+  clocks_mimo_config(MC_WE_LOCK_TO_MIMO);
+  
+  // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
+  //hal_gpio_set_sels(GPIO_TX_BANK, "1111111111111111");
+  //hal_gpio_set_sels(GPIO_RX_BANK, "1111111111111111");
+
+  putstr("\nserdes_to_dsp\n");
+
+  ethernet_register_link_changed_callback(link_changed_callback);
+  ethernet_init();
+
+
+  // initialize double buffering state machine for ethernet -> DSP Tx
+
+  dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0,
+           &dsp_tx_recv_args, &dsp_tx_send_args,
+           eth_pkt_inspector);
+
+  // program tx registers
+  setup_tx();
+
+  // kick off the state machine
+  dbsm_start(&dsp_tx_sm);
+
+  while(1){
+    buffer_irq_handler(0);
+
+    int pending = pic_regs->pending;   // poll for under or overrun
+
+    if (pending & PIC_UNDERRUN_INT){
+      dbsm_handle_tx_underrun(&dsp_tx_sm);
+      pic_regs->pending = PIC_UNDERRUN_INT;    // clear interrupt
+      putchar('U');
+    }
+  }
+}
+
index 1becc205ec52809ad604fa9502c73230936b69af..aa4a3f33cc3fed38bd89ec4e5933e9014de3b76d 100644 (file)
@@ -152,7 +152,7 @@ restart_streaming(void)
   dsp_rx_regs->rx_command =
     MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
              streaming_items_per_frame,
-             1, 1);                            
+             1, 1);
 
   dsp_rx_regs->rx_time = 0;            // enqueue second command
 }
@@ -168,6 +168,7 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed, 0, 0);
   // DSP RX will fill in timestamp
@@ -183,6 +184,10 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   restart_streaming();
 }
 
+void start_rx_streaming_at_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p, uint32_t time)
+{}
+void restart_streaming_at(uint32_t time)
+{}
 
 void
 stop_rx_cmd(void)
@@ -221,7 +226,7 @@ setup_tx()
  * that we didn't handle the packet.  A bit of a kludge
  * but it should work.
  */
-bool 
+bool
 fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)      // returns false
 {
   uint32_t *p = buffer_ram(buf_this);
@@ -301,7 +306,7 @@ main(void)
 
 
   //output_regs->flush_icache = 1;
+
   // initialize double buffering state machine for DSP RX -> Ethernet
 
   if (FW_SETS_SEQNO){
index 25ba8fd40aed8cba2b3ea0d0f5f9570f8afaac2d..6350a69566cd06f68eff6465f9dd3b16edee2796 100644 (file)
@@ -195,6 +195,7 @@ start_tx_transfers(void)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   //pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed,
                U2P_TX_IMMEDIATE | U2P_TX_START_OF_BURST, 0);
index 730ee66c59fee791ebaf4c17fca805d6ff22347e..975f314bd94c0152b9f2423c1b1b366c92038dbb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -152,7 +152,35 @@ restart_streaming(void)
   dsp_rx_regs->rx_command =
     MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
              streaming_items_per_frame,
-             1, 1);                            
+             1, 1);
+
+  dsp_rx_regs->rx_time = 0;            // enqueue second command
+}
+
+void
+restart_streaming_at(uint32_t time)
+{
+  // setup RX DSP regs
+  dsp_rx_regs->clear_state = 1;                        // reset
+
+  streaming_p = true;
+  streaming_frame_count = FRAMES_PER_CMD;
+
+  dsp_rx_regs->rx_command =
+    MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
+             streaming_items_per_frame,
+             0, 1);                    // set "chain" bit
+
+  // kick off the state machine
+  dbsm_start(&dsp_rx_sm);
+
+  dsp_rx_regs->rx_time = time;         // enqueue first of two commands
+
+  // make sure this one and the rest have the "now" and "chain" bits set.
+  dsp_rx_regs->rx_command =
+    MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
+             streaming_items_per_frame,
+             1, 1);
 
   dsp_rx_regs->rx_time = 0;            // enqueue second command
 }
@@ -168,6 +196,7 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   u2_eth_packet_t      pkt;
   memset(&pkt, 0, sizeof(pkt));
   pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
   pkt.ehdr.ethertype = U2_ETHERTYPE;
   u2p_set_word0(&pkt.fixed, 0, 0);
   // DSP RX will fill in timestamp
@@ -183,6 +212,33 @@ start_rx_streaming_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p)
   restart_streaming();
 }
 
+void
+start_rx_streaming_at_cmd(const u2_mac_addr_t *host, op_start_rx_streaming_t *p, uint32_t time)
+{
+  host_mac_addr = *host;       // remember who we're sending to
+
+  /*
+   * Construct  ethernet header and word0 and preload into two buffers
+   */
+  u2_eth_packet_t      pkt;
+  memset(&pkt, 0, sizeof(pkt));
+  pkt.ehdr.dst = *host;
+  pkt.ehdr.src = *ethernet_mac_addr();
+  pkt.ehdr.ethertype = U2_ETHERTYPE;
+  u2p_set_word0(&pkt.fixed, 0, 0);
+  // DSP RX will fill in timestamp
+
+  memcpy_wa(buffer_ram(DSP_RX_BUF_0), &pkt, sizeof(pkt));
+  memcpy_wa(buffer_ram(DSP_RX_BUF_1), &pkt, sizeof(pkt));
+
+
+  if (FW_SETS_SEQNO)
+    fw_seqno = 0;
+
+  streaming_items_per_frame = p->items_per_frame;
+  restart_streaming_at(time);
+}
+
 
 void
 stop_rx_cmd(void)
@@ -221,7 +277,7 @@ setup_tx()
  * that we didn't handle the packet.  A bit of a kludge
  * but it should work.
  */
-bool 
+bool
 fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)      // returns false
 {
   uint32_t *p = buffer_ram(buf_this);
@@ -257,14 +313,13 @@ main(void)
 {
   u2_init();
 
-  putstr("\nTxRx\n");
+  putstr("\nTxRx-NEWETH\n");
   print_mac_addr(ethernet_mac_addr()->addr);
   newline();
 
   ethernet_register_link_changed_callback(link_changed_callback);
   ethernet_init();
 
-
 #if 0
   // make bit 15 of Tx gpio's be a s/w output
   hal_gpio_set_sel(GPIO_TX_BANK, 15, 's');
diff --git a/usrp2/firmware/config/.gitignore b/usrp2/firmware/config/.gitignore
new file mode 100644 (file)
index 0000000..b11bb11
--- /dev/null
@@ -0,0 +1,20 @@
+/configure
+/Makefile.in
+/config.log
+/config.h
+/ltmain.sh
+/Makefile
+/config.status
+/stamp-h1
+/config.h.in
+/autom4te.cache
+/libtool
+/missing
+/aclocal.m4
+/install-sh
+/depcomp
+/py-compile
+/compile
+/build
+/run_tests.sh
+/*-stamp
index 7f1f9a796dc0669be1c520cc0664c6fd117dd2db..53ff03ce404740cce7d7f1449ed06b0327dcb4f8 100644 (file)
@@ -17,6 +17,12 @@ dnl along with GNU Radio; see the file COPYING.  If not, write to
 dnl the Free Software Foundation, Inc., 51 Franklin Street,
 dnl Boston, MA 02110-1301, USA.
 
+dnl Fix 2.64 cross compile detection for AVR and RTEMS
+dnl by not trying to compile fopen.
+m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.64],
+  [m4_foreach([_GCC_LANG], [C, C++, Fortran, Fortran 77],
+     [m4_define([_AC_LANG_IO_PROGRAM(]_GCC_LANG[)], m4_defn([AC_LANG_PROGRAM(]_GCC_LANG[)]))])]) 
+
 AC_DEFUN([GRC_USRP2_FIRMWARE],[
     dnl we use  --enable-usrp2-firmware to enable this
     GRC_ENABLE(usrp2-firmware)
index 60d6d2a7ecb2118ac084b6d25f45f54dfa9a8346..53ca9b518aede547457118c36d464e35acd9bffc 100755 (executable)
@@ -3,7 +3,7 @@
 # wrapper to setup cross-compilation of firmware
 #
 
-for v in CC CPP CXX AS AR NM RANLIB STRIP F77 CFLAGS CXXFLAGS CPPFLAGS LDFLAGS 
+for v in CC CPP CXX AS AR NM RANLIB STRIP F77 CFLAGS CXXFLAGS CPPFLAGS LDFLAGS CCAS CCASFLAGS USB_LIBS USB_CFLAGS
 do
   unset $v
 done
@@ -26,6 +26,10 @@ do
       (CXXFLAGS=*) ;;
       (CPPFLAGS=*) ;;
       (LDFLAGS=*)  ;;
+      (CCAS=*)     ;;
+      (CCASFLAGS=*)  ;;
+      (USB_CFLAGS=*) ;;
+      (USB_LIBS=*) ;;
       (*)  args="$args $t" ;;
   esac
 done
diff --git a/usrp2/firmware/divisors.py b/usrp2/firmware/divisors.py
new file mode 100755 (executable)
index 0000000..d31bd4d
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+speeds = (9600, 19200, 38400, 57600, 115200, 230400)
+
+master_clk = 100e6
+wb_clk = master_clk / 2
+
+def divisor(speed):
+    div0 = wb_clk // (speed * 16)
+    div1 = div0 + 1
+    actual0 = actual_speed(div0)
+    actual1 = actual_speed(div1)
+    if abs(actual0 - speed) < abs(actual1 - speed):
+        return div0
+    else:
+        return div1
+
+def actual_speed(divisor):
+    return (wb_clk // divisor) / 16
+
+def doit(speed):
+    div = divisor(speed)
+    actual = actual_speed(div)
+    rel_error = (actual - speed) / speed
+    print "target: %6d  divisor: %6d  actual: %11.4f  %6.3f%%" % (speed, div, actual, rel_error*100)
+
+def main():
+    print "wb_clk = %f" % (wb_clk,)
+    for s in speeds:
+        doit(s)
+
+if __name__ == '__main__':
+    main()
+    
diff --git a/usrp2/firmware/include/.gitignore b/usrp2/firmware/include/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index b0123c5844e0e84b9bfce53cafff40fc70c00b83..2f24556f06b48b11f3bc41b177d4a80ffed6388b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -147,10 +147,11 @@ typedef struct {
  *   ethernet header + transport header + fixed header + maximum number of samples.
  *   sizeof(u2_eth_samples_t) == 1512
  *   (payload is 1498 bytes, two bytes shorter than 1500 byte MTU)
+ *   (sample numbers are made even to force pairwise alignment in the interleaved case)
  */
 
-#define U2_MAX_SAMPLES 371
-#define        U2_MIN_SAMPLES    9
+#define U2_MAX_SAMPLES 370
+#define        U2_MIN_SAMPLES   10
 
 typedef struct {
   u2_eth_packet_t      hdrs;
@@ -208,6 +209,10 @@ typedef struct {
 #define OP_GPIO_WRITE_REPLY          (OP_GPIO_WRITE | OP_REPLY_BIT)
 #define OP_GPIO_STREAM               21
 #define OP_GPIO_STREAM_REPLY         (OP_GPIO_STREAM | OP_REPLY_BIT)
+#define OP_RX_ANTENNA                22
+#define OP_RX_ANTENNA_REPLY          (OP_RX_ANTENNA | OP_REPLY_BIT)
+#define OP_TX_ANTENNA                23
+#define OP_TX_ANTENNA_REPLY          (OP_RX_ANTENNA | OP_REPLY_BIT)
 
 /*
  * All subpackets are a multiple of 4 bytes long.
index dd2bcf1edd5edc39a82c5a7104276a80f83b8978..32cb25c4191e434da1119a78f814ec1aeb7292cc 100644 (file)
@@ -50,6 +50,12 @@ u2_fxpt_freq_round_to_int(u2_fxpt_freq_t fx)
   return (int)((fx+(1<<(U2_FPF_RP-1)))>>U2_FPF_RP);
 }
 
+static inline unsigned int
+u2_fxpt_freq_round_to_uint(u2_fxpt_freq_t fx)
+{
+  return (unsigned int)((fx+(1<<(U2_FPF_RP-1)))>>U2_FPF_RP);
+}
+
 static inline double
 u2_fxpt_freq_to_double(u2_fxpt_freq_t fx)
 {
diff --git a/usrp2/firmware/lib/.gitignore b/usrp2/firmware/lib/.gitignore
new file mode 100644 (file)
index 0000000..5d838bf
--- /dev/null
@@ -0,0 +1,40 @@
+*~
+/*-stamp
+/*.a
+/*.bin
+/*.dump
+/*.log
+/*.rom
+/.deps
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/blink_leds
+/blink_leds2
+/build
+/compile
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/eth_test
+/gen_eth_packets
+/ibs_rx_test
+/ibs_tx_test
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/py-compile
+/rcv_eth_packets
+/run_tests.sh
+/stamp-h1
+/test1
+/test_phy_comm
+/timer_test
+/buf_ram_test
+/buf_ram_zero
+/hello
index 37c74c91ea3ca321e99fcae0bd3b3c783340270b..d6bb4edc382405e83a3b30b19a5380c5cfe7e410 100644 (file)
 include $(top_srcdir)/Makefile.common
 
 noinst_LIBRARIES = \
-       libu2fw.a
+       libu2fw.a \
+       libu2fw_wbx.a \
+       libu2fw_xcvr.a
 
-
-libu2fw_a_SOURCES = \
+U2FW_COMMON = \
+       _exit.c \
        abort.c \
        ad9510.c \
        ad9777.c \
@@ -29,16 +31,10 @@ libu2fw_a_SOURCES = \
        buffer_pool.c \
        clocks.c \
        db_basic.c \
-       db_dbsrx.c \
-       db_init.c \
-       db_rfx.c \
-       db_tvrx.c \
-       db_xcvr2450.c \
        dbsm.c \
        eeprom.c \
-       ethernet.c \
        eth_mac.c \
-       _exit.c \
+       ethernet.c \
        exit.c \
        hal_io.c \
        hal_uart.c \
@@ -50,18 +46,42 @@ libu2fw_a_SOURCES = \
        memset_wa.c \
        nonstdio.c \
        pic.c \
+       print_buffer.c \
+       print_fxpt.c \
        print_mac_addr.c \
        print_rmon_regs.c \
-       print_fxpt.c \
-       print_buffer.c \
        printf.c \
        sd.c \
        spi.c \
-       u2_init.c       
+       u2_init.c
+
+libu2fw_a_SOURCES = \
+       $(U2FW_COMMON) \
+       db_init.c \
+       db_bitshark_rx.c \
+       db_dbsrx.c \
+       db_rfx.c \
+       db_tvrx.c
+
+libu2fw_wbx_a_SOURCES = \
+       $(U2FW_COMMON) \
+       db_init_wbx.c \
+       adf4350.c \
+       adf4350_regs.c \
+       db_wbxng.c 
+
+libu2fw_xcvr_a_SOURCES = \
+       $(U2FW_COMMON) \
+       db_init_xcvr.c \
+       adf4350.c \
+       adf4350_regs.c \
+       db_xcvr2450.c
 
 
 noinst_HEADERS = \
        ad9510.h \
+       adf4350.h \
+       adf4350_regs.h \
        ad9777.h \
        ad9777_regs.h \
        bool.h \
@@ -70,6 +90,8 @@ noinst_HEADERS = \
        clocks.h \
        db.h \
        db_base.h \
+       db_wbxng.h \
+       db_bitshark_rx.h \
        dbsm.h \
        eth_mac.h \
        eth_mac_regs.h \
diff --git a/usrp2/firmware/lib/adf4350.c b/usrp2/firmware/lib/adf4350.c
new file mode 100644 (file)
index 0000000..dbab654
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "adf4350.h"
+#include "adf4350_regs.h"
+#include "db_wbxng.h"
+#include <spi.h>
+#include <hal_io.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define INPUT_REF_FREQ U2_DOUBLE_TO_FXPT_FREQ(50e6)
+#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
+#define MAX_RF_DIV UINT8_C(16)                                          /* max rf divider, divides rf output */
+#define MIN_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(2.2e9)                      /* minimum vco freq */
+#define MAX_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(4.4e9)                      /* minimum vco freq */
+#define MAX_FREQ MAX_VCO_FREQ                                           /* upper bound freq (rf div = 1) */
+#define MIN_FREQ U2_DOUBLE_TO_FXPT_FREQ(68.75e6)                        /* lower bound freq (rf div = 16) */
+
+u2_fxpt_freq_t adf4350_get_max_freq(void){
+       return MAX_FREQ;
+}
+
+u2_fxpt_freq_t adf4350_get_min_freq(void){
+       return MIN_FREQ;
+}
+
+void adf4350_init(struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       /* Initialize the pin levels. */
+       hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_CE, PLL_CE );
+       adf4350_enable(true, dbb);
+       /* Initialize the registers. */
+       adf4350_load_register(5, dbb);
+       adf4350_load_register(4, dbb);
+       adf4350_load_register(3, dbb);
+       adf4350_load_register(2, dbb);
+       adf4350_load_register(1, dbb);
+       adf4350_load_register(0, dbb);
+}
+
+/*
+void adf4350_update(void){
+       // mirror the lock detect pin to the led debug
+       if (adf4350_get_locked()){
+               io_set_pin(led_pin);
+       }else{
+               io_clear_pin(led_pin);
+       }
+}
+*/
+
+bool adf4350_get_locked(struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       int pins;
+       pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
+       if(pins & PLL_LOCK_DETECT)
+               return true;
+       return false;
+}
+
+void adf4350_enable(bool enable, struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       if (enable){ /* chip enable */
+               hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_PDBRF, PLL_PDBRF );
+       }else{
+               hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, 0, PLL_PDBRF );
+       }
+}
+
+void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       //printf("SPI write ADDR 0x%x, WORD 0x%x\n", (int) (addr), (int) (data));
+       data |= addr;
+       spi_transact(SPI_TXONLY,db->common.spi_mask,data,32,SPIF_PUSH_FALL);
+       //spi_read_write(clk_pin, data_pin, ld_pin, &data, 32);
+       /* pulse latch */
+       //io_set_pin(le_pin);
+       //io_clear_pin(le_pin);
+}
+
+bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       /* Set the frequency by setting int, frac, mod, r, div */
+       if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
+
+       /* Set the prescaler and the min N based on the freq. */
+       uint16_t min_int_div;
+       if (freq > U2_DOUBLE_TO_FXPT_FREQ(3e9) ){
+               db->common.adf4350_regs_prescaler = (uint8_t) 1;
+               min_int_div = UINT16_C(75);
+       }else{
+               db->common.adf4350_regs_prescaler = (uint8_t) 0;
+               min_int_div = UINT16_C(23);
+       }
+
+       /* Ramp up the RF divider until the VCO is within range. */
+       db->common.adf4350_regs_divider_select = (uint8_t) 0;
+       while (freq < MIN_VCO_FREQ){
+               freq <<= 1; //double the freq
+               db->common.adf4350_regs_divider_select++; //double the divider
+       }
+
+       /* Ramp up the R divider until the N divider is at least the minimum. */
+       db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND((INPUT_REF_FREQ*min_int_div), freq));
+       //printf("Initial R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div);
+       if (db->common.adf4350_regs_10_bit_r_counter * U2_DOUBLE_TO_FXPT_FREQ(32e6) < INPUT_REF_FREQ){
+               db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND(INPUT_REF_FREQ, U2_DOUBLE_TO_FXPT_FREQ(32e6)));
+               //printf("Updating R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div);
+       }
+
+       db->common.adf4350_regs_10_bit_r_counter--;
+       //db->common.adf4350_regs_10_bit_r_counter=1;
+
+       do{
+               db->common.adf4350_regs_10_bit_r_counter++;
+               /* throw out some fractional bits in freq to avoid overflow */
+               u2_fxpt_freq_t some_frac_freq = (U2_DOUBLE_TO_FXPT_FREQ(1.0)/db->common.adf4350_regs_mod);
+               uint64_t n_mod = DIV_ROUND(freq, some_frac_freq);
+               n_mod *= db->common.adf4350_regs_10_bit_r_counter;
+               n_mod *= db->common.adf4350_regs_mod;
+               n_mod = DIV_ROUND(n_mod, DIV_ROUND(INPUT_REF_FREQ, some_frac_freq));
+               /* calculate int and frac: regs_mod is a power of 2, this will optimize to a bitwise operation */
+               db->common.adf4350_regs_int = (uint16_t) (n_mod/db->common.adf4350_regs_mod);
+               db->common.adf4350_regs_frac = (uint16_t) (n_mod%db->common.adf4350_regs_mod);
+               //printf("Int %u < Min %u\n", db->common.adf4350_regs_int, min_int_div);
+       }while(db->common.adf4350_regs_int < min_int_div);
+
+       /* calculate the band select so PFD is under 125 KHz */
+       db->common.adf4350_regs_8_bit_band_select_clock_divider_value = \
+               (uint8_t) (INPUT_REF_FREQ/(U2_DOUBLE_TO_FXPT_FREQ(30e3)*db->common.adf4350_regs_10_bit_r_counter)) + 1;
+
+       /*
+       printf(
+               "VCO %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u, BandSelect %u\n",
+               (uint32_t) ((freq >> U2_FPF_RP)/1000),
+               (uint32_t) db->common.adf4350_regs_int,
+               (uint32_t) db->common.adf4350_regs_frac,
+               (uint32_t) db->common.adf4350_regs_mod,
+               (uint32_t) db->common.adf4350_regs_10_bit_r_counter,
+               (uint32_t) (1 << db->common.adf4350_regs_divider_select),
+               (uint32_t) db->common.adf4350_regs_8_bit_band_select_clock_divider_value
+       );
+       */
+
+       /* load involved registers */
+       adf4350_load_register(5, dbb);
+       adf4350_load_register(3, dbb);
+       adf4350_load_register(1, dbb);
+       adf4350_load_register(2, dbb);
+       adf4350_load_register(4, dbb);
+       adf4350_load_register(0, dbb); /* register 0 must be last */
+       return adf4350_get_locked(dbb);
+}
+
+u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+       /* Calculate the freq from int, frac, mod, ref, r, div:
+        *  freq = (int + frac/mod) * (ref/r)
+        * Keep precision by doing multiplies first:
+        *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
+        */
+       uint64_t temp;
+       temp = (uint64_t) db->common.adf4350_regs_int;
+       temp *= (uint64_t) db->common.adf4350_regs_mod;
+       temp += (uint64_t) db->common.adf4350_regs_frac;
+       temp *= (uint64_t) (INPUT_REF_FREQ >> U2_FPF_RP);
+       temp /= (uint64_t) db->common.adf4350_regs_mod;
+       temp /= (uint64_t) db->common.adf4350_regs_10_bit_r_counter;
+       temp /= (uint64_t) (1 << db->common.adf4350_regs_divider_select);
+
+       /* Shift 1Hz Radix Point for u2_fxpt_freq_t */
+       temp = temp << U2_FPF_RP;
+
+       /*
+       printf(
+               "Got Freq %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
+               (uint32_t) ((temp >> U2_FPF_RP)/1000),
+               (uint32_t) db->common.adf4350_regs_int,
+               (uint32_t) db->common.adf4350_regs_frac,
+               (uint32_t) db->common.adf4350_regs_mod,
+               (uint32_t) db->common.adf4350_regs_10_bit_r_counter,
+               (uint32_t) (1 << db->common.adf4350_regs_divider_select)
+       );
+       */
+
+       return (u2_fxpt_freq_t) (temp);
+}
diff --git a/usrp2/firmware/lib/adf4350.h b/usrp2/firmware/lib/adf4350.h
new file mode 100644 (file)
index 0000000..3c66ec3
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef ADF4350_H
+#define ADF4350_H
+
+#include <db_base.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
+#define UINT8_C(num) ((uint8_t) (num))
+#define UINT16_C(num) ((uint16_t) (num))
+
+void adf4350_init(struct db_base *dbb);
+//void adf4350_update(void);
+bool adf4350_get_locked(struct db_base *dbb);
+void adf4350_enable(bool enable, struct db_base *dbb);
+void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb);
+bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb);
+u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb);
+u2_fxpt_freq_t adf4350_get_max_freq(void);
+u2_fxpt_freq_t adf4350_get_min_freq(void);
+
+#endif /* ADF4350_H */
diff --git a/usrp2/firmware/lib/adf4350_regs.c b/usrp2/firmware/lib/adf4350_regs.c
new file mode 100644 (file)
index 0000000..e2740d3
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "adf4350_regs.h"
+#include "adf4350.h"
+#include "db_wbxng.h"
+
+#define _REG_SHIFT(reg, shift) (((uint32_t)(reg)) << (shift))
+
+/* reg 0 */
+/* reg 1 */
+static const uint16_t adf4350_regs_phase = 0;                           /* 0 */
+/* reg 2 */
+static const uint8_t adf4350_regs_low_noise_and_low_spur_modes = 3;     /* low noise mode */
+static const uint8_t adf4350_regs_muxout = 3;                           /* digital lock detect */
+static const uint8_t adf4350_regs_reference_doubler = 0;                /* disabled */
+static const uint8_t adf4350_regs_rdiv2 = 1;                            /* disabled */
+static const uint8_t adf4350_regs_double_buff = 0;                      /* disabled */
+static const uint8_t adf4350_regs_charge_pump_setting = 5;              /* 2.50 mA */
+static const uint8_t adf4350_regs_ldf = 0;                              /* frac-n */
+static const uint8_t adf4350_regs_ldp = 0;                              /* 10 ns */
+static const uint8_t adf4350_regs_pd_polarity = 1;                      /* positive */
+static const uint8_t adf4350_regs_power_down = 0;                       /* disabled */
+static const uint8_t adf4350_regs_cp_three_state = 0;                   /* disabled */
+static const uint8_t adf4350_regs_counter_reset = 0;                    /* disabled */
+/* reg 3 */
+static const uint8_t adf4350_regs_csr = 0;                              /* disabled */
+static const uint8_t adf4350_regs_clk_div_mode = 0;                     /* clock divider off */
+static const uint16_t adf4350_regs_12_bit_clock_divider_value = 0;      /* 0 */
+/* reg 4 */
+static const uint8_t adf4350_regs_feedback_select = 1;                  /* fundamental */
+static const uint8_t adf4350_regs_vco_power_down = 0;                   /* vco powered up */
+static const uint8_t adf4350_regs_mtld = 0;                             /* mute disabled */
+static const uint8_t adf4350_regs_aux_output_select = 1;                /* divided output */
+static const uint8_t adf4350_regs_aux_output_enable = 1;                /* disabled */
+static const uint8_t adf4350_regs_aux_output_power = 0;                 /* -4 */
+static const uint8_t adf4350_regs_rf_output_enable = 1;                 /* enabled */
+static const uint8_t adf4350_regs_output_power = 3;                     /* -1 */
+/* reg 5 */
+static const uint8_t adf4350_regs_ld_pin_mode = 1;                      /* digital lock detect */
+
+void adf4350_load_register(uint8_t addr, struct db_base *dbb){
+       struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+       uint32_t data;
+       switch (addr){
+               case 0: data = (
+                       _REG_SHIFT(db->common.adf4350_regs_int, 15)                |
+                       _REG_SHIFT(db->common.adf4350_regs_frac, 3)); break;
+               case 1: data = (
+                       _REG_SHIFT(db->common.adf4350_regs_prescaler, 27)          |
+                       _REG_SHIFT(adf4350_regs_phase, 15)                         |
+                       _REG_SHIFT(db->common.adf4350_regs_mod, 3)); break;
+               case 2: data = (
+                       _REG_SHIFT(adf4350_regs_low_noise_and_low_spur_modes, 29)  |
+                       _REG_SHIFT(adf4350_regs_muxout, 26)                        |
+                       _REG_SHIFT(adf4350_regs_reference_doubler, 25)             |
+                       _REG_SHIFT(adf4350_regs_rdiv2, 24)                         |
+                       _REG_SHIFT(db->common.adf4350_regs_10_bit_r_counter, 14)   |
+                       _REG_SHIFT(adf4350_regs_double_buff, 13)                   |
+                       _REG_SHIFT(adf4350_regs_charge_pump_setting, 9)            |
+                       _REG_SHIFT(adf4350_regs_ldf, 8)                            |
+                       _REG_SHIFT(adf4350_regs_ldp, 7)                            |
+                       _REG_SHIFT(adf4350_regs_pd_polarity, 6)                    |
+                       _REG_SHIFT(adf4350_regs_power_down, 5)                     |
+                       _REG_SHIFT(adf4350_regs_cp_three_state, 4)                 |
+                       _REG_SHIFT(adf4350_regs_counter_reset, 3)); break;
+               case 3: data = (
+                       _REG_SHIFT(adf4350_regs_csr, 18)                           |
+                       _REG_SHIFT(adf4350_regs_clk_div_mode, 15)                  |
+                       _REG_SHIFT(adf4350_regs_12_bit_clock_divider_value, 3)); break;
+               case 4: data = (
+                       _REG_SHIFT(adf4350_regs_feedback_select, 23)               |
+                       _REG_SHIFT(db->common.adf4350_regs_divider_select, 20)     |
+                       _REG_SHIFT(db->common.adf4350_regs_8_bit_band_select_clock_divider_value, 12) |
+                       _REG_SHIFT(adf4350_regs_vco_power_down, 11)                |
+                       _REG_SHIFT(adf4350_regs_mtld, 10)                          |
+                       _REG_SHIFT(adf4350_regs_aux_output_select, 9)              |
+                       _REG_SHIFT(adf4350_regs_aux_output_enable, 8)              |
+                       _REG_SHIFT(adf4350_regs_aux_output_power, 6)               |
+                       _REG_SHIFT(adf4350_regs_rf_output_enable, 5)               |
+                       _REG_SHIFT(adf4350_regs_output_power, 3)); break;
+               case 5: data = (
+                       _REG_SHIFT(adf4350_regs_ld_pin_mode, 22)); break;
+               default: return;
+       }
+       /* write the data out to spi */
+       adf4350_write(addr, data, dbb);
+}
diff --git a/usrp2/firmware/lib/adf4350_regs.h b/usrp2/firmware/lib/adf4350_regs.h
new file mode 100644 (file)
index 0000000..f7c160f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * Copyright 2010 Ettus Research LLC
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef ADF4350_REGS_H
+#define ADF4350_REGS_H
+
+#include <db_base.h>
+#include <stdint.h>
+
+void adf4350_load_register(uint8_t addr, struct db_base *dbb);
+
+#endif /* ADF4350_REGS_H */
index cec960267d2f072354199fc113249c27a3efd029..9c0f41da5dbceccd30fef5c56d965fcfc764bd3f 100644 (file)
@@ -99,6 +99,14 @@ db_set_duc_freq(u2_fxpt_freq_t dxc_freq, u2_fxpt_freq_t *actual_dxc_freq);
  */
 bool
 db_set_gain(struct db_base *db, u2_fxpt_gain_t gain);
+
+bool
+db_set_antenna(struct db_base *db, int ant);
+
+/*!
+ * \brief Read the eeprom value from the db, without defaulting to BasicRX/TX
+ */
+int
+read_dboard_eeprom(int i2c_addr);
 
 #endif /* INCLUDED_DB_H */
index 2ccfbf50985f1c61828edce431d7e3d7c1ae0a42..1945efe0b9286299ad150b18e129a1fd156df97d 100644 (file)
@@ -63,6 +63,7 @@ struct db_base {
   bool (*set_freq)(struct db_base *, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
   bool (*set_gain)(struct db_base *, u2_fxpt_gain_t gain);
   bool (*set_tx_enable)(struct db_base *, bool on);
+  bool (*set_antenna)(struct db_base *, int ant);
 };
 
 
index 2bd4ebfbe492d6cf6eceb6750d8929936d3060fe..8f86f060b389dbf43cbaed4aa4edc16c00963629 100644 (file)
@@ -53,6 +53,7 @@ struct db_basic db_basic_tx = {
   .base.set_freq = db_basic_set_freq,
   .base.set_gain = db_basic_set_gain,
   .base.set_tx_enable = db_basic_set_tx_enable,
+  .base.set_antenna = 0,
 };
 
 struct db_basic db_basic_rx = {
@@ -79,6 +80,7 @@ struct db_basic db_basic_rx = {
   .base.set_freq = db_basic_set_freq,
   .base.set_gain = db_basic_set_gain,
   .base.set_tx_enable = db_basic_set_tx_enable,
+  .base.set_antenna = 0,
 };
 
 struct db_basic db_lf_tx = {
@@ -105,6 +107,7 @@ struct db_basic db_lf_tx = {
   .base.set_freq = db_basic_set_freq,
   .base.set_gain = db_basic_set_gain,
   .base.set_tx_enable = db_basic_set_tx_enable,
+  .base.set_antenna = 0,
 };
 
 struct db_basic db_lf_rx = {
@@ -131,6 +134,7 @@ struct db_basic db_lf_rx = {
   .base.set_freq = db_basic_set_freq,
   .base.set_gain = db_basic_set_gain,
   .base.set_tx_enable = db_basic_set_tx_enable,
+  .base.set_antenna = 0,
 };
 
 
diff --git a/usrp2/firmware/lib/db_bitshark_rx.c b/usrp2/firmware/lib/db_bitshark_rx.c
new file mode 100644 (file)
index 0000000..4c126de
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "db_bitshark_rx.h"
+#include <memory_map.h>
+#include <db_base.h>
+#include <hal_io.h>
+#include <mdelay.h>
+#include <lsdac.h>
+#include <clocks.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <i2c.h>
+
+/* Note: Thie general structure of this file is based on the db_wbxng.c 
+   codebase for the wbx daughterboard. */
+
+/* The following defines specify the address map provided by the
+   Bitshark USRP Rx (BURX) board. These registers are all accessed over I2C. */
+#define RF_CENTER_FREQ_REG 0x00
+#define RF_CHAN_FILTER_BW_REG 0x01
+#define RF_GAIN_REG 0x02
+#define BB_GAIN_REG 0x03
+#define ADF4350_REG 0x10
+#define SKY73202_REG 0x11
+#define CLOCK_SCHEME_REG 0x20
+
+/* The following table lists the registers provided by the Bitshark board 
+   that are accessible over I2C:
+   --------------------------------------------------------
+   |RegAddr: 0x00-RF Center Freq register |
+       |4-bytes 0x00|
+       |4-byte unsigned RF center freq (in KHz)|
+   |RegAddr: 0x01-RF channel filter bandwidth register |
+       |4-bytes 0x00|
+       |4-byte unsigned RF channel filter bw (in KHz)|
+   |RegAddr: 0x02-RF gain register |
+       |7-bytes 0x00|
+       |1-byte signed RF gain (in dB)|
+   |RegAddr: 0x03-Baseband gain register |
+       |4-bytes 0x00|
+       |4-byte signed baseband filter gain (in dB)|
+   |RegAddr: 0x10-ADF4350 register |
+       |4-bytes 0x00|
+       |4-byte ADF4350 register value (actual ADF4350 reg addr embedded 
+        within 4-byte value)|
+   |RegAddr: 0x11-SKY73202 register |
+       |5-bytes 0x00|
+       |1-byte reg 0 of SKY73202 |
+       |1-byte reg 1 of SKY73202 |
+       |1-byte reg 2 of SKY73202 |
+   |RegAddr: 0x20-Clock Scheme |
+       |3-bytes 0x00|
+       |1-byte indicating clocking scheme:
+        -0x00 -> BURX local TCXO off, BURX accepts ref clock from
+                USRP2 (freq of USRP2's ref clock specified in bytes 2-5)
+       -0x01 -> BURX local TCXO on, BURX uses its local TCXO as its ref
+                clock, TCXO signal output for use as phase lock for USRP2 |
+       |4-byte USRP2 ref clock freq in hz (only needed if byte 1 set to 0x00) |
+       
+  ---------------------------------------------------------------------------
+   
+   As an example, lets say the client wants to set an RF center freq of
+   1000 MHz.  In KHz, this translates to 1000000 (resolution is only down to
+   steps of 1 KHz), which is 0x000F4240 in hex.  So the complete 9-byte I2C 
+   sequence that the client should send is as follows:
+   byte 0: 0x00-register 0x00 is the target of the write operation
+   bytes 1-4: 0x00 (padding)
+   byte 5: 0x00 (MSB of the 1000000 KHz value, in hex)
+   byte 6: 0x0F
+   byte 7: 0x42
+   byte 8: 0x40 (LSB of the 1000000 KHz value, in hex)
+   
+   How about another example...lets say the client wants to setup the clock
+   scheme to use scheme #1 where the 26 MHz TCXO on the BURX board is enabled,
+   and is provided to the USRP2 for it to phase lock to it as an external ref.  
+   26 MHz (i.e. 26 million), in hex, is 0x18CBA80.
+   So the complete 9-byte I2C sequence that the client should send is as follows:
+   byte 0: 0x20-register 0x20 is the target of the write operation
+   bytes 1-3: 0x00 (padding)
+   byte 4: 0x01 (indicating that clock scheme #1 is wanted)
+   byte 5: 0x01 (MSB of the BURX ref clk freq)
+   byte 6: 0x8C
+   byte 7: 0xBA
+   byte 8: 0x80 (LSB of the BURX ref clk freq)
+
+   Note: The endian-ness of 4-byte values used in I2C cmds is different on 
+   USRP2 compared to USRP1.
+   
+*/
+
+#define NUM_BYTES_IN_I2C_CMD 9
+#define I2C_ADDR 0x47
+
+bool bitshark_rx_init(struct db_base *dbb);
+bool bitshark_rx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
+bool bitshark_rx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain);
+bool bitshark_rx_set_bw(struct db_base *dbb, uint16_t bw);
+
+static bool set_clock_scheme(uint8_t clock_scheme, uint32_t ref_clk_freq);
+
+/*
+ * The class instances
+ */
+struct db_bitshark_rx db_bitshark_rx = {
+    .base.dbid = 0x0070,
+    .base.is_tx = false,
+    .base.output_enables = 0x0000,
+    .base.used_pins = 0x0000,
+    .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(300e6),
+    .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(4000e6),
+    .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+    .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(42),
+    .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(6),
+    .base.is_quadrature = true,
+    .base.i_and_q_swapped = true,
+    .base.spectrum_inverted = false,
+    .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+    .base.init = bitshark_rx_init,
+    .base.set_freq = bitshark_rx_set_freq,
+    .base.set_gain = bitshark_rx_set_gain,
+    .base.set_tx_enable = 0,
+    .base.atr_mask = 0x0000,
+    .base.atr_txval = 0,
+    .base.atr_rxval = 0,
+    .base.set_antenna = 0,
+    .extra.bw_min = 660, /* in KHz, so 660 KHz */
+    .extra.bw_max = 56000, /* in KHz, so 56 MHz */
+    .extra.set_bw = bitshark_rx_set_bw
+};
+
+bool
+bitshark_rx_init(struct db_base *dbb)
+{
+    struct db_bitshark_rx_dummy *db = (struct db_bitshark_rx_dummy *) dbb;    
+
+    clocks_enable_rx_dboard(true, 0);
+    /* hal_gpio_write( GPIO_RX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 ); */
+    /* above isn't needed, since we don't have any GPIO from the FPGA */
+    
+    /* setup the clock scheme to accept the USRP2's 100 MHz ref clk */
+    set_clock_scheme(0,100000000);
+
+    /* initial setting of gain */
+    dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(20.0));
+
+    /* Set the freq now to get the one time 10ms delay out of the way. */
+    u2_fxpt_freq_t     dc;
+    dbb->set_freq(dbb, dbb->freq_min, &dc);
+
+    /* set up the RF bandwidth of the signal of interest...Note: there
+       doesn't appear to be a standard way of setting this bandwidth
+       in USRP2-land (compared to USRP1-land, where we have the
+       straight-forward set_bw() method).  Not sure why this is, but
+       for now, simply set the bandwidth once for the intended
+       application. */
+    db->extra.set_bw(dbb, 25000);  /* 25 MHz channel bw */
+
+    return true;
+}
+
+bool
+bitshark_rx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
+{
+    struct db_bitshark_rx_dummy *db = (struct db_bitshark_rx_dummy *) dbb;    
+    unsigned char args[NUM_BYTES_IN_I2C_CMD];
+    unsigned char val[4];
+    uint32_t freq_in_khz = (uint32_t)(u2_fxpt_freq_round_to_uint(freq)/1000);
+    
+    if(!(freq>=db->base.freq_min && freq<=db->base.freq_max)) 
+    {
+       return false;
+    }
+    
+    memset(args,0x00,NUM_BYTES_IN_I2C_CMD);
+    memcpy(val,&freq_in_khz,4);
+    args[0] = RF_CENTER_FREQ_REG;
+    args[5] = val[3];
+    args[6] = val[2];
+    args[7] = val[1];
+    args[8] = val[0];
+    
+    i2c_write(I2C_ADDR, args, NUM_BYTES_IN_I2C_CMD);
+    /* Add a brief delay after each command.  This only seems to be
+       necessary when sending a sequence of commands one after the other.
+       This issue appears to be specific to the USRP2, since it isn't
+       necessary on the USRP1.  The 5 mS delay is a bit of 
+       an emperical compromise: too short (say, 1 mS), and every once
+       in a great while a command will still be magically dropped on its
+       way out...too long (say, 500 mS) and higher-level apps such as
+       usrp2_fft.py seem to choke because the init sequence is taking
+       too long.  So 5 mS was tested repeatedly without error, and deemed
+       reasonable. Not sure if this is an issue with the I2C master
+       code in the microblaze or some place else, and I hate magic
+       delays too, but this seems to be stable. */
+    mdelay(5);
+
+   *dc = freq;
+    return true;
+}
+
+bool
+bitshark_rx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain)
+{
+    struct db_bitshark_rx_dummy *db = (struct db_bitshark_rx_dummy *) dbb;
+    
+    unsigned char args[NUM_BYTES_IN_I2C_CMD];
+    uint8_t final_gain = (uint8_t)(u2_fxpt_gain_round_to_int(gain));
+    
+    if(!(gain >= db->base.gain_min && gain <= db->base.gain_max)) 
+    {
+       return false;
+    }
+    
+    memset(args,0x00,NUM_BYTES_IN_I2C_CMD);
+    args[0] = RF_GAIN_REG;
+    args[5] = final_gain;
+
+    i2c_write(I2C_ADDR, args, NUM_BYTES_IN_I2C_CMD);
+    /* Add a brief delay after each command.  This only seems to be
+       necessary when sending a sequence of commands one after the other.
+       This issue appears to be specific to the USRP2, since it isn't
+       necessary on the USRP1.  The 5 mS delay is a bit of 
+       an emperical compromise: too short (say, 1 mS), and every once
+       in a great while a command will still be magically dropped on its
+       way out...too long (say, 500 mS) and higher-level apps such as
+       usrp2_fft.py seem to choke because the init sequence is taking
+       too long.  So 5 mS was tested repeatedly without error, and deemed
+       reasonable. Not sure if this is an issue with the I2C master
+       code in the microblaze or some place else, and I hate magic
+       delays too, but this seems to be stable. */
+    mdelay(5);
+
+    return true;
+}
+
+bool
+bitshark_rx_set_bw(struct db_base *dbb, uint16_t bw_in_khz)
+{
+    struct db_bitshark_rx_dummy *db = (struct db_bitshark_rx_dummy *) dbb;
+    unsigned char val[2];
+    unsigned char args[NUM_BYTES_IN_I2C_CMD];
+    
+    if(!(bw_in_khz >= db->extra.bw_min && bw_in_khz <= db->extra.bw_max)) 
+    {
+       return false;
+    }
+    
+    memset(args,0x00,NUM_BYTES_IN_I2C_CMD);
+    memcpy(val,&bw_in_khz,2);
+    args[0] = RF_CHAN_FILTER_BW_REG;
+    args[5] = val[1];
+    args[6] = val[0];
+
+    i2c_write(I2C_ADDR, args, NUM_BYTES_IN_I2C_CMD);
+    /* Add a brief delay after each command.  This only seems to be
+       necessary when sending a sequence of commands one after the other.
+       This issue appears to be specific to the USRP2, since it isn't
+       necessary on the USRP1.  The 5 mS delay is a bit of 
+       an emperical compromise: too short (say, 1 mS), and every once
+       in a great while a command will still be magically dropped on its
+       way out...too long (say, 500 mS) and higher-level apps such as
+       usrp2_fft.py seem to choke because the init sequence is taking
+       too long.  So 5 mS was tested repeatedly without error, and deemed
+       reasonable. Not sure if this is an issue with the I2C master
+       code in the microblaze or some place else, and I hate magic
+       delays too, but this seems to be stable. */
+    mdelay(5);
+
+    return true;
+}
+
+static bool
+set_clock_scheme(uint8_t clock_scheme, uint32_t ref_clk_freq)
+{
+    /* Set the clock scheme for determining how the BURX
+       dboard receives its clock.  For the USRP2, there is really only
+       one way of doing this, which is to use the 100 MHz ref clk
+       on the USRP2 as its reference.  However, it is possible to
+       use the BURX's 26 MHz TCXO as the external reference input to
+       the USRP, which would provide phase lock between our oscillator
+       and the USRP's 100 MHz oscillator.  And since the BURX board
+       provides the ability to warp the oscillator, this may be
+       useful to some folks.  Otherwise, the BURX board will always
+       just take the 100 MHz reference from the USRP2 as its reference.
+    */
+    
+    unsigned char args[NUM_BYTES_IN_I2C_CMD];
+    char val[4];
+
+    if (clock_scheme > 1) 
+    {
+       return false;
+    }
+
+    memcpy(val,&ref_clk_freq,4);
+    args[0] = CLOCK_SCHEME_REG;
+    args[4] = clock_scheme;
+    args[5] = val[3];
+    args[6] = val[2];
+    args[7] = val[1];
+    args[8] = val[0];
+
+    i2c_write(I2C_ADDR, args, NUM_BYTES_IN_I2C_CMD);
+    /* Add a brief delay after each command.  This only seems to be
+       necessary when sending a sequence of commands one after the other.
+       This issue appears to be specific to the USRP2, since it isn't
+       necessary on the USRP1.  The 5 mS delay is a bit of 
+       an emperical compromise: too short (say, 1 mS), and every once
+       in a great while a command will still be magically dropped on its
+       way out...too long (say, 500 mS) and higher-level apps such as
+       usrp2_fft.py seem to choke because the init sequence is taking
+       too long.  So 5 mS was tested repeatedly without error, and deemed
+       reasonable. Not sure if this is an issue with the I2C master
+       code in the microblaze or some place else, and I hate magic
+       delays too, but this seems to be stable. */
+    mdelay(5);
+
+    return true;
+}
+
diff --git a/usrp2/firmware/lib/db_bitshark_rx.h b/usrp2/firmware/lib/db_bitshark_rx.h
new file mode 100644 (file)
index 0000000..3651f27
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DB_BITSHARK_RX_H
+#define DB_BITSHARK_RX_H
+
+#include <db_base.h>
+
+struct db_bitshark_rx_extra 
+{
+    uint16_t bw_min;
+    uint16_t bw_max;
+    bool     (*set_bw)(struct db_base *, uint16_t bw);
+       
+};
+
+struct db_bitshark_rx_dummy 
+{
+  struct db_base       base;
+  struct db_bitshark_rx_extra  extra;
+};
+
+
+struct db_bitshark_rx 
+{
+  struct db_base       base;
+  struct db_bitshark_rx_extra extra;
+};
+
+
+#endif /* DB_BITSHARK_RX_H */
index 2174a6cd865209a2bb03035e762ce912886cc4b2..ce1300bf27e2e324f2c571bc4fb75a5d03f1fc23 100644 (file)
@@ -103,6 +103,7 @@ struct db_dbsrx db_dbsrx = {
   .common.d_adl = 0,
   .common.d_gc2 = 31,
   .common.d_diag = 0,
+  .base.set_antenna = 0,
 };
 
 bool
index 925a34f399b06f77db829de0c936711ee9b36fe9..d58badc9e5d9907c12c5899c2010e617838115f4 100644 (file)
@@ -45,13 +45,13 @@ extern struct db_base db_rfx_1800_tx;
 extern struct db_base db_rfx_1800_rx;
 extern struct db_base db_rfx_2400_tx;
 extern struct db_base db_rfx_2400_rx;
+extern struct db_base db_wbxng_rx;
+extern struct db_base db_wbxng_tx;
 extern struct db_base db_tvrx1;
 extern struct db_base db_tvrx2;
 extern struct db_base db_tvrx3;
 extern struct db_base db_dbsrx;
-
-extern struct db_base db_xcvr2450_tx;
-extern struct db_base db_xcvr2450_rx;
+extern struct db_base db_bitshark_rx;
 
 struct db_base *all_dboards[] = {
   &db_basic_tx,
@@ -69,11 +69,12 @@ struct db_base *all_dboards[] = {
   &db_rfx_2400_tx,
   &db_rfx_2400_rx,
   &db_tvrx1,
+#if 0
   &db_tvrx2,
+#endif
   &db_tvrx3,
   &db_dbsrx,
-  &db_xcvr2450_tx,
-  &db_xcvr2450_rx,
+  &db_bitshark_rx,
   0
 };
 
@@ -424,3 +425,10 @@ db_set_gain(struct db_base *db, u2_fxpt_gain_t gain)
 {
   return db->set_gain(db, gain);
 }
+
+bool
+db_set_antenna(struct db_base *db, int ant)
+{
+  if (db->set_antenna == 0) return false;
+  return db->set_antenna(db, ant);
+}
diff --git a/usrp2/firmware/lib/db_init_wbx.c b/usrp2/firmware/lib/db_init_wbx.c
new file mode 100644 (file)
index 0000000..8810e0d
--- /dev/null
@@ -0,0 +1,404 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <memory_map.h>
+#include <i2c.h>
+#include <usrp2_i2c_addr.h>
+#include <string.h>
+#include <stdio.h>
+#include <db.h>
+#include <db_base.h>
+#include <hal_io.h>
+#include <nonstdio.h>
+
+
+struct db_base *tx_dboard;     // the tx daughterboard that's installed
+struct db_base *rx_dboard;     // the rx daughterboard that's installed
+
+extern struct db_base db_basic_tx;
+extern struct db_base db_basic_rx;
+extern struct db_base db_lf_tx;
+extern struct db_base db_lf_rx;
+extern struct db_base db_wbxng_rx;
+extern struct db_base db_wbxng_tx;
+
+struct db_base *all_dboards[] = {
+  &db_basic_tx,
+  &db_basic_rx,
+  &db_lf_tx,
+  &db_lf_rx,
+  &db_wbxng_rx,
+  &db_wbxng_tx,
+  0
+};
+
+
+typedef enum { UDBE_OK, UDBE_NO_EEPROM, UDBE_INVALID_EEPROM } usrp_dbeeprom_status_t;
+
+static usrp_dbeeprom_status_t
+read_raw_dboard_eeprom (unsigned char *buf, int i2c_addr)
+{
+  if (!eeprom_read (i2c_addr, 0, buf, DB_EEPROM_CLEN))
+    return UDBE_NO_EEPROM;
+
+  if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE)
+    return UDBE_INVALID_EEPROM;
+
+  int sum = 0;
+  unsigned int i;
+  for (i = 0; i < DB_EEPROM_CLEN; i++)
+    sum += buf[i];
+
+  if ((sum & 0xff) != 0)
+    return UDBE_INVALID_EEPROM;
+
+  return UDBE_OK;
+}
+
+
+/*
+ * Return DBID, -1 <none> or -2 <invalid eeprom contents>
+ */
+int
+read_dboard_eeprom(int i2c_addr)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  usrp_dbeeprom_status_t s = read_raw_dboard_eeprom (buf, i2c_addr);
+
+  //printf("\nread_raw_dboard_eeprom: %d\n", s);
+
+  switch (s){
+  case UDBE_OK:
+    return (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB];
+
+  case UDBE_NO_EEPROM:
+  default:
+    return -1;
+
+  case UDBE_INVALID_EEPROM:
+    return -2;
+  }
+}
+
+
+static struct db_base *
+lookup_dbid(int dbid)
+{
+  if (dbid < 0)
+    return 0;
+
+  int i;
+  for (i = 0; all_dboards[i]; i++)
+    if (all_dboards[i]->dbid == dbid)
+      return all_dboards[i];
+
+  return 0;
+}
+
+static struct db_base *
+lookup_dboard(int i2c_addr, struct db_base *default_db, char *msg)
+{
+  struct db_base *db;
+  int dbid = read_dboard_eeprom(i2c_addr);
+
+  // FIXME removing this printf has the system hang if there are two d'boards
+  // installed.  (I think the problem is in i2c_read/write or the way
+  // I kludge the zero-byte write to set the read address in eeprom_read.)
+  printf("%s dbid: 0x%x\n", msg, dbid);
+
+  if (dbid < 0){       // there was some kind of problem.  Treat as Basic Tx
+    return default_db;
+  }
+  else if ((db = lookup_dbid(dbid)) == 0){
+    printf("No daugherboard code for dbid = 0x%x\n", dbid);
+    return default_db;
+  }
+  return db;
+}
+
+void
+set_atr_regs(int bank, struct db_base *db)
+{
+  uint32_t     val[4];
+  int          shift;
+  int          mask;
+  int          i;
+
+  val[ATR_IDLE] = db->atr_rxval;
+  val[ATR_RX]   = db->atr_rxval;
+  val[ATR_TX]   = db->atr_txval;
+  val[ATR_FULL] = db->atr_txval;
+
+  if (bank == GPIO_TX_BANK){
+    mask = 0xffff0000;
+    shift = 16;
+  }
+  else {
+    mask = 0x0000ffff;
+    shift = 0;
+  }
+
+  for (i = 0; i < 4; i++){
+    int t = (atr_regs->v[i] & ~mask) | ((val[i] << shift) & mask);
+    //printf("atr_regs[%d] = 0x%x\n", i, t);
+    atr_regs->v[i] = t;
+  }
+}
+
+static void
+set_gpio_mode(int bank, struct db_base *db)
+{
+  int  i;
+
+  hal_gpio_set_ddr(bank, db->output_enables, 0xffff);
+  set_atr_regs(bank, db);
+
+  for (i = 0; i < 16; i++){
+    if (db->used_pins & (1 << i)){
+      // set to either GPIO_SEL_SW or GPIO_SEL_ATR
+      hal_gpio_set_sel(bank, i, (db->atr_mask & (1 << i)) ? 'a' : 's');
+    }
+  }
+}
+
+static int __attribute__((unused))
+determine_tx_mux_value(struct db_base *db) 
+{
+  if (db->i_and_q_swapped)
+    return 0x01;
+  else
+    return 0x10;
+}
+
+static int
+determine_rx_mux_value(struct db_base *db)
+{
+#define        ADC0 0x0
+#define        ADC1 0x1
+#define ZERO 0x2
+  
+  static int truth_table[8] = {
+    /* swap_iq, uses */
+    /* 0, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 0, 0x1 */    (ZERO << 2) | ADC0,
+    /* 0, 0x2 */    (ZERO << 2) | ADC1,
+    /* 0, 0x3 */    (ADC1 << 2) | ADC0,
+    /* 1, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 1, 0x1 */    (ZERO << 2) | ADC0,
+    /* 1, 0x2 */    (ZERO << 2) | ADC1,
+    /* 1, 0x3 */    (ADC0 << 2) | ADC1,
+  };
+
+  int  subdev0_uses;
+  int  subdev1_uses;
+  int  uses;
+
+  if (db->is_quadrature)
+    subdev0_uses = 0x3;                // uses A/D 0 and 1
+  else
+    subdev0_uses = 0x1;                // uses A/D 0 only
+
+  // FIXME second subdev on Basic Rx, LF RX
+  // if subdev2 exists
+  // subdev1_uses = 0x2;
+  subdev1_uses = 0;
+
+  uses = subdev0_uses;
+
+  int swap_iq = db->i_and_q_swapped & 0x1;
+  int index = (swap_iq << 2) | uses;
+
+  return truth_table[index];
+}
+
+
+void
+db_init(void)
+{
+  int  m;
+
+  tx_dboard = lookup_dboard(I2C_ADDR_TX_A, &db_basic_tx, "Tx");
+  //printf("db_init: tx dbid = 0x%x\n", tx_dboard->dbid);
+  set_gpio_mode(GPIO_TX_BANK, tx_dboard);
+  tx_dboard->init(tx_dboard);
+  m = determine_tx_mux_value(tx_dboard);
+  dsp_tx_regs->tx_mux = m;
+  //printf("tx_mux = 0x%x\n", m);
+  tx_dboard->current_lo_offset = tx_dboard->default_lo_offset;
+
+  rx_dboard = lookup_dboard(I2C_ADDR_RX_A, &db_basic_rx, "Rx");
+  //printf("db_init: rx dbid = 0x%x\n", rx_dboard->dbid);
+  set_gpio_mode(GPIO_RX_BANK, rx_dboard);
+  rx_dboard->init(rx_dboard);
+  m = determine_rx_mux_value(rx_dboard);
+  dsp_rx_regs->rx_mux = m;
+  //printf("rx_mux = 0x%x\n", m);
+  rx_dboard->current_lo_offset = rx_dboard->default_lo_offset;
+}
+
+/*!
+ *  Calculate the frequency to use for setting the digital down converter.
+ *
+ *  \param[in] target_freq   desired RF frequency (Hz)
+ *  \param[in] baseband_freq the RF frequency that corresponds to DC in the IF.
+ * 
+ *  \param[out] dxc_freq is the value for the ddc
+ *  \param[out] inverted is true if we're operating in an inverted Nyquist zone.
+*/
+void
+calc_dxc_freq(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t baseband_freq,
+             u2_fxpt_freq_t *dxc_freq, bool *inverted)
+{
+  u2_fxpt_freq_t fs = U2_DOUBLE_TO_FXPT_FREQ(100e6);   // converter sample rate
+  u2_fxpt_freq_t delta = target_freq - baseband_freq;
+
+#if 0
+  printf("calc_dxc_freq\n");
+  printf("  fs       = "); print_fxpt_freq(fs); newline();
+  printf("  target   = "); print_fxpt_freq(target_freq); newline();
+  printf("  baseband = "); print_fxpt_freq(baseband_freq); newline();
+  printf("  delta    = "); print_fxpt_freq(delta); newline();
+#endif  
+
+  if (delta >= 0){
+    while (delta > fs)
+      delta -= fs;
+    if (delta <= fs/2){                // non-inverted region
+      *dxc_freq = -delta;
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta - fs;
+      *inverted = true;
+    }
+  }
+  else {
+    while (delta < -fs)
+      delta += fs;
+    if (delta >= -fs/2){       // non-inverted region
+      *dxc_freq = -delta;
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta + fs;
+      *inverted = true;
+    }
+  }
+}
+
+bool
+db_set_lo_offset(struct db_base *db, u2_fxpt_freq_t offset)
+{
+  db->current_lo_offset = offset;
+  return true;
+}
+
+bool
+db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *result)
+{
+  memset(result, 0, sizeof(*result));
+  bool inverted = false;
+  u2_fxpt_freq_t dxc_freq;
+  u2_fxpt_freq_t actual_dxc_freq;
+
+  // Ask the d'board to tune as closely as it can to target_freq+lo_offset
+  bool ok = db->set_freq(db, target_freq+db->current_lo_offset, &result->baseband_freq);
+
+  // Calculate the DDC setting that will downconvert the baseband from the
+  // daughterboard to our target frequency.
+  calc_dxc_freq(target_freq, result->baseband_freq, &dxc_freq, &inverted);
+
+  // If the spectrum is inverted, and the daughterboard doesn't do
+  // quadrature downconversion, we can fix the inversion by flipping the
+  // sign of the dxc_freq...  (This only happens using the basic_rx board)
+  
+  if (db->spectrum_inverted)
+    inverted = !inverted;
+
+  if (inverted && !db->is_quadrature){
+    dxc_freq = -dxc_freq;
+    inverted = !inverted;
+  }
+
+  if (db->is_tx){
+    dxc_freq = -dxc_freq;      // down conversion versus up conversion
+    ok &= db_set_duc_freq(dxc_freq, &actual_dxc_freq);
+  }
+  else {
+    ok &= db_set_ddc_freq(dxc_freq, &actual_dxc_freq);
+  }
+
+  result->dxc_freq = dxc_freq;
+  result->residual_freq = dxc_freq - actual_dxc_freq;
+  result->inverted = inverted;
+  return ok;
+}
+
+static int32_t
+compute_freq_control_word(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t *actual_freq)
+{
+  // If we were using floating point, we'd calculate
+  //   master = 100e6;
+  //   v = (int) rint(target_freq / master_freq) * pow(2.0, 32.0);
+
+  //printf("compute_freq_control_word\n");
+  //printf("  target_freq = "); print_fxpt_freq(target_freq); newline();
+
+  int32_t master_freq = 100000000;     // 100M
+
+  int32_t v = ((target_freq << 12)) / master_freq;
+  //printf("  fcw = %d\n", v);
+
+  *actual_freq = (v * (int64_t) master_freq) >> 12;
+
+  //printf("  actual = "); print_fxpt_freq(*actual_freq); newline();
+
+  return v;
+}
+
+
+bool
+db_set_ddc_freq(u2_fxpt_freq_t dxc_freq, u2_fxpt_freq_t *actual_dxc_freq)
+{
+  int32_t v = compute_freq_control_word(dxc_freq, actual_dxc_freq);
+  dsp_rx_regs->freq = v;
+  return true;
+}
+
+bool
+db_set_duc_freq(u2_fxpt_freq_t dxc_freq, u2_fxpt_freq_t *actual_dxc_freq)
+{
+  int32_t v = compute_freq_control_word(dxc_freq, actual_dxc_freq);
+  dsp_tx_regs->freq = v;
+  return true;
+}
+
+bool
+db_set_gain(struct db_base *db, u2_fxpt_gain_t gain)
+{
+  return db->set_gain(db, gain);
+}
+
+bool
+db_set_antenna(struct db_base *db, int ant)
+{
+  if (db->set_antenna == 0) return false;
+  return db->set_antenna(db, ant);
+}
diff --git a/usrp2/firmware/lib/db_init_xcvr.c b/usrp2/firmware/lib/db_init_xcvr.c
new file mode 100644 (file)
index 0000000..3e3d3eb
--- /dev/null
@@ -0,0 +1,404 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <memory_map.h>
+#include <i2c.h>
+#include <usrp2_i2c_addr.h>
+#include <string.h>
+#include <stdio.h>
+#include <db.h>
+#include <db_base.h>
+#include <hal_io.h>
+#include <nonstdio.h>
+
+
+struct db_base *tx_dboard;     // the tx daughterboard that's installed
+struct db_base *rx_dboard;     // the rx daughterboard that's installed
+
+extern struct db_base db_basic_tx;
+extern struct db_base db_basic_rx;
+extern struct db_base db_lf_tx;
+extern struct db_base db_lf_rx;
+extern struct db_base db_xcvr2450_tx;
+extern struct db_base db_xcvr2450_rx;
+
+struct db_base *all_dboards[] = {
+  &db_basic_tx,
+  &db_basic_rx,
+  &db_lf_tx,
+  &db_lf_rx,
+  &db_xcvr2450_rx,
+  &db_xcvr2450_tx,
+  0
+};
+
+
+typedef enum { UDBE_OK, UDBE_NO_EEPROM, UDBE_INVALID_EEPROM } usrp_dbeeprom_status_t;
+
+static usrp_dbeeprom_status_t
+read_raw_dboard_eeprom (unsigned char *buf, int i2c_addr)
+{
+  if (!eeprom_read (i2c_addr, 0, buf, DB_EEPROM_CLEN))
+    return UDBE_NO_EEPROM;
+
+  if (buf[DB_EEPROM_MAGIC] != DB_EEPROM_MAGIC_VALUE)
+    return UDBE_INVALID_EEPROM;
+
+  int sum = 0;
+  unsigned int i;
+  for (i = 0; i < DB_EEPROM_CLEN; i++)
+    sum += buf[i];
+
+  if ((sum & 0xff) != 0)
+    return UDBE_INVALID_EEPROM;
+
+  return UDBE_OK;
+}
+
+
+/*
+ * Return DBID, -1 <none> or -2 <invalid eeprom contents>
+ */
+int
+read_dboard_eeprom(int i2c_addr)
+{
+  unsigned char buf[DB_EEPROM_CLEN];
+
+  usrp_dbeeprom_status_t s = read_raw_dboard_eeprom (buf, i2c_addr);
+
+  //printf("\nread_raw_dboard_eeprom: %d\n", s);
+
+  switch (s){
+  case UDBE_OK:
+    return (buf[DB_EEPROM_ID_MSB] << 8) | buf[DB_EEPROM_ID_LSB];
+
+  case UDBE_NO_EEPROM:
+  default:
+    return -1;
+
+  case UDBE_INVALID_EEPROM:
+    return -2;
+  }
+}
+
+
+static struct db_base *
+lookup_dbid(int dbid)
+{
+  if (dbid < 0)
+    return 0;
+
+  int i;
+  for (i = 0; all_dboards[i]; i++)
+    if (all_dboards[i]->dbid == dbid)
+      return all_dboards[i];
+
+  return 0;
+}
+
+static struct db_base *
+lookup_dboard(int i2c_addr, struct db_base *default_db, char *msg)
+{
+  struct db_base *db;
+  int dbid = read_dboard_eeprom(i2c_addr);
+
+  // FIXME removing this printf has the system hang if there are two d'boards
+  // installed.  (I think the problem is in i2c_read/write or the way
+  // I kludge the zero-byte write to set the read address in eeprom_read.)
+  printf("%s dbid: 0x%x\n", msg, dbid);
+
+  if (dbid < 0){       // there was some kind of problem.  Treat as Basic Tx
+    return default_db;
+  }
+  else if ((db = lookup_dbid(dbid)) == 0){
+    printf("No daugherboard code for dbid = 0x%x\n", dbid);
+    return default_db;
+  }
+  return db;
+}
+
+void
+set_atr_regs(int bank, struct db_base *db)
+{
+  uint32_t     val[4];
+  int          shift;
+  int          mask;
+  int          i;
+
+  val[ATR_IDLE] = db->atr_rxval;
+  val[ATR_RX]   = db->atr_rxval;
+  val[ATR_TX]   = db->atr_txval;
+  val[ATR_FULL] = db->atr_txval;
+
+  if (bank == GPIO_TX_BANK){
+    mask = 0xffff0000;
+    shift = 16;
+  }
+  else {
+    mask = 0x0000ffff;
+    shift = 0;
+  }
+
+  for (i = 0; i < 4; i++){
+    int t = (atr_regs->v[i] & ~mask) | ((val[i] << shift) & mask);
+    //printf("atr_regs[%d] = 0x%x\n", i, t);
+    atr_regs->v[i] = t;
+  }
+}
+
+static void
+set_gpio_mode(int bank, struct db_base *db)
+{
+  int  i;
+
+  hal_gpio_set_ddr(bank, db->output_enables, 0xffff);
+  set_atr_regs(bank, db);
+
+  for (i = 0; i < 16; i++){
+    if (db->used_pins & (1 << i)){
+      // set to either GPIO_SEL_SW or GPIO_SEL_ATR
+      hal_gpio_set_sel(bank, i, (db->atr_mask & (1 << i)) ? 'a' : 's');
+    }
+  }
+}
+
+static int __attribute__((unused))
+determine_tx_mux_value(struct db_base *db) 
+{
+  if (db->i_and_q_swapped)
+    return 0x01;
+  else
+    return 0x10;
+}
+
+static int
+determine_rx_mux_value(struct db_base *db)
+{
+#define        ADC0 0x0
+#define        ADC1 0x1
+#define ZERO 0x2
+  
+  static int truth_table[8] = {
+    /* swap_iq, uses */
+    /* 0, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 0, 0x1 */    (ZERO << 2) | ADC0,
+    /* 0, 0x2 */    (ZERO << 2) | ADC1,
+    /* 0, 0x3 */    (ADC1 << 2) | ADC0,
+    /* 1, 0x0 */    (ZERO << 2) | ZERO,                // N/A
+    /* 1, 0x1 */    (ZERO << 2) | ADC0,
+    /* 1, 0x2 */    (ZERO << 2) | ADC1,
+    /* 1, 0x3 */    (ADC0 << 2) | ADC1,
+  };
+
+  int  subdev0_uses;
+  int  subdev1_uses;
+  int  uses;
+
+  if (db->is_quadrature)
+    subdev0_uses = 0x3;                // uses A/D 0 and 1
+  else
+    subdev0_uses = 0x1;                // uses A/D 0 only
+
+  // FIXME second subdev on Basic Rx, LF RX
+  // if subdev2 exists
+  // subdev1_uses = 0x2;
+  subdev1_uses = 0;
+
+  uses = subdev0_uses;
+
+  int swap_iq = db->i_and_q_swapped & 0x1;
+  int index = (swap_iq << 2) | uses;
+
+  return truth_table[index];
+}
+
+
+void
+db_init(void)
+{
+  int  m;
+
+  tx_dboard = lookup_dboard(I2C_ADDR_TX_A, &db_basic_tx, "Tx");
+  //printf("db_init: tx dbid = 0x%x\n", tx_dboard->dbid);
+  set_gpio_mode(GPIO_TX_BANK, tx_dboard);
+  tx_dboard->init(tx_dboard);
+  m = determine_tx_mux_value(tx_dboard);
+  dsp_tx_regs->tx_mux = m;
+  //printf("tx_mux = 0x%x\n", m);
+  tx_dboard->current_lo_offset = tx_dboard->default_lo_offset;
+
+  rx_dboard = lookup_dboard(I2C_ADDR_RX_A, &db_basic_rx, "Rx");
+  //printf("db_init: rx dbid = 0x%x\n", rx_dboard->dbid);
+  set_gpio_mode(GPIO_RX_BANK, rx_dboard);
+  rx_dboard->init(rx_dboard);
+  m = determine_rx_mux_value(rx_dboard);
+  dsp_rx_regs->rx_mux = m;
+  //printf("rx_mux = 0x%x\n", m);
+  rx_dboard->current_lo_offset = rx_dboard->default_lo_offset;
+}
+
+/*!
+ *  Calculate the frequency to use for setting the digital down converter.
+ *
+ *  \param[in] target_freq   desired RF frequency (Hz)
+ *  \param[in] baseband_freq the RF frequency that corresponds to DC in the IF.
+ * 
+ *  \param[out] dxc_freq is the value for the ddc
+ *  \param[out] inverted is true if we're operating in an inverted Nyquist zone.
+*/
+void
+calc_dxc_freq(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t baseband_freq,
+             u2_fxpt_freq_t *dxc_freq, bool *inverted)
+{
+  u2_fxpt_freq_t fs = U2_DOUBLE_TO_FXPT_FREQ(100e6);   // converter sample rate
+  u2_fxpt_freq_t delta = target_freq - baseband_freq;
+
+#if 0
+  printf("calc_dxc_freq\n");
+  printf("  fs       = "); print_fxpt_freq(fs); newline();
+  printf("  target   = "); print_fxpt_freq(target_freq); newline();
+  printf("  baseband = "); print_fxpt_freq(baseband_freq); newline();
+  printf("  delta    = "); print_fxpt_freq(delta); newline();
+#endif  
+
+  if (delta >= 0){
+    while (delta > fs)
+      delta -= fs;
+    if (delta <= fs/2){                // non-inverted region
+      *dxc_freq = -delta;
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta - fs;
+      *inverted = true;
+    }
+  }
+  else {
+    while (delta < -fs)
+      delta += fs;
+    if (delta >= -fs/2){       // non-inverted region
+      *dxc_freq = -delta;
+      *inverted = false;
+    }
+    else {                     // inverted region
+      *dxc_freq = delta + fs;
+      *inverted = true;
+    }
+  }
+}
+
+bool
+db_set_lo_offset(struct db_base *db, u2_fxpt_freq_t offset)
+{
+  db->current_lo_offset = offset;
+  return true;
+}
+
+bool
+db_tune(struct db_base *db, u2_fxpt_freq_t target_freq, struct tune_result *result)
+{
+  memset(result, 0, sizeof(*result));
+  bool inverted = false;
+  u2_fxpt_freq_t dxc_freq;
+  u2_fxpt_freq_t actual_dxc_freq;
+
+  // Ask the d'board to tune as closely as it can to target_freq+lo_offset
+  bool ok = db->set_freq(db, target_freq+db->current_lo_offset, &result->baseband_freq);
+
+  // Calculate the DDC setting that will downconvert the baseband from the
+  // daughterboard to our target frequency.
+  calc_dxc_freq(target_freq, result->baseband_freq, &dxc_freq, &inverted);
+
+  // If the spectrum is inverted, and the daughterboard doesn't do
+  // quadrature downconversion, we can fix the inversion by flipping the
+  // sign of the dxc_freq...  (This only happens using the basic_rx board)
+  
+  if (db->spectrum_inverted)
+    inverted = !inverted;
+
+  if (inverted && !db->is_quadrature){
+    dxc_freq = -dxc_freq;
+    inverted = !inverted;
+  }
+
+  if (db->is_tx){
+    dxc_freq = -dxc_freq;      // down conversion versus up conversion
+    ok &= db_set_duc_freq(dxc_freq, &actual_dxc_freq);
+  }
+  else {
+    ok &= db_set_ddc_freq(dxc_freq, &actual_dxc_freq);
+  }
+
+  result->dxc_freq = dxc_freq;
+  result->residual_freq = dxc_freq - actual_dxc_freq;
+  result->inverted = inverted;
+  return ok;
+}
+
+static int32_t
+compute_freq_control_word(u2_fxpt_freq_t target_freq, u2_fxpt_freq_t *actual_freq)
+{
+  // If we were using floating point, we'd calculate
+  //   master = 100e6;
+  //   v = (int) rint(target_freq / master_freq) * pow(2.0, 32.0);
+
+  //printf("compute_freq_control_word\n");
+  //printf("  target_freq = "); print_fxpt_freq(target_freq); newline();
+
+  int32_t master_freq = 100000000;     // 100M
+
+  int32_t v = ((target_freq << 12)) / master_freq;
+  //printf("  fcw = %d\n", v);
+
+  *actual_freq = (v * (int64_t) master_freq) >> 12;
+
+  //printf("  actual = "); print_fxpt_freq(*actual_freq); newline();
+
+  return v;
+}
+
+
+bool
+db_set_ddc_freq(u2_fxpt_freq_t dxc_freq, u2_fxpt_freq_t *actual_dxc_freq)
+{
+  int32_t v = compute_freq_control_word(dxc_freq, actual_dxc_freq);
+  dsp_rx_regs->freq = v;
+  return true;
+}
+
+bool
+db_set_duc_freq(u2_fxpt_freq_t dxc_freq, u2_fxpt_freq_t *actual_dxc_freq)
+{
+  int32_t v = compute_freq_control_word(dxc_freq, actual_dxc_freq);
+  dsp_tx_regs->freq = v;
+  return true;
+}
+
+bool
+db_set_gain(struct db_base *db, u2_fxpt_gain_t gain)
+{
+  return db->set_gain(db, gain);
+}
+
+bool
+db_set_antenna(struct db_base *db, int ant)
+{
+  if (db->set_antenna == 0) return false;
+  return db->set_antenna(db, ant);
+}
index 2f950016fb2304e3bef4ef5d779965cf38b2a497..546559010de4bc42a2b6236a77f9d3ebf8197b39 100644 (file)
@@ -157,6 +157,7 @@ struct db_rfx_400_rx db_rfx_400_rx = {
   .base.atr_rxval = POWER_UP|MIX_EN,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 0,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -188,6 +189,7 @@ struct db_rfx_400_tx db_rfx_400_tx = {
   .base.atr_rxval = POWER_UP|ANT_SW,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 1,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -200,8 +202,8 @@ struct db_rfx_900_rx db_rfx_900_rx = {
   .base.is_tx = false,
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
-  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(800e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1000e6),
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(750e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1050e6),
   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
@@ -218,6 +220,7 @@ struct db_rfx_900_rx db_rfx_900_rx = {
   .base.atr_rxval = MIX_EN,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 1,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -231,8 +234,8 @@ struct db_rfx_900_tx db_rfx_900_tx = {
   .base.is_tx = true,
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
-  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(800e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1000e6),
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(750e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1050e6),
   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
@@ -249,6 +252,7 @@ struct db_rfx_900_tx db_rfx_900_tx = {
   .base.atr_rxval = ANT_SW,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 1,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -262,7 +266,7 @@ struct db_rfx_1200_rx db_rfx_1200_rx = {
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1150e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1350e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1450e6),
   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
@@ -279,6 +283,7 @@ struct db_rfx_1200_rx db_rfx_1200_rx = {
   .base.atr_rxval = MIX_EN,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 1,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -293,7 +298,7 @@ struct db_rfx_1200_tx db_rfx_1200_tx = {
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1150e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1350e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1450e6),
   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
@@ -310,6 +315,7 @@ struct db_rfx_1200_tx db_rfx_1200_tx = {
   .base.atr_rxval = ANT_SW,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 1,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -322,8 +328,8 @@ struct db_rfx_1800_rx db_rfx_1800_rx = {
   .base.is_tx = false,
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
-  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1600e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1500e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2100e6),
   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
@@ -340,6 +346,7 @@ struct db_rfx_1800_rx db_rfx_1800_rx = {
   .base.atr_rxval = MIX_EN,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 0,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -353,8 +360,8 @@ struct db_rfx_1800_tx db_rfx_1800_tx = {
   .base.is_tx = true,
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
-  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1600e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1500e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2100e6),
   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
@@ -371,6 +378,7 @@ struct db_rfx_1800_tx db_rfx_1800_tx = {
   .base.atr_rxval = ANT_SW,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 0,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -385,7 +393,7 @@ struct db_rfx_2400_rx db_rfx_2400_rx = {
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2300e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2700e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2900e6),
   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
@@ -402,6 +410,7 @@ struct db_rfx_2400_rx db_rfx_2400_rx = {
   .base.atr_rxval = MIX_EN,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 0,
   .common.CP1 = 7,
   .common.CP2 = 7,
@@ -416,7 +425,7 @@ struct db_rfx_2400_tx db_rfx_2400_tx = {
   .base.output_enables = 0x00E0,
   .base.used_pins = 0x00FF,
   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2300e6),
-  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2700e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2900e6),
   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
@@ -433,6 +442,7 @@ struct db_rfx_2400_tx db_rfx_2400_tx = {
   .base.atr_rxval = ANT_SW,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.DIV2 = 0,
   .common.CP1 = 7,
   .common.CP2 = 7,
index ba70b6402cdb9e8c78f2f9332608d1c8fa17f287..077e59e88bd3e00aa5713d65cbe9329e9a5a6a21 100644 (file)
@@ -28,7 +28,7 @@ bool tvrx_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
 bool tvrx_set_gain(struct db_base *db, u2_fxpt_gain_t gain);
 
 #define I2C_ADDR 0x60
-#define ref_freq (U2_DOUBLE_TO_FXPT_FREQ(4e6)/640*8)
+#define REF_FREQ (U2_DOUBLE_TO_FXPT_FREQ(4e6)/640*8)
 
 #define ref_div 640  /* choices are 640, 512, 1024 */
 
@@ -97,10 +97,12 @@ struct db_tvrx1 db_tvrx1 = {
   .base.atr_rxval = 0,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(43.75e6),
   .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(5.75e6),
 };
 
+#if 0
 struct db_tvrx2 db_tvrx2 = {
   .base.dbid = 0x000c,
   .base.is_tx = false,
@@ -113,7 +115,7 @@ struct db_tvrx2 db_tvrx2 = {
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1),
   .base.is_quadrature = false,
   .base.i_and_q_swapped = false,
-  .base.spectrum_inverted = true,
+  .base.spectrum_inverted = false,
   .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
   .base.init = tvrx_init,
   .base.set_freq = tvrx_set_freq,
@@ -124,9 +126,11 @@ struct db_tvrx2 db_tvrx2 = {
   .base.atr_rxval = 0,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
-  .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
+  .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(56e6),    // Fs - 44e6
 };
+#endif
 
 struct db_tvrx3 db_tvrx3 = {
   .base.dbid = 0x0040,
@@ -140,7 +144,7 @@ struct db_tvrx3 db_tvrx3 = {
   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1),
   .base.is_quadrature = false,
   .base.i_and_q_swapped = false,
-  .base.spectrum_inverted = true,
+  .base.spectrum_inverted = false,
   .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
   .base.init = tvrx_init,
   .base.set_freq = tvrx_set_freq,
@@ -151,8 +155,9 @@ struct db_tvrx3 db_tvrx3 = {
   .base.atr_rxval = 0,
   // .base.atr_tx_delay =
   // .base.atr_rx_delay =
+  .base.set_antenna = 0,
   .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
-  .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
+  .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(56e6),    // Fs - 44e6
 };
 
 bool
@@ -173,25 +178,25 @@ tvrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
   struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb;
 
   u2_fxpt_freq_t target_lo_freq = freq + db->common.first_if;
-  int N_DIV = u2_fxpt_freq_round_to_int(((1LL<<20) * target_lo_freq)/ref_freq);
+  int n_div = u2_fxpt_freq_round_to_int(((1LL<<20) * target_lo_freq)/REF_FREQ);
   
-  u2_fxpt_freq_t actual_lo_freq = ref_freq * N_DIV;
+  u2_fxpt_freq_t actual_lo_freq = REF_FREQ * n_div;
   u2_fxpt_freq_t actual_freq = actual_lo_freq - db->common.first_if;
-  if(N_DIV > 32767)
+  if(n_div > 32767)
     return false;
 
   if (0)
-    printf("N_DIV = %d, actual_freq = %d, actual_lo_freq = %d\n",
-          N_DIV, u2_fxpt_freq_round_to_int(actual_freq),
+    printf("n_div = %d, actual_freq = %d, actual_lo_freq = %d\n",
+          n_div, u2_fxpt_freq_round_to_int(actual_freq),
           u2_fxpt_freq_round_to_int(actual_lo_freq));
 
   unsigned char buf[4];
-  buf[0] = (N_DIV>>8) & 0xff;
-  buf[1] = N_DIV & 0xff;
+  buf[0] = (n_div>>8) & 0xff;
+  buf[1] = n_div & 0xff;
   buf[2] = control_byte_1;
-  buf[3] = (freq < U2_DOUBLE_TO_FXPT_FREQ(158e6)) ? 0xa8 :  // VHF LOW
-    (freq < U2_DOUBLE_TO_FXPT_FREQ(464e6)) ? 0x98 :  // VHF HIGH
-    0x38;  // UHF
+  buf[3] = ((actual_freq < U2_DOUBLE_TO_FXPT_FREQ(158e6)) ? 0xa8 :  // VHF LOW
+           (actual_freq < U2_DOUBLE_TO_FXPT_FREQ(464e6)) ? 0x98 :  // VHF HIGH
+           0x38);  // UHF
 
   *dc = actual_freq - db->common.second_if;
   return i2c_write(I2C_ADDR,buf,4);
diff --git a/usrp2/firmware/lib/db_wbxng.c b/usrp2/firmware/lib/db_wbxng.c
new file mode 100644 (file)
index 0000000..954633d
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "db_wbxng.h"
+#include "adf4350.h"
+#include <spi.h>
+#include <memory_map.h>
+#include <db_base.h>
+#include <hal_io.h>
+#include <mdelay.h>
+#include <lsdac.h>
+#include <clocks.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define min(X,Y) ((X) < (Y) ? (X) : (Y))
+#define max(X,Y) ((X) > (Y) ? (X) : (Y))
+
+bool wbxng_init_rx(struct db_base *dbb);
+bool wbxng_init_tx(struct db_base *dbb);
+bool wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
+bool wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain);
+bool wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain);
+bool wbxng_set_tx_enable(struct db_base *dbb, bool on);
+
+
+/*
+ * The class instances
+ */
+struct db_wbxng_rx db_wbxng_rx = {
+  .base.dbid = 0x0053,
+  .base.is_tx = false,
+  .base.output_enables = RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF|ATTN_MASK,
+  .base.used_pins = 0xFFFF,
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(68.75e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6),
+  .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+  .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(31.5),
+  .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.5),
+  .base.is_quadrature = true,
+  .base.i_and_q_swapped = false,
+  .base.spectrum_inverted = false,
+  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+  .base.init = wbxng_init_rx,
+  .base.set_freq = wbxng_set_freq,
+  .base.set_gain = wbxng_set_gain_rx,
+  .base.set_tx_enable = 0,
+  .base.atr_mask = RXBB_EN | RX2_RX1N,
+  .base.atr_txval = RX2_RX1N,
+  .base.atr_rxval = RXBB_EN,
+  // .base.atr_tx_delay =
+  // .base.atr_rx_delay =
+  .base.set_antenna = 0,
+  .common.adf4350_regs_int = UINT16_C(100),
+  .common.adf4350_regs_frac = 0,
+  .common.adf4350_regs_prescaler = 1,
+  .common.adf4350_regs_mod = UINT16_C(0xfff),
+  .common.adf4350_regs_10_bit_r_counter = UINT16_C(1),
+  .common.adf4350_regs_divider_select = 0,
+  .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0,
+  .common.spi_mask = SPI_SS_RX_DB,
+  .common.freq_mult = 2
+};
+
+
+struct db_wbxng_tx db_wbxng_tx = {
+  .base.dbid = 0x0052,
+  .base.is_tx = true,
+  .base.output_enables = RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF,
+  .base.used_pins = 0xFFFF,
+  .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(68.75e6),
+  .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6),
+  .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
+  .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(25),
+  .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.1),
+  .base.is_quadrature = true,
+  .base.i_and_q_swapped = false,
+  .base.spectrum_inverted = false,
+  .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
+  .base.init = wbxng_init_tx,
+  .base.set_freq = wbxng_set_freq,
+  .base.set_gain = wbxng_set_gain_tx,
+  .base.set_tx_enable = wbxng_set_tx_enable,
+  .base.atr_mask = RX_TXN | TXMOD_EN,
+  .base.atr_txval = TXMOD_EN,
+  .base.atr_rxval = RX_TXN,
+  // .base.atr_tx_delay =
+  // .base.atr_rx_delay =
+  .base.set_antenna = 0,
+  .common.adf4350_regs_int = UINT16_C(100),
+  .common.adf4350_regs_frac = 0,
+  .common.adf4350_regs_prescaler = 1,
+  .common.adf4350_regs_mod = UINT16_C(0xfff),
+  .common.adf4350_regs_10_bit_r_counter = UINT16_C(1),
+  .common.adf4350_regs_divider_select = 0,
+  .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0,
+  .common.spi_mask = SPI_SS_TX_DB,
+  .common.freq_mult = 2
+};
+
+
+bool
+wbxng_init_tx(struct db_base *dbb)
+{
+  //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+  clocks_enable_tx_dboard(true, 0);
+  hal_gpio_write( GPIO_TX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 );
+
+  adf4350_init(dbb);
+
+  // Set the freq now to get the one time 10ms delay out of the way.
+  u2_fxpt_freq_t       dc;
+  dbb->set_freq(dbb, dbb->freq_min, &dc);
+  return true;
+}
+
+bool
+wbxng_init_rx(struct db_base *dbb)
+{
+  //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+  clocks_enable_rx_dboard(true, 0);
+  hal_gpio_write( GPIO_RX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 );
+
+  adf4350_init(dbb);
+
+  // test gain
+  dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(20.0));
+
+  // Set the freq now to get the one time 10ms delay out of the way.
+  u2_fxpt_freq_t       dc;
+  dbb->set_freq(dbb, dbb->freq_min, &dc);
+
+  return true;
+}
+
+bool
+wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
+{
+  // clamp freq
+  u2_fxpt_freq_t clamp_freq = max(dbb->freq_min, min(freq, dbb->freq_max));
+  //printf("Requested LO freq = %u", (uint32_t) ((clamp_freq >> U2_FPF_RP)/1000));
+  bool ok = adf4350_set_freq(clamp_freq<<1,dbb);
+  *dc = adf4350_get_freq(dbb)>>1;
+
+  return ok;
+}
+
+bool
+wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain)
+{
+  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+  // clamp gain
+  //gain = max(db->gain_min, min(gain, db->gain_max));
+
+  int offset_q8 = (int)(1.4/3.3*4096*(1<<15));
+  int range_q15 = (int)(-0.9*4096/3.3*256*128);
+  int slope_q8 = range_q15/db->base.gain_max;
+
+  int dacword = ((slope_q8 * gain) + offset_q8)>>15;
+  //printf("DACWORD 0x%x\n",dacword);
+  lsdac_write_tx(0,dacword);
+  return true;
+}
+
+bool
+wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain)
+{
+  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+  // clamp gain
+  //gain = max(db->gain_min, min(gain, db->gain_max));
+
+  int iobits = (int) ((~((db->base.gain_max - gain) << 2)) & ATTN_MASK);
+  //printf("gain %d, gainmax %d, RX_ATTN_MASK = 0x%x, RX_ATTN_WORD = 0x%x\n", gain, db->base.gain_max, (int) (ATTN_MASK), (int) (iobits));
+
+  hal_gpio_write( GPIO_RX_BANK, (int) (iobits), ATTN_MASK );
+  return true;
+}
+
+
+bool
+wbxng_set_tx_enable(struct db_base *dbb, bool on)
+{
+  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+  // FIXME
+
+  return false;
+}
+
+bool
+wbxng_lock_detect(struct db_base *dbb)
+{
+  struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb;
+
+  int pins;
+  pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
+  if(pins & PLL_LOCK_DETECT)
+    //printf("Got Locked Status from Synth");
+    return true;
+
+  //printf("Got Unlocked Status from Synth");
+  return false;
+}
+
diff --git a/usrp2/firmware/lib/db_wbxng.h b/usrp2/firmware/lib/db_wbxng.h
new file mode 100644 (file)
index 0000000..3756e6c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DB_WBXNG_H
+#define DB_WBXNG_H
+
+#include <db_base.h>
+
+// IO Pin functions
+// Tx and Rx have shared defs, but different i/o regs
+#define ENABLE_5        (1 << 7)              // enables 5.0V power supply
+#define ENABLE_33       (1 << 6)              // enables 3.3V supply
+//#define RX_TXN          (1 << 15)             // Tx only: T/R antenna switch for TX/RX port
+//#define RX2_RX1N        (1 << 15)             // Rx only: antenna switch between RX2 and TX/RX port
+#define RX_TXN          ((1 << 5)|(1 << 15))  // Tx only: T/R antenna switch for TX/RX port
+#define RX2_RX1N        ((1 << 5)|(1 << 15))  // Rx only: antenna switch between RX2 and TX/RX port
+#define RXBB_EN         (1 << 4)
+#define TXMOD_EN        (1 << 4)
+#define PLL_CE          (1 << 3)
+#define PLL_PDBRF       (1 << 2)
+#define PLL_MUXOUT      (1 << 1)
+#define PLL_LOCK_DETECT (1 << 0)
+
+// RX Attenuator constants
+#define ATTN_SHIFT     8
+#define ATTN_MASK      (63 << ATTN_SHIFT)
+
+struct db_wbxng_common {
+  // RFX common stuff
+  uint16_t adf4350_regs_int;
+  uint16_t adf4350_regs_frac;
+  uint8_t adf4350_regs_prescaler;
+  uint16_t adf4350_regs_mod;
+  uint16_t adf4350_regs_10_bit_r_counter;
+  uint8_t adf4350_regs_divider_select;
+  uint8_t adf4350_regs_8_bit_band_select_clock_divider_value;
+
+  int freq_mult;
+  int spi_mask;
+};
+
+struct db_wbxng_dummy {
+  struct db_base       base;
+  struct db_wbxng_common       common;
+};
+
+
+struct db_wbxng_rx {
+  struct db_base       base;
+  struct db_wbxng_common       common;
+};
+
+struct db_wbxng_tx {
+  struct db_base       base;
+  struct db_wbxng_common       common;
+};
+
+
+#endif /* DB_WBXNG_H */
index ffdf8d66073102dac7a347acffe10b04b8a83823..4cdcf031eab8ca4a35b668ecb58f6d1b3be46d33 100644 (file)
@@ -64,6 +64,8 @@ bool xcvr2450_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *
 bool xcvr2450_set_gain_rx(struct db_base *db, u2_fxpt_gain_t gain);
 bool xcvr2450_set_gain_tx(struct db_base *db, u2_fxpt_gain_t gain);
 bool xcvr2450_set_tx_enable(struct db_base *db, bool on);
+bool xcvr2450_set_rx_antenna(struct db_base *db, int ant);
+bool xcvr2450_set_tx_antenna(struct db_base *db, int ant);
 
 struct db_xcvr2450_common {
   int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig;
@@ -154,6 +156,7 @@ struct db_xcvr2450_rx db_xcvr2450_rx = {
   .base.atr_mask = RX_ATR_MASK,
   .base.atr_txval = 0x0,
   .base.atr_rxval = 0x0,
+  .base.set_antenna = xcvr2450_set_rx_antenna,
   .common = &db_xcvr2450_common,
 };
 
@@ -178,6 +181,7 @@ struct db_xcvr2450_tx db_xcvr2450_tx = {
   .base.atr_mask = TX_ATR_MASK,
   .base.atr_txval = 0x0,
   .base.atr_rxval = 0x0,
+  .base.set_antenna = xcvr2450_set_tx_antenna,
   .common = &db_xcvr2450_common,
 };
 
@@ -250,8 +254,8 @@ static void
 set_reg_lpf(struct db_xcvr2450_dummy *db){
   int reg_lpf = (
     (db->common->d_rssi_hbw<<15)  |
-    (db->common->d_txlpf_bw<<10)  |
-    (db->common->d_rxlpf_bw<<9)   |
+    (db->common->d_txlpf_bw<<9)  |
+    (db->common->d_rxlpf_bw<<7)   |
     (db->common->d_rxlpf_fine<<4) | 7);
   send_reg(reg_lpf);
 }
@@ -494,3 +498,24 @@ xcvr2450_set_tx_enable(struct db_base *dbb, bool on){
   set_gpio(db);
   return true;
 }
+
+/**************************************************
+ * Set Antennas
+ **************************************************/
+bool xcvr2450_set_rx_antenna(struct db_base *dbb, int ant){
+    printf("xcvr set rx ant %d\n", ant);
+    if (ant > 1) return false;
+    struct db_xcvr2450_dummy *db = (struct db_xcvr2450_dummy *) dbb;
+    db->common->d_rx_ant = ant;
+    set_gpio(db);
+    return true;
+}
+
+bool xcvr2450_set_tx_antenna(struct db_base *dbb, int ant){
+    printf("xcvr set tx ant %d\n", ant);
+    if (ant > 1) return false;
+    struct db_xcvr2450_dummy *db = (struct db_xcvr2450_dummy *) dbb;
+    db->common->d_tx_ant = ant;
+    set_gpio(db);
+    return true;
+}
index 8f774d9162bfe090b6ceaf380b76d35fb2c9268b..96484d577bd36a901dfb8a5a1a08d7e6dfc26c0b 100644 (file)
@@ -62,7 +62,8 @@ dbsm_init(dbsm_t *sm, int buf0,
 
   // How much to adjust the last_line register.
   // It's 1 for everything but the ethernet.
-  sm->last_line_adj = recv->port == PORT_ETH ? 3 : 1;
+  //sm->last_line_adj = recv->port == PORT_ETH ? 3 : 1;
+  sm->last_line_adj = 1;
 
   buffer_state[sm->buf0] = BS_EMPTY;
   buffer_state[sm->buf0 ^ 1] = BS_EMPTY;
index 5fadaf40bd987dcd957a3913a56ec5e968d52c6d..88051dca0e926e04563a8be2a867efabbeb043c0 100644 (file)
 #include "bool.h"
 #include "eth_phy.h"   // for simulation constants
 #include "mdelay.h"
-
+#include "stdio.h"
 
 #define PHY_ADDR 1
 
 void
 eth_mac_set_addr(const u2_mac_addr_t *src)
 {
-  int i;
-
-  // tell mac our source address and enable automatic insertion on Tx.
-  eth_mac->mac_tx_add_prom_wr = 0;     // just in case
-  for (i = 0; i < 6; i++){
-    eth_mac->mac_tx_add_prom_add = i;
-    eth_mac->mac_tx_add_prom_data = src->addr[i];
-    eth_mac->mac_tx_add_prom_wr = 1;
-    mdelay(1);
-    eth_mac->mac_tx_add_prom_wr = 0;
-    mdelay(1);
-  }
-  eth_mac->mac_tx_add_en = 1;  // overwrite pkt src addr field with this stuff
-
-  // set up receive destination address filter
-  eth_mac->mac_rx_add_prom_wr = 0;     // just in case
-  for (i = 0; i < 6; i++){
-    eth_mac->mac_rx_add_prom_add = i;
-    eth_mac->mac_rx_add_prom_data = src->addr[i];
-    eth_mac->mac_rx_add_prom_wr = 1;
-    mdelay(1);
-    eth_mac->mac_rx_add_prom_wr = 0;
-    mdelay(1);
-  }
-  // eth_mac->mac_rx_add_chk_en = 1;  // FIXME enable when everything's working
+  eth_mac->ucast_hi = 
+    (((unsigned int)src->addr[0])<<8) + 
+    ((unsigned int)src->addr[1]);
+  eth_mac->ucast_lo = 
+    (((unsigned int)src->addr[2])<<24) + 
+    (((unsigned int)src->addr[3])<<16) +
+    (((unsigned int)src->addr[4])<<8) +
+    (((unsigned int)src->addr[5]));
 }
 
 
@@ -62,14 +45,18 @@ eth_mac_init(const u2_mac_addr_t *src)
   eth_mac->miimoder = 25;      // divider from CPU clock (50MHz/25 = 2MHz)
 
   eth_mac_set_addr(src);
+  eth_mac->settings = MAC_SET_PAUSE_EN | MAC_SET_PASS_BCAST | MAC_SET_PASS_UCAST | MAC_SET_PAUSE_SEND_EN; 
+
+  eth_mac->pause_time = 38;
+  eth_mac->pause_thresh = 1200;
 
   // set rx flow control high and low water marks
   // unsigned int lwmark = (2*2048 + 64)/4; // 2 * 2048-byte frames + 1 * 64-byte pause frame
   // eth_mac->fc_hwmark = lwmark + 2048/4;  // plus a 2048-byte frame
 
-  eth_mac->fc_lwmark = 600;            // there are currently 2047 lines in the fifo
-  eth_mac->fc_hwmark = 1200;
-  eth_mac->fc_padtime = 1700;           // how long before flow control runs out do we 
+  //  eth_mac->fc_lwmark = 600;                // there are currently 2047 lines in the fifo
+  // eth_mac->fc_hwmark = 1200;
+  //eth_mac->fc_padtime = 1700;           // how long before flow control runs out do we 
                                         // request a re-pause.  Units of 8ns (bytes)
 
   //eth_mac->tx_pause_en = 0;          // pay attn to pause frames sent to us
@@ -80,8 +67,8 @@ eth_mac_init(const u2_mac_addr_t *src)
 int
 eth_mac_read_rmon(int addr)
 {
-  int t;
-  
+  int t = 0;
+  /*  
   eth_mac->rmon_rd_addr = addr;
   eth_mac->rmon_rd_apply = 1;
   while(eth_mac->rmon_rd_grant == 0)
@@ -89,6 +76,7 @@ eth_mac_read_rmon(int addr)
 
   t = eth_mac->rmon_rd_dout;
   eth_mac->rmon_rd_apply = 0;
+  */
   return t;
 }
 
@@ -111,7 +99,9 @@ eth_mac_miim_read(int addr)
   while((eth_mac->miistatus & MIIS_BUSY) != 0)
     ;
 
-  return eth_mac->miirx_data;
+  int r = eth_mac->miirx_data;
+  //printf("MIIM-READ ADDR 0x%x DATA 0x%x\n",addr, r);
+  return r;
 }
 
 void
@@ -122,6 +112,7 @@ eth_mac_miim_write(int addr, int value)
   eth_mac->miitx_data = value;
   eth_mac->miicommand = MIIC_WCTRLDATA;
 
+  //printf("MIIM-WRITE ADDR 0x%x VAL 0x%x\n",addr,value);
   while((eth_mac->miistatus & MIIS_BUSY) != 0)
     ;
 }
index 8daab937d4fb760dd2283212e289f5b065c5ab12..d680f8de0bb2a7b715f0171799ab611e91869269 100644 (file)
 #define INCLUDED_ETH_MAC_REGS_H
 
 /*
- * See opencores.org 10_100_1000 Mbps Tri-mode Ethernet MAC Specification
+ * Simple GEMAC
  *
- * In reality, these are 16-bit regs, but are assigned
- * on 32-bit boundaries.  Because we're little endian,
- * declaring them "int" works.
  */
 typedef struct {
-  volatile int tx_hwmark;
-  volatile int tx_lwmark;
-
-  //! if set, send pause frames automatically
-  volatile int pause_frame_send_en;
-
-  //! quanta value for pause frame in units of 512 bit times.
-  volatile int pause_quanta_set;
-
-  volatile int ifg_set;
-  volatile int full_duplex;
-  volatile int max_retry;
-  volatile int mac_tx_add_en;
-  volatile int mac_tx_add_prom_data;
-  volatile int mac_tx_add_prom_add;
-  volatile int mac_tx_add_prom_wr;
-
-  //! if set, other end can pause us (i.e., we pay attention to pause frames)
-  volatile int tx_pause_en;
-
-  // Flow Control high and low water marks
-  //! when space available (in 32-bit lines) > hwmark, send un-pause frame
-  volatile int fc_hwmark;      
-
-  //! when space avail (in 32-bit lines) < lwmark, send pause frame
-  volatile int fc_lwmark;      
-
-  volatile int mac_rx_add_chk_en;
-  volatile int mac_rx_add_prom_data;
-  volatile int mac_rx_add_prom_add;
-  volatile int mac_rx_add_prom_wr;
-  volatile int broadcast_filter_en;
-  volatile int broadcast_bucket_depth;
-  volatile int broadcast_bucket_interval;
-  volatile int rx_append_crc;
-  volatile int rx_hwmark;
-  volatile int rx_lwmark;
-  volatile int crc_chk_en;
-  volatile int rx_ifg_set;
-  volatile int rx_max_length;
-  volatile int rx_min_length;
-  volatile int rmon_rd_addr;           // performance counter access
-  volatile int rmon_rd_apply;          
-  volatile int rmon_rd_grant;          // READONLY
-  volatile int rmon_rd_dout;           // READONLY
-  volatile int dummy;  // READONLY
-  volatile int line_loop_en;
-  volatile int speed;
-  volatile int miimoder;
-  volatile int miicommand;
-  volatile int miiaddress;
-  volatile int miitx_data;
-  volatile int miirx_data;
-  volatile int miistatus;
-  volatile int fc_padtime;
+  volatile int settings;
+  volatile int ucast_hi;
+  volatile int ucast_lo;
+  volatile int mcast_hi;
+  volatile int mcast_lo;
+  volatile int miimoder;
+  volatile int miiaddress;
+  volatile int miitx_data;
+  volatile int miicommand;
+  volatile int miistatus;
+  volatile int miirx_data;
+  volatile int pause_time;
+  volatile int pause_thresh;
 } eth_mac_regs_t;
 
+// settings register
+#define MAC_SET_PAUSE_EN  (1 << 0)   // Makes us respect received pause frames (normally on)
+#define MAC_SET_PASS_ALL  (1 << 1)   // Enables promiscuous mode, currently broken
+#define MAC_SET_PASS_PAUSE (1 << 2)  // Sends pause frames through (normally off)
+#define MAC_SET_PASS_BCAST (1 << 3)  // Sends broadcast frames through (normally on)
+#define MAC_SET_PASS_MCAST (1 << 4)  // Sends multicast frames that match mcast addr (normally off)
+#define MAC_SET_PASS_UCAST (1 << 5)  // Sends unicast (normal) frames through if they hit in address filter (normally on)
+#define MAC_SET_PAUSE_SEND_EN (1 << 6) // Enables sending pause frames
+
 // miicommand register
 #define MIIC_SCANSSTAT (1 << 0)        // Scan status
 #define MIIC_RSTAT      (1 << 1)       // Read status
index d19287044b5bdea518e97d974988594b40e09422..f554e0179cabbf9e47ea52b667e27a6223c51ebb 100644 (file)
@@ -43,6 +43,8 @@ ethernet_register_link_changed_callback(ethernet_link_changed_callback_t new_cal
 static void
 ed_set_mac_speed(int speed)
 {
+  printf("Speed set to %d\n",speed);
+  /*
   switch(speed){
   case 10:
     eth_mac->speed = 1;
@@ -56,6 +58,7 @@ ed_set_mac_speed(int speed)
   default:
     break;
   }
+  */
 }
 
 static void
@@ -196,17 +199,17 @@ ethernet_init(void)
   ed_state.link_speed = S_UNKNOWN;
 
   // initialize MAC registers
-  eth_mac->tx_hwmark = 0x1e;
-  eth_mac->tx_lwmark = 0x19;
+  //  eth_mac->tx_hwmark = 0x1e;
+  //eth_mac->tx_lwmark = 0x19;
 
-  eth_mac->crc_chk_en = 1;
-  eth_mac->rx_max_length = 2048;
+  //eth_mac->crc_chk_en = 1;
+  //eth_mac->rx_max_length = 2048;
 
   // configure PAUSE frame stuff
-  eth_mac->tx_pause_en = 1;            // pay attn to pause frames sent to us
+  //eth_mac->tx_pause_en = 1;          // pay attn to pause frames sent to us
 
-  eth_mac->pause_quanta_set = 38;      // a bit more than 1 max frame 16kb/512 + fudge
-  eth_mac->pause_frame_send_en = 1;    // enable sending pause frames
+  //eth_mac->pause_quanta_set = 38;    // a bit more than 1 max frame 16kb/512 + fudge
+  //eth_mac->pause_frame_send_en = 1;  // enable sending pause frames
 
 
   // setup PHY to interrupt on changes
@@ -256,6 +259,10 @@ ethernet_init(void)
   t &= ~(NWAY_AR_10T_HD_CAPS | NWAY_AR_10T_FD_CAPS | NWAY_AR_100TX_HD_CAPS | NWAY_AR_100TX_FD_CAPS);
 
   eth_mac_miim_write(PHY_AUTONEG_ADV, t);
+  int r = eth_mac_miim_read(PHY_AUTONEG_ADV);                  // DEBUG, read back
+  if (t != r){
+    printf("PHY_AUTONEG_ADV: wrote 0x%x, got 0x%x\n", t, r);
+  }
 
   // Restart autonegotation.  
   // We want to ensure that we're advertising our PAUSE capabilities.
@@ -322,6 +329,7 @@ ethernet_check_errors(void)
   // these registers are reset when read
   
   int  r = 0;
+  /*
   if (eth_mac_read_rmon(0x05) != 0)
     r |= RME_RX_CRC;
   if (eth_mac_read_rmon(0x06) != 0)
@@ -335,6 +343,6 @@ ethernet_check_errors(void)
     r |= RME_TX_FIFO_UNDER;
   if (eth_mac_read_rmon(0x27) != 0)
     r |= RME_TX_FIFO_OVER;
-
+  */
   return r;
 }
index 78a4330d2ffce689f267ba9f3702f834164bcbea..0d0cf04f6853e5bdc128be550fa11e19a58e24cf 100644 (file)
@@ -175,6 +175,10 @@ typedef struct {
   volatile uint32_t last_line[NBUFFERS]; // last line xfer'd in buffer
   volatile uint32_t status;             // error and done flags
   volatile uint32_t hw_config;          // see below
+  volatile uint32_t dummy[3];
+  volatile uint32_t irqs;
+  volatile uint32_t pri_enc_bp_status;
+  volatile uint32_t cycle_count;
 } buffer_pool_status_t;
 
 #define buffer_pool_status ((buffer_pool_status_t *) BUFFER_POOL_STATUS_BASE)
diff --git a/usrp2/firmware/lib/printf.c.smaller b/usrp2/firmware/lib/printf.c.smaller
new file mode 100644 (file)
index 0000000..4d85864
--- /dev/null
@@ -0,0 +1,134 @@
+/* -*- c -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on code from the SDCC z80 library ;)
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <hal_io.h>            /* FIXME refactor into stdio */
+
+#define PUTCHAR(x) hal_putc(x)
+
+
+static void 
+_printn(unsigned u, unsigned base, char issigned)
+{
+  const char *_hex = "0123456789ABCDEF";
+  if (issigned && ((int)u < 0)) {
+    PUTCHAR('-');
+    u = (unsigned)-((int)u);
+  }
+  if (u >= base)
+    _printn(u/base, base, 0);
+  PUTCHAR(_hex[u%base]);
+}
+
+static void 
+_printf(const char *format, va_list va)
+{
+  while (*format) {
+    if (*format != '%')
+      PUTCHAR(*format);
+    else {
+      switch (*++format) {
+      case 0:                  /* hit end of format string */
+       return;
+      case 'c':
+       {
+         char c = (char)va_arg(va, int);
+         PUTCHAR(c);
+         break;
+       }
+      case 'u':
+       {
+         unsigned u = va_arg(va, unsigned);
+         _printn(u, 10, 0);
+         break;
+       }
+      case 'd':
+       {
+         unsigned u = va_arg(va, unsigned);
+         _printn(u, 10, 1);
+         break;
+       }
+      case 'x':
+      case 'p':
+       {
+         unsigned u = va_arg(va, unsigned);
+         _printn(u, 16, 0);
+         break;
+       }
+      case 's':
+       {
+         char *s = va_arg(va, char *);
+         while (*s) {
+           PUTCHAR(*s);
+           s++;
+         }
+         break;
+       }
+      }
+    }
+    format++;
+  }
+}
+
+#if 0
+static void 
+_char_emitter(char c, void *pData __attribute__((unused)))
+{
+  hal_putc(c);
+}
+#endif
+
+int 
+printf(const char *format, ...)
+{
+  va_list va;
+  va_start(va, format);
+
+  _printf(format, va);
+
+  // wrong return value...
+  return 0;
+}
+
+
+#if 0
+
+// Totally dangerous.  Don't use
+static void 
+_buf_emitter(char c, void *pData)
+{
+  *((*((char **)pData)))++ = c;
+}
+
+int sprintf(char *pInto, const char *format, ...)
+{
+  va_list va;
+  va_start(va, format);
+
+  _printf(format, _buf_emitter, &pInto, va);
+  *pInto++ = '\0';
+
+  // FIXME wrong return value
+  return 0;
+}
+#endif
diff --git a/usrp2/firmware/u2_flash_tool b/usrp2/firmware/u2_flash_tool
new file mode 100755 (executable)
index 0000000..2b66a4a
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+import sys
+from optparse import OptionParser
+
+SECTOR_SIZE = 512                 # bytes
+MAX_FILE_SIZE =  1 * (2**20)      # maximum number of bytes we'll burn to a slot
+
+FPGA_OFFSET = 0                   # offset in flash to fpga image
+FIRMWARE_OFFSET = 1 * (2**20)     # offset in flash to firmware image
+
+def read_file_data(filename):
+    f = open(filename, "rb")
+    file_data = f.read(MAX_FILE_SIZE)
+    t = len(file_data) % SECTOR_SIZE
+    if t != 0:
+        file_data += (SECTOR_SIZE - t)*chr(0)  # pad to an even sector size w/ zeros
+    return file_data
+
+
+def write_flash(offset, filename, devname):
+    file_data = read_file_data(filename)
+    dev = open(devname, "wb")
+    dev.seek(offset, 0)                 # seek to absolute byte offset
+    dev.write(file_data)
+    dev.flush()
+    dev.close()
+    return True
+
+
+def verify_flash(offset, filename, devname):
+    file_data = read_file_data(filename)
+    dev = open(devname, "rb")
+    dev.seek(offset, 0)                 # seek to absolute byte offset
+    dev_data = dev.read(len(file_data))
+    if len(dev_data) != len(file_data):
+        sys.stderr.write("short read on device %s\n" % (devname,))
+        return False
+
+    if file_data == dev_data:
+        return True
+
+    # doesn't match
+    nwrong = 0
+    for i in range(len(file_data)):
+        if dev_data[i] != file_data[i]:
+            sys.stderr.write("mismatch at offset %7d.  Expected 0x%02x, got 0x%02x\n" % (
+                i, ord(file_data[i]), ord(dev_data[i])))
+            nwrong += 1
+            if nwrong > 16:
+                sys.stderr.write("> 16 errors, stopping comparison\n")
+                break
+    return False
+
+def read_flash(offset, filename, devname):
+    dev = open(devname, "rb")
+    dev.seek(offset, 0)                 # seek to absolute byte offset
+    dev_data = dev.read(MAX_FILE_SIZE)
+    dev.close()
+    open(filename, "wb").write(dev_data)
+
+    
+def main():
+    parser = OptionParser(usage="%prog: [options] filename")
+    parser.add_option("-w", "--write", action="store_const", const="write", dest="mode",
+                      help="write FILE to TARGET slot")
+    parser.add_option("-v", "--verify",  action="store_const", const="verify", dest="mode",
+                      help="verify FILE against TARGET slot")
+    parser.add_option("-r", "--read",  action="store_const", const="read", dest="mode",
+                      help="read TARGET slot, write to FILE")
+    parser.add_option("-t", "--target", type="choice", choices=("fpga", "s/w"), default="s/w",
+                      help="select TARGET slot from: fpga, s/w [default=%default]")
+    parser.add_option("", "--dev", default=None,
+                      help="specify flash device file, e.g., /dev/sdb.  Be careful!")
+    parser.set_defaults(target="s/w", mode=None)
+
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        raise SystemExit
+
+    filename = args[0]
+
+    if options.mode is None:
+        sys.stderr.write("specify mode with -w, -v or -r\n")
+        parser.print_help()
+        raise SystemExit
+
+    if options.dev is None:
+        sys.stderr.write("specify the device file with --dev\n")
+        parser.print_help()
+        raise SystemExit
+
+    offset = { "fpga" : FPGA_OFFSET, "s/w" : FIRMWARE_OFFSET }[options.target]
+    
+    if options.mode == "write":
+        r = (write_flash(offset, filename, options.dev)
+             and verify_flash(offset, filename, options.dev))
+    elif options.mode == "verify":
+        r = verify_flash(offset, filename, options.dev)
+    elif options.mode == "read":
+        r = read_flash(offset, filename, options.dev)
+    else:
+        raise NotImplemented
+
+    if not r:
+        raise SystemExit, 1
+
+
+if __name__ == "__main__":
+    main()
+
+    
+
+
+    
diff --git a/usrp2/fpga/README b/usrp2/fpga/README
new file mode 100644 (file)
index 0000000..802b984
--- /dev/null
@@ -0,0 +1,3 @@
+The FPGA directory that used to be here is now hosted at:
+
+git://ettus.sourcerepo.com/ettus/fpga.git
diff --git a/usrp2/host/.gitignore b/usrp2/host/.gitignore
new file mode 100644 (file)
index 0000000..605b6fe
--- /dev/null
@@ -0,0 +1,20 @@
+/configure
+/Makefile.in
+/config.log
+/config.status
+/config.guess
+/stamp-h1
+/config.h
+/ltmain.sh
+/config.sub
+/config.h.in
+/libtool
+/autom4te.cache
+/missing
+/aclocal.m4
+/Makefile
+/install-sh
+/depcomp
+/usrp2*.tar.gz
+/py-compile
+/usrp2.pc
diff --git a/usrp2/host/apps/.gitignore b/usrp2/host/apps/.gitignore
new file mode 100644 (file)
index 0000000..4b66ac0
--- /dev/null
@@ -0,0 +1,16 @@
+/Makefile
+/Makefile.in
+/.libs
+/.deps
+/test_eth
+/test_usrp2
+/gen_const
+/find_usrps
+/cerr
+/*.sh
+/tx_samples
+/rx_streaming_samples
+/u2_burn_mac_addr
+/usrp2_burn_mac_addr
+/test_mimo_tx
+/gpio
index db76601967611015358a0b1ca1ce8dbe22aa5d6d..4a26898fa7d9f5303f7b3f91ec5bc648d79ff9ee 100644 (file)
@@ -24,9 +24,8 @@ AM_CPPFLAGS = \
     $(GRUEL_INCLUDES)
 
 LDADD = \
-       $(USRP2_LA) \
-       $(GRUEL_LA) \
-        $(OMNITHREAD_LA)
+    $(USRP2_LA) \
+    $(GRUEL_LA)
 
 bin_PROGRAMS = \
        find_usrps \
diff --git a/usrp2/host/apps/bitrot/rx_samples.cc b/usrp2/host/apps/bitrot/rx_samples.cc
new file mode 100644 (file)
index 0000000..c1c3b59
--- /dev/null
@@ -0,0 +1,382 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "usrp2_basic.h"
+#include <iostream>
+#include <complex>
+#include <getopt.h>
+#include <string.h>
+#include "strtod_si.h"
+#include <signal.h>
+#include <stdexcept>
+#include "gri_if_stats.h"
+#include <gr_realtime.h>
+
+
+typedef std::complex<float> fcomplex;
+
+static volatile bool signaled = false;
+
+static void 
+sig_handler(int sig)
+{
+  signaled = true;
+}
+
+static void
+install_sig_handler(int signum,
+                   void (*new_handler)(int))
+{
+  struct sigaction new_action;
+  memset (&new_action, 0, sizeof (new_action));
+
+  new_action.sa_handler = new_handler;
+  sigemptyset (&new_action.sa_mask);
+  new_action.sa_flags = 0;
+
+  if (sigaction (signum, &new_action, 0) < 0){
+    perror ("sigaction (install new)");
+    throw std::runtime_error ("sigaction");
+  }
+}
+
+
+/*
+ * Vectorize me!
+ */
+void
+convert_samples_to_complex(size_t nsamples,
+                          uint32_t *i_samples,
+                          fcomplex *c_samples)
+{
+  uint32_t *p = i_samples;
+  for (size_t i = 0; i < nsamples; i++){
+    int16_t  si = ((int16_t) (p[i] >> 16));
+    int16_t  sq = ((int16_t) (p[i] & 0xffff));
+    c_samples[i] = fcomplex((float) si, (float) sq);
+  }
+}
+
+
+static void
+usage(const char *progname)
+{
+  const char *p = strrchr(progname, '/');      // drop leading directory path
+  if (p)
+    p++;
+
+  if (strncmp(p, "lt-", 3) == 0)               // drop lt- libtool prefix
+    p += 3;
+  
+  fprintf(stderr, "Usage: %s [options]\n\n", p);
+  fprintf(stderr, "Options:\n");
+  fprintf(stderr, "  -h                   show this message and exit\n");
+  fprintf(stderr, "  -e ETH_INTERFACE     specify ethernet interface [default=eth0]\n");
+  fprintf(stderr, "  -m MAC_ADDR          mac address of USRP2 HH:HH [default=first one found]\n");
+  fprintf(stderr, "  -o OUTPUT_FILE       set output filename [default=NONE]\n");
+  fprintf(stderr, "  -f FREQ              set frequency to FREQ [default=0]\n");
+  fprintf(stderr, "  -d DECIM             set decimation rate to DECIM [default=32]\n");
+  fprintf(stderr, "  -N NSAMPLES          total number of samples to receive [default=2.5e6]\n");
+  fprintf(stderr, "  -F SAMPLES_PER_FRAME number of samples in each frame [default=371]\n");
+  fprintf(stderr, "  -S SCALE             fpga scaling factor for I & Q [default=1024]\n");
+  fprintf(stderr, "  -M DONT_LOCK|LOCK_TO_SMA|LOCK_TO_MIMO   specify MIMO clock source\n");
+  fprintf(stderr, "  -P                   provide clock to MIMO connector\n");
+}
+
+struct pkt_info {
+  int          d_nsamples;
+  int          d_timestamp;
+  unsigned int d_seqno;
+
+  pkt_info(int nsamples, int timestamp, int seqno)
+    : d_nsamples(nsamples),
+      d_timestamp(timestamp),
+      d_seqno(seqno) {}
+};
+
+int
+main(int argc, char **argv)
+{
+
+  // options and their defaults
+  const char *interface = "eth0";
+  const char *mac_addr_str = 0;
+  const char *output_filename = 0;
+  double freq = 0;
+  int32_t decim = 32;
+  int32_t nsamples = static_cast<int32_t>(2.5e6);
+  int32_t samples_per_frame = 371;
+  int32_t scale = 1024;
+  int    mimo_config = MC_WE_DONT_LOCK;
+  bool   provide_clock = false;
+
+  int    ch;
+  double tmp;
+  u2_mac_addr_t mac_addr;
+
+  setvbuf(stdout, 0, _IOFBF, 64 * 1024); // make stdout fully buffered
+
+  while ((ch = getopt(argc, argv, "he:m:o:f:d:N:F:S:M:P")) != EOF){
+    switch (ch){
+
+    case 'e':
+      interface = optarg;
+      break;
+      
+    case 'm':
+      mac_addr_str = optarg;
+      if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){
+       std::cerr << "invalid mac addr: " << optarg << std::endl;
+       usage(argv[0]);
+       exit(1);
+      }
+      break;
+
+    case 'o':
+      output_filename = optarg;
+      break;
+      
+    case 'f':
+      if (!strtod_si(optarg, &freq)){
+       std::cerr << "invalid number: " << optarg << std::endl;
+       usage(argv[0]);
+       exit(1);
+      }
+      break;
+
+    case 'N':
+      if (!strtod_si(optarg, &tmp)){
+       std::cerr << "invalid number: " << optarg << std::endl;
+       usage(argv[0]);
+       exit(1);
+      }
+      nsamples = static_cast<int32_t>(tmp);
+      break;
+
+    case 'F':
+      samples_per_frame = strtol(optarg, 0, 0);
+      break;
+
+    case 'd':
+      decim = strtol(optarg, 0, 0);
+      break;
+
+    case 'S':
+      if (!strtod_si(optarg, &tmp)){
+       std::cerr << "invalid number: " << optarg << std::endl;
+       usage(argv[0]);
+       exit(1);
+      }
+      scale = static_cast<int32_t>(tmp);
+      break;
+      
+    case 'M':
+      if (strcmp(optarg, "DONT_LOCK") == 0)
+       mimo_config = MC_WE_DONT_LOCK;
+      else if (strcmp(optarg, "LOCK_TO_SMA") == 0)
+       mimo_config = MC_WE_LOCK_TO_SMA;
+      else if (strcmp(optarg, "LOCK_TO_MIMO") == 0)
+       mimo_config = MC_WE_LOCK_TO_MIMO;
+      else {
+       usage(argv[0]);
+       exit(1);
+      }
+      break;
+
+    case 'P':
+      provide_clock = true;
+      break;
+
+    case 'h':
+    default:
+      usage(argv[0]);
+      exit(1);
+    }
+  }
+  
+  if (argc - optind != 0){
+    usage(argv[0]);
+    exit(1);
+  }
+
+  FILE *of = 0;
+  if (output_filename)
+    of = fopen(output_filename, "wb");
+
+  usrp2_basic *u2 = new usrp2_basic();
+
+  if (!u2->open(interface)){
+    std::cerr << "couldn't open " << interface << std::endl;
+    return 0;
+  }
+
+
+  install_sig_handler(SIGINT, sig_handler);
+  if (1){
+    install_sig_handler(SIGALRM, sig_handler);
+    alarm(5);
+  }
+
+  
+  std::vector<op_id_reply_t> r = u2->find_usrps();
+
+  for (size_t i = 0; i < r.size(); i++){
+    std::cout << r[i] << std::endl;
+  }
+
+  if (r.size() == 0){
+    std::cerr << "No USRP2 found.\n";
+    return 1;
+  }
+
+  u2_mac_addr_t which = r[0].addr;     // pick the first one
+
+
+  gr_rt_status_t rt = gr_enable_realtime_scheduling();
+  if (rt != RT_OK)
+    std::cerr << "failed to enable realtime scheduling\n";
+
+  if (provide_clock)
+    mimo_config |= MC_PROVIDE_CLK_TO_MIMO;
+
+  u2->config_mimo(which, mimo_confg);
+  
+
+  gri_if_stats start, stop;
+  gri_get_if_stats(interface, &start);
+
+  if (!u2->start_rx(which, freq, decim, nsamples, samples_per_frame, scale, scale)){
+    std::cerr << "start_rx failed\n";
+    return 1;
+  }
+
+
+  std::vector<pkt_info> history;
+  history.reserve(64*1024);            // preallocate 64K entries
+
+  
+  long total_samples_recvd = 0;
+
+  while (!signaled && total_samples_recvd < nsamples){
+    u2_eth_samples_t   pkt;
+    // fcomplex                c_samples[U2_MAX_SAMPLES];
+    
+    // read samples
+    int n = u2->read_samples(which, &pkt);
+    if (n <= 0)
+      break;
+    
+    total_samples_recvd += n;
+
+    history.push_back(pkt_info(n, u2p_timestamp(&pkt.hdrs.fixed), pkt.hdrs.thdr.seqno));
+
+    // convert_samples_to_complex(n, pkt.samples, c_samples);
+    // size_t r = fwrite(c_samples, sizeof(fcomplex), n, of);
+
+    if (of){
+      fwrite(pkt.samples, sizeof(uint32_t), n, of);
+      fflush(of);
+    }
+  }
+
+
+  gri_get_if_stats(interface, &stop);
+
+  if (!u2->stop_rx(which)){
+    std::cerr << "stop_rx failed\n";
+    return 1;
+  }
+
+
+  long expected_rx_packets =
+    (nsamples + samples_per_frame - 1)/samples_per_frame;
+
+  long expected_rx_bytes   =
+    expected_rx_packets * sizeof(u2_eth_packet_t) + nsamples * 4;
+
+
+  long total_pkts_recvd = 0;
+  total_samples_recvd = 0;
+
+  int nbad_seqno = 0;
+
+  for (unsigned i = 0; i < history.size(); i++){
+    total_pkts_recvd++;
+    total_samples_recvd += history[i].d_nsamples;
+
+    bool bad_seqno = history[i].d_seqno != (i & 0xff);
+    if (bad_seqno)
+      nbad_seqno++;
+    
+    printf("%3d  %8d  %8ld  %8ld  %3d %s\n",
+          history[i].d_nsamples,
+          history[i].d_timestamp,
+          total_pkts_recvd, total_samples_recvd,
+          history[i].d_seqno,
+          bad_seqno ? "BAD SEQNO" : ""
+          );
+  }
+
+  if (nbad_seqno == 0)
+    printf("\nAll sequence numbers are correct\n");
+  else
+    printf("\n%d sequence numbers were INCORRECT\n", nbad_seqno);
+    
+
+  printf("\nUser space statistics:\n");
+  printf("  rx_samples:  %8ld",     total_samples_recvd);
+  printf("   expected  %8d  %s\n",
+        nsamples,
+        nsamples - total_samples_recvd == 0 ? "OK" : "NOT OK");
+  
+  printf("  rx_packets:  %8ld",     total_pkts_recvd);
+  printf("   expected  %8ld  %s\n",
+        expected_rx_packets,
+        expected_rx_packets - total_pkts_recvd == 0 ? "OK" : "NOT OK");
+  
+
+  fflush(stdout);
+
+  printf("\nKernel interface statistics:\n");
+
+  long long delta;
+  delta = stop.rx_bytes - start.rx_bytes;
+  printf("  rx_bytes:    %8Ld",     delta);
+  printf("   expected  %8ld  %s\n",
+        expected_rx_bytes,
+        expected_rx_bytes - delta == 0 ? "OK" : "NOT OK");
+
+  delta = stop.rx_packets - start.rx_packets;
+  printf("  rx_packets:  %8Ld",     delta);
+  printf("   expected  %8ld  %s\n",
+        expected_rx_packets,
+        expected_rx_packets - delta == 0 ? "OK" : "NOT OK");
+
+  printf("  rx_errs:     %8Ld\n",   stop.rx_errs - start.rx_errs);
+  printf("  rx_drop:     %8Ld\n",   stop.rx_drop - start.rx_drop);
+  printf("  tx_bytes:    %8Ld\n",   stop.tx_bytes - start.tx_bytes);
+  printf("  tx_packets:  %8Ld\n",   stop.tx_packets - start.tx_packets);
+  printf("  tx_errs:     %8Ld\n",   stop.tx_errs - start.tx_errs);
+  printf("  tx_drop:     %8Ld\n",   stop.tx_drop - start.tx_drop);
+
+
+  return 0;
+}
diff --git a/usrp2/host/apps/gen_2tone.py b/usrp2/host/apps/gen_2tone.py
new file mode 100755 (executable)
index 0000000..ec681d3
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from gnuradio import gr, eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+master_clock = 100e6
+
+class my_top_block(gr.top_block):
+
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-f", "--freq1", type="eng_float", default=1e6,
+                          help="set waveform frequency to FREQ [default=%default]")
+        parser.add_option("-g", "--freq2", type="eng_float", default=1e6,
+                          help="set waveform frequency to FREQ [default=%default]")
+        parser.add_option ("-a", "--amplitude1", type="eng_float", default=16e3,
+                           help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL")
+        parser.add_option ("-b", "--amplitude2", type="eng_float", default=16e3,
+                           help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL")
+
+        parser.add_option("-i", "--interp", type="int", default=32,
+                          help="assume fgpa interpolation rate is INTERP [default=%default]")
+
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        
+        src0 = gr.sig_source_c(master_clock/options.interp,
+                               gr.GR_SIN_WAVE,
+                               options.freq1,
+                               options.amplitude1)
+        src1 = gr.sig_source_c(master_clock/options.interp,
+                               gr.GR_SIN_WAVE,
+                               options.freq2,
+                               options.amplitude2)
+
+       adder = gr.add_cc()
+
+        
+        c2s = gr.complex_to_interleaved_short()
+
+        stdout_sink = gr.file_descriptor_sink(gr.sizeof_short, 1)
+
+        self.connect(src0, (adder,0))
+        self.connect(src1, (adder,1))
+        self.connect(adder, c2s, stdout_sink)
+
+        
+if __name__ == '__main__':
+    try:
+        my_top_block().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/usrp2/host/apps/gen_sine.py b/usrp2/host/apps/gen_sine.py
new file mode 100755 (executable)
index 0000000..6a44dd1
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from gnuradio import gr, eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+master_clock = 100e6
+
+class my_top_block(gr.top_block):
+
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-f", "--freq", type="eng_float", default=1e6,
+                          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("-i", "--interp", type="int", default=32,
+                          help="assume fgpa interpolation rate is INTERP [default=%default]")
+
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        
+        src0 = gr.sig_source_c(master_clock/options.interp,
+                               gr.GR_SIN_WAVE,
+                               options.freq,
+                               options.amplitude)
+
+        
+        c2s = gr.complex_to_interleaved_short()
+
+        stdout_sink = gr.file_descriptor_sink(gr.sizeof_short, 1)
+
+        self.connect(src0, c2s, stdout_sink)
+
+        
+if __name__ == '__main__':
+    try:
+        my_top_block().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/usrp2/host/apps/stdin_int32_fft.py b/usrp2/host/apps/stdin_int32_fft.py
new file mode 100755 (executable)
index 0000000..1596fa0
--- /dev/null
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2008,2010 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 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
+import numpy
+
+
+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("-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("-W", "--waterfall", action="store_true", default=False,
+                          help="Enable waterfall display")
+        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.options = options
+        self.options.gain = 1.0
+        self.show_debug_info = True
+        
+
+        input_rate = 100e6 / options.decim
+
+        self.src = gr.file_descriptor_source(gr.sizeof_short, 0, False);
+        self.s2c = gr.interleaved_short_to_complex()
+
+        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, y_divs=12, sample_rate=input_rate,ref_level=110,fft_rate=20)
+
+        self.connect(self.src, self.s2c, self.scope)
+
+        self._build_gui(vbox)
+       self._setup_events()
+       
+        # set initial values
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            options.freq = 0.0
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.options.decim)
+
+
+    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)
+        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), 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.
+        """
+        
+        if True:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+           if not self.options.waterfall and not self.options.oscilloscope:
+               self.scope.set_baseband_freq(target_freq)
+           return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+
+    def set_decim(self, decim):
+        input_rate = 100e6 / self.options.decim
+        self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(self.u.decim_rate())
+        return ok
+
+    def _setup_events(self):
+       if not self.options.waterfall and not self.options.oscilloscope:
+           self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
+           
+    def evt_left_dclick(self, event):
+       (ux, uy) = self.scope.win.GetXY(event)
+       if event.CmdDown():
+           # Re-center on maximum power
+           points = self.scope.win._points
+           if self.scope.win.peak_hold:
+               if self.scope.win.peak_vals is not None:
+                   ind = numpy.argmax(self.scope.win.peak_vals)
+               else:
+                   ind = int(points.shape()[0]/2)
+           else:
+               ind = numpy.argmax(points[:,1])
+            (freq, pwr) = points[ind]
+           target_freq = freq/self.scope.win._scale_factor
+           print ind, freq, pwr
+            self.set_freq(target_freq)            
+       else:
+           # Re-center on clicked frequency
+           target_freq = ux/self.scope.win._scale_factor
+           self.set_freq(target_freq)
+           
+       
+def main ():
+    app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/usrp2/host/apps/streaming_fft.py b/usrp2/host/apps/streaming_fft.py
new file mode 100755 (executable)
index 0000000..4d34149
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import os
+import os.path
+import sys
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+def main():
+    parser = OptionParser(option_class=eng_option)
+    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=0.0,
+                      help="set frequency to FREQ", metavar="FREQ")
+    parser.add_option("-g", "--gain", type="string", default=None,
+                      help="set gain to GAIN [default=%default]")
+    parser.add_option("-W", "--waterfall", action="store_true", default=False,
+                      help="Enable waterfall display")
+    parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+                      help="Enable oscilloscope display")
+    parser.add_option("-F", "--samples-per-frame", type="int", default=250,
+                      help="[default=%default]")
+    parser.add_option("-e", "--eth", default="eth0",
+                      help="specify ethernet interface [default=%default]")
+
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+
+    path = os.path.dirname(sys.argv[0])
+    if path == '':
+        path = '.'
+    
+    
+    display_type = ''
+    if options.waterfall:
+        display_type = '-W'
+    if options.oscilloscope:
+        display_type = '-S'
+
+    gain_clause = ''
+    if options.gain:
+        gain_clause = '-g ' + options.gain
+
+    # FIXME: restore -F
+    cmd = "%s/rx_streaming_samples -s -e %s -f %g -d %d %s -o /proc/self/fd/1 | %s/stdin_int32_fft.py %s -f %g -d %d" % (
+        path, options.eth, options.freq, options.decim, gain_clause,
+        path, display_type, options.freq, options.decim)
+
+    print cmd
+    os.system(cmd)
+    
+
+if __name__ == '__main__':
+    main()
diff --git a/usrp2/host/apps/test.sh b/usrp2/host/apps/test.sh
new file mode 100755 (executable)
index 0000000..c533c33
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sudo ./rx_streaming_samples -d 4 -v -N 100M
+
index 5c3728fb1518d2859dc1b56fc6bb089c5e33f9d1..3e41bbf8d0ad454627f225ecd83fb39f4b8c3e19 100644 (file)
@@ -150,6 +150,10 @@ main(int argc, char **argv)
       interp = strtol(optarg, 0, 0);
       break;
 
+    case 'g':
+      gain = strtod(optarg, 0);
+      break;
+
     case 'S':
       if (!strtod_si(optarg, &tmp)){
        std::cerr << "invalid number: " << optarg << std::endl;
diff --git a/usrp2/host/include/.gitignore b/usrp2/host/include/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/usrp2/host/include/usrp2/.gitignore b/usrp2/host/include/usrp2/.gitignore
new file mode 100644 (file)
index 0000000..b336cc7
--- /dev/null
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
index 7a612f945bba06380af6cccb9df9c8a7997dff4d..e29caa33db1bacb71132b415ac6b4ac235c96a15 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <boost/shared_ptr.hpp>
 #include <boost/utility.hpp>
+#include <boost/bind.hpp>
 #include <vector>
 #include <complex>
 #include <usrp2/rx_sample_handler.h>
@@ -60,7 +61,7 @@ namespace usrp2 {
    *
    * \returns a vector of properties, 1 entry for each matching USRP2 found.
    */
-  props_vector_t find(const std::string &ifc, const std::string &mac_addr=""); 
+  props_vector_t find(const std::string &ifc, const std::string &mac_addr="");
 
   class tune_result;
 
@@ -79,10 +80,10 @@ namespace usrp2 {
 
     /*!
      * Shared pointer to this class
-     */ 
+     */
     typedef boost::shared_ptr<usrp2> sptr;
-    /*! 
+
+    /*!
      * Static function to return an instance of usrp2 as a shared pointer
      *
      * \param ifc   Network interface name, e.g., "eth0"
@@ -96,7 +97,7 @@ namespace usrp2 {
     /*!
      * Class destructor
      */
-    ~usrp2();  
+    ~usrp2();
 
     /*!
      * Returns the MAC address associated with this USRP
@@ -114,16 +115,21 @@ namespace usrp2 {
      * ----------------------------------------------------------------
      */
 
+    /*!
+     * Set the rx antenna
+     */
+    bool set_rx_antenna(int ant);
+
     /*!
      * Set receiver gain
      * \param gain in dB (more or less)
      */
     bool set_rx_gain(double gain);
 
-    //! return minimum Rx gain 
+    //! return minimum Rx gain
     double rx_gain_min();
 
-    //! return maximum Rx gain 
+    //! return maximum Rx gain
     double rx_gain_max();
 
     //! return Rx gain db_per_step
@@ -160,7 +166,7 @@ namespace usrp2 {
 
     /*!
      * Set received sample format
-     *   
+     *
      *    domain: complex or real
      *      type: floating, fixed point, or raw
      *     depth: bits per sample
@@ -172,12 +178,33 @@ namespace usrp2 {
     /*!
      * Start streaming receive mode.  USRP2 will send a continuous stream of
      * DSP pipeline samples to host.  Call rx_samples(...) to access.
-     * 
+     *
      * \param channel          Stream channel number (0-30)
      * \param items_per_frame  Number of 32-bit items per frame.
      */
     bool start_rx_streaming(unsigned int channel=0, unsigned int items_per_frame=0);
-  
+
+    /*!
+     * Start streaming receive mode at specified timestamp. USRP2 will send a
+     * continuous stream of DSP pipeline samples to host. Call rx_samples(...)
+     * to access.
+     *
+     * \param channel          Stream channel number (0-30)
+     * \param items_per_frame  Number of 32-bit items per frame.
+     * \param time             Timestamp to start streaming at
+     */
+    bool start_rx_streaming_at(unsigned int channel=0, unsigned int items_per_frame=0, unsigned int time=0);
+
+    /*!
+     * Sync to PPS and start streaming receive mode at specified timestamp.
+     * Just like calling sync_to_pps() and start_rx_streaming_at().
+     *
+     * \param channel          Stream channel number (0-30)
+     * \param items_per_frame  Number of 32-bit items per frame.
+     * \param time             Timestamp to start streaming at
+     */
+    bool sync_and_start_rx_streaming_at(unsigned int channel=0, unsigned int items_per_frame=0, uint32_t time=0);
+
     /*!
      * Stop streaming receive mode.
      */
@@ -193,7 +220,7 @@ namespace usrp2 {
      * Returns number of times receive overruns have occurred
      */
     unsigned int rx_overruns();
-    
+
     /*!
      * Returns total number of missing frames from overruns.
      */
@@ -205,15 +232,20 @@ namespace usrp2 {
      * ----------------------------------------------------------------
      */
 
+    /*!
+     * Set the tx antenna
+     */
+    bool set_tx_antenna(int ant);
+
     /*!
      * Set transmitter gain
      */
     bool set_tx_gain(double gain);
 
-    //! return minimum Tx gain 
+    //! return minimum Tx gain
     double tx_gain_min();
 
-    //! return maximum Tx gain 
+    //! return maximum Tx gain
     double tx_gain_max();
 
     //! return Tx gain db_per_step
@@ -255,7 +287,7 @@ namespace usrp2 {
 
     /*!
      * Set transmit sample format
-     *   
+     *
      *    domain: complex or real
      *      type: floating, fixed point, or raw
      *     depth: bits per sample
@@ -272,7 +304,7 @@ namespace usrp2 {
      * \param nsamples is the number of samples to transmit
      * \param metadata provides the timestamp and flags
      *
-     * The complex<float> samples are converted to the appropriate 
+     * The complex<float> samples are converted to the appropriate
      * "on the wire" representation, depending on the current USRP2
      * configuration.  Typically, this is big-endian 16-bit I & Q.
      */
@@ -400,12 +432,12 @@ namespace usrp2 {
      *
      * \param addr      32-bit aligned address.  Only the lower 16-bits are significant.
      * \param words     Number of 32-bit words
-     * 
+     *
      * \returns         Vector of 32-bit read values
      *
      * WARNING: Attempts to read memory from addresses that do not correspond to RAM or
      * memory-mapped peripherals may cause the USRP2 to hang, requiring a power cycle.
-     * 
+     *
      */
     std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
 
@@ -419,7 +451,7 @@ namespace usrp2 {
      *
      * WARNING: Attempts to read memory from addresses that do not correspond to RAM or
      * memory-mapped peripherals may cause the USRP2 to hang, requiring a power cycle.
-     * 
+     *
      */
     bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
 
@@ -587,7 +619,7 @@ namespace usrp2 {
 
     // Only class members can instantiate this class
     usrp2(const std::string &ifc, props *p, size_t rx_bufsize);
-  
+
     // All private state is held in opaque pointer
     std::auto_ptr<impl> d_impl;
   };
diff --git a/usrp2/host/lib/.gitignore b/usrp2/host/lib/.gitignore
new file mode 100644 (file)
index 0000000..8f5500b
--- /dev/null
@@ -0,0 +1,5 @@
+/.libs
+/.deps
+/Makefile
+/Makefile.in
+/usrp2_socket_opener
index 772cf1446d80739753f99ebceaa7bf2b2f6a5bff..209cb70953d88886b2aa1759c88cde1f443c8cbd 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2007,2008 Free Software Foundation, Inc.
+# Copyright 2007,2008,2010 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@ usrp2_socket_opener_SOURCES = usrp2_socket_opener.cc
 lib_LTLIBRARIES = \
        libusrp2.la
 
+libusrp2_la_LDFLAGS = $(LTVERSIONFLAGS)
+
 libusrp2_la_SOURCES = \
        control.cc \
        copiers.cc \
@@ -45,11 +47,9 @@ libusrp2_la_SOURCES = \
        rx_sample_handler.cc \
        strtod_si.c \
        usrp2.cc \
-       usrp2_impl.cc \
-       usrp2_thread.cc
+       usrp2_impl.cc
 
 libusrp2_la_LIBADD = \
-       $(OMNITHREAD_LA) \
        $(GRUEL_LA) \
        $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB)
 
@@ -63,5 +63,4 @@ noinst_HEADERS = \
        pktfilter.h \
        ring.h \
        usrp2_bytesex.h \
-       usrp2_impl.h \
-       usrp2_thread.h
+       usrp2_impl.h
\ No newline at end of file
index 4b8597c6003a15983d0c12fe3e28e18e68978ca5..33a95c078722a8893e3ce9c5854a7d90a18fd6a2 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <config.h>
 #endif
 
-#include <gnuradio/omni_time.h>
 #include "control.h"
 #include <iostream>
+#include <gruel/thread.h>
 
 namespace usrp2 {
 
   pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len)
-    : d_rid(rid), d_mutex(), d_cond(&d_mutex), d_buffer(buffer), d_len(len)
+    : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(),
+      d_complete(false)
   {
   }
 
   pending_reply::~pending_reply()
   {
-    signal(); // Needed?
+    notify_completion(); // Needed?
   }
 
   int
-  pending_reply::wait(double secs)
+  pending_reply::wait_for_completion(double secs)
   {
-    omni_mutex_lock l(d_mutex);
-    omni_time abs_timeout = omni_time::time(omni_time(secs));
-    return d_cond.timedwait(abs_timeout.d_secs, abs_timeout.d_nsecs);
+    gruel::scoped_lock l(d_mutex);
+    boost::system_time to(gruel::get_new_timeout(secs));
+
+    while (!d_complete) {
+      if (!d_cond.timed_wait(l, to))
+       return 0; // timed out
+    }
+
+    return 1;
   }
 
   void
-  pending_reply::signal()
+  pending_reply::notify_completion()
   {
-    d_cond.signal();
+    gruel::scoped_lock l(d_mutex);
+    d_complete = true;
+    d_cond.notify_one();
   }
   
 } // namespace usrp2
index 9adc1618f8ce251b270374c4cde9ec5a5cf3cd1c..3515ba10fe6dc8de3c904dedc9de025d3a63d731 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 #ifndef INCLUDED_CONTROL_H
 #define INCLUDED_CONTROL_H
 
-#include <gnuradio/omnithread.h>
+#include <gruel/thread.h>
 #include <usrp2_eth_packet.h>
 
 namespace usrp2 {
@@ -33,27 +33,35 @@ namespace usrp2 {
   /*!
    * OP_CONFIG_RX_V2 command packet
    */
-  struct op_config_rx_v2_cmd 
+  struct op_config_rx_v2_cmd
   {
     u2_eth_packet_t   h;
     op_config_rx_v2_t op;
     op_generic_t      eop;
   };
 
-  struct op_start_rx_streaming_cmd 
+  struct op_start_rx_streaming_cmd
   {
     u2_eth_packet_t        h;
     op_start_rx_streaming_t op;
     op_generic_t           eop;
   };
-    
+
+  struct op_sync_and_start_rx_streaming_cmd
+  {
+    u2_eth_packet_t        h;
+    op_generic_t            sync_op;
+    op_start_rx_streaming_t rx_op;
+    op_generic_t           eop;
+  };
+
   struct op_stop_rx_cmd {
     u2_eth_packet_t h;
     op_generic_t    op;
     op_generic_t    eop;
   };
 
-  struct op_config_tx_v2_cmd 
+  struct op_config_tx_v2_cmd
   {
     u2_eth_packet_t   h;
     op_config_tx_v2_t op;
@@ -67,7 +75,7 @@ namespace usrp2 {
     op_generic_t      eop;
   };
 
-  struct op_burn_mac_addr_cmd 
+  struct op_burn_mac_addr_cmd
   {
     u2_eth_packet_t    h;
     op_burn_mac_addr_t op;
@@ -113,17 +121,20 @@ namespace usrp2 {
 
   /*!
    * Control mechanism to allow API calls to block waiting for reply packets
-   */    
+   */
   class pending_reply
   {
   private:
     unsigned int    d_rid;
-    omni_mutex      d_mutex;
-    omni_condition  d_cond;
     void           *d_buffer;
     size_t         d_len;
 
-  public:  
+    // d_mutex is used with d_cond and also protects d_complete
+    gruel::mutex      d_mutex;
+    gruel::condition_variable d_cond;
+    bool           d_complete;
+
+  public:
     /*!
      * Construct a pending reply from the reply ID, response packet
      * buffer, and buffer length.
@@ -140,12 +151,12 @@ namespace usrp2 {
      * Returns: 1 = ok, reply packet in buffer
      *          0 = timeout
      */
-    int wait(double secs);
+    int wait_for_completion(double secs);
 
     /*!
      * Allows creating thread to resume after copying reply into buffer
      */
-    void signal();
+    void notify_completion();
 
     /*!
      * Retrieve pending reply ID
@@ -162,7 +173,7 @@ namespace usrp2 {
      */
     size_t len() const { return d_len; }
   };
-  
+
 } // namespace usrp2
 
 #endif /* INCLUDED_CONTROL_H */
index 3c45821f84136373cb84261bab28fd07a51f19ff..d0048418cfe61eba72d833bd2a2dbc01badba72b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -29,7 +29,7 @@ namespace usrp2 {
 
   ring::ring(unsigned int entries)
     : d_max(entries), d_read_ind(0), d_write_ind(0), d_ring(entries),
-      d_mutex(), d_not_empty(&d_mutex)
+      d_mutex(), d_not_empty()
   {
     for (unsigned int i = 0; i < entries; i++) {
       d_ring[i].d_base = 0;
@@ -40,15 +40,15 @@ namespace usrp2 {
   void 
   ring::wait_for_not_empty() 
   { 
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     while (empty()) 
-      d_not_empty.wait();
+      d_not_empty.wait(l);
   }
 
   bool
   ring::enqueue(void *p, size_t len)
   {
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     if (full())
       return false;
       
@@ -56,14 +56,14 @@ namespace usrp2 {
     d_ring[d_write_ind].d_base = p;
 
     inc_write_ind();
-    d_not_empty.signal();
+    d_not_empty.notify_one();
     return true;
   }
 
   bool
   ring::dequeue(void **p, size_t *len)
   {
-    omni_mutex_lock l(d_mutex);
+    gruel::scoped_lock l(d_mutex);
     if (empty())
       return false;
       
index 19ae9ae97221ff756e9f9bdc68a718631559c772..fd0ad0a9f3098e9e929feafd253df17ca99ee7eb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2010 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #ifndef INCLUDED_RING_H
 #define INCLUDED_RING_H
 
-#include <gnuradio/omnithread.h>
 #include <stddef.h>
 #include <vector>
 #include <boost/shared_ptr.hpp>
+#include <gruel/thread.h>
 
 namespace usrp2 {
 
@@ -46,8 +46,8 @@ namespace usrp2 {
     };
     std::vector<ring_desc> d_ring;
 
-    omni_mutex d_mutex;
-    omni_condition d_not_empty;
+    gruel::mutex d_mutex;
+    gruel::condition_variable d_not_empty;
 
     void inc_read_ind()
     {
index a2a9ecc1158a5b5a2483bca6ae111c38109506b4..f0ee564be002e6702c34019b3e030c8a305da442 100644 (file)
@@ -62,7 +62,7 @@ namespace usrp2 {
       else {
        if (key == p->key)      // found it
          return usrp2::sptr(p->value);
-       else                    
+       else
          ++p;                  // keep looking
       }
     }
@@ -90,15 +90,15 @@ namespace usrp2 {
     p.addr[3] = 0x85;
     p.addr[4] = 0x30;
     p.addr[5] = 0x00;
-    
+
     int len = s.size();
     switch (len) {
-      
+
     case 5:
       if (sscanf(s.c_str(), "%hhx:%hhx", &p.addr[4], &p.addr[5]) != 2)
        return false;
       break;
-      
+
     case 17:
       if (sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
                 &p.addr[0], &p.addr[1], &p.addr[2],
@@ -109,7 +109,7 @@ namespace usrp2 {
     default:
       return false;
     }
-    
+
     char buf[128];
     snprintf(buf, sizeof(buf),
             "%02x:%02x:%02x:%02x:%02x:%02x",
@@ -148,13 +148,13 @@ namespace usrp2 {
   {
     // NOP
   }
-  
+
   // Public class destructor.  d_impl will auto-delete.
   usrp2::~usrp2()
   {
     // NOP
   }
-  
+
   std::string
   usrp2::mac_addr()
   {
@@ -169,12 +169,17 @@ namespace usrp2 {
 
   // Receive
 
-  bool 
+  bool
+  usrp2::set_rx_antenna(int ant){
+    return d_impl->set_rx_antenna(ant);
+  }
+
+  bool
   usrp2::set_rx_gain(double gain)
   {
     return d_impl->set_rx_gain(gain);
   }
-  
+
   double
   usrp2::rx_gain_min()
   {
@@ -204,7 +209,7 @@ namespace usrp2 {
   {
     return d_impl->set_rx_center_freq(frequency, result);
   }
-  
+
   double
   usrp2::rx_freq_min()
   {
@@ -222,7 +227,7 @@ namespace usrp2 {
   {
     return d_impl->set_rx_decim(decimation_factor);
   }
-  
+
   int
   usrp2::rx_decim()
   {
@@ -234,13 +239,25 @@ namespace usrp2 {
   {
     return d_impl->set_rx_scale_iq(scale_i, scale_q);
   }
-  
+
   bool
   usrp2::start_rx_streaming(unsigned int channel, unsigned int items_per_frame)
   {
     return d_impl->start_rx_streaming(channel, items_per_frame);
   }
-  
+
+  bool
+  usrp2::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
+  {
+    return d_impl->start_rx_streaming_at(channel, items_per_frame,time);
+  }
+
+  bool
+  usrp2::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
+  {
+    return d_impl->sync_and_start_rx_streaming_at(channel, items_per_frame, time);
+  }
+
   bool
   usrp2::rx_samples(unsigned int channel, rx_sample_handler *handler)
   {
@@ -258,7 +275,7 @@ namespace usrp2 {
   {
     return d_impl->rx_overruns();
   }
-  
+
   unsigned int
   usrp2::rx_missing()
   {
@@ -267,12 +284,17 @@ namespace usrp2 {
 
   // Transmit
 
-  bool 
+  bool
+  usrp2::set_tx_antenna(int ant){
+    return d_impl->set_tx_antenna(ant);
+  }
+
+  bool
   usrp2::set_tx_gain(double gain)
   {
     return d_impl->set_tx_gain(gain);
   }
-  
+
   double
   usrp2::tx_gain_min()
   {
@@ -302,7 +324,7 @@ namespace usrp2 {
   {
     return d_impl->set_tx_center_freq(frequency, result);
   }
-  
+
   double
   usrp2::tx_freq_min()
   {
@@ -321,7 +343,7 @@ namespace usrp2 {
   {
     return d_impl->set_tx_interp(interpolation_factor);
   }
-  
+
   int
   usrp2::tx_interp()
   {
@@ -339,7 +361,7 @@ namespace usrp2 {
   {
     return d_impl->set_tx_scale_iq(scale_i, scale_q);
   }
-  
+
   bool
   usrp2::tx_32fc(unsigned int channel,
                 const std::complex<float> *samples,
@@ -404,7 +426,7 @@ namespace usrp2 {
   {
     return d_impl->rx_daughterboard_id(dbid);
   }
-  
+
 
   // low level methods
 
index 1ecfd7348e65a5bf79b521591b69f49ff8e725fc..333e2d1e78b0aff85e1256f219093a45a09d2e83 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <usrp2/tune_result.h>
 #include <usrp2/copiers.h>
 #include <gruel/inet.h>
+#include <gruel/realtime.h>
+#include <boost/bind.hpp>
 #include <usrp2_types.h>
 #include "usrp2_impl.h"
-#include "usrp2_thread.h"
 #include "eth_buffer.h"
 #include "pktfilter.h"
 #include "control.h"
@@ -106,7 +107,7 @@ namespace usrp2 {
     //assert((((uintptr_t) p) % 4) == 0);              // must be 4-byte aligned
 
     u2_fixed_hdr_t *fh = static_cast<u2_fixed_hdr_t *>(p);
-    
+
     // FIXME unaligned loads!
     md->word0 = u2p_word0(fh);
     md->timestamp = u2p_timestamp(fh);
@@ -129,15 +130,15 @@ namespace usrp2 {
 
 
   usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize)
-    : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0), d_bg_thread(0),
+    : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0),
       d_bg_running(false), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0),
-      d_num_rx_frames(0), d_num_rx_missing(0), d_num_rx_overruns(0), d_num_rx_bytes(0), 
-      d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(&d_enqueued_mutex),
-      d_channel_rings(NCHANS), d_tx_interp(0), d_rx_decim(0)
+      d_num_rx_frames(0), d_num_rx_missing(0), d_num_rx_overruns(0), d_num_rx_bytes(0),
+      d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(),
+      d_channel_rings(NCHANS), d_tx_interp(0), d_rx_decim(0), d_dont_enqueue(true)
   {
     if (!d_eth_buf->open(ifc, htons(U2_ETHERTYPE)))
       throw std::runtime_error("Unable to register USRP2 protocol");
-    
+
     d_addr = p->addr;
 
     // Create a packet filter for U2_ETHERTYPE packets sourced from target USRP2
@@ -146,14 +147,14 @@ namespace usrp2 {
     d_pf = pktfilter::make_ethertype_inbound_target(U2_ETHERTYPE, (const unsigned char*)&(usrp_mac.addr));
     if (!d_pf || !d_eth_buf->attach_pktfilter(d_pf))
       throw std::runtime_error("Unable to attach packet filter.");
-    
+
     if (USRP2_IMPL_DEBUG)
       std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl;
 
     memset(d_pending_replies, 0, sizeof(d_pending_replies));
 
-    d_bg_thread = new usrp2_thread(this);
-    d_bg_thread->start();
+    // Kick off receive thread
+    start_bg();
 
     // In case the USRP2 was left streaming RX
     // FIXME: only one channel right now
@@ -199,30 +200,29 @@ namespace usrp2 {
 
     if (!set_rx_decim(12))
       std::cerr << "usrp2::ctor set_rx_decim failed\n";
-      
+
     // set workable defaults for scaling
     if (!set_rx_scale_iq(DEFAULT_RX_SCALE, DEFAULT_RX_SCALE))
       std::cerr << "usrp2::ctor set_rx_scale_iq failed\n";
   }
-  
+
   usrp2::impl::~impl()
   {
     stop_bg();
-    d_bg_thread = 0; // thread class deletes itself
     delete d_pf;
     d_eth_buf->close();
     delete d_eth_buf;
-    
+
     if (USRP2_IMPL_DEBUG) {
       std::cerr << std::endl
-                << "usrp2 destructor: received " << d_num_rx_frames 
+                << "usrp2 destructor: received " << d_num_rx_frames
                << " frames, with " << d_num_rx_missing << " lost ("
                << (d_num_rx_frames == 0 ? 0 : (int)(100.0*d_num_rx_missing/d_num_rx_frames))
                << "%), totaling " << d_num_rx_bytes
                << " bytes" << std::endl;
     }
   }
-  
+
   bool
   usrp2::impl::parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
   {
@@ -232,14 +232,14 @@ namespace usrp2 {
     p->addr[3] = 0x85;
     p->addr[4] = 0x30;
     p->addr[5] = 0x00;
-    
+
     int len = s.size();
-    
+
     switch (len){
-      
+
     case 5:
       return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2;
-      
+
     case 17:
       return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
                    &p->addr[0], &p->addr[1], &p->addr[2],
@@ -248,36 +248,36 @@ namespace usrp2 {
       return false;
     }
   }
-  
+
   void
   usrp2::impl::init_et_hdrs(u2_eth_packet_t *p, const std::string &dst)
   {
     p->ehdr.ethertype = htons(U2_ETHERTYPE);
-    parse_mac_addr(dst, &p->ehdr.dst); 
+    parse_mac_addr(dst, &p->ehdr.dst);
     memcpy(&p->ehdr.src, d_eth_buf->mac(), 6);
     p->thdr.flags = 0; // FIXME transport header values?
     p->thdr.seqno = d_tx_seqno++;
     p->thdr.ack = 0;
   }
-  
-  void 
+
+  void
   usrp2::impl::init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
                             int word0_flags, int chan, uint32_t timestamp)
   {
     init_et_hdrs(p, dst);
     u2p_set_word0(&p->fixed, word0_flags, chan);
     u2p_set_timestamp(&p->fixed, timestamp);
-    
+
     if (chan == CONTROL_CHAN) { // no sequence numbers, back it out
       p->thdr.seqno = 0;
       d_tx_seqno--;
     }
   }
-  
+
   void
   usrp2::impl::init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd)
   {
-    memset(cmd, 0, sizeof(*cmd)); 
+    memset(cmd, 0, sizeof(*cmd));
     init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1);
     cmd->op.opcode = OP_CONFIG_RX_V2;
     cmd->op.len = sizeof(cmd->op);
@@ -289,7 +289,7 @@ namespace usrp2 {
   void
   usrp2::impl::init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd)
   {
-    memset(cmd, 0, sizeof(*cmd)); 
+    memset(cmd, 0, sizeof(*cmd));
     init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1);
     cmd->op.opcode = OP_CONFIG_TX_V2;
     cmd->op.len = sizeof(cmd->op);
@@ -298,22 +298,35 @@ namespace usrp2 {
     cmd->eop.len = sizeof(cmd->eop);
   }
 
+
+  bool
+  usrp2::impl::transmit_cmd(void *cmd_, size_t len_)
+  {
+    const void *cmd = cmd_;
+    int len = len_;
+    unsigned char tmp[64];
+
+    if (len_ < 64){            // pad to minimum ethernet frame size
+      memset(tmp, 0, sizeof(tmp));
+      memcpy(tmp, cmd_, len_);
+      cmd = tmp;
+      len = sizeof(tmp);
+    }
+
+    return d_eth_buf->tx_frame(cmd, len) == eth_buffer::EB_OK;
+  }
+
   bool
-  usrp2::impl::transmit_cmd(void *cmd, size_t len, pending_reply *p, double secs)
+  usrp2::impl::transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs)
   {
-    if (p)    
-      d_pending_replies[p->rid()] = p;
-    
-    // Transmit command
-    if (d_eth_buf->tx_frame(cmd, len) != eth_buffer::EB_OK) {
+    d_pending_replies[p->rid()] = p;
+
+    if (!transmit_cmd(cmd, len)){
       d_pending_replies[p->rid()] = 0;
       return false;
     }
 
-    int res = 1;
-    if (p)
-      res = p->wait(secs);
-      
+    int res = p->wait_for_completion(secs);
     d_pending_replies[p->rid()] = 0;
     return res == 1;
   }
@@ -322,19 +335,25 @@ namespace usrp2 {
   //        Background loop: received packet demuxing
   // ----------------------------------------------------------------
 
+  void
+  usrp2::impl::start_bg()
+  {
+    d_rx_tg.create_thread(boost::bind(&usrp2::impl::bg_loop, this));
+  }
+
   void
   usrp2::impl::stop_bg()
   {
     d_bg_running = false;
-    d_bg_pending_cond.signal();
-    
-    void *dummy_status;
-    d_bg_thread->join(&dummy_status);  
+    d_bg_pending_cond.notify_one(); // FIXME: check if needed
+    d_rx_tg.join_all();
   }
-  
+
   void
   usrp2::impl::bg_loop()
   {
+    gruel::enable_realtime_scheduling();
+
     d_bg_running = true;
     while(d_bg_running) {
       DEBUG_LOG(":");
@@ -343,20 +362,20 @@ namespace usrp2 {
       // rings, and signal blocked API threads
       int res = d_eth_buf->rx_frames(this, 100); // FIXME magic timeout
       if (res == eth_buffer::EB_ERROR)
-       break;  
+       break;
 
       // Wait for user API thread(s) to process all enqueued packets.
-      // The channel ring thread that decrements d_num_enqueued to zero 
+      // The channel ring thread that decrements d_num_enqueued to zero
       // will signal this thread to continue.
       {
-        omni_mutex_lock l(d_enqueued_mutex);
+        gruel::scoped_lock l(d_enqueued_mutex);
         while(d_num_enqueued > 0 && d_bg_running)
-         d_bg_pending_cond.wait();
+         d_bg_pending_cond.wait(l);
       }
     }
     d_bg_running = false;
   }
-  
+
   //
   // passed to eth_buffer::rx_frames
   //
@@ -373,6 +392,10 @@ namespace usrp2 {
       return handle_control_packet(base, len);
     }
     else {                             // data packets
+
+      if (d_dont_enqueue)              // toss packet
+       return data_handler::RELEASE;
+
       return handle_data_packet(base, len);
     }
 
@@ -384,11 +407,11 @@ namespace usrp2 {
   {
     // point to beginning of payload (subpackets)
     unsigned char *p = (unsigned char *)base + sizeof(u2_eth_packet_t);
-    
+
     // FIXME (p % 4) == 2.  Not good.  Must watch for unaligned loads.
 
     // FIXME iterate over payload, handling more than a single subpacket.
-    
+
     int opcode = p[0];
     unsigned int oplen = p[1];
     unsigned int rid = p[2];
@@ -400,11 +423,11 @@ namespace usrp2 {
        std::cerr << "usrp2: mismatched command reply length (expected: "
                  << buflen << " got: " << oplen << "). "
                  << "op = " << opcode_to_string(opcode) << std::endl;
-      }     
-    
+      }
+
       // Copy reply into caller's buffer
       memcpy(rp->buffer(), p, std::min(oplen, buflen));
-      rp->signal();
+      rp->notify_completion();
       d_pending_replies[rid] = 0;
       return data_handler::RELEASE;
     }
@@ -413,26 +436,26 @@ namespace usrp2 {
     DEBUG_LOG("l");
     return data_handler::RELEASE;
   }
-  
+
   data_handler::result
   usrp2::impl::handle_data_packet(const void *base, size_t len)
   {
     u2_eth_samples_t *pkt = (u2_eth_samples_t *)base;
     d_num_rx_frames++;
     d_num_rx_bytes += len;
-    
+
     /* --- FIXME start of fake transport layer handler --- */
 
     if (d_rx_seqno != -1) {
       int expected_seqno = (d_rx_seqno + 1) & 0xFF;
-      int seqno = pkt->hdrs.thdr.seqno; 
-      
+      int seqno = pkt->hdrs.thdr.seqno;
+
       if (seqno != expected_seqno) {
        ::write(2, "S", 1); // missing sequence number
        int missing = seqno - expected_seqno;
        if (missing < 0)
          missing += 256;
-       
+
        d_num_rx_overruns++;
        d_num_rx_missing += missing;
       }
@@ -446,15 +469,15 @@ namespace usrp2 {
     unsigned int chan = u2p_chan(&pkt->hdrs.fixed);
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
 
       if (!d_channel_rings[chan]) {
        DEBUG_LOG("!");
        return data_handler::RELEASE;   // discard packet, no channel handler
       }
-      
+
       // Strip off ethernet header and transport header and enqueue the rest
-      
+
       size_t offset = offsetof(u2_eth_samples_t, hdrs.fixed);
       if (d_channel_rings[chan]->enqueue(&pkt->hdrs.fixed, len-offset)) {
        inc_enqueued();
@@ -464,7 +487,7 @@ namespace usrp2 {
       else {
        DEBUG_LOG("!");
        return data_handler::RELEASE;   // discard, no room in channel ring
-      }        
+      }
       return data_handler::RELEASE;
     }
   }
@@ -474,7 +497,28 @@ namespace usrp2 {
   //                          Receive
   // ----------------------------------------------------------------
 
-  bool 
+  bool
+  usrp2::impl::set_rx_antenna(int ant){
+    op_config_mimo_cmd cmd;
+    op_generic_t reply;
+
+    memset(&cmd, 0, sizeof(cmd));
+    init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+    cmd.op.opcode = OP_RX_ANTENNA;
+    cmd.op.len = sizeof(cmd.op);
+    cmd.op.rid = d_next_rid++;
+    cmd.op.flags = ant;
+    cmd.eop.opcode = OP_EOP;
+    cmd.eop.len = sizeof(cmd.eop);
+
+    pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+      return false;
+
+    return ntohx(reply.ok) == 1;
+  }
+
+  bool
   usrp2::impl::set_rx_gain(double gain)
   {
     op_config_rx_v2_cmd cmd;
@@ -483,15 +527,15 @@ namespace usrp2 {
     init_config_rx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_GAIN);
     cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
     return success;
   }
-  
+
   bool
   usrp2::impl::set_rx_lo_offset(double frequency)
   {
@@ -510,9 +554,9 @@ namespace usrp2 {
 
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -530,26 +574,26 @@ namespace usrp2 {
     u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
     cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
     cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
     if (result && success) {
       result->baseband_freq =
-        u2_fxpt_freq_to_double( 
-         u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi), 
+        u2_fxpt_freq_to_double(
+         u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi),
                                 ntohl(reply.baseband_freq_lo)));
 
       result->dxc_freq =
-        u2_fxpt_freq_to_double( 
-         u2_fxpt_freq_from_hilo(ntohl(reply.ddc_freq_hi), 
+        u2_fxpt_freq_to_double(
+         u2_fxpt_freq_from_hilo(ntohl(reply.ddc_freq_hi),
                                 ntohl(reply.ddc_freq_lo)));
 
       result->residual_freq =
-        u2_fxpt_freq_to_double( 
-        u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi), 
+        u2_fxpt_freq_to_double(
+        u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi),
                                ntohl(reply.residual_freq_lo)));
 
       result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1);
@@ -557,7 +601,7 @@ namespace usrp2 {
 
     return success;
   }
-  
+
   bool
   usrp2::impl::set_rx_decim(int decimation_factor)
   {
@@ -567,9 +611,9 @@ namespace usrp2 {
     init_config_rx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_INTERP_DECIM);
     cmd.op.decim = htonl(decimation_factor);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -577,7 +621,7 @@ namespace usrp2 {
       d_rx_decim = decimation_factor;
     return success;
   }
-  
+
   bool
   usrp2::impl::set_rx_scale_iq(int scale_i, int scale_q)
   {
@@ -587,15 +631,15 @@ namespace usrp2 {
     init_config_rx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_SCALE_IQ);
     cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
     return success;
   }
-  
+
   bool
   usrp2::impl::start_rx_streaming(unsigned int channel, unsigned int items_per_frame)
   {
@@ -612,16 +656,16 @@ namespace usrp2 {
     }
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
       if (d_channel_rings[channel]) {
        std::cerr << "usrp2: channel " << channel
                  << " already streaming" << std::endl;
        return false;
       }
-      
+
       if (items_per_frame == 0)
        items_per_frame = U2_MAX_SAMPLES;               // minimize overhead
-      
+
       op_start_rx_streaming_cmd cmd;
       op_generic_t reply;
 
@@ -633,19 +677,133 @@ namespace usrp2 {
       cmd.op.items_per_frame = htonl(items_per_frame);
       cmd.eop.opcode = OP_EOP;
       cmd.eop.len = sizeof(cmd.eop);
-    
+
+      d_dont_enqueue = false;
       bool success = false;
       pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-      success = transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+      success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
       success = success && (ntohx(reply.ok) == 1);
-      
+
       if (success)
        d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
+      else
+       d_dont_enqueue = true;
 
+      //fprintf(stderr, "usrp2::start_rx_streaming: success = %d\n", success);
       return success;
     }
   }
-  
+
+  bool
+  usrp2::impl::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
+  {
+    if (channel > MAX_CHAN) {
+      std::cerr << "usrp2: invalid channel number (" << channel
+               << ")" << std::endl;
+      return false;
+    }
+
+    if (channel > 0) { // until firmware supports multiple streams
+      std::cerr << "usrp2: channel " << channel
+               << " not implemented" << std::endl;
+      return false;
+    }
+
+    {
+      gruel::scoped_lock guard(d_channel_rings_mutex);
+      if (d_channel_rings[channel]) {
+       std::cerr << "usrp2: channel " << channel
+                 << " already streaming" << std::endl;
+       return false;
+      }
+
+      if (items_per_frame == 0)
+       items_per_frame = U2_MAX_SAMPLES;               // minimize overhead
+
+      op_start_rx_streaming_cmd cmd;
+      op_generic_t reply;
+
+      memset(&cmd, 0, sizeof(cmd));
+      init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time);
+      cmd.op.opcode = OP_START_RX_STREAMING;
+      cmd.op.len = sizeof(cmd.op);
+      cmd.op.rid = d_next_rid++;
+      cmd.op.items_per_frame = htonl(items_per_frame);
+      cmd.eop.opcode = OP_EOP;
+      cmd.eop.len = sizeof(cmd.eop);
+
+      d_dont_enqueue = false;
+      bool success = false;
+      pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+      success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+      success = success && (ntohx(reply.ok) == 1);
+
+      if (success)
+       d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
+      else
+       d_dont_enqueue = true;
+
+      return success;
+    }
+  }
+
+  bool
+  usrp2::impl::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
+  {
+
+    if (channel > MAX_CHAN) {
+      std::cerr << "usrp2: invalid channel number (" << channel
+               << ")" << std::endl;
+      return false;
+    }
+
+    if (channel > 0) { // until firmware supports multiple streams
+      std::cerr << "usrp2: channel " << channel
+               << " not implemented" << std::endl;
+      return false;
+    }
+
+    {
+      gruel::scoped_lock guard(d_channel_rings_mutex);
+      if (d_channel_rings[channel]) {
+       std::cerr << "usrp2: channel " << channel
+                 << " already streaming" << std::endl;
+       return false;
+      }
+
+      if (items_per_frame == 0)
+       items_per_frame = U2_MAX_SAMPLES;               // minimize overhead
+
+      op_sync_and_start_rx_streaming_cmd cmd;
+      op_generic_t reply;
+
+      memset(&cmd, 0, sizeof(cmd));
+      init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time);
+      cmd.sync_op.opcode = OP_SYNC_TO_PPS;
+      cmd.sync_op.len = sizeof(cmd.sync_op);
+      cmd.sync_op.rid = d_next_rid++;
+      cmd.rx_op.opcode = OP_START_RX_STREAMING;
+      cmd.rx_op.len = sizeof(cmd.rx_op);
+      cmd.rx_op.rid = d_next_rid++;
+      cmd.rx_op.items_per_frame = htonl(items_per_frame);
+      cmd.eop.opcode = OP_EOP;
+      cmd.eop.len = sizeof(cmd.eop);
+
+      d_dont_enqueue = false;
+      bool success = false;
+      pending_reply p(cmd.sync_op.rid, &reply, sizeof(reply));
+      success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+      success = success && (ntohx(reply.ok) == 1);
+
+      if (success)
+       d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
+      else
+       d_dont_enqueue = true;
+
+      return success;
+    }
+  }
+
   bool
   usrp2::impl::stop_rx_streaming(unsigned int channel)
   {
@@ -661,11 +819,14 @@ namespace usrp2 {
       return false;
     }
 
+    d_dont_enqueue = true;     // no new samples
+    flush_rx_samples(channel); // dump any we may already have
+
     op_stop_rx_cmd cmd;
     op_generic_t reply;
 
     {
-      omni_mutex_lock l(d_channel_rings_mutex);
+      gruel::scoped_lock l(d_channel_rings_mutex);
 
       memset(&cmd, 0, sizeof(cmd));
       init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
@@ -674,12 +835,14 @@ namespace usrp2 {
       cmd.op.rid = d_next_rid++;
       cmd.eop.opcode = OP_EOP;
       cmd.eop.len = sizeof(cmd.eop);
-    
+
       bool success = false;
       pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-      success = transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
+      success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
       success = success && (ntohx(reply.ok) == 1);
       d_channel_rings[channel].reset();
+      d_rx_seqno = -1;
+      //fprintf(stderr, "usrp2::stop_rx_streaming:  success = %d\n", success);
       return success;
     }
   }
@@ -692,25 +855,25 @@ namespace usrp2 {
                 << " )" << std::endl;
       return false;
     }
-    
+
     if (channel > 0) {
       std::cerr << "usrp2: channel " << channel
                 << " not implemented" << std::endl;
       return false;
     }
-    
+
     ring_sptr rp = d_channel_rings[channel];
     if (!rp){
       std::cerr << "usrp2: channel " << channel
                 << " not receiving" << std::endl;
       return false;
     }
-    
+
     // Wait for frames available in channel ring
     DEBUG_LOG("W");
     rp->wait_for_not_empty();
     DEBUG_LOG("s");
-    
+
     // Iterate through frames and present to user
     void *p;
     size_t frame_len_in_bytes;
@@ -732,11 +895,62 @@ namespace usrp2 {
     return true;
   }
 
+  bool
+  usrp2::impl::flush_rx_samples(unsigned int channel)
+  {
+    if (channel > MAX_CHAN) {
+      std::cerr << "usrp2: invalid channel (" << channel
+                << " )" << std::endl;
+      return false;
+    }
+
+    if (channel > 0) {
+      std::cerr << "usrp2: channel " << channel
+                << " not implemented" << std::endl;
+      return false;
+    }
+
+    ring_sptr rp = d_channel_rings[channel];
+    if (!rp){
+      return false;
+    }
+
+    // Iterate through frames and drop them
+    void *p;
+    size_t frame_len_in_bytes;
+    while (rp->dequeue(&p, &frame_len_in_bytes)) {
+      d_eth_buf->release_frame(p);
+      dec_enqueued();
+    }
+    return true;
+  }
+
   // ----------------------------------------------------------------
   //                           Transmit
   // ----------------------------------------------------------------
 
-  bool 
+  bool
+  usrp2::impl::set_tx_antenna(int ant){
+    op_config_mimo_cmd cmd;
+    op_generic_t reply;
+
+    memset(&cmd, 0, sizeof(cmd));
+    init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+    cmd.op.opcode = OP_TX_ANTENNA;
+    cmd.op.len = sizeof(cmd.op);
+    cmd.op.rid = d_next_rid++;
+    cmd.op.flags = ant;
+    cmd.eop.opcode = OP_EOP;
+    cmd.eop.len = sizeof(cmd.eop);
+
+    pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+      return false;
+
+    return ntohx(reply.ok) == 1;
+  }
+
+  bool
   usrp2::impl::set_tx_gain(double gain)
   {
     op_config_tx_v2_cmd cmd;
@@ -745,15 +959,15 @@ namespace usrp2 {
     init_config_tx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_GAIN);
     cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
     return success;
   }
-  
+
   bool
   usrp2::impl::set_tx_lo_offset(double frequency)
   {
@@ -772,9 +986,9 @@ namespace usrp2 {
 
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -792,26 +1006,26 @@ namespace usrp2 {
     u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
     cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
     cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
     if (result && success) {
       result->baseband_freq =
-        u2_fxpt_freq_to_double( 
-         u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi), 
+        u2_fxpt_freq_to_double(
+         u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi),
                                 ntohl(reply.baseband_freq_lo)));
 
       result->dxc_freq =
-        u2_fxpt_freq_to_double( 
-         u2_fxpt_freq_from_hilo(ntohl(reply.duc_freq_hi), 
+        u2_fxpt_freq_to_double(
+         u2_fxpt_freq_from_hilo(ntohl(reply.duc_freq_hi),
                                 ntohl(reply.duc_freq_lo)));
 
       result->residual_freq =
-        u2_fxpt_freq_to_double( 
-        u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi), 
+        u2_fxpt_freq_to_double(
+        u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi),
                                ntohl(reply.residual_freq_lo)));
 
       result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1);
@@ -819,7 +1033,7 @@ namespace usrp2 {
 
     return success;
   }
-  
+
   bool
   usrp2::impl::set_tx_interp(int interpolation_factor)
   {
@@ -829,9 +1043,9 @@ namespace usrp2 {
     init_config_tx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_INTERP_DECIM);
     cmd.op.interp = htonl(interpolation_factor);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -846,7 +1060,7 @@ namespace usrp2 {
 
     return success;
   }
-  
+
   void
   usrp2::impl::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q)
   {
@@ -859,7 +1073,7 @@ namespace usrp2 {
 
     // Calculate dsp_core_tx gain absent scale multipliers
     float gain = (1.65*i*i*i)/(4096*pow(2, ceil(log2(i*i*i))));
-    
+
     // Calculate closest multiplier constant to reverse gain
     int scale = (int)rint(1.0/gain);
     // fprintf(stderr, "if=%i i=%i gain=%f scale=%i\n", interpolation_factor, i, gain, scale);
@@ -880,9 +1094,9 @@ namespace usrp2 {
     init_config_tx_v2_cmd(&cmd);
     cmd.op.valid = htons(CFGV_SCALE_IQ);
     cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1008,9 +1222,9 @@ namespace usrp2 {
     cmd.op.flags = flags;
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     return ntohx(reply.ok) == 1;
@@ -1069,7 +1283,7 @@ namespace usrp2 {
       return false;
 
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1082,10 +1296,10 @@ namespace usrp2 {
     dst->dbid = ntohl(src->dbid);
 
     dst->freq_min =
-      u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_min_hi), 
+      u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_min_hi),
                                                    ntohl(src->freq_min_lo)));
     dst->freq_max =
-      u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_max_hi), 
+      u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_max_hi),
                                                    ntohl(src->freq_max_lo)));
 
     dst->gain_min = u2_fxpt_gain_to_double(ntohs(src->gain_min));
@@ -1106,9 +1320,9 @@ namespace usrp2 {
     cmd.op.rid = d_next_rid++;
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1133,9 +1347,9 @@ namespace usrp2 {
     cmd.op.rid = d_next_rid++;
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     return ntohx(reply.ok) == 1;
@@ -1155,9 +1369,9 @@ namespace usrp2 {
     cmd.op.ok = enable ? 1 : 0;
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     return ntohx(reply.ok) == 1;
@@ -1170,7 +1384,7 @@ namespace usrp2 {
     // fprintf(stderr, "usrp2::peek: addr=%08X words=%u\n", addr, words);
 
     if (addr % 4 != 0) {
-      fprintf(stderr, "usrp2::peek: addr (=%08X) must be 32-bit word aligned\n", addr); 
+      fprintf(stderr, "usrp2::peek: addr (=%08X) must be 32-bit word aligned\n", addr);
       return result;
     }
 
@@ -1197,7 +1411,7 @@ namespace usrp2 {
 
     reply = (op_generic_t *)malloc(rlen+bytes);
     pending_reply p(cmd.op.rid, reply, rlen+bytes);
-    if (transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
+    if (transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
       uint32_t nwords = (reply->len-rlen)/sizeof(uint32_t);
       uint32_t *data = (uint32_t *)(reply+rlen/wlen);
       for (unsigned int i = 0; i < nwords; i++)
@@ -1212,7 +1426,7 @@ namespace usrp2 {
   usrp2::impl::poke32(uint32_t addr, const std::vector<uint32_t> &data)
   {
     if (addr % 4 != 0) {
-      fprintf(stderr, "usrp2::poke32: addr (=%08X) must be 32-bit word aligned\n", addr); 
+      fprintf(stderr, "usrp2::poke32: addr (=%08X) must be 32-bit word aligned\n", addr);
       return false;
     }
 
@@ -1264,7 +1478,7 @@ namespace usrp2 {
     bool ok = false;
     op_generic_t reply;
     pending_reply p(cmd->op.rid, &reply, sizeof(reply));
-    if (transmit_cmd(cmd, l, &p, DEF_CMD_TIMEOUT))
+    if (transmit_cmd_and_wait(cmd, l, &p, DEF_CMD_TIMEOUT))
       ok = (ntohx(reply.ok) == 1);
 
     free(cmd);
@@ -1284,9 +1498,9 @@ namespace usrp2 {
     cmd.op.rid = d_next_rid++;
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1313,9 +1527,9 @@ namespace usrp2 {
     cmd.op.mask = htons(mask);
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1346,9 +1560,9 @@ namespace usrp2 {
     memcpy(&cmd.op.sels, sels.c_str(), 16);
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1375,9 +1589,9 @@ namespace usrp2 {
     cmd.op.mask = htons(mask);
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1404,9 +1618,9 @@ namespace usrp2 {
     cmd.op.mask = 0;  // not used
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
@@ -1441,9 +1655,9 @@ namespace usrp2 {
     cmd.op.mask = 0;  // not used
     cmd.eop.opcode = OP_EOP;
     cmd.eop.len = sizeof(cmd.eop);
-    
+
     pending_reply p(cmd.op.rid, &reply, sizeof(reply));
-    if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+    if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
       return false;
 
     bool success = (ntohx(reply.ok) == 1);
index ec96f3a7095d8692c0c9c8ec4ff73d33072d227c..eee26358eaca556852b83f68e55cf9699719d0f7 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2010 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #include <usrp2/usrp2.h>
 #include <usrp2/data_handler.h>
 #include <usrp2_eth_packet.h>
+#include <gruel/thread.h>
 #include <boost/scoped_ptr.hpp>
 #include "control.h"
 #include "ring.h"
@@ -30,7 +31,7 @@
 #define MAX_SUBPKT_LEN 252
 
 namespace usrp2 {
-  
+
   class eth_buffer;
   class pktfilter;
   class usrp2_thread;
@@ -60,9 +61,10 @@ namespace usrp2 {
     std::string    d_interface_name;
     pktfilter     *d_pf;
     std::string    d_addr;       // FIXME: use u2_mac_addr_t instead
-    usrp2_thread  *d_bg_thread;
+
+    boost::thread_group d_rx_tg;
     volatile bool  d_bg_running; // TODO: multistate if needed
-    
+
     int            d_rx_seqno;
     int            d_tx_seqno;
     int            d_next_rid;
@@ -72,40 +74,44 @@ namespace usrp2 {
     unsigned int   d_num_rx_bytes;
 
     unsigned int   d_num_enqueued;
-    omni_mutex     d_enqueued_mutex;
-    omni_condition d_bg_pending_cond;
+    gruel::mutex   d_enqueued_mutex;
+    gruel::condition_variable d_bg_pending_cond;
 
     // all pending_replies are stack allocated, thus no possibility of leaking these
     pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id
 
     std::vector<ring_sptr>   d_channel_rings; // indexed by 5-bit channel number
-    omni_mutex     d_channel_rings_mutex;
+    gruel::mutex   d_channel_rings_mutex;
 
     db_info       d_tx_db_info;
     db_info       d_rx_db_info;
 
-    int                   d_tx_interp;         // shadow tx interp 
+    int                   d_tx_interp;         // shadow tx interp
     int                   d_rx_decim;          // shadow rx decim
 
+    bool          d_dont_enqueue;
+
     void inc_enqueued() {
-      omni_mutex_lock l(d_enqueued_mutex);
+      gruel::scoped_lock l(d_enqueued_mutex);
       d_num_enqueued++;
     }
-    
+
     void dec_enqueued() {
-      omni_mutex_lock l(d_enqueued_mutex);
+      gruel::scoped_lock l(d_enqueued_mutex);
       if (--d_num_enqueued == 0)
-        d_bg_pending_cond.signal();
+        d_bg_pending_cond.notify_one();
     }
-    
+
     static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
     void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
     void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
                       int word0_flags, int chan, uint32_t timestamp);
+    void start_bg();
     void stop_bg();
     void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
     void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
-    bool transmit_cmd(void *cmd, size_t len, pending_reply *p, double secs=0.0);
+    bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs=0.0);
+    bool transmit_cmd(void *cmd, size_t len);
     virtual data_handler::result operator()(const void *base, size_t len);
     data_handler::result handle_control_packet(const void *base, size_t len);
     data_handler::result handle_data_packet(const void *base, size_t len);
@@ -115,14 +121,13 @@ namespace usrp2 {
   public:
     impl(const std::string &ifc, props *p, size_t rx_bufsize);
     ~impl();
-    
-    void bg_loop();
 
     std::string mac_addr() const { return d_addr; } // FIXME: convert from u2_mac_addr_t
     std::string interface_name() const { return d_interface_name; }
 
     // Rx
 
+    bool set_rx_antenna(int ant);
     bool set_rx_gain(double gain);
     double rx_gain_min() { return d_rx_db_info.gain_min; }
     double rx_gain_max() { return d_rx_db_info.gain_max; }
@@ -140,13 +145,17 @@ namespace usrp2 {
     bool write_gpio(int bank, uint16_t value, uint16_t mask);
     bool read_gpio(int bank, uint16_t *value);
     bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame);
+    bool start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
+    bool sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
     bool rx_samples(unsigned int channel, rx_sample_handler *handler);
+    bool flush_rx_samples(unsigned int channel);
     bool stop_rx_streaming(unsigned int channel);
     unsigned int rx_overruns() const { return d_num_rx_overruns; }
     unsigned int rx_missing() const { return d_num_rx_missing; }
 
     // Tx
 
+    bool set_tx_antenna(int ant);
     bool set_tx_gain(double gain);
     double tx_gain_min() { return d_tx_db_info.gain_min; }
     double tx_gain_max() { return d_tx_db_info.gain_max; }
@@ -191,8 +200,11 @@ namespace usrp2 {
     bool sync_every_pps(bool enable);
     std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
     bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
+
+    // Receive thread, need to be public for boost::bind
+    void bg_loop();
   };
-  
+
 } // namespace usrp2
 
 #endif /* INCLUDED_USRP2_IMPL_H */
index eaef5f41d290dce72588ca00c5f32adc404334c3..0c862a87741259121e9af60eb2ac2153ac3cf125 100644 (file)
@@ -5,7 +5,7 @@ includedir=@includedir@
 
 Name: usrp2
 Description: Universal Software Radio Peripheral 2
-Requires: gnuradio-omnithread gruel
-Version: @VERSION@
+Requires: gruel
+Version: @LIBVER@
 Libs: -L${libdir} -lusrp2
 Cflags: -I${includedir} @DEFINES@
diff --git a/version.sh b/version.sh
new file mode 100644 (file)
index 0000000..01a47b5
--- /dev/null
@@ -0,0 +1,4 @@
+MAJOR_VERSION=3
+API_COMPAT=3
+MINOR_VERSION=0
+MAINT_VERSION=0